/* =====================================================================
   Prosyjob — component layer   (was main.css until E7-14)
   =====================================================================
   Per-module component CSS: the `.jo-`, `.co-`, `.cv-`, `.cand-`, `.mt-`,
   `.ap-`, `.connected-`, `.commercial-`, `.rf-`, `.cms-` … families that the
   pages actually mark up. Every prefix is one module's, so nothing here can
   collide with a vendor theme.

   It used to be called main.css and was described as "the legacy sheet, to be
   deleted at the end of E7". Measurement in E7-14 said otherwise: of its 7 938
   lines only 1 193 were genuinely dead (the pre-E7 login/guest layout, the old
   dashboard, the legacy `.card`/`.btn` gate). Those are gone. The remaining
   ~6 700 lines are live component CSS that the converted pages still use, so
   the file survives under a name that says what it is.

   POSITION IN THE CASCADE IS LOAD-BEARING, and it is *not* last:

       bootstrap → fontawesome → fonts → THIS FILE → [vendor theme] → prosyjob-app.css

   AssetStacks injects the active vendor theme immediately before the
   `#app-css-tail` marker, which sits on prosyjob-app.css. So a vendor rule of
   equal specificity beats a rule in this file — that is deliberate, it is what
   lets the Kofejob themes own `.card`, `.btn` and `.form-control` while these
   module prefixes own everything else. Contracts that must be unbeatable
   (`[hidden]`, the token scale, the dark theme) live in prosyjob-app.css.

   Dark mode: the `--color-*` / `--connected-*` tokens declared below are
   re-pointed at their `--pj-*` equivalents by the dark block in
   prosyjob-app.css, which is what makes ~6 700 lines follow the theme without
   a second pass. Raw hex written here does NOT follow it — use the tokens.

   Mobile-first: base rules target small phone screens, then min-width
   breakpoints layer on more room as the viewport grows (not the other way
   around), per the spec's "90% mobile, mobile 1st" directive.
   ===================================================================== */

:root {
  --color-bg: #f6f7f9;
  --color-surface: #ffffff;
  --color-text: #1c1f26;
  --color-muted: #6b7280;
  /* Was `var(--color-border)` from ef7463c (2026-09-10) to 2026-10-05: a
     custom property defined from itself is invalid, so every
     `border: 1px solid var(--color-border)` of this sheet — 71 of them —
     painted no border at all in the light theme. The dark theme redefines it
     (prosyjob-app.css), which is why nobody saw it there. */
  --color-border: #e2e5ea;
  /* A form control's outline, a step darker than a divider: on a white card
     #e2e5ea is a line you look for, and a field must be found at a glance.
     Mixed from the theme's own tokens, so it follows the dark theme with no
     second definition. */
  --color-field-border: color-mix(in srgb, var(--pj-muted) 45%, var(--pj-card));
  --color-primary: #1a73e8;
  --color-primary-dark: #1558b0;
  /* E8-02: was #1a8754 — 4,53:1 on white but only 4,03:1 on the pale green
     the success chips actually use (`.jo-badge--verified`, #e7f5ed). Judged
     against the surface it sits on, not against white. */
  --color-success: #17724a;
  --color-error: #d1373f;
  --color-warning: #b7791f;
  --radius: 10px;
  --spacing: 16px;

  /* E7-15. Surfaces and labels this sheet used to write as raw hex in a few
     dozen places. They carry theme-following text, so in dark the background
     has to move with it — which raw hex cannot do. Light values are the ones
     that were already there (#f8fbff, #eef2f8, #eef1f6, #405168 and their near
     neighbours, unified: the members of each family differ by two or three
     units out of 255). The dark values live in prosyjob-app.css with the rest
     of the remap. */
  --surface-sunken: #f8fbff;   /* recessed panel inside a card */
  --surface-chip: #eef2f8;     /* pale chip / small tag */
  --surface-track: #eef1f6;    /* progress and meter tracks */
  --chip-ink: #405168;         /* label on a neutral chip */

  /* The primary blue does two opposite jobs: it is text on a card (where dark
     mode has to LIFT it to stay readable) and it is a solid fill under a white
     label (where lifting costs contrast instead of buying it). E7-15 splits
     them: `--connected-primary` is the text one and follows the theme,
     `--primary-fill` is the surface one and deliberately does not. Same value
     in light, so nothing moves there. */
  --primary-fill: #264A78;
}

* {
  box-sizing: border-box;
}

/* The `hidden` guard moved to assets/css/prosyjob-app.css.
   It has to be in the LAST stylesheet loaded to be unbeatable, and since E7
   this sheet is no longer last — the vendor theme is injected after it. Do
   not restore a copy here; two sources for one contract is how it rots. */

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.45;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

img {
  max-width: 100%;
}

a {
  color: var(--color-primary);
}

h1,
h2,
h3 {
  line-height: 1.25;
  margin: 0 0 8px;
}

/* `.hidden` moved to assets/css/prosyjob-app.css alongside the [hidden]
   guard — same reason: it must live in the last sheet loaded. */

/* ── Layouts ─────────────────────────────────────────────────────────── */

.layout-guest {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  padding: 20px;
  background:
    radial-gradient(circle at top left, rgba(47, 124, 243, 0.10), transparent 30%),
    linear-gradient(135deg, var(--surface-sunken) 0%, var(--surface-sunken) 100%);
}

.layout-guest #content {
  flex: 1;
  display: flex;
  align-items: stretch;
  justify-content: center;
  padding: 0;
}

.layout-auth {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.layout-auth__body {
  flex: 1;
  padding: var(--spacing);
  padding-bottom: 80px;
}

/* ── Top bar (NavComponent) ─────────────────────────────────────────── */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px var(--spacing);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: 10;
}

/* ── Language switcher (LangSwitcherComponent) ──────────────────────── */

.lang-switcher {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 16px;
  padding: 10px 42px 10px 14px;
  min-height: 48px;
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%231c1f26' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 16px 16px;
  box-shadow: 0 8px 18px rgba(28, 31, 38, 0.05);
}

.lang-switcher:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* ── Sidebar / nav (rendered by SidebarComponent) ───────────────────── */

#myTopnav {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

#myTopnav .tab {
  display: block;
  padding: 14px var(--spacing);
  min-height: 44px;
  text-decoration: none;
  color: var(--color-text);
  border-bottom: 1px solid var(--color-border);
}

#myTopnav .tab.active {
  color: var(--color-primary);
  font-weight: 600;
}

#myTopnav img {
  display: none;
}

/* ── Cards / containers ──────────────────────────────────────────────── */

/* E7 legacy gate — see the note at the `button, .btn` rule below. */
.stack {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.muted {
  color: var(--color-muted);
  font-size: 0.9rem;
}

/* ── Forms ───────────────────────────────────────────────────────────── */

.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 14px;
}

.field label {
  font-size: 0.9rem;
  font-weight: 600;
}

/* `textarea` belongs here too: without it the browser default applies, and a
   monospace box at a different size sits next to every sans-serif input in
   the app — the candidate profile, the company description, the CV summary,
   the offer description. `font: inherit` is what makes it match. */
/* Une case a cocher n est PAS un champ de texte : 44 px de hauteur, un
   rembourrage et une bordure la transforment, dans une etiquette flex, en
   un rectangle qui prend la place restante et rejette son libelle a l autre
   bout (mesure : 326 x 44 px sur le volet de la vitrine, 2026-10-04).
   L exclusion est celle que prosyjob-app.css ecrit deja pour le theme
   sombre ; cette regle-ci ne l avait jamais eue. La cible tactile de 44 px
   se porte sur l ETIQUETTE, qui entoure la case et son texte. */
.field input:not([type="checkbox"]):not([type="radio"]),
.field select,
.field textarea {
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--color-field-border);
  border-radius: var(--radius);
  font: inherit;
  font-size: 1rem;
  background: var(--color-surface);
  color: var(--color-text);
  width: 100%;
}

/* A checkbox field: the box on the left at its own size, the sentence beside
   it, aligned on the first line. Without this the box inherited the text
   input above — `width: 100%`, 44px tall, padded — and sat stretched on its
   own line over the sentence it confirms. The whole label stays the target. */
.field.field--check {
  flex-direction: row;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
}

.field.field--check input[type="checkbox"] {
  flex: none;
  width: 20px;
  height: 20px;
  min-height: 0;
  margin: 2px 0 0;
  padding: 0;
  accent-color: var(--pj-orange-fill);
  cursor: pointer;
}

.field.field--check > span {
  line-height: 1.45;
}

.field textarea {
  resize: vertical;
  line-height: 1.5;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.field-error {
  color: var(--color-error);
  font-size: 0.85rem;
}

/* The E7 legacy gate stood here: five rules scoped to
   `#app:not(.layout-admin) #content[data-tpl="legacy"]` so this sheet's
   `.card` / `.btn` contract and the vendor theme's could coexist while the
   pages were converted one wave at a time. Removed in E7-14 once the last page
   on the legacy dialect (`/profil`) was converted — no page opts out any more,
   so the gate guarded nothing. `data-tpl` is still stamped on `#content`: it
   has no stylesheet reading it now, but it is the one place the dialect of the
   page on screen is visible from a console. */
button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ── Referral / commercial dashboard ────────────────────────────────── */

.history-item {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 0;
  border-bottom: 1px solid var(--color-border);
}

.history-item:last-child {
  border-bottom: none;
}

/* The miles ledger holds both directions. It used to paint every line green
   and prefix it with "+", so a `transfer_out` read as a gain. The sign carries
   the meaning; colour only reinforces it, which is why the "−" is in the markup
   and not left to CSS. */
.history-item__credit {
  font-weight: 600;
  white-space: nowrap;
}

.history-item__credit--credit {
  color: var(--color-success);
}

.history-item__credit--debit {
  color: var(--color-muted);
}

/* ── Flash messages ──────────────────────────────────────────────────── */

#pan-display-messages {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 12px;
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}

#pan-display-messages > div {
  border-radius: var(--radius);
  padding: 12px 16px;
  font-size: 0.9rem;
  pointer-events: auto;
}

#pan-display-messages .success-message > div {
  background: var(--color-success);
  color: #fff;
  margin-top: 8px;
  border-radius: var(--radius);
  padding: 10px 14px;
}

#pan-display-messages .error-message > div {
  background: var(--color-error);
  color: #fff;
  margin-top: 8px;
  border-radius: var(--radius);
  padding: 10px 14px;
}

#pan-display-messages .warning-message > div {
  background: var(--color-warning);
  color: #fff;
  margin-top: 8px;
  border-radius: var(--radius);
  padding: 10px 14px;
}

/* ── Loader ──────────────────────────────────────────────────────────── */

.global-loader {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 200;
  display: flex;
  justify-content: center;
  padding-top: 4px;
}

.loader-spinner {
  width: 22px;
  height: 22px;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ── Breakpoints: layer on more room as viewport grows ──────────────── */

@media (min-width: 640px) {
  .card--narrow {
    max-width: 460px;
  }

  .field-row--2col .field {
    flex: 1;
  }
}

@media (min-width: 900px) {
  .layout-auth__body {
    padding: 24px 32px;
  }

  #myTopnav {
    display: flex;
  }

  #myTopnav .tab {
    border-bottom: none;
    border-right: 1px solid var(--color-border);
  }
}

/* ── Admin layout: neutralize the properties above that would otherwise
   leak into the Kofejob/Bootstrap admin template (loaded only for staff
   sessions) — e.g. our full-width button rule would force every small
   Bootstrap icon button (edit/delete/add) to stretch edge to edge. Only
   resetting the specific properties that have no Bootstrap equivalent to
   naturally win; everything else is left to Bootstrap's own cascade. ── */

.layout-admin .card {
  padding: 0;
  margin-bottom: 1.5rem;
}

.layout-admin button,
.layout-admin .btn {
  width: auto;
  min-height: auto;
  display: inline-block;
}

.login-lang-slot .lang-switcher {
  min-width: 150px;
}

@media (max-width: 959px) {
  .layout-guest {
    padding: 14px;
  }

}

@media (max-width: 639px) {
  .login-lang-slot .lang-switcher {
    width: 100%;
  }
}

.guest-lang-slot .lang-switcher {
  min-width: 150px;
}


@media (max-width: 639px) {
  .guest-lang-slot .lang-switcher {
    width: 100%;
  }
}

/* ── Connected user shell redesign ───────────────────────────────────── */

:root {
  --connected-bg: #f3f6fb;
  --connected-surface: #ffffff;
  --connected-border: #dfe7f2;
  --connected-text: #16233b;
  /* E8-02: was #66758f — 4,31:1 on the connected background, the same near-miss
     as --pj-muted. Consolidated onto that token's value so the app has one
     muted grey rather than three within 6 units of each other. */
  --connected-muted: #657085;
  --connected-primary: #264A78;
  --connected-primary-deep: #264A78;
  --connected-accent: #ff592d;
  --connected-accent-soft: #fff0eb;
  --connected-shadow: 0 22px 50px rgba(22, 35, 59, 0.08);
  --connected-radius-xl: 28px;
  --connected-radius-lg: 22px;
  --connected-radius-md: 18px;
}

body {
  font-family: Aptos, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  color: var(--connected-text);
}

.layout-auth {
  min-height: 100vh;
  background:
    radial-gradient(circle at top left, rgba(47, 124, 243, 0.08), transparent 24%),
    linear-gradient(180deg, var(--surface-sunken) 0%, var(--color-bg) 100%);
}

#auth-header {
  position: sticky;
  top: 0;
  z-index: 30;
}

.connected-surface-card,
.dashboard-hero-card,
.dashboard-stat-card,
.profile-panel,
.companies-panel {
  border-radius: var(--connected-radius-lg);
  background: var(--connected-surface);
  border: 1px solid var(--connected-border);
  box-shadow: var(--connected-shadow);
}

.connected-page {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/*
  La carte se replie sur la largeur de SON CONTENEUR, pas sur celle du
  viewport.

  Elle était `display: grid` en `minmax(0, 1.1fr) minmax(260px, 0.9fr)`, avec
  un repli en une colonne sous 1080px de viewport. Cela tient tant que la
  carte occupe toute la colonne centrale — mais /commercial/activer
  l'imbrique dans une grille à deux colonnes. Dans les 463px qui lui
  restaient, le plancher de 260px de l'illustration gagnait et le texte
  tombait à 127px : titre découpé un mot par ligne, puces de faits à 23px de
  large. Une media query interroge le viewport ; elle ne peut pas voir qu'une
  grille est imbriquée dans une colonne étroite.

  D'où le passage en flex : c'est la seule des deux mises en page qui sache
  à la fois RENVOYER À LA LIGNE quand la place manque (les pistes explicites
  d'une grille ne se replient jamais, seul `repeat(auto-fit)` le fait) et
  GARDER DES PROPORTIONS INÉGALES (auto-fit impose des colonnes égales, ce
  qui aplatissait le 1,1 / 0,9 d'origine en 50/50 sur les pages larges).
  Les `flex-basis` jouent le rôle des anciens planchers, les `flex-grow`
  celui des fractions.

  Mesuré — imbriquée dans 463px : texte 127px -> 405px, puce 57px -> 196px,
  titre 4 lignes -> 2, illustration passée dessous. En pleine largeur
  (900px) : 432px / 392px, soit les proportions d'avant, côte à côte.

  La règle `grid-template-columns: 1fr` que la media query 1080px applique
  encore à ce sélecteur est devenue inerte ; elle reste en place parce
  qu'elle sert aux autres grilles listées à côté.
*/
.dashboard-hero-card {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
  padding: 28px;
  overflow: hidden;
}

.dashboard-hero-card__content {
  flex: 1.1 1 320px;
  min-width: 0;
}

/*
  `.dashboard-hero-card__badge` was removed from the product: the chip above
  the title repeated the page label, and on two pages it repeated the `<h1>`
  verbatim. The label belongs in the heading. `tools/check-hero-badge.mjs`
  fails the build if the class comes back into a page template.
*/

.dashboard-hero-card h1,
.connected-section-heading h1 {
  font-size: clamp(2rem, 3.5vw, 3.35rem);
  letter-spacing: -0.04em;
}

.dashboard-hero-card p,
.connected-section-heading p,
.connected-surface-card p,
.profile-panel p,
.companies-panel p {
  color: var(--connected-muted);
  font-size: 1.06rem;
  line-height: 1.7;
}

.dashboard-hero-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 22px;
}

/* E7 legacy gate — second, conflicting `.btn` contract. See the note above.

   Harmonisation des boutons (2026-09-08) : ces deux-la portaient les derniers
   hex bruts du systeme bleu d'avant E7 — un degrade `#2f7cf3 → #ff7b57` dont le
   bleu n'existe plus dans la palette, et un `#ffffff` fixe qui ne suivait pas
   le theme (1,18:1 en sombre, texte quasi blanc sur fond blanc).

   `.btn--primary` prend maintenant exactement l'aspect de `.btn-primary` : sept
   usages qui disaient « primaire » et ne ressemblaient a aucun autre primaire
   de l'app. On garde la classe plutot que de toucher au HTML — c'est le meme
   choix que partout ailleurs dans cette passe. */
.btn--primary {
  color: #fff;
  background: var(--pj-orange-fill);
  border-color: var(--pj-orange-fill);
  box-shadow: none;
}

.btn--primary:hover,
.btn--primary:focus-visible {
  color: #fff;
  background: var(--pj-orange-fill-hover);
  border-color: var(--pj-orange-fill-hover);
}

/* Classe doublee : `.pj-app a { color: inherit }` (prosyjob.css) pese
   (0,1,1) et battait cette regle (0,1,0), donc le lien heritait de la
   couleur de son parent au lieu de la sienne. Voir check-link-colors.mjs. */
.btn--ghost.btn--ghost {
  color: var(--pj-ink);
  background: var(--pj-card);
  border-color: var(--pj-line);
}

.dashboard-hero-card__visual {
  position: relative;
  /* Pendant du flex-basis du contenu ci-dessus : les deux passent à la ligne
     ensemble quand le conteneur ne peut plus les tenir côte à côte. */
  flex: 0.9 1 300px;
  min-width: 0;
  min-height: 310px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.dashboard-hero-card__visual-sun {
  position: absolute;
  /* width: 360px;
  height: 360px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #ff7c55 0%, #ff4f24 70%);
  right: 24px;
  bottom: -180px; */
}

.dashboard-hero-card__wordmark {
  position: relative;
  width: min(100%, 290px);
  z-index: 1;
  filter: drop-shadow(0 18px 28px rgba(22, 35, 59, 0.12));
}

.dashboard-hero-card__mark {
  position: absolute;
  top: 42px;
  left: 40px;
  width: 56px;
  height: 56px;
  padding: 14px;
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.88); /* couleur-litterale-ok: plaque sous un PNG de marque à fond transparent, ne porte aucun texte */
  z-index: 1;
}

.dashboard-stats-grid,
.connected-overview-grid,
.profile-grid,
.companies-grid {
  display: grid;
  gap: 18px;
}

.dashboard-stats-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.dashboard-stat-card {
  padding: 24px;
}

.dashboard-stat-card__icon {
  width: 54px;
  height: 54px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 18px;
  font-size: 1.2rem;
}

.dashboard-stat-card--blue .dashboard-stat-card__icon {
  background: var(--pj-info-soft);
  color: var(--connected-primary);
}

.dashboard-stat-card--orange .dashboard-stat-card__icon {
  background: var(--pj-orange-soft);
  color: var(--connected-accent);
}

.dashboard-stat-card--slate .dashboard-stat-card__icon {
  background: var(--surface-chip);
  color: var(--chip-ink);
}

.dashboard-stat-card strong {
  display: block;
  margin: 18px 0 6px;
  font-size: clamp(2rem, 3vw, 2.6rem);
  letter-spacing: -0.04em;
}

.dashboard-stat-card h2,
.profile-panel h2,
.companies-panel h2,
.connected-surface-card h2 {
  margin-bottom: 10px;
  font-size: 1.18rem;
}

.connected-surface-card,
.profile-panel,
.companies-panel {
  padding: 24px;
}

.connected-section-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 18px;
}

.connected-section-heading--stacked {
  align-items: flex-start;
}

.connected-status-pill,
.companies-panel__chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 9px 14px;
  border-radius: 999px;
  background: var(--surface-chip);
  color: var(--connected-primary);
  font-size: 0.92rem;
  font-weight: 800;
}

.connected-overview-grid {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.connected-overview-card {
  padding: 18px;
  border-radius: 20px;
  background: var(--surface-sunken);
  border: 1px solid var(--color-border);
}

.connected-overview-card span,
.profile-fields span,
.profile-status-item span,
.companies-kpis span {
  display: block;
  color: var(--connected-muted);
  font-size: 0.92rem;
}

.connected-overview-card strong,
.profile-fields strong,
.profile-status-item strong,
.companies-kpis strong {
  display: block;
  margin-top: 8px;
  font-size: 1.06rem;
}

.connected-overview-card small {
  display: block;
  margin-top: 6px;
  color: #7d879b;
}

.profile-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

/* E7-14: /profil now lays its three panels out in a Bootstrap row, so each
   list is one column wide. */
.profile-fields--single {
  grid-template-columns: minmax(0, 1fr);
}

/* Was var(--surface-sunken) / #e6edf7. Tokenised in E7-14 — the legacy tokens follow the
   dark remap, the raw hex did not, and these are the tiles of every field on
   /profil. */
.profile-fields div,
.profile-status-item,
.companies-kpis div {
  padding: 16px;
  border-radius: 18px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
}

@media (max-width: 1280px) {

  .connected-overview-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 1080px) {

  .dashboard-hero-card,
.profile-grid,
.companies-grid,
.dashboard-stats-grid,
.connected-overview-grid,
.profile-fields,
.profile-status-list,
.companies-kpis {
    grid-template-columns: 1fr;
  }

}

@media (max-width: 720px) {

  .dashboard-hero-card,
.dashboard-stat-card,
.connected-surface-card,
.profile-panel,
.companies-panel {
    padding: 18px;
  }

  .dashboard-hero-card__visual {
    min-height: 210px;
  }

  .dashboard-hero-card__visual-sun {
    width: 240px;
    height: 240px;
    right: 10px;
    bottom: -120px;
  }
}

.commercial-dashboard-grid {
  display: grid;
  gap: 18px;
}

.commercial-dashboard-grid {
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
}

.commercial-form-card,
.commercial-dashboard-panel {
  min-height: 100%;
}

.commercial-form {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.commercial-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 10px;
}

/* ── Confirmation d'un transfert de miles (E16-03) ─────────────────────── */

.cm-confirm__recap {
  font-size: 1.125rem;
  font-weight: 600;
}

.cm-confirm__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 10px;
}

/* The `button, .btn { width: 100% }` opt-out, and E10-01's 44px floor. */
.cm-confirm__btn {
  width: auto;
  min-height: 44px;
}

.cm-hold__cancel {
  width: auto;
  min-height: 44px;
}

/* A six-digit code: wide enough to read, not a full-width field. */
.cm-confirm #tr-code {
  max-width: 12ch;
  letter-spacing: 0.25em;
  font-size: 1.125rem;
}

.commercial-dashboard-hero__visual {
  min-height: 320px;
}

.commercial-dashboard-hero__qr-shell {
  position: relative;
  z-index: 1;
  width: 220px;
  height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  border-radius: 34px;
  background: rgba(255, 255, 255, 0.96); /* couleur-litterale-ok: zone de silence du QR — un scanner exige une marge claire autour des modules */
  box-shadow: 0 26px 46px rgba(22, 35, 59, 0.14);
}

.commercial-dashboard-hero__qr {
  width: 100%;
  height: auto;
}

.commercial-dashboard-stats-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.commercial-link-box {
  /* display: flex; */
  align-items: center;
  gap: 12px;
  padding: 16px;
  border-radius: 20px;
  background: var(--surface-sunken);
  border: 1px solid var(--color-border);
}

.commercial-link-box code {
  flex: 1;
  overflow-wrap: anywhere;
  color: var(--connected-text);
  font-family: Consolas, 'Courier New', monospace;
  font-size: 0.95rem;
}

.commercial-history-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.commercial-history-empty {
  margin: 0;
  padding: 18px;
  border-radius: 18px;
  background: var(--surface-sunken);
  border: 1px dashed var(--color-border);
  color: var(--connected-muted);
}

@media (max-width: 1080px) {
  .commercial-dashboard-grid,
  .commercial-dashboard-stats-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .commercial-link-box,
  .commercial-history-item,
  .commercial-form__actions {
    flex-direction: column;
    align-items: stretch;
  }

  .commercial-dashboard-hero__qr-shell {
    width: 180px;
    height: 180px;
  }
}

/* --- Mon portefeuille commercial (E3-08, maquette 2026-09-29) `.cw-` ---
   Header card (title, intro, the balance beside, the one action), three
   totals, then commissions and withdrawals side by side. Below 768px the
   header stacks, the totals become rows, the lists stack, and each list
   shows PREVIEW_ROWS (CommercialWalletPage.js) until « Voir tout » removes
   `data-collapsed` from its panel. Every bare button of this shell is
   `width: 100%` (the `button, .btn` rule at the top of this sheet), hence
   the `width: auto` on the small ones. */
.cw-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "text balance"
    "cta  balance";
  align-items: center;
  gap: 20px 32px;
}
.cw-hero__text { grid-area: text; }
.cw-hero__title { margin: 0; font-size: var(--pj-fs-display); font-weight: 800; line-height: 1.1; color: var(--pj-ink); }
.cw-hero__intro { margin: 10px 0 0; max-width: 34rem; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.cw-hero__balance {
  grid-area: balance;
  display: grid;
  gap: 6px;
  padding: 18px 22px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow);
}
.cw-hero__balance span { color: var(--pj-muted); font-size: var(--pj-fs-md); }
.cw-hero__balance strong { color: var(--pj-ink); font-size: var(--pj-fs-display); font-weight: 800; line-height: 1.1; white-space: nowrap; }
.cw-hero .cw-hero__cta.btn { grid-area: cta; justify-self: start; width: auto; min-height: 48px; padding: 10px 28px; }
/* Why « Demander un retrait » is closed (backend `retrait.motif`). */
.cw-hero__notice { margin: 12px 0 0; padding: 10px 14px; border-radius: var(--pj-radius-sm); background: var(--pj-warning-soft); color: var(--pj-warning-ink); font-size: var(--pj-fs-body); }
.cw-hero__notice i { margin-right: 8px; }
.cw-hero .cw-hero__cta.btn:disabled { opacity: .55; cursor: not-allowed; }

.cw-page { container: cw-page / inline-size; }
.cw-stats { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr); }
.cw-stat { display: flex; align-items: flex-start; gap: 16px; }
.cw-stat--orange { background: color-mix(in srgb, var(--pj-orange-soft) 45%, var(--pj-card)); }
.cw-stat__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  font-size: 1.3rem;
}
.cw-stat--blue .cw-stat__icon { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.cw-stat--orange .cw-stat__icon { background: var(--pj-orange-soft); color: var(--pj-orange-text); }
.cw-stat--slate .cw-stat__icon { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }
.cw-stat__body { min-width: 0; }
.cw-stat__label { margin: 0; font-size: var(--pj-fs-md); font-weight: 600; color: var(--pj-ink); }
.cw-stat__value { display: block; margin-top: 4px; font-size: var(--pj-fs-display); font-weight: 800; line-height: 1.15; color: var(--pj-ink); white-space: nowrap; }
.cw-stat__copy { margin: 8px 0 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.cw-stat__held { margin: 6px 0 0; color: var(--pj-warning-ink); font-size: var(--pj-fs-body); font-weight: 600; }
.cw-stat__held i { margin-right: 6px; }

.cw-lists { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr); align-items: start; }
.cw-panel { display: grid; gap: 12px; }
.cw-panel__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cw-panel__title { margin: 0; font-size: var(--pj-fs-card); font-weight: 800; color: var(--pj-ink); }
.cw-panel__intro { margin: -6px 0 4px; color: var(--pj-muted); }
.cw-lines { display: grid; gap: 10px; }

.cw-line {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}
.cw-line__body { display: grid; gap: 2px; min-width: 0; }
.cw-line__title { color: var(--pj-ink); font-weight: 700; }
.cw-line__meta { color: var(--pj-muted); font-size: var(--pj-fs-body); }
.cw-line__side { display: grid; justify-items: end; gap: 8px; flex: 0 0 auto; text-align: right; }
.cw-line__amount { color: var(--pj-ink); font-weight: 700; white-space: nowrap; }
.cw-line .cw-line__proof {
  width: auto;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
  cursor: pointer;
}
.cw-line .cw-line__proof:hover { text-decoration: underline; }

/* « Voir tout › » — a phone control only: on a wide screen every row shows. */
.cw-panel .cw-more {
  display: none;
  align-items: center;
  gap: 6px;
  width: auto;
  min-height: 36px;
  padding: 4px 12px;
  border: 0;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: 0.9rem;
  white-space: nowrap;
  cursor: pointer;
}
.cw-panel .cw-more i { font-size: 0.75rem; transition: transform .15s ease; }
.cw-panel:not([data-collapsed]) .cw-more i { transform: rotate(90deg); }

/* « Demander un retrait » (maquette 2026-09-29): a stack of fields with one
   gap, an input carrying its currency as an addon, a blue note that follows
   the method, and the detail field with its icon inside. */
.cw-form { display: grid; gap: 24px; }
.cw-form__head { display: grid; gap: 6px; }
.cw-form__title { margin: 0; font-size: var(--pj-fs-card); font-weight: 800; line-height: 1.15; color: var(--pj-ink); }
.cw-form__hint { margin: 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.cw-form__balance { color: var(--pj-info-ink); font-weight: 800; }
.cw-form__body { display: grid; gap: 22px; }

.cw-field { display: grid; gap: 8px; margin: 0; }
.cw-field__label { margin: 0; font-weight: 700; color: var(--pj-ink); }
.cw-req { color: var(--pj-danger); }
.cw-field__help { margin: 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.cw-form .cw-field .form-control,
.cw-form .cw-field .form-select { min-height: 52px; border-radius: var(--pj-radius-sm); }
.cw-field .invalid-feedback:empty { display: none !important; }

.cw-input-group { display: flex; align-items: stretch; }
.cw-form .cw-input-group .form-control { flex: 1 1 auto; min-width: 0; border-top-right-radius: 0; border-bottom-right-radius: 0; }
.cw-input-group__addon {
  display: inline-flex;
  align-items: center;
  padding: 0 18px;
  border: 1px solid var(--pj-line);
  border-left: 0;
  border-radius: 0 var(--pj-radius-sm) var(--pj-radius-sm) 0;
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-weight: 600;
}

.cw-info {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 20px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
}
.cw-info__icon { flex: 0 0 auto; color: var(--pj-info-ink); font-size: 1.6rem; line-height: 1; }
.cw-info__title { display: block; color: var(--pj-info-ink); font-weight: 700; }
.cw-info__text { margin: 2px 0 0; color: var(--pj-ink); }

.cw-input-icon { position: relative; }
.cw-input-icon .form-control { padding-left: 48px; }
.cw-input-icon__icon { position: absolute; left: 18px; top: 50%; transform: translateY(-50%); color: var(--pj-muted); pointer-events: none; }

.cw-form__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.cw-form .cw-form__submit.btn,
.cw-form .cw-form__cancel.btn { width: auto; min-height: 52px; gap: 10px; padding: 10px 28px; font-size: var(--pj-fs-md); }
.cw-form .cw-form__cancel.btn { border: 0; background: var(--pj-orange-soft); color: var(--pj-orange-text); }
.cw-form .cw-form__cancel.btn:hover { background: color-mix(in srgb, var(--pj-orange-soft) 70%, var(--pj-orange)); }

@media (max-width: 767px) {
  .cw-form { gap: 18px; }
  .cw-form__hint { font-size: var(--pj-fs-body); }
  .cw-form__hint > span { display: block; }
  .cw-form__hint > .cw-form__sep { display: none; }
  .cw-form__body { gap: 18px; }
  .cw-info { padding: 12px 14px; }
  .cw-input-group__addon { padding: 0 12px; }
  .cw-form .cw-field .form-control { padding-left: 12px; font-size: var(--pj-fs-md); }
  .cw-form .cw-input-icon .form-control { padding-left: 40px; }
  .cw-input-icon__icon { left: 14px; }
  .cw-form__actions { flex-direction: column; }
  .cw-form .cw-form__submit.btn,
  .cw-form .cw-form__cancel.btn { width: 100%; }
}

/* 360px, measured: the card's own padding left 162px to an amount field
   whose example needs 176. Same answer as the Assistant credits journal. */
@media (max-width: 480px) {
  .cw-page .cw-form.pj-card { padding: 18px 14px; }
}

/* The columns follow the page's own width, not the window's: at a 1366px
   window the centre column is ~690px, and three totals side by side there
   broke « 154 244 XAF » over two lines. */
@container cw-page (min-width: 800px) {
  .cw-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@container cw-page (min-width: 900px) {
  .cw-lists { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
}

@media (max-width: 767px) {
  .cw-hero {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "text" "balance" "cta";
    gap: 14px;
  }
  .cw-hero__intro { font-size: var(--pj-fs-body); }
  .cw-hero__balance { box-shadow: none; background: var(--pj-bg); padding: 14px 18px; }
  .cw-hero__balance strong { font-size: var(--pj-fs-display); }
  .cw-hero .cw-hero__cta.btn { justify-self: stretch; width: 100%; }

  .cw-stats { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .cw-stat__value { font-size: var(--pj-fs-card); }
  .cw-stat__copy { margin-top: 4px; }

  .cw-panel__title { font-size: var(--pj-fs-card); }
  .cw-line { padding: 10px 12px; }
  .cw-line__meta--rate { display: none; }

  .cw-panel .cw-more { display: inline-flex; }
  .cw-panel .cw-more[hidden] { display: none; }
  .cw-panel[data-collapsed] .cw-lines > :nth-child(n+3),
  .cw-panel[data-collapsed] .cw-pager { display: none; }
}

.commercial-form__actions {
  display: flex;
  gap: 12px;
  margin-top: 4px;
}

.commercial-form__actions .btn {
  width: auto;
}

.commercial-lines {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.commercial-line {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 16px;
  border-radius: 18px;
  background: var(--surface-sunken);
  border: 1px solid var(--color-border);
}

.commercial-line__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.commercial-line__title {
  color: var(--connected-text);
  font-weight: 700;
}

.commercial-line__meta,
.commercial-line__date,
.commercial-line__note {
  color: var(--connected-muted);
  font-size: 0.9rem;
}

.commercial-line__side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  text-align: right;
  flex-shrink: 0;
}

.commercial-line__amount {
  color: var(--connected-primary);
  font-weight: 800;
}

.commercial-empty {
  margin: 0;
  padding: 18px;
  border-radius: 18px;
  background: var(--surface-sunken);
  border: 1px dashed var(--color-border);
  color: var(--connected-muted);
}

.commercial-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 14px;
}

.commercial-pager:empty {
  display: none;
}

.commercial-pager .btn {
  width: auto;
}

.commercial-pager__label {
  color: var(--connected-muted);
  font-size: 0.9rem;
}

/* Status badges — shared by the wallet and the admin desk. */
.cm-badge,
.wd-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 700;
  white-space: nowrap;
}

.cm-badge--pending,
.wd-badge--pending {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.cm-badge--available,
.wd-badge--validated {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.cm-badge--paid,
.wd-badge--paid {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.cm-badge--reversed,
.cm-badge--cancelled,
.wd-badge--refused {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

/* ═══ Tableau de bord de l'apporteur (maquette 2026-09-15) ═══════════════
   Trois blocs, dans l'ordre de lecture : ce que je partage, où j'en suis,
   ce qui s'est passé. La maquette donne une version poste et une version
   téléphone ; elles ne diffèrent que par la mise en page, jamais par le
   contenu — deux balisages seraient deux choses à tenir en phase. */

/* Le bouton icône, partagé par le QR, le champ du lien et les replis. Il
   porte sa propre largeur : `button, .btn { width: 100% }` s'applique à
   tout bouton nu de la coque connectée. 44px, parce que c'est une cible. */
.cd-iconbtn {
  width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border: 0;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--surface-sunken);
  color: var(--connected-primary);
  cursor: pointer;
}

.cd-iconbtn:hover {
  background: var(--surface-chip);
}

/* ── 1. L'en-tête ──────────────────────────────────────────────────────── */
/* Flex, et non trois pistes de grille : la carte doit se replier sur la
   largeur de SON CONTENEUR. La colonne centrale fait 900px quand le viewport
   en fait 1568 — une media query ne voit que le second et laisserait les
   trois pistes se serrer jusqu'à ce que le lien déborde. Mesuré avant
   correction : piste de 262px pour un contenu de 430px, 141px hors carte.
   C'est le même raisonnement que `.dashboard-hero-card` plus haut. */
.cd-hero {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  padding: 22px;
  align-items: stretch;
}

.cd-hero__intro {
  flex: 1.6 1 320px;
  min-width: 0;
}

.cd-hero__title {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 800;
}

.cd-hero__lead {
  margin: 6px 0 0;
  color: var(--connected-muted);
}

.cd-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-top: 16px;
}

.cd-fact {
  display: grid;
  gap: 2px;
  padding: 12px 14px;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--surface-sunken);
}

.cd-fact__label {
  color: var(--connected-muted);
  font-size: 0.85rem;
}

.cd-fact__value {
  font-weight: 700;
  overflow-wrap: anywhere;
}

/* Un contact absent n'est pas une valeur : c'est la seule chose de ce bloc
   sur laquelle il y a quelque chose à faire, et la couleur le dit. */
.cd-fact__value--missing {
  color: var(--pj-orange-text);
}

.cd-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 16px;
}

.cd-btn {
  width: auto;
  min-width: 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  flex: 1 1 0;
}

.cd-qr,
.cd-share {
  display: grid;
  gap: 10px;
  padding: 16px;
  border-radius: var(--pj-radius, 16px);
  background: var(--surface-sunken);
  min-width: 0;
}

.cd-qr {
  flex: 0 1 190px;
  justify-items: center;
  text-align: center;
  align-content: start;
}

.cd-share {
  flex: 1 1 300px;
  align-content: start;
}

.cd-qr__img {
  width: 148px;
  max-width: 100%;
  height: auto;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--pj-card);
  padding: 6px;
}

.cd-qr__copy {
  margin: 0;
  color: var(--connected-muted);
  font-size: 0.9rem;
}

.cd-share__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 800;
}

.cd-share__lead {
  margin: 0;
  color: var(--connected-muted);
  font-size: 0.9rem;
}

.cd-linkbox {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 6px 6px 12px;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--pj-card);
  border: 1px solid var(--color-border);
}

/* Le lien est long et ne se coupe pas aux espaces : sans `min-width: 0` la
   piste flex prend sa largeur de contenu et pousse le bouton hors carte. */
.cd-linkbox__value {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.85rem;
  color: var(--connected-text);
}

/* Le second titre du bloc : le `gap` de 10px de la carte suffirait à le
   séparer de la boîte du dessus, mais pas à dire qu'il ouvre autre chose. */
.cd-share__title--code {
  margin-top: 6px;
}

/* ── 2. Progression + carte de visite ──────────────────────────────────── */
.cd-duo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: 20px;
  align-items: start;
}

/* ── 3. Les compteurs ──────────────────────────────────────────────────── */
.cd-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 20px;
}

.cd-stat {
  display: grid;
  gap: 6px;
  align-content: start;
  padding: 20px;
}

.cd-stat__icon {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: var(--pj-radius-sm, 12px);
  margin-bottom: 6px;
}

.cd-stat__icon--miles {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.cd-stat__icon--people {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.cd-stat__icon--date {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.cd-stat__icon--rank {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.cd-stat__value {
  font-size: 1.7rem;
  font-weight: 800;
  line-height: 1.15;
  color: var(--connected-text);
}

.cd-stat__label {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 700;
}

/* Deux libellés écrits, un seul rendu. La maquette nomme ces compteurs d'un
   mot au téléphone (« Miles », « Filleuls ») et d'une phrase sur poste : ce
   n'est pas une abréviation, c'est un autre libellé. */
.cd-stat__short {
  display: none;
}

.cd-stat__copy {
  margin: 0;
  color: var(--connected-muted);
  font-size: 0.85rem;
}

/* ── 4. Les deux registres ─────────────────────────────────────────────── */
.cd-hist {
  display: grid;
  gap: 14px;
  padding: 22px;
}

.cd-hist__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 12px;
}

.cd-hist__heading {
  flex: 1 1 240px;
  min-width: 0;
}

.cd-hist__title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 800;
}

.cd-hist__intro {
  margin: 4px 0 0;
  color: var(--connected-muted);
  font-size: 0.9rem;
}

/* Deux classes, pas une : `.pj-app a { color: inherit }` est écrit à
   (0,1,1) et bat une classe seule, quel que soit l'ordre des feuilles —
   le lien arriverait en couleur d'encre ordinaire. */
/* 44px de haut, mesurés : le lien faisait 20px, soit une cible de moins de
   la moitié de la règle sur un public à ~90 % au téléphone. */
.cd-hist .cd-hist__all {
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  white-space: nowrap;
  font-weight: 700;
  color: var(--connected-primary);
  text-decoration: none;
}

.cd-hist .cd-hist__all:hover {
  text-decoration: underline;
}

/* Le repli n'existe qu'au téléphone : sur poste il n'y a rien à gagner à
   cacher cinq lignes, et un bouton qui reste tenterait quelqu'un. */
.cd-hist__toggle,
.cg-ladder__toggle {
  display: none;
}

.cd-hist__body {
  display: grid;
}

.cd-row {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  padding: 12px 2px;
  border-top: 1px solid var(--color-border);
}

.cd-hist__body .cd-row:first-child {
  border-top: 0;
}

.cd-row__dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--connected-muted);
}

.cd-row__dot--credit {
  background: var(--pj-success);
}

.cd-row__dot--debit {
  background: var(--pj-danger);
}

.cd-row__dot--pending {
  background: var(--pj-warning-ink);
}

.cd-row__label {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 600;
}

/* Le taux et son assiette, sous l'intitule : « 6 % de 35,00 EUR ». En bloc et
   non en ligne, parce qu'un intitule de service peut etre long et qu'un detail
   qui se faufile en bout de ligne ne se lit plus. Vide quand la commission
   n'en porte pas (une reprise d'ancienne base) : `:empty` retire alors la
   marge, sinon la ligne gagnerait un blanc sans raison. */
.cd-row__detail {
  display: block;
  margin-top: 2px;
  font-style: normal;
  font-weight: 400;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.cd-row__detail:empty {
  display: none;
}

/* ---- Le bareme : l'annexe 1 du contrat partenaire -------------------- */
.cd-bareme {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
}

.cd-bareme__title {
  margin: 0 0 10px;
  font-size: var(--pj-fs-lg);
}

.cd-bareme__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  margin: 0 0 10px;
}

.cd-bareme__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.cd-bareme__item dt {
  min-width: 0;
  font-size: var(--pj-fs-body);
}

.cd-bareme__item dd {
  margin: 0;
  font-size: var(--pj-fs-lg);
  white-space: nowrap;
}

.cd-bareme__note {
  margin: 0 0 6px;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.cd-bareme__subtitle {
  margin: 12px 0 6px;
  font-size: var(--pj-fs-body);
}

.cd-bareme__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.cd-bareme__exc {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  border-top: 1px solid var(--color-border);
  font-size: var(--pj-fs-body);
}

@media (min-width: 640px) {
  .cd-bareme__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.cd-row__date {
  color: var(--connected-muted);
  font-size: 0.85rem;
  white-space: nowrap;
}

/* La cellule gagne sur son contenu : `.cd-row` ne fixe pas de `color`,
   justement pour que celle-ci tienne. Écrire une couleur sur la ligne
   aurait suffi à effacer le vert et le rouge, qui sont tout l'intérêt de
   la colonne. */
.cd-row__amount {
  font-weight: 700;
  white-space: nowrap;
  text-align: right;
}

.cd-row__amount--credit {
  color: var(--pj-success);
}

.cd-row__amount--debit {
  color: var(--pj-danger);
}

.cd-row__amount--pending {
  color: var(--pj-warning-ink);
}

@media (max-width: 900px) {
  .cd-hero {
    padding: 18px;
  }

  .cd-hero__title {
    font-size: 1.4rem;
  }

  /* Empilés, les deux blocs prennent la ligne entière. Sans cela le QR
     gardait sa largeur de poste (190px, `flex-grow: 0`) : piste du milieu
     mesurée à 0px, légende écrasée sous le bouton de téléchargement. */
  .cd-qr,
  .cd-share {
    flex: 1 1 100%;
  }

  .cd-hist__toggle {
    display: inline-flex;
    margin-left: auto;
  }

  .cd-hist.is-collapsed .cd-hist__body {
    display: none;
  }

  .cd-stats {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
  }

  .cd-stat__long {
    display: none;
  }

  .cd-stat__short {
    display: inline;
  }

  .cd-stat {
    padding: 12px 10px;
    gap: 4px;
  }

  .cd-stat__icon {
    width: 34px;
    height: 34px;
    margin-bottom: 2px;
  }

  .cd-stat__value {
    font-size: 1.1rem;
  }

  .cd-stat__label {
    font-size: 0.78rem;
  }

  /* La phrase d'explication tient sur poste ; à 90px de large elle ferait
     huit lignes sous un chiffre. Le libellé suffit. */
  .cd-stat__copy {
    display: none;
  }

  /* La date et le montant repassent sous le libellé : à cette largeur,
     quatre colonnes sur une ligne, c'est le montant coupé. */
  .cd-row {
    grid-template-columns: 10px minmax(0, 1fr) auto;
  }

  .cd-row__date {
    grid-column: 2;
    grid-row: 2;
  }

  .cd-row__amount {
    grid-column: 3;
    grid-row: 1 / span 2;
  }
}

/* La maquette met le QR en ligne sur téléphone : image, légende, bouton.
   Elle tient sur un téléphone large. À 380px la légende n'obtient que 63px
   — mesuré — pour « Scannez pour accéder à mon profil », soit cinq lignes
   dans un filet. En dessous de 560px on garde donc la colonne centrée, qui
   est plus haute et lisible ; au-dessus, la ligne de la maquette. */
@media (min-width: 561px) and (max-width: 900px) {
  .cd-qr {
    grid-template-columns: auto minmax(0, 1fr) auto;
    justify-items: start;
    align-items: center;
    text-align: left;
  }

  .cd-qr__img {
    width: 104px;
  }
}

/* Mesuré à 360px, la largeur de ~90 % du public : quatre compteurs sur une
   ligne donnent des cartes de 66px, où « 46 500 » se coupe en deux et où
   « Activation » perd son n. La maquette tient à quatre parce qu'elle est
   dessinée sur un téléphone plus large ; à 360 il en faut deux. */
@media (max-width: 560px) {
  .cd-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Trois compteurs sur deux colonnes : le classement prend la ligne
     entière, et ses deux rangs y tiennent sans se couper. */
  .cd-stats > :last-child {
    grid-column: 1 / -1;
  }

  .cd-stat__value {
    font-size: 1.25rem;
  }
}

/* ── L'échelle du commercial (E18-01/02) ────────────────────────────────
   « Une sorte de jauge indiquant les niveaux atteints », « similaire à
   celui utilisé par les compagnies aériennes » : toute l'échelle d'un
   coup, avec le barreau courant marqué. Rien n'est calculé ici — la
   largeur du remplissage arrive décidée par le serveur. */
.cg-ladder {
  display: grid;
  gap: 16px;
  padding: 22px;
}

.cg-ladder__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.cg-ladder__title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 800;
}

.cg-ladder__intro {
  margin: 4px 0 0;
  color: var(--connected-muted);
  font-size: 0.9rem;
}

.cg-ladder__heading {
  min-width: 0;
}

/* `margin-left: auto` rather than relying on space-between: once the head
   wraps on a narrow card, space-between has nothing left to space and the
   block sat mid-card, right-aligned to its own content instead of the
   card edge. */
.cg-ladder__now {
  display: grid;
  gap: 2px;
  text-align: right;
  margin-left: auto;
}

/* La pastille « Grade actuel » : une étiquette, pas un état. Elle nomme le
   nombre d'en dessous, comme sur la maquette, et n'est jamais colorée par
   le grade — sinon elle se lirait comme une deuxième information. */
.cg-ladder__chip {
  justify-self: end;
  padding: 3px 12px;
  border-radius: var(--pj-radius-pill, 999px);
  background: var(--surface-sunken);
  color: var(--connected-muted);
  font-size: 0.8rem;
}

.cg-ladder__grade {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--connected-primary);
}

/* Le metal du partenaire a cote du grade (PO, 2026-10-04). Il remplace
   `.cg-ladder__star`, une etoile orange identique pour les quatre grades :
   elle decorait sans rien dire, la pastille dit lequel. */
.cg-ladder__metal {
  display: inline-flex;
  align-items: center;
}

.cg-ladder__next-grade {
  color: var(--connected-muted);
  font-size: 0.85rem;
}

.cg-ladder__body {
  display: grid;
  gap: 16px;
}

.cg-bar {
  height: 12px;
  border-radius: var(--pj-radius-pill, 999px);
  background: var(--surface-sunken);
  overflow: hidden;
}

.cg-bar__fill {
  height: 100%;
  border-radius: inherit;
  background: var(--connected-primary);
  /* La barre bouge quand la page se rend, pas quand l'utilisateur agit :
     une transition la rend lisible au lieu de la faire apparaître pleine. */
  transition: width 600ms ease-out;
}

.cg-ladder__next {
  margin: 0;
  font-weight: 600;
}

.cg-rungs {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: none;
}

.cg-rung {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--surface-sunken);
  color: var(--connected-muted);
}

.cg-rung__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 2px solid var(--color-border);
}

.cg-rung.is-reached {
  color: var(--color-text);
}

.cg-rung.is-reached .cg-rung__dot {
  background: var(--connected-primary);
  border-color: var(--connected-primary);
}

/* Le barreau courant : marqué par la couleur ET par le poids, jamais par
   la couleur seule — c'est la seule information de l'écran qu'on ne peut
   pas déduire d'ailleurs. */
.cg-rung.is-current {
  color: var(--color-text);
  font-weight: 800;
  outline: 2px solid var(--connected-primary);
  outline-offset: -2px;
}

.cg-rung__cost {
  white-space: nowrap;
  font-size: 0.9rem;
}

.cg-rung__short {
  display: none;
}

/* ── Sous 900px : la maquette « Version Mobile » ─────────────────────────
   L'échelle devient une frise horizontale et la carte se replie. Le repli
   ne vit QUE dans cette requête média : une section repliée au téléphone
   puis rouverte sur poste doit réapparaître d'elle-même, sinon elle reste
   invisible là où le bouton qui la rouvre n'existe pas. */
@media (max-width: 900px) {
  .cg-ladder__toggle {
    display: inline-flex;
  }

  .cg-ladder.is-collapsed .cg-ladder__body {
    display: none;
  }

  .cg-ladder__now {
    text-align: right;
  }

  /* La frise : une colonne par barreau, le point au-dessus du libellé. */
  .cg-rungs {
    position: relative;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 0;
  }

  /* Le trait de liaison passe derrière les points. Il s'arrête à un huitième
     de chaque bord — le centre du premier et du dernier point — pour ne pas
     dépasser dans le vide. */
  .cg-rungs::before {
    content: "";
    position: absolute;
    left: 12.5%;
    right: 12.5%;
    top: var(--cg-rail-y, 20px);
    height: 2px;
    background: var(--color-border);
  }

  .cg-rung {
    position: relative;
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    text-align: center;
    gap: 4px;
    padding: 8px 2px;
    background: transparent;
    font-size: 0.8rem;
  }

  .cg-rung__dot {
    background: var(--pj-card);
  }

  .cg-rung.is-reached .cg-rung__dot {
    background: var(--connected-primary);
  }

  .cg-rung.is-current {
    background: var(--surface-sunken);
    border-radius: var(--pj-radius-sm, 12px);
    outline: none;
  }

  .cg-rung__long {
    display: none;
  }

  .cg-rung__short {
    display: inline;
  }

  .cg-rung__label,
  .cg-rung__cost {
    font-size: 0.78rem;
    white-space: normal;
  }
}

/* ── La carte de visite (E18-03) ────────────────────────────────────────
   L'aperçu EST le canvas téléchargé : pas de maquette HTML à côté, qui
   serait un second dessin à tenir en phase. */
.cg-card {
  display: grid;
  gap: 16px;
  padding: 22px;
}

.cg-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.cg-card__title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 800;
}

.cg-card__intro {
  margin: 4px 0 0;
  color: var(--connected-muted);
  font-size: 0.9rem;
}

.cg-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.cg-card__btn {
  width: auto;
  min-height: 44px;
}

/* Un bloc, pas un conteneur flex : le canvas porte une taille intrinsèque
   (1200×675), donc en élément flex il se laissait rétrécir bien en deçà de
   son `width: 100%` — mesuré à 109 px de large. */
.cg-card__preview {
  display: block;
}

/* Le canvas est dessiné à 1200×675 quel que soit l'écran — c'est un
   fichier destiné à WhatsApp ou à une imprimante. Il ne se met à
   l'échelle qu'à l'affichage. */
.cg-card__canvas {
  display: block;
  width: 100%;
  max-width: 640px;
  height: auto;
  margin: 0 auto;
  border-radius: var(--pj-radius-sm, 12px);
  border: 1px solid var(--color-border);
  box-shadow: var(--pj-shadow-sm);
}

@media (max-width: 720px) {
  .cg-card__actions {
    width: 100%;
  }

  .cg-card__btn {
    flex: 1 1 140px;
  }
}

/* ── Tableau de bord commercial, 2026-09-23 ─────────────────────────────
   Les soldes sur les boutons, la tuile des filleuls qui mène à leur liste,
   le classement en deux rangs, et le formulaire de la carte de visite. */

/* Le bouton dit d'abord combien il y a derrière : l'intitulé en petit, le
   montant dessous. */
/* 150px de base : sous cette largeur les deux boutons passent l'un sous
   l'autre, chacun sur toute la ligne, plutôt que de couper « 154 244 XAF »
   en deux — mesuré à 360px, où la colonne ne laisse que 241px aux deux. */
.cd-balance {
  flex: 1 1 150px;
  flex-direction: column;
  gap: 2px;
  line-height: 1.2;
  padding-top: 8px;
  padding-bottom: 8px;
}

.cd-balance__label {
  font-size: 0.78rem;
  font-weight: 600;
  opacity: 0.85;
}

.cd-balance__value {
  font-size: 1.05rem;
  font-weight: 800;
  white-space: nowrap;
}

/* La tuile entière est le lien : c'est elle qu'un pouce vise. */
.cd-stat--link {
  color: inherit;
  text-decoration: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}

.cd-stat--link:hover,
.cd-stat--link:focus-visible {
  border-color: var(--pj-orange);
  box-shadow: var(--pj-shadow);
}

.cd-stat__more {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  color: var(--pj-orange-text);
  font-size: 0.85rem;
  font-weight: 700;
}

/* Le classement : deux rangs, l'un sous l'autre. */
.cd-rank {
  display: grid;
  gap: 6px;
  margin: 2px 0 0;
}

.cd-rank__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.cd-rank dt {
  color: var(--pj-muted);
  font-size: 0.85rem;
  font-weight: 600;
}

.cd-rank dd {
  margin: 0;
  color: var(--pj-ink);
  font-size: 1.05rem;
  font-weight: 800;
  text-align: right;
}

.cd-rank__none {
  color: var(--pj-muted);
  font-size: 0.9rem;
  font-weight: 600;
}

/* La carte de visite : ce qui a été généré, puis les actions ou le
   formulaire. */
.cg-card__body {
  display: grid;
  gap: 12px;
}

.cg-card__meta {
  margin: 0;
  color: var(--pj-muted);
  font-size: 0.88rem;
}

.cg-form {
  display: grid;
  gap: 4px;
}

.cg-form__row {
  display: grid;
  gap: 12px;
}

@media (min-width: 560px) {
  .cg-form__row {
    grid-template-columns: 1fr 1fr;
  }
}

.cg-form__color {
  max-width: 120px;
  height: 44px;
  padding: 4px;
}

/* ── Mes filleuls (2026-09-23) ───────────────────────────────────────────
   Mise en page de la maquette « mes_filleuls.png ». Téléphone d'abord : une
   colonne, chaque personne en ligne-carte. À partir de 768px, le retour passe
   en haut à droite, la recherche se range à côté des niveaux, et la liste
   devient un tableau. */
.nw-head {
  display: grid;
  gap: 14px;
}

a.nw-back {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--pj-ink);
  font-weight: 600;
  text-decoration: none;
}

.nw-head__title {
  margin: 0;
  color: var(--pj-ink);
  font-size: clamp(1.6rem, 5vw, 2.3rem);
  font-weight: 800;
  line-height: 1.15;
}

.nw-head__intro {
  margin: 8px 0 0;
  color: var(--pj-navy);
  font-size: 0.92rem;
  line-height: 1.55;
  max-width: 68ch;
}

.nw-head__total {
  margin: 14px 0 0;
  color: var(--pj-ink);
  font-size: 1.05rem;
  font-weight: 700;
}

.nw-head__tools {
  display: grid;
  gap: 12px;
}

@media (min-width: 768px) {
  .nw-head {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "text back"
      "tools tools";
    column-gap: 24px;
  }

  .nw-head__text { grid-area: text; }

  a.nw-back {
    grid-area: back;
    align-self: start;
    padding: 0 18px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
  }

  .nw-head__tools {
    grid-area: tools;
    grid-template-columns: minmax(0, 1fr) minmax(220px, 280px);
    align-items: center;
  }
}

/* Des puces, pas des boutons de la gamme `.btn` : elles montrent un choix
   (voir NetworkPage.js). `width: auto` parce qu'un <button> nu est pleine
   largeur dans ce thème (CLAUDE.md §9). */
.nw-levels {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.nw-levels:empty {
  display: none;
}

.nw-chip {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 0 18px;
  border: 1.5px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-weight: 700;
  cursor: pointer;
}

.nw-chip.is-active {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.nw-chip__count {
  min-width: 24px;
  padding: 1px 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
}

/* La recherche : un champ avec sa loupe, pas un formulaire — elle part
   seule, après une courte pause dans la frappe. */
.nw-search {
  position: relative;
  display: block;
  margin: 0;
}

.nw-search i {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--pj-muted);
  pointer-events: none;
}

.nw-search__input {
  width: 100%;
  min-height: 44px;
  padding: 0 14px 0 40px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: 0.92rem;
}

.nw-search__input:focus {
  outline: 2px solid var(--pj-orange);
  outline-offset: 1px;
  border-color: var(--pj-orange);
}

/* La liste bascule en tableau selon SA largeur, pas celle de l'écran : à
   1366px, entre la barre latérale et le rail, il ne reste que ~690px. */
.nw-list {
  display: grid;
  gap: 12px;
  container: nw-list / inline-size;
}

/* Sur téléphone la carte se resserre : avec ses 26px de marge et ceux de la
   ligne, le nom n'obtenait que 77px entre l'avatar et le niveau — mesuré à
   360px, trois lignes pour « Sampro02 Camerounais ». */
@media (max-width: 559px) {
  .pj-card.nw-list {
    padding: 14px;
  }
}

.nw-empty {
  margin: 0;
  color: var(--pj-muted);
}

/* La barre de la liste : le compte à gauche, le nombre de lignes à droite.
   Sur téléphone, l'intitulé « Lignes par page » s'efface : le sélecteur,
   à côté d'un compte, se comprend seul (maquette). */
.nw-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.nw-toolbar__range {
  margin: 0;
  color: var(--pj-ink);
  font-size: 0.92rem;
  font-weight: 600;
}

.nw-toolbar__size {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  color: var(--pj-muted);
  font-size: 0.9rem;
}

.nw-toolbar__label {
  display: none;
}

.nw-toolbar__select {
  width: auto;
  min-width: 80px;
  min-height: 44px;
}

@media (min-width: 768px) {
  .nw-toolbar__label {
    display: inline;
  }
}

/* Sur téléphone, chaque personne est une ligne-carte : avatar à gauche, nom,
   date et lieu empilés, niveau à droite. L'en-tête et le numéro de ligne
   disparaissent. */
/* `display: block` sur téléphone : un `<table>` resté en `display: table`
   autour d'un corps en grille se rétractait à la largeur de son contenu —
   mesuré à 190px sur 297, chaque ligne-carte haute de 175px. */
.nw-table {
  display: block;
  width: 100%;
  border-collapse: collapse;
}

.nw-table thead,
.nw-table .nw-table__num {
  display: none;
}

.nw-table tbody {
  display: grid;
  gap: 8px;
}

.nw-table tr {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "avatar name level"
    "avatar date level"
    "avatar place level";
  align-items: center;
  column-gap: 10px;
  row-gap: 2px;
  padding: 10px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.nw-table tr .nw-level {
  padding: 2px 8px;
  font-size: 0.72rem;
}

.nw-table td {
  padding: 0;
  color: var(--pj-ink);
  font-size: 0.85rem;
}

/* La cellule du nom porte l'avatar et le nom : sur téléphone elle et son
   bloc s'effacent (`display: contents`) pour que chacun prenne sa place dans
   la grille. */
.nw-table .nw-table__who,
.nw-table .nw-who { display: contents; }
.nw-table .nw-avatar { grid-area: avatar; }

.nw-table .nw-table__name {
  grid-area: name;
  font-weight: 700;
  font-size: 0.95rem;
  overflow-wrap: anywhere;
}

.nw-table .nw-table__date { grid-area: date; color: var(--pj-muted); }
.nw-table .nw-table__place { grid-area: place; color: var(--pj-muted); }
.nw-table .nw-table__level { grid-area: level; }

.nw-table__place i {
  margin-right: 4px;
  color: var(--pj-muted);
}

@container nw-list (min-width: 620px) {
  .nw-table {
    display: table;
  }

  .nw-table thead {
    display: table-header-group;
  }

  .nw-table tbody {
    display: table-row-group;
  }

  .nw-table tr {
    display: table-row;
    border: 0;
  }

  .nw-table .nw-table__num,
  .nw-table th,
  .nw-table td {
    display: table-cell;
  }

  .nw-table th {
    padding: 10px 12px;
    border-bottom: 1px solid var(--pj-line);
    color: var(--pj-ink);
    font-size: 0.85rem;
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
  }

  .nw-table td {
    padding: 12px;
    border-bottom: 1px solid var(--pj-line);
    font-size: 0.95rem;
    vertical-align: middle;
  }

  .nw-table tbody tr:last-child td {
    border-bottom: 0;
  }

  .nw-table .nw-table__num {
    width: 48px;
    color: var(--pj-muted);
  }

  .nw-table .nw-table__who {
    display: table-cell;
  }

  .nw-table .nw-who {
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .nw-table .nw-table__name {
    font-size: 1rem;
  }

  .nw-table .nw-table__date,
  .nw-table .nw-table__place {
    color: var(--pj-ink);
  }

  .nw-table tr .nw-level {
    padding: 3px 10px;
    font-size: 0.8rem;
  }

  /* La date, le lieu et le niveau restent sur une ligne : c'est le nom qui
     cède la place, et il se coupe proprement à côté de son avatar. */
  .nw-table .nw-table__date,
  .nw-table .nw-table__place,
  .nw-table .nw-table__level {
    white-space: nowrap;
  }
}

/* Un en-tête triable est un bouton dans la cellule : `width: auto`, et
   l'allure d'un intitulé, pas d'un bouton. */
.nw-sort {
  width: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.nw-sort i {
  color: var(--pj-muted);
  font-size: 0.8rem;
}

.nw-sort.is-active,
.nw-sort.is-active i {
  color: var(--pj-orange-text);
}

/* Les initiales, sur une teinte choisie par le nom : toujours la même pour
   une même personne. */
.nw-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  font-size: 0.9rem;
  font-weight: 700;
}

.nw-avatar--0 { background: var(--pj-orange-soft); color: var(--pj-orange-text); }
.nw-avatar--1 { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.nw-avatar--2 { background: var(--pj-success-soft); color: var(--pj-success); }
.nw-avatar--3 { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.nw-avatar--4 { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.nw-avatar--5 { background: var(--pj-danger-soft); color: var(--pj-danger); }

.nw-level {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--pj-radius-sm);
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
}

.nw-level--1 { background: var(--pj-danger-soft); color: var(--pj-orange-text); }
.nw-level--2 { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.nw-level--3 { background: var(--pj-card-2); color: var(--pj-ink); }

/* Le pied : le résumé et la pagination, centrés sur téléphone, de part et
   d'autre sur poste. La pagination est toujours dessinée, même pour une page. */
.nw-foot {
  display: flex;
  flex-direction: column-reverse;
  align-items: center;
  gap: 12px;
  padding-top: 4px;
}

.nw-foot__summary {
  margin: 0;
  color: var(--pj-muted);
  font-size: 0.9rem;
  text-align: center;
}

.nw-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.nw-pager__btn {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-weight: 700;
  cursor: pointer;
}

/* Blanc sur `--pj-orange-fill`, comme la gamme de boutons (§5) : ce fond
   est le même dans les deux thèmes, son texte aussi. */
.nw-pager__btn.is-active {
  background: var(--pj-orange-fill);
  color: white;
}

.nw-pager__btn:disabled {
  opacity: 0.45;
  cursor: default;
}

.nw-pager__gap {
  color: var(--pj-muted);
}

@media (min-width: 768px) {
  .nw-foot {
    flex-direction: row;
    justify-content: space-between;
  }

  .nw-foot__summary {
    text-align: left;
  }
}

/* ── Proof of payment (E16-06) ──────────────────────────────────────────── */

/* The commercial's inline panel, and the admin desk's modal body. Same two
   pieces either side — the picture and the way to keep it — because the
   tester's note gives both roles the same right to see it. */
.cm-proof,
.wd-proof {
  display: grid;
  gap: 12px;
  justify-items: start;
}

.cm-proof {
  margin-top: 16px;
  padding: 18px;
  border-radius: var(--pj-radius, 16px);
  background: var(--surface-sunken);
  border: 1px solid var(--color-border);
}

.cm-proof__title {
  margin: 0;
  font-size: 1rem;
  font-weight: 800;
}

/* Bounded height, not just width: a receipt photographed portrait at 3000px
   would otherwise push the download button below three screens of paper. */
.cm-proof__img,
.wd-proof__img {
  max-width: 100%;
  max-height: 60vh;
  border-radius: var(--pj-radius-sm, 12px);
  border: 1px solid var(--color-border);
}

.cm-proof__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.cm-proof__btn,
.wd-proof__dl {
  width: auto;
}

/* The button is inside .commercial-line__side, a column that right-aligns its
   children; the link's own padding would otherwise sit it off the badge's
   edge. */
.commercial-line__link {
  width: auto;
  padding: 0;
  font-size: 0.875rem;
}

@media (max-width: 720px) {
  .commercial-line {
    flex-direction: column;
  }

  .cm-proof__actions .btn {
    width: 100%;
  }

  .commercial-line__side {
    align-items: flex-start;
    text-align: left;
  }

  .commercial-form__actions {
    flex-direction: column;
  }

  .commercial-form__actions .btn {
    width: 100%;
  }
}

/* --- CVthèque (E4-02): company-facing search + paid unlock ---
   Advanced filters moved into the shared .jo-filters / .jo-filters__grid
   panel (2026-09-10, mobile-first pass) — one grid definition rather than a
   second copy, see TrainingSearchPage/JobSearchPage for the same pattern. */
.cvtheque-company {
  display: flex;
  align-items: center;
  gap: 8px;
}

.cvtheque-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}

.cvtheque-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  border-radius: 18px;
  background: var(--surface-sunken);
  border: 1px solid var(--color-border);
}

.cvtheque-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

/* Keeps `.cvtheque-card__head` at exactly two children (identity, badge/actions)
   so its `space-between` still reads as "these two ends", not three items
   spread evenly — the avatar and the name/headline are one unit. */
.cvtheque-card__identity {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* A candidate's photo where they have one, initials where they do not
   (2026-09) — a plain grey silhouette does not tell two candidates apart in
   a results grid. `--sm` on a card, `--lg` on the profile fiche/modal. */
.cvt-avatar {
  flex-shrink: 0;
  border-radius: 50%;
  overflow: hidden;
  background: var(--pj-card-2);
}

.cvt-avatar--sm {
  width: 48px;
  height: 48px;
}

.cvt-avatar--lg {
  width: 72px;
  height: 72px;
}

.cvt-avatar__img,
.cvt-avatar__initials {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
  object-fit: cover;
}

.cvt-avatar__initials {
  color: var(--pj-muted);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.cvt-avatar--sm .cvt-avatar__initials {
  font-size: 1rem;
}

.cvt-avatar--lg .cvt-avatar__initials {
  font-size: 1.4rem;
}

.cvtheque-card__name,
.cvtheque-profile-name {
  color: var(--connected-text);
  font-weight: 800;
}

.cvtheque-card__headline {
  color: var(--connected-text);
}

.cvtheque-card__meta {
  font-size: 0.9rem;
}

.cvtheque-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cvt-chip {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-chip);
  color: var(--connected-primary);
  font-size: 0.8rem;
  font-weight: 600;
}

.cvtheque-card__actions {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.cvtheque-card__actions .btn {
  width: auto;
}

/* The "candidates for this offer" badge (2026-09) — status pill reused from
   the pipeline page (`.ap-status`, prosyjob-components.css §Application) plus
   a plain score figure. Nothing here duplicates that page's own styling. */
.cvtheque-card__candidature {
  display: flex;
  align-items: center;
  gap: 8px;
}

.cvtheque-card__score {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--pj-muted);
}

.cvtheque-offer-invalid {
  color: var(--pj-danger, var(--pj-muted));
}

/* A 44px square so the star stays a real tap target next to the pill-shaped
   "view profile" button, on a screen where ~90% of visitors are on a phone.
   Selector carries two classes on purpose: `.cvtheque-card__actions .btn`
   above also sets `width`, at the same specificity, so a bare `.cvt-favorite-btn`
   loses that tie by source order and the button shrinks to its icon's
   content width instead of staying a square. */
.btn.cvt-favorite-btn {
  width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  flex-shrink: 0;
  border: 1px solid var(--pj-line);
  border-radius: 12px;
  background: transparent;
  color: var(--connected-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
}

/* Same two-class bump as `.btn.cvt-favorite-btn` above, for the same reason:
   a bare `.cvt-favorite-btn--on` (one class) loses every one of these
   properties to that rule's higher specificity (two classes) — the star's
   glyph still swapped shape (outline to solid), which reads as "changed"
   from a distance, but the colour never did. Found by inspecting computed
   style, not by eye — the gray outline and gray "on" state look alike. */
.btn.cvt-favorite-btn.cvt-favorite-btn--on {
  color: var(--pj-orange);
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
}

.cvtheque-sort {
  display: flex;
  align-items: center;
}

.cvtheque-sort select {
  min-height: 40px;
}

/* Language filter chips (2026-09) — a `<label>` wrapping a `.sr-only`
   checkbox forwards a click on the whole pill to the input natively, so the
   full padded `span` is the tap target, not a fixed-size overlay guessing at
   the pill's rendered width. */
.cvt-lang-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.cvt-lang-chip {
  display: inline-flex;
  cursor: pointer;
}

.cvt-lang-chip span {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--pj-line);
  border-radius: 999px;
  color: var(--pj-ink);
  background: var(--pj-card);
  font-size: 0.9rem;
}

.cvt-lang-chip input:checked + span {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
}

.cvt-lang-chip input:focus-visible + span {
  outline: 2px solid var(--pj-orange);
  outline-offset: 2px;
}

.cvt-lang-mode {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 10px;
}

.cvt-lang-mode__option {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  font-size: 0.9rem;
}

.cvt-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 700;
  white-space: nowrap;
}

.cvt-badge--off {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.cvt-badge--on {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.cvtheque-notice {
  margin-top: 14px;
  padding: 14px 16px;
  border-radius: 16px;
}

.cvtheque-notice--lock {
  background: var(--pj-warning-soft);
  border: 1px solid color-mix(in srgb, var(--pj-warning-ink) 35%, transparent);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cvtheque-notice--lock .btn {
  width: auto;
}

.cvtheque-notice--ok {
  background: var(--pj-success-soft);
  border: 1px solid color-mix(in srgb, var(--pj-success) 35%, transparent);
  color: var(--pj-success);
}

/* La marge compensait à la main le `gap` que `#cvt-profile` n'avait pas.
   Le conteneur l'a maintenant (`pj-stack`) et les deux s'additionnaient :
   32px mesurés. L'espacement vient du `gap`, et d'une seule chose. */
.cvtheque-detail-card h3 {
  margin-bottom: 10px;
}

.cvtheque-detail-row {
  display: flex;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--surface-sunken);
}

.cvtheque-detail-label {
  flex: 0 0 40%;
  color: var(--connected-muted);
}

.cvtheque-detail-value {
  color: var(--connected-text);
  overflow-wrap: anywhere;
}

.cvtheque-profile-top {
  margin-bottom: 12px;
}

.cvtheque-profile-top .btn {
  width: auto;
}

@media (max-width: 720px) {
  .cvtheque-detail-row {
    flex-direction: column;
    gap: 2px;
  }

  .cvtheque-detail-label {
    flex-basis: auto;
  }
}

/* --- « Mes notifications » (maquette notifications.png, 2026-10-01) ---
   Une seule carte : l'en-tete (icone, titre, « Tout marquer comme lu », le
   filtre), la liste, la pagination numerotee. Chaque ligne porte l'icone et
   la couleur de son type ; une non lue, une pastille orange a gauche. */
.nc-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.nc-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "icon text text"
    "icon mark filter";
  align-items: center;
  gap: 8px 24px;
}

.nc-head__icon {
  grid-area: icon;
  align-self: start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-display);
}

.nc-head__text {
  grid-area: text;
  display: grid;
  gap: 4px;
  min-width: 0;
}

.nc-head__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.15;
  color: var(--pj-ink);
}

.nc-head__lead {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

.nc-head .nc-head__mark.btn {
  grid-area: mark;
  justify-self: start;
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.nc-head__filter {
  grid-area: filter;
  margin: 0;
  min-width: 0;
}

.nc-head__filter .form-select {
  min-height: 44px;
  min-width: 220px;
}

.nc-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
}

.nc-empty {
  margin: 0;
  padding: 16px 0;
}

.nc-item {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 12px 16px 12px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.nc-item:hover,
.nc-item:focus-visible {
  border-color: var(--pj-orange);
}

/* La pastille garde sa place sur une ligne lue, pour que les icones restent
   alignees ; elle n'est simplement pas peinte. */
.nc-item__dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
}

.nc-item--unread .nc-item__dot {
  background: var(--pj-orange);
}

.nc-item__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-card);
}

.nc-tone--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.nc-tone--success { background: var(--pj-success-soft); color: var(--pj-success); }
.nc-tone--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.nc-tone--accent { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.nc-tone--orange { background: var(--pj-orange-soft); color: var(--pj-orange); }
.nc-tone--danger { background: var(--pj-danger-soft); color: var(--pj-danger); }
.nc-tone--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.nc-item__body {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.nc-item__title {
  font-size: var(--pj-fs-md);
  font-weight: 600;
  color: var(--pj-ink);
}

.nc-item--unread .nc-item__title {
  font-weight: 700;
}

.nc-item__text {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  overflow-wrap: anywhere;
}

.nc-item__date {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.nc-pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 6px;
}

.nc-pager:empty {
  display: none;
}

.nc-pager__num,
.nc-pager__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  min-width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: none;
  color: var(--pj-ink);
  font: inherit;
  font-size: var(--pj-fs-md);
  cursor: pointer;
}

.nc-pager__arrow {
  border: 1px solid var(--pj-line);
  border-radius: 50%;
}

.nc-pager__num:hover,
.nc-pager__arrow:hover {
  background: var(--pj-orange-soft);
}

.nc-pager__num.is-current {
  background: var(--pj-orange-fill);
  color: var(--pj-card);
  font-weight: 700;
  cursor: default;
}

.nc-pager__arrow.is-disabled {
  opacity: 0.4;
  cursor: default;
}

@media (max-width: 720px) {
  /* Quatre pistes pour que la seconde rangee se partage a peu pres en deux :
     le bouton prend l'icone et une piste, le filtre les deux autres. */
  .nc-head {
    grid-template-columns: 60px repeat(3, minmax(0, 1fr));
    grid-template-areas:
      "icon text text text"
      "mark mark filter filter";
    gap: 12px 8px;
  }

  .nc-head__icon {
    width: 60px;
    height: 60px;
    font-size: var(--pj-fs-title);
  }

  .nc-head__title {
    font-size: var(--pj-fs-card);
  }

  .nc-head__lead {
    font-size: var(--pj-fs-sm);
  }

  .nc-head .nc-head__mark.btn {
    justify-self: stretch;
    justify-content: center;
    gap: 6px;
    padding-inline: 8px;
    font-size: var(--pj-fs-xs);
    white-space: nowrap;
  }

  .nc-head__filter .form-select {
    min-width: 0;
    padding-inline: 8px 28px;
    background-position: right 8px center;
    font-size: var(--pj-fs-xs);
  }

  .nc-item {
    align-items: flex-start;
    gap: 10px;
    padding: 10px;
  }

  .nc-item__dot {
    margin-top: 8px;
  }

  .nc-item__icon {
    width: 44px;
    height: 44px;
    font-size: var(--pj-fs-md);
  }

  .nc-item__title {
    font-size: var(--pj-fs-body);
  }

  .nc-item__text {
    font-size: var(--pj-fs-sm);
  }

  .nc-item__date {
    font-size: var(--pj-fs-xs);
  }

  .nc-pager {
    justify-content: center;
    gap: 2px;
  }
}

/* Sous 420 px la carte n'offre plus que ~230 px utiles : « Tout marquer comme
   lu » et le filtre ne tiennent plus cote a cote sans etre tronques (mesure a
   360 px), alors chacun prend sa rangee. */
@media (max-width: 420px) {
  .nc-head {
    grid-template-areas:
      "icon text text text"
      "mark mark mark mark"
      "filter filter filter filter";
  }

  .nc-head .nc-head__mark.btn {
    justify-self: start;
    font-size: var(--pj-fs-sm);
  }

  .nc-head__filter .form-select {
    font-size: var(--pj-fs-sm);
  }
}

/* Retour de désinscription (E25-04) : la personne arrive ici depuis un e-mail,
   après un clic qu'elle a pu faire par erreur. Le bandeau dit ce qui a changé,
   la ligne concernée est désignée — sans quoi l'écran montre six lignes
   identiques et ne répond pas à la question posée par le clic. */
.notif-unsub-notice {
  margin: 0 0 16px;
  padding: 12px 14px;
  border: 1px solid var(--pj-orange);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-ink);
  font-size: 0.92rem;
  line-height: 1.5;
}

/* La piece « payant » a cote d'une case WhatsApp (credits WhatsApp, 2026-10-01). */
.notif-paid-mark {
  color: var(--pj-orange);
  font-size: var(--pj-fs-xs);
}

/* Preferences de notification (maquette preference_notifications.png,
   2026-10-01) : une carte d'en-tete, puis une carte qui tient le tableau,
   l'encart des credits WhatsApp et celui des offres commerciales. */
.np-head {
  display: flex;
  align-items: center;
  gap: 24px;
}

.np-head__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-display);
}

.np-head__text {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.np-head__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.15;
  color: var(--pj-ink);
}

.np-head__lead {
  margin: 0;
  max-width: 520px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

.np-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

/* Le tableau */
.np-table {
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
}

.np-row {
  display: grid;
  grid-template-columns: minmax(0, 2.2fr) repeat(3, minmax(0, 1fr));
  align-items: center;
  gap: 8px;
  padding: 4px 20px;
  border-top: 1px solid var(--pj-line);
}

.np-row--head {
  padding-block: 14px;
  border-top: 0;
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.np-row__label {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
  color: var(--pj-ink);
  font-weight: 600;
}

.np-row--head .np-row__label {
  color: var(--pj-neutral-ink);
}

.np-row__label > i {
  flex: 0 0 auto;
  width: 24px;
  text-align: center;
  font-size: var(--pj-fs-card);
}

.np-tone--info { color: var(--pj-info-ink); }
.np-tone--success { color: var(--pj-success); }
.np-tone--accent { color: var(--pj-accent-ink); }
.np-tone--orange { color: var(--pj-orange); }
.np-tone--neutral { color: var(--pj-neutral-ink); }

.np-col {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.np-row--head .np-col i {
  font-size: var(--pj-fs-lg);
  color: var(--pj-ink);
}

.np-row--head .np-col .np-col__wa {
  color: var(--pj-success);
}

.np-col__short {
  display: none;
}

/* La case reste petite, la cible ne l'est pas (E25-04) : le label porte les
   44 px, la piece « payant » vit dedans. */
.np-cell {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  cursor: pointer;
}

.np-cell input {
  width: 22px;
  height: 22px;
  margin: 0;
}

/* La case « Dans l'app » est toujours cochee et non modifiable ; elle garde
   l'aspect d'une case cochee plutot que le gris d'un controle desactive. */
.np-cell input:disabled {
  opacity: 1;
}

.np-cell--paid .notif-paid-mark {
  position: absolute;
  left: calc(50% + 22px);
}

.np-row.is-unsubscribed {
  background: var(--pj-orange-soft);
}

/* Les deux encarts */
.np-box {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 18px 20px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.np-box p {
  margin: 0;
}

.np-credits__icon {
  flex: 0 0 auto;
  color: var(--pj-orange);
  font-size: var(--pj-fs-lg);
}

.np-credits__body {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.np-credits__legend {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.np-credits__balance {
  font-weight: 700;
  color: var(--pj-ink);
}

.np-credits__warning {
  padding: 10px 12px;
  border: 1px solid var(--pj-orange);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.np-credits__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 8px;
}

.np-credits__actions .btn,
.np-actions .np-save.btn {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

.np-offers__badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--pj-orange-fill);
  color: var(--pj-card);
  font-size: var(--pj-fs-sm);
}

.np-offers__body {
  flex: 1 1 auto;
  display: grid;
  gap: 6px;
  min-width: 0;
}

.np-offers__title {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.np-offers__list {
  display: grid;
  gap: 2px;
}

.np-check {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 40px;
  margin: 0;
  color: var(--pj-ink);
  cursor: pointer;
}

.np-check .form-check-input {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin: 0;
}

.np-offers__hint {
  margin-top: 8px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.np-actions {
  display: flex;
  justify-content: flex-end;
}

.np-actions .np-save.btn {
  min-width: 190px;
}

@media (max-width: 720px) {
  .np-head {
    align-items: flex-start;
    gap: 14px;
  }

  .np-head__icon {
    width: 60px;
    height: 60px;
    font-size: var(--pj-fs-title);
  }

  .np-head__title {
    font-size: var(--pj-fs-card);
  }

  .np-head__lead {
    font-size: var(--pj-fs-sm);
  }

  /* A 360 px la carte n'a que ~230 px utiles : sa marge interieure et celle
     des lignes se resserrent, et les trois colonnes de cases passent a 40 px,
     pour que « Candidatures » tienne en entier (mesure). */
  .np-card.pj-card {
    padding: 12px;
  }

  .np-row {
    grid-template-columns: minmax(0, 1fr) repeat(3, 40px);
    gap: 2px;
    padding: 2px 8px 2px 10px;
  }

  .np-row--head {
    padding-block: 10px;
    font-size: var(--pj-fs-2xs);
  }

  .np-row--head .np-col span {
    white-space: nowrap;
  }

  .np-cell {
    min-width: 40px;
  }

  .np-row--head .np-col {
    flex-direction: column;
    gap: 2px;
  }

  .np-col__long {
    display: none;
  }

  .np-col__short {
    display: inline;
  }

  .np-row__label {
    gap: 8px;
    font-size: var(--pj-fs-xs);
  }

  .np-row__label > i {
    width: 18px;
    font-size: var(--pj-fs-body);
  }

  .np-cell--paid .notif-paid-mark {
    left: auto;
    right: -4px;
  }

  .np-box {
    gap: 12px;
    padding: 14px 12px;
  }

  .np-actions .np-save.btn {
    width: 100%;
  }

  .np-offers__hint,
  .np-credits__legend {
    font-size: var(--pj-fs-sm);
  }

}

/* --- Help centre & terms (E4-09) --- */
/* « A QUOI SERT PROSYJOB ? » -- le bloc d accueil du centre d aide (PO,
   2026-10-05).

   Trois lignes a icone plutot qu un paragraphe continu : la demande porte
   justement sur le fait que la plateforme fait TROIS choses, et un bloc de
   prose les ferait lire comme une seule. Sur un telephone, trois reperes
   visuels valent trois paragraphes.

   La colonne de texte est bornee a 65 signes : c est la largeur ou l oeil
   retrouve le debut de la ligne suivante sans la chercher, et une page large
   etirerait ce texte sur toute sa mesure. */
.help-about__title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-card);
}

.help-about__lead {
  margin: 0;
  max-width: 65ch;
  font-size: var(--pj-fs-md);
}

.help-about__list {
  list-style: none;
  margin: 16px 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

.help-about__item {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* Largeur fixe : sans elle, une icone large et une etroite decalent leurs
   textes l un par rapport a l autre et la colonne ondule. */
.help-about__icon {
  flex: none;
  width: 24px;
  margin-top: 2px;
  text-align: center;
  color: var(--pj-orange);
}

.help-about__text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 60ch;
}

/* La phrase sur la simplicite se detache : c est la promesse, pas une
   quatrieme fonction. Un filet plutot qu un encadre -- un second cadre dans
   une carte ferait deux boites pour une idee. */
.help-about__simple {
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
  max-width: 65ch;
  color: var(--pj-muted);
}

/* LE CENTRE D AIDE SE REPLIE PAR RUBRIQUE (PO, 2026-10-05).

   Mesure a 360 px avant : 75 articles en 16 rubriques, extrait compris,
   184 px chacun -- pres de 14 000 px a faire defiler, dix-neuf ecrans. Replie,
   c'est seize lignes.

   Le `gap` tombe de 22 a 0 : des rubriques repliees sont une LISTE, et un
   intervalle de 22 px entre seize lignes en ferait a nouveau trois ecrans. Les
   bordures les separent. */
.help-list {
  display: flex;
  flex-direction: column;
}

.help-group {
  border-bottom: 1px solid var(--color-border);
}

.help-group:last-child {
  border-bottom: 0;
}

/* `list-style: none` ET `::-webkit-details-marker` : le triangle natif de
   `<summary>` se retire differemment selon les moteurs, et n'en traiter qu'un
   laisse l'autre afficher deux marqueurs -- le sien et notre chevron. */
.help-group__summary {
  display: flex;
  align-items: center;
  gap: 12px;
  /* 44 px : plancher de cible tactile, et cette ligne est ce qu'on vient
     toucher. */
  min-height: 44px;
  padding: 12px 4px;
  cursor: pointer;
  list-style: none;
}

.help-group__summary::-webkit-details-marker {
  display: none;
}

.help-group__title {
  flex: 1;
  min-width: 0;
  font-size: var(--pj-fs-md);
  font-weight: 600;
  color: var(--connected-text);
}

/* Le compte, parce qu'une ligne repliee ne dit rien de ce qu'elle cache :
   « Mes Miles (9) » se choisit, « Mes Miles » tout seul se tente. */
.help-group__count {
  flex: none;
  min-width: 24px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-align: center;
}

.help-group__chevron {
  flex: none;
  color: var(--pj-muted);
  transition: transform 0.15s ease;
}

.help-group[open] .help-group__chevron {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .help-group__chevron {
    transition: none;
  }
}

.help-group__items {
  list-style: none;
  margin: 0;
  padding: 0 0 8px;
}

/* Classe doublee : `.pj-app a { color: inherit }` (prosyjob.css) pese
   (0,1,1) et battait cette regle (0,1,0), donc le lien heritait de la
   couleur de son parent au lieu de la sienne. Voir check-link-colors.mjs.

   Plus une carte mais une LIGNE depuis le 2026-10-05 : l'extrait a disparu,
   donc il n'y a plus qu'un titre a porter, et un encadre par titre ferait de
   la rubrique ouverte ce que la page entiere etait avant. */
.help-item.help-item {
  display: block;
  padding: 10px 8px 10px 16px;
  /* 44 px de cible tactile, bord a bord : un titre court ne doit pas donner
     une zone cliquable plus petite qu'un titre long. */
  min-height: 44px;
  color: var(--pj-orange-text);
  text-decoration: none;
  overflow-wrap: anywhere;
}

/* LES TROIS PORTES DE L AIDE (PO, 2026-10-05).

   Le meme bloc sur le centre d'aide, l'annuaire et -- demain -- l'Academie.
   Chaque page montre les DEUX AUTRES ; voir `framework/utils/ressourceLinks`.

   En colonne et non en grille : il n'y en a que deux, et deux colonnes sur un
   telephone donnent deux boites etroites ou le sous-titre se coupe en six
   lignes. */
/* La bouée devant le titre, et des tuiles carrées : maquette de l'annuaire
   des partenaires (2026-10-05), valable pour les trois pages qui montrent
   ce bloc. */
.rs-doors__title {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 14px;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.rs-doors__title i {
  color: var(--pj-orange);
}

.rs-doors__list {
  display: grid;
  gap: 8px;
}

/* Classe DOUBLEE : `.pj-app a { color: inherit }` (prosyjob.css, chargee apres
   cette feuille) pese (0,1,1), et une qualification par la balise EGALISE au
   lieu de battre -- le piege paye trois fois le 2026-10-04. */
.rs-door.rs-door {
  display: flex;
  align-items: center;
  gap: 16px;
  /* 44 px : ces deux liens sont des portes, on les touche au pouce. */
  min-height: 44px;
  padding: 14px 16px;
  border: 1px solid var(--color-border);
  border-radius: 10px;
  background: var(--pj-card-2);
  color: var(--pj-ink);
  text-decoration: none;
}

.rs-door__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-lg);
}

.rs-door__text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.rs-door__title {
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

.rs-door__sub {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.rs-door__chevron {
  flex: none;
  color: var(--pj-muted);
}

/* « Obtenir le code d'un partenaire certifié », sur l'inscription (PO,
   2026-10-05), affiché par SHOW_PARTNER_LINK en bêta comme hors bêta
   (2026-10-06). Un bouton LÉGER : sa largeur et non la ligne entière (la
   règle `button, .btn` de cette feuille étire tout), 44 px de haut pour le
   pouce. Doublé pour passer devant `.btn`.

   Il est sorti du bloc du code parrain, donc il vit entre deux
   `.input-block` : en bloc (`flex` + `fit-content`) pour que ses marges se
   combinent avec celles des blocs voisins — -10 px contre les 20 px du bloc
   précédent le gardent à 10 px du champ, comme avant ; ses 20 px du bas
   rendent au formulaire le rythme que le bouton collé au prénom lui
   retirait (mesuré : 0 px). */
.btn.ref-find {
  display: flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  max-width: 100%;
  min-height: 44px;
  margin: -10px 0 20px;
  padding: 0 16px;
  font-size: var(--pj-fs-sm);
}

.btn.ref-find[hidden] { display: none; }

.ref-find__ext {
  font-size: var(--pj-fs-xs);
  opacity: 0.75;
}

.help-article__title {
  margin: 12px 0;
}

.help-article__body,
/* Le `white-space` n'est PLUS ici : il depend du dialecte du document, et
   `doc-body--plain` / `doc-body--html` en repondent (prosyjob-app.css §16).
   Le poser inconditionnellement ajoutait un interligne vide par bloc des
   que le corps etait du HTML, le source etant indente. */
.terms-body {
  line-height: 1.6;
  color: var(--connected-text);
  overflow-wrap: anywhere;
}

.terms-country {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  flex-wrap: wrap;
}

.terms-accept {
  margin-top: 18px;
}

.terms-accept .btn {
  width: auto;
}


/* ── Guest home landing ─────────────────────────────────────────────── */

.guest-home-header__actions .lang-switcher {
  min-width: 148px;
  min-height: 50px;
  border-radius: 18px;
  border-color: var(--color-border);
  box-shadow: none;
}


@media (max-width: 720px) {
  .layout-guest {
    padding: 12px;
  }

  .guest-home-header__actions #lang-switcher,
  .guest-home-header__actions .lang-switcher,
  .guest-home-header__button {
    width: 100%;
  }

}

@media (max-width: 480px) {
  .layout-guest {
    padding: 10px;
  }

  .guest-home-hero__cta,
  .guest-home-header__button,
  .guest-home-header__actions .lang-switcher {
    min-height: 52px;
  }

}

@media (max-width: 720px) {
  .layout-auth {
    overflow-x: hidden;
  }

  .layout-auth.is-mobile-sidebar-open::after {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(18, 28, 43, 0.32);
    z-index: 40;
  }
}


.dashboard-hero-card__mark,
.logo.logo-small img {
  object-fit: contain;
}
/* ══════════════════════════════════════════════════════════════════════════
   M1 Referentiel (E1-02)

   Mobile-first like the rest of this file: the base rules are what a 360px
   phone gets, breakpoints add room. Two groups here —

     .rf-autocomplete / .rf-chip / .rf-skills  are components reused outside
       the admin console (the candidate profile will mount the same city and
       skill controls), so they are deliberately NOT scoped to .layout-admin;
     everything else is admin-console furniture and is scoped.

   The tables become stacked cards below 768px using the data-label attribute
   each cell carries, per the project rule that a table must never force a
   phone to scroll sideways.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Shared: autocomplete dropdown ─────────────────────────────────────── */

/* The shared referential controls (.rf-autocomplete, .rf-chip, .rf-skills)
   moved to assets/css/prosyjob-app.css in E7. They are shared infrastructure
   used by 15 modules, not legacy markup, so they outlive this file. */

/* ── Admin console ─────────────────────────────────────────────────────── */

/*
  Les marges de cette phrase d'introduction étaient des compensations : quand
  la colonne de contenu de la console n'avait aucun `gap`, il fallait remonter
  le paragraphe de 8px vers son titre et le repousser de 16px du bloc suivant.
  `.layout-admin #content` porte maintenant l'espacement (20px, comme
  `.connected-page`), et ces deux corrections s'y ajoutaient au lieu de s'y
  substituer — 12px au-dessus, 36px en dessous, là où 20 étaient voulus.

  Si cette phrase doit un jour se coller à son titre, sa place est DANS
  `.page-header`, pas dans une marge négative qui lutte contre la coque.
*/
.layout-admin .rf-intro {
  margin: 0;
  max-width: 70ch;
}

.layout-admin .rf-filters .card-body {
  padding: 12px;
}

.layout-admin .rf-inline-check {
  padding-top: 8px;
}

.layout-admin .rf-form-label,
.layout-admin .form-label {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--color-muted);
  margin-bottom: 4px;
}

/* Tabs — a horizontal scroller on a phone rather than a wrapped pile. */
.layout-admin .rf-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 16px;
  padding-bottom: 4px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.layout-admin .rf-tab {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.88rem;
  white-space: nowrap;
  cursor: pointer;
}

.layout-admin .rf-tab.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

/* Queue rows — the shape shared by cities, skills and countries. */
.layout-admin .rf-queue-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 12px;
}

.layout-admin .rf-queue-title {
  margin: 0;
  font-size: 1rem;
}

.layout-admin .rf-queue-legend {
  font-size: 0.8rem;
}

.layout-admin .rf-queue__row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 0;
  border-bottom: 1px solid var(--color-border);
}

.layout-admin .rf-queue__row:last-child {
  border-bottom: none;
}

.layout-admin .rf-queue__name {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 2px;
  font-size: 0.98rem;
}

.layout-admin .rf-queue__meta {
  margin: 0;
  color: var(--color-muted);
  font-size: 0.84rem;
}

.layout-admin .rf-queue__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.layout-admin .rf-queue__actions .btn {
  min-height: 44px;
}

.layout-admin .rf-icon-btn {
  width: 44px;
  padding-left: 0;
  padding-right: 0;
  text-align: center;
}

/* Usage weight — the whole point of the curation queue: how much this row
   matters relative to the heaviest one on screen. */
.layout-admin .rf-weight {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

.layout-admin .rf-weight__bar {
  flex: 1;
  height: 6px;
  /* Was #eef1f5. Tokenised in E7-13: --color-border is var(--color-border) in light (no
     visible change) and follows the dark remap, so the usage track stops
     being a pale bar on a dark card. */
  background: var(--color-border);
  border-radius: 999px;
  overflow: hidden;
}

.layout-admin .rf-weight__bar span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #1a73e8, #4c9aff);
  border-radius: inherit;
}

.layout-admin .rf-weight__value {
  min-width: 5ch;
  text-align: right;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  color: var(--color-muted);
}

.layout-admin .rf-queue__row.is-verified .rf-weight__bar span {
  background: var(--surface-track);
}

/* Country facts */
.layout-admin .rf-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.82rem;
  color: var(--color-muted);
}

.layout-admin .rf-facts b {
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

.layout-admin .rf-facts__alert b {
  color: var(--color-warning);
}

.layout-admin .rf-iso {
  font-size: 0.75rem;
  color: var(--color-muted);
  font-weight: 400;
}

/* Tables that become cards on a phone */
.layout-admin .rf-table thead {
  display: none;
}

.layout-admin .rf-table,
.layout-admin .rf-table tbody,
.layout-admin .rf-table tr,
.layout-admin .rf-table td {
  display: block;
  width: 100%;
}

.layout-admin .rf-table tr {
  padding: 12px 0;
  border-bottom: 1px solid var(--color-border);
}

.layout-admin .rf-table td {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  border: none;
  text-align: right;
}

.layout-admin .rf-table td::before {
  content: attr(data-label);
  flex: 0 0 auto;
  color: var(--color-muted);
  font-size: 0.8rem;
  text-align: left;
}

.layout-admin .rf-table td:last-child {
  justify-content: flex-end;
}

.layout-admin .rf-table td:last-child::before {
  content: none;
}

.layout-admin .rf-row-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}

/* La file de moderation et la fusion (point 5). `.layout-admin` neutralise le
   `width: 100%` des boutons, donc rien a redresser ici — mais la zone tactile
   reste le seuil que le projet s'est donne. */
.layout-admin .rf-queue {
  margin: 12px 0 0;
  font-weight: 600;
  color: var(--color-muted);
}

.layout-admin .rf-merge-results {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  max-height: 220px;
  overflow-y: auto;
}

.layout-admin .rf-merge-result {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  text-align: left;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  margin-bottom: 6px;
}

.layout-admin .rf-merge-result:hover,
.layout-admin .rf-merge-result:focus-visible {
  background: var(--surface-sunken);
}

.layout-admin .rf-code {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  color: var(--color-muted);
}

/* Pager */
.layout-admin .rf-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
}

.layout-admin .rf-pager .btn {
  min-height: 44px;
}

.layout-admin .rf-pager__state {
  font-size: 0.85rem;
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

.layout-admin .rf-empty {
  padding: 24px 0;
  text-align: center;
  color: var(--color-muted);
}

/* Settings */
.layout-admin .rf-setting {
  padding: 14px 0;
  border-bottom: 1px solid var(--color-border);
}

.layout-admin .rf-setting:last-child {
  border-bottom: none;
}

.layout-admin .rf-setting__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.layout-admin .rf-setting__label {
  margin: 0;
  font-weight: 600;
  font-size: 0.92rem;
}

.layout-admin .rf-setting__key {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
  color: var(--color-muted);
}

.layout-admin .rf-rule {
  padding: 1px 6px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-size: 0.7rem;
  color: var(--color-muted);
}

/*
  `bg-secondary-light` n'existe nulle part — ni dans Bootstrap, qui a
  `bg-secondary` et pas cette variante, ni dans le thème admin, ni ici. Cinq
  badges de la console la portaient donc sans qu'elle ne déclare quoi que ce
  soit : il ne restait que `.badge`, dont la couleur de texte est blanche, sur
  un fond transparent. Blanc sur blanc, mesuré à l'écran — le badge « Hérité »
  des réglages était invisible depuis qu'il existe, et « Réglage global »
  (E30-05) l'aurait été aussi.

  Traité sur la classe plutôt que dans les trois gabarits qui l'écrivent : c'est
  le même défaut aux cinq endroits. Le rendu reprend celui de `.rf-rule`
  ci-dessus, la puce lisible que cette même ligne porte déjà.
*/
.layout-admin .badge.bg-secondary-light {
  padding: 1px 6px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--color-muted);
  background: transparent;
}

.layout-admin .rf-setting__edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.layout-admin .rf-setting__edit .btn {
  min-height: 44px;
}

/* Un réglage que seul le rôle global peut écrire, vu depuis un pays (E30-05).
   Le champ reste lisible et copiable — la règle s'applique à ce marché, son
   administrateur doit pouvoir la lire — mais il n'y a plus de bouton à
   cliquer : il répondait 422 à tous les coups. La mention prend sa place. */
.layout-admin .rf-setting__locked-hint {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--color-muted);
  font-size: 0.85rem;
}

.layout-admin .rf-setting--locked .form-control {
  background: var(--color-surface-2, transparent);
  cursor: default;
}

.layout-admin .rf-setting__json {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8rem;
}

/* Translations */
.layout-admin .rf-translation {
  padding: 14px 0;
  border-bottom: 1px solid var(--color-border);
}

.layout-admin .rf-translation:last-child {
  border-bottom: none;
}

.layout-admin .rf-translation__key {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.layout-admin .rf-translation__key code {
  font-size: 0.8rem;
  color: var(--color-text);
}

.layout-admin .rf-translation__file {
  margin: 0 0 8px;
  font-size: 0.84rem;
  color: var(--color-muted);
}

.layout-admin .rf-translation__file span {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.layout-admin .rf-translation__edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.layout-admin .rf-translation__edit .btn {
  min-height: 44px;
}

.layout-admin .rf-translation.is-overridden {
  border-left: 3px solid var(--color-warning);
  padding-left: 12px;
}

/* Price history */
.layout-admin .rf-history-title {
  margin: 20px 0 8px;
  font-size: 0.9rem;
}

.layout-admin .rf-history__line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 0;
  border-bottom: 1px dashed var(--color-border);
  font-size: 0.84rem;
}

.layout-admin .rf-history__line.is-inactive {
  opacity: 0.55;
  text-decoration: line-through;
}

.layout-admin .rf-history__date {
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* E15-06b — where a price came from, said next to the price itself. A number
   whose rung is invisible is a number nobody can correct: the console showed a
   dash for months while the checkout charged from the euro base. */
.layout-admin .rf-origin {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 0.7rem;
  white-space: nowrap;
  vertical-align: middle;
  background: var(--color-bg-soft, rgba(0, 0, 0, 0.05));
  color: var(--color-muted);
}

.layout-admin .rf-origin--base {
  background: rgba(13, 110, 253, 0.12);
  color: #0a58ca;
}

/* Which rung the price dialog writes. Only a global admin sees it, so it is a
   plain radio pair rather than a control that has to look disabled. */
.layout-admin .rf-scope-switch {
  margin-bottom: 14px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: 6px;
}

.layout-admin .rf-scope-switch__options {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-bottom: 6px;
}

.layout-admin .rf-scope-switch__option {
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 44px;
  margin: 0;
  cursor: pointer;
}

/* Merge dialog: say what will happen before it is done. */
.layout-admin .rf-merge__lead {
  margin-bottom: 12px;
}

.layout-admin .rf-merge__consequence {
  margin: 12px 0;
  padding: 10px 12px;
  background: var(--pj-warning-soft);
  border: 1px solid color-mix(in srgb, var(--pj-warning-ink) 35%, transparent);
  border-radius: var(--radius);
  font-size: 0.85rem;
}

.layout-admin .rf-alias-list {
  min-height: 44px;
  margin-bottom: 12px;
}

.layout-admin .rf-alias-form {
  display: flex;
  gap: 8px;
}

.layout-admin .rf-alias-form .btn {
  min-height: 44px;
  white-space: nowrap;
}

/* Field-level messages */
.layout-admin .rf-field-error {
  display: block;
  margin-top: 4px;
  color: var(--color-error);
  font-size: 0.8rem;
}

.layout-admin .rf-required {
  color: var(--color-error);
}

.layout-admin .rf-warn {
  color: var(--color-warning);
}

.layout-admin #country-active-group.is-locked {
  opacity: 0.6;
}

/* Modal subtitle: the template centers a short header title over a corner
   accent, so the entity name (a long, dynamic string) goes here, below the
   title, instead of in it — where it would collide with that accent. */
.layout-admin .rf-modal-sub {
  margin: -10px 0 18px;
  text-align: center;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--color-text);
}

.layout-admin .rf-modal-sub:empty {
  display: none;
}

/* ── 768px and up: rows become two-column, tables become tables ────────── */

@media (min-width: 768px) {
  .layout-admin .rf-queue__row {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }

  .layout-admin .rf-queue__main {
    flex: 1;
    min-width: 0;
  }

  .layout-admin .rf-queue__actions {
    flex: 0 0 auto;
    justify-content: flex-end;
  }

  .layout-admin .rf-weight {
    max-width: 320px;
  }

  .layout-admin .rf-table thead {
    display: table-header-group;
  }

  .layout-admin .rf-table {
    display: table;
  }

  .layout-admin .rf-table tbody {
    display: table-row-group;
  }

  .layout-admin .rf-table tr {
    display: table-row;
    padding: 0;
  }

  .layout-admin .rf-table td {
    display: table-cell;
    padding: 12px 8px;
    border-bottom: 1px solid var(--color-border);
    text-align: left;
  }

  .layout-admin .rf-table td::before {
    content: none;
  }

  .layout-admin .rf-setting__edit,
  .layout-admin .rf-translation__edit {
    flex-direction: row;
    align-items: flex-start;
  }

  .layout-admin .rf-setting__edit .form-control,
  .layout-admin .rf-translation__edit .form-control {
    flex: 1;
  }
}

/* ── 1200px and up: keep long text readable rather than edge-to-edge ───── */

@media (min-width: 1200px) {
  .layout-admin .rf-translation__edit .form-control,
  .layout-admin .rf-setting__edit .form-control {
    max-width: 720px;
  }
}

/* ══════════════════════════════════════════════════════════════════════════
   M2 Candidate (E1-04) — profile editor + public view.

   User-facing, so it lives in the connected-* design system, not the admin
   template. Mobile-first: single column on a phone, two columns from 640px.
   The completion meter is the anchor — it tells the candidate how credible
   their profile is and what to add next, which is the page's real job.
   ══════════════════════════════════════════════════════════════════════════ */

/*
  `display: grid` n'est pas décoratif ici : `gap` n'existe que sur un
  conteneur flex ou grid. Sur un élément resté en `display: block` la
  déclaration est purement inerte, et les blocs de la page se touchent —
  mesuré à 0px entre chacun des 10 blocs de cette page. Quatre coques de page
  du projet avaient perdu cette ligne (`.cand-editor`, `.cv-*`, `.co-*`,
  `.jo-*`) ; les coques voisines qui l'ont gardée (`.ap-*`, `.mt-page`,
  `.pay-*`, `.sub-page`) espacent correctement.
*/
/* `minmax(0, 1fr)` et pas la piste `auto` implicite : sans elle, le minimum
   automatique d'un enfant elargit la colonne au lieu de le faire deborder de
   lui-meme. Mesure a 357 px : la piste valait 593 px dans un element de 291,
   donc le hero — et tout ce qu'il contient — sortait de la colonne. Le defaut
   preexistait a E48 ; la barre d'onglets defilante est simplement le premier
   contenu assez large pour l'avoir revele. Meme raison que `.pj-stack` dans
   prosyjob-app.css §2. */
.cand-editor {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

/* ── Head: completion + visibility ─────────────────────────────────────── */

.cand-head {
  display: grid;
  gap: 18px;
  padding: 22px;
}

.cand-head__name {
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  margin: 0;
}

.cand-head__headline {
  margin: 2px 0 0;
}

.cand-meter {
  display: flex;
  align-items: center;
  gap: 12px;
}

.cand-meter__track {
  flex: 1;
  height: 10px;
  background: var(--surface-track);
  border-radius: 999px;
  overflow: hidden;
}

.cand-meter__fill {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, #1a73e8, #4c9aff);
  transition: width 0.5s ease;
}

.cand-meter__value {
  min-width: 3.5ch;
  text-align: right;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.cand-next {
  margin: 8px 0 0;
  font-size: 0.92rem;
}

.cand-head__views {
  margin: 4px 0 0;
  font-size: 0.85rem;
}

/* A CSS toggle switch — no external component. */
.cand-switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

.cand-switch input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.cand-switch__slider {
  position: relative;
  width: 46px;
  height: 26px;
  border-radius: 999px;
  background: var(--surface-track);
  transition: background 0.2s ease;
  flex: 0 0 auto;
}

.cand-switch__slider::before {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.2s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

.cand-switch input:checked + .cand-switch__slider {
  background: var(--color-success);
}

.cand-switch input:checked + .cand-switch__slider::before {
  transform: translateX(20px);
}

.cand-switch input:focus-visible + .cand-switch__slider {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.cand-switch__label {
  font-weight: 600;
}

.cand-visibility-hint {
  margin: 8px 0 0;
  font-size: 0.85rem;
}

/* ── Sections ──────────────────────────────────────────────────────────── */

.cand-section {
  padding: 20px;
}

.cand-section__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.cand-section__head h2 {
  font-size: 1.15rem;
  margin: 0;
}

.cand-section__note {
  margin: -4px 0 12px;
  font-size: 0.86rem;
}

.cand-subhead {
  margin: 20px 0 10px;
  font-size: 1rem;
}

/* 44px, not 38: ~90% of this platform's users are on a phone, and a small
   button is still a button someone taps with a thumb. The class stays "small"
   in type size and padding — what it gives up is the under-sized hit area. */
/* Personal-info grid: one column on a phone, two from 640px. */
.cand-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 16px;
}

.cand-req {
  color: var(--color-error);
}

.cand-form__actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
}

/* ── List items (experiences, educations, ...) ─────────────────────────── */

.cand-item {
  display: flex;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--color-border);
}

.cand-item:first-child {
  padding-top: 0;
}

.cand-item__body {
  flex: 1;
  min-width: 0;
}

.cand-item__actions {
  display: flex;
  gap: 6px;
  align-items: flex-start;
}

/* ── Un titre MÉRITÉ, dans la rubrique des certifications ───────────────
   La pastille verte dit « vérifié », la note dit pourquoi la ligne n'a ni
   crayon ni corbeille, le lien mène à la vérification publique. Le vert est
   `--pj-success`, qui tient son contraste dans les deux thèmes. */
.cand-item__badge {
  display: inline-flex;
  align-items: center;
  color: var(--pj-success);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
}

.cand-item__note {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.cand-item__link {
  display: inline-block;
  margin-top: 4px;
  font-size: var(--pj-fs-xs);
}

.cand-empty {
  padding: 8px 0;
  font-size: 0.9rem;
}

.cand-form {
  margin-top: 12px;
  padding: 16px;
  border: 1px dashed var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
}

/* ── Languages rows ────────────────────────────────────────────────────── */

.cand-lang-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-border);
}

.cand-lang-row__name {
  font-weight: 600;
}

.cand-lang-row__level {
  flex: 1;
  font-size: 0.88rem;
}

.rf-inline-add {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.rf-inline-add select {
  flex: 1;
  min-width: 120px;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
}

/* ── Interests input ───────────────────────────────────────────────────── */

.cand-interests__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 8px;
}

.cand-interests__input {
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
}

/* Static chips reused on the public view. */
/* .rf-chip--static moved to prosyjob-app.css with the rest of .rf-chip — a
   modifier has to live beside the base rule or the two drift apart. */

/* ── Danger zone ───────────────────────────────────────────────────────── */

.cand-danger {
  padding: 18px 20px;
  text-align: center;
}

/* Comme `.co-danger__btn` : deplace en fin de cascade (prosyjob-app.css §5),
   parce qu'il doit surclasser la definition du bouton secondaire. Le
   `border-color: #f3c9cc` qui etait ici etait par ailleurs le dernier hex brut
   de la zone de danger. */

/* ── Public view ───────────────────────────────────────────────────────── */

/* Le pendant de `.co-public` / `.jo-public`, qui manquait : sans lui la
   section empile en flux, et `.pj-card` n'a pas de marge. */
.cand-public {
  display: grid;
  gap: 16px;
}

.cand-public__locked {
  margin: 12px 0 0;
  padding: 10px 12px;
  background: var(--pj-warning-soft);
  border: 1px solid color-mix(in srgb, var(--pj-warning-ink) 35%, transparent);
  border-radius: var(--radius);
  font-size: 0.86rem;
}

.cand-public__notice {
  text-align: center;
  padding: 40px 20px;
}

/* ── Le profil, maquette `Candidat/apercu_du_profil.png` (2026-10-01) ───
   `renderCandidateProfile()` : une carte par section, ouverte par une icône
   dans un rond de couleur. Les colonnes suivent la largeur du PROFIL
   (`@container cand-profile`) et non celle de l'écran : la colonne centrale
   change de largeur avec les menus latéraux. Partagé par l'aperçu du
   candidat et la fiche qu'une entreprise consulte. */
.cpx {
  container: cand-profile / inline-size;
  display: grid;
  gap: 16px;
}

.cpx-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  align-items: stretch;
}

@container cand-profile (min-width: 640px) {
  .cpx-row--head,
  .cpx-row--two,
  .cpx-row--three {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* The company's view has no intro card: the identity takes the row. */
  .cpx-row--head:has(> :only-child) {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* 720, not 900: between the two side menus the profile is at most ~765px
   wide (measured at 1440px), and the maquette wants these three side by side. */
@container cand-profile (min-width: 720px) {
  .cpx-row--three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.cpx-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}

.cpx-card__body {
  min-width: 0;
}

.cpx-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  font-size: var(--pj-fs-lg);
}

.cpx-icon--orange { background: var(--pj-orange-soft); color: var(--pj-orange-text); }
.cpx-icon--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.cpx-icon--success { background: var(--pj-success-soft); color: var(--pj-success); }
.cpx-icon--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.cpx-icon--danger { background: var(--pj-danger-soft); color: var(--pj-danger); }
.cpx-icon--accent { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.cpx-icon--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.cpx-title,
.cpx-name {
  margin: 0 0 8px;
  font-size: var(--pj-fs-card);
  line-height: 1.25;
}

.cpx-lead {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.cpx-headline {
  margin: 0 0 4px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.cpx-facts {
  margin: 0 0 10px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.cpx-contact {
  display: grid;
  gap: 6px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--pj-fs-sm);
}

.cpx-contact li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.cpx-contact i {
  flex: 0 0 16px;
  color: var(--pj-info-ink);
  text-align: center;
}

.cpx-text {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.cpx-text p {
  margin: 0 0 8px;
}

.cpx-text p:last-child {
  margin-bottom: 0;
}

/* Les expériences : titre, entreprise et dates à gauche, la description à
   droite sur un profil large ; sur téléphone la description se replie
   derrière une flèche (`wireCandidateProfile()`). */
.cpx-exp {
  border-bottom: 1px solid var(--pj-line);
}

.cpx-exp:last-child {
  border-bottom: 0;
}

.cpx-exp__head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 10px 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.cpx-exp__dot {
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  margin-top: 4px;
  border: 2px solid var(--pj-info-ink);
  border-radius: 50%;
}

.cpx-exp__main {
  display: grid;
  flex: 1 1 auto;
  gap: 2px;
  min-width: 0;
}

.cpx-exp__title {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.cpx-exp__sub {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.cpx-exp__chevron {
  flex: 0 0 auto;
  margin-top: 4px;
  color: var(--pj-muted);
  transition: transform 0.15s ease;
}

.cpx-exp.is-open .cpx-exp__chevron {
  transform: rotate(90deg);
}

@media (prefers-reduced-motion: reduce) {
  .cpx-exp__chevron {
    transition: none;
  }
}

.cpx-exp__desc {
  display: none;
  margin: 0 0 12px 24px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  white-space: pre-line;
}

.cpx-exp.is-open .cpx-exp__desc {
  display: block;
}

@container cand-profile (min-width: 640px) {
  .cpx-exp {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    gap: 24px;
    padding: 12px 0;
  }

  /* Nothing folds on a wide profile: the head is a plain block there. */
  .cpx-exp__head {
    min-height: 0;
    padding: 0;
    cursor: default;
    pointer-events: none;
  }

  .cpx-exp__dot,
  .cpx-exp__chevron {
    display: none;
  }

  .cpx-exp__desc {
    display: block;
    margin: 0;
  }
}

.cpx-list {
  display: grid;
  gap: 12px;
}

.cpx-list--tight {
  gap: 8px;
}

.cpx-item {
  display: grid;
  gap: 2px;
}

.cpx-item strong {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.cpx-item__sub {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

/* ── Le titre vérifié sur la fiche QU'UNE ENTREPRISE CONSULTE ───────────
   Le `.cpx-item` est une grille d'une colonne (`display: grid` au-dessus),
   donc la pastille se justifie à gauche pour ne pas s'étirer sur la largeur
   de la carte. */
.cpx-item__badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  justify-self: start;
  color: var(--pj-success);
  font-size: var(--pj-fs-2xs);
  font-weight: 600;
}

.cpx-item__verify {
  justify-self: start;
  font-size: var(--pj-fs-2xs);
  font-variant-numeric: tabular-nums;
}

.cpx-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.cpx-chip {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 6px 14px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 500;
}

.cpx-chips--small .cpx-chip {
  min-height: 28px;
  padding: 4px 12px;
  font-size: var(--pj-fs-xs);
}

/* ── Self-preview (2026-09-12) ────────────────────────────────────────── */

.cand-preview {
  display: grid;
  gap: 16px;
}

.cand-preview__cv-head-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.cand-preview__cv-head-row h2 {
  margin: 0;
}

.cand-preview__cv-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.cand-preview__cv-actions button {
  width: auto;
}

/* ── « Vos autres CV », maquette `…_vos_autres_cv.png` (2026-10-01) ──────
   Une carte par CV : l'icône à la couleur de sa mise en page, le nom, la
   date et la mise en page, trois boutons et un « ⋮ ». Sur une carte étroite
   les boutons passent dessous et « Supprimer » ne garde que son icône. */
.cvo {
  container: cvo / inline-size;
  display: grid;
  gap: 16px;
}

.cvo-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 14px 16px;
}

.cvo-head__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-title);
}

.cvo-head__text h2 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-title);
}

.cvo-head__text p {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.cvo-head__add.btn {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
}

.cvo-list {
  display: grid;
  gap: 12px;
}

.cvo-cv {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "icon main more"
    "actions actions actions";
  align-items: start;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.cvo-cv__icon {
  grid-area: icon;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 12px;
  font-size: var(--pj-fs-lg);
}

.cvo-cv__icon--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.cvo-cv__icon--success { background: var(--pj-success-soft); color: var(--pj-success); }
.cvo-cv__icon--accent { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.cvo-cv__icon--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.cvo-cv__icon--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.cvo-cv__main {
  grid-area: main;
  min-width: 0;
}

.cvo-cv__name {
  margin: 0 0 4px;
  font-size: var(--pj-fs-md);
  overflow-wrap: anywhere;
}

.cvo-cv__meta span {
  white-space: nowrap;
}

.cvo-cv__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin: 4px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.cvo-cv__more {
  grid-area: more;
}

.cvo-cv__kebab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--pj-muted);
  cursor: pointer;
}

.cvo-cv__actions {
  grid-area: actions;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  gap: 8px;
}

.cvo-cv__btn.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: auto;
  min-width: 0;
  min-height: 44px;
  padding: 0 10px;
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

/* The « ⋮ » entries: an icon and its label, a tap target each. */
.cvo-cv .dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

/* « Supprimer » : rouge sur fond rouge doux, comme sur la maquette — un
   bouton du signal danger, pas une variante de couleur de la marque. */
.btn.cvo-cv__btn--danger {
  /* Icon-only on a phone: still a 44px target (measured at 36 before). */
  min-width: 44px;
  border: 0;
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.btn.cvo-cv__btn--danger:hover {
  background: color-mix(in srgb, var(--pj-danger) 16%, var(--pj-danger-soft));
  color: var(--pj-danger);
}

.cvo-cv__btn-label {
  display: none;
}

/* A phone-width card: the labels need every pixel — measured at 360px,
   « Aperçu » and « Définir par défaut » overlapped with their icons. The
   icons go (the trash keeps its own, it has no label), and each button
   takes its natural width with « Définir par défaut » taking the rest. */
@container cvo (max-width: 440px) {
  .cvo-cv__actions {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .cvo-cv__btn:not(.cvo-cv__btn--danger) i {
    display: none;
  }
}

@container cvo (min-width: 620px) {
  .cvo-head {
    grid-template-columns: auto minmax(0, 1fr) auto;
  }

  .cvo-head__add.btn {
    grid-column: auto;
    width: auto;
  }

  .cvo-cv {
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas: "icon main actions more";
    align-items: center;
  }

  .cvo-cv__actions {
    display: flex;
  }

  .cvo-cv__btn-label {
    display: inline;
  }
}

/* ── Activation ────────────────────────────────────────────────────────── */

.candidate-activate__points {
  margin: 16px 0 0;
  padding-left: 18px;
  display: grid;
  gap: 6px;
}

.candidate-activate-card {
  padding: 22px;
}

.candidate-activate__actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.candidate-activate__mode-switch {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 18px;
}

.candidate-activate__mode-switch .btn {
  width: auto;
}

.candidate-activate__mode-switch .btn.is-active {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text, var(--pj-orange));
  border-color: var(--pj-orange);
}

/* ── 640px and up: two-column forms and a row-based head ───────────────── */

@media (min-width: 640px) {
  .cand-grid {
    grid-template-columns: 1fr 1fr;
  }

  .cand-grid .field--check {
    justify-content: flex-start;
  }

  .cand-head {
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .cand-head__visibility {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 18px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
  }

  .cand-visibility-hint {
    flex: 1;
    min-width: 220px;
    margin: 0;
  }
}

/* ======================================================================== *
 *  M3 CvLibrary — Mes CV, composition editor, preview
 *  Mobile-first: single column at 360px, richer from 640px. Reuses the
 *  candidate editor's card/section/switch vocabulary where it fits.
 * ======================================================================== */

/* `gap` sans `display` ne produit rien — voir la note sur `.cand-editor`. */
.cv-list,
.cv-editor,
.cv-preview {
  display: grid;
  gap: 16px;
}

/* ── Mes CV ─────────────────────────────────────────────────────────────── */

.cv-list__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 22px;
}

.cv-list__intro h1 {
  margin: 0;
  font-size: clamp(1.4rem, 3.5vw, 1.9rem);
}

.cv-list__intro p {
  margin: 4px 0 0;
}

.cv-list__new {
  flex: 0 0 auto;
}

.cv-list__body {
  display: grid;
  gap: 14px;
}

.cv-card {
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.cv-card--archived {
  opacity: 0.72;
}

.cv-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px 12px;
}

.cv-card__name {
  margin: 0;
  font-size: 1.2rem;
  flex: 1;
  min-width: 0;
  word-break: break-word;
}

.cv-card__badges {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
}

.cv-badge {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}

.cv-badge--default {
  background: var(--surface-chip);
  color: var(--connected-primary);
}

.cv-badge--archived,
.cv-badge--virtual {
  background: var(--surface-track);
  color: var(--color-muted);
}

.cv-badge--featured {
  background: var(--pj-warning-soft);
  color: #8a5b00;
}

.cv-card__desc {
  margin: 0;
  font-size: 0.9rem;
}

.cv-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cv-chip {
  font-size: 0.8rem;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-chip);
  border: 1px solid var(--color-border);
  white-space: nowrap;
}

.cv-chip--muted {
  background: var(--color-bg);
  border-color: var(--color-border);
  color: var(--color-muted);
}

.cv-card__meta {
  margin: 0;
  font-size: 0.82rem;
}

.cv-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 4px;
  border-top: 1px solid var(--color-border);
  margin-top: 2px;
}

.cv-action--danger {
  color: var(--color-error);
  border-color: color-mix(in srgb, var(--pj-danger) 35%, transparent);
}

.cv-empty {
  text-align: center;
  padding: 40px 22px;
  display: grid;
  gap: 10px;
  justify-items: center;
}

.cv-empty h2 {
  margin: 0;
}

/* ── Composition editor ─────────────────────────────────────────────────── */

.cv-back {
  font-size: 0.9rem;
  font-weight: 600;
}

.cv-section {
  padding: 20px;
}

.cv-hint {
  display: block;
  margin-top: 4px;
  font-size: 0.82rem;
}

.cv-pick__item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 8px;
  border-radius: var(--radius);
  cursor: pointer;
  min-height: 44px;
}

.cv-pick__item:hover {
  background: var(--color-bg);
}

.cv-pick__item input {
  width: 20px;
  height: 20px;
  margin-top: 1px;
  flex: 0 0 auto;
}

.cv-pick__label {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.cv-pick__title {
  font-weight: 500;
}

.cv-pick__sub {
  font-size: 0.83rem;
}

/* Un titre mérité, dans la pioche : cocher est la seule décision qui reste
   à son sujet, et la pastille dit pourquoi. */
.cv-pick__badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--pj-success);
  font-size: var(--pj-fs-2xs);
  font-weight: 600;
  white-space: nowrap;
}

/* ── Le composeur, maquette `Candidat/CV.png` (2026-09-30) ──────────────
   Deux colonnes sur ordinateur — « Le CV » à gauche, « Contenu du CV » et les
   boutons à droite — une seule sur téléphone, où les boutons deviennent la
   barre fixe `.pj-savebar` (prosyjob-app.css). Chaque boîte qui tient deux
   cartes déclare son `gap` : la page n'a pas d'autre espacement (§9). */
.cv-editor__head {
  display: grid;
  gap: 4px;
}

/* Opening the composer scrolls its host to the top; on a wide screen the top
   bar is sticky and hid « Nouveau CV » under it (measured at 1440px). */
.cv-editor-host {
  scroll-margin-top: calc(var(--pj-topbar-h) + 12px);
}

/* « Retour à mes CV » : un lien d'action, à la taille d'une cible tactile. */
.cv-editor__back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: start;
  width: auto;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  cursor: pointer;
}

.cv-editor__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  line-height: 1.15;
}

.cv-editor__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.cv-editor__side {
  display: grid;
  gap: 16px;
  align-content: start;
}

@media (min-width: 992px) {
  .cv-editor__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
}

.cv-editor__card-head {
  margin-bottom: 16px;
}

.cv-editor__card-head h3 {
  margin: 0 0 6px;
  font-size: var(--pj-fs-card);
}

.cv-editor__card-head p {
  margin: 0;
  font-size: var(--pj-fs-sm);
}

/* Mise en page + langue côte à côte, même sur téléphone ; le statut seul
   prend une demi-largeur, comme sur la maquette. */
.cv-editor__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 16px;
}

/* Une section du contenu : repliée, une case pour toute la section. */
.cv-acc-list {
  display: grid;
  gap: 12px;
}

.cv-acc {
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.cv-acc__head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px 0 16px;
}

.cv-acc__all.form-check-input {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin: 0;
}

.cv-acc__toggle {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
  min-height: 56px;
  padding: 12px 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.cv-acc__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.cv-acc__title {
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.cv-acc__count {
  font-size: var(--pj-fs-sm);
  font-weight: 400;
  color: var(--pj-muted);
}

.cv-acc__hint {
  font-size: var(--pj-fs-sm);
}

.cv-acc__chevron {
  flex: 0 0 auto;
  color: var(--pj-muted);
  transition: transform 0.15s ease;
}

.cv-acc.is-open .cv-acc__chevron {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .cv-acc__chevron {
    transition: none;
  }
}

.cv-acc__body {
  display: grid;
  gap: 2px;
  padding: 0 12px 12px;
  border-top: 1px solid var(--pj-line);
}

.cv-acc__empty {
  margin: 12px 4px 0;
  font-size: var(--pj-fs-sm);
}

/* « Inclure mes centres d'intérêt » : une option du CV entier, pas d'une
   section — posée à part, sur le fond doux de la marque. */
.cv-editor__interests {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  margin: 16px 0 0;
  padding: 14px 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-ink);
  font-weight: 600;
  cursor: pointer;
}

.cv-editor__interests .form-check-input {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin: 0;
}

.cv-editor__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.cv-editor__actions .btn {
  display: inline-flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

@media (max-width: 576px) {
  /* The count keeps its number, the hints go: five folded sections must fit
     on one phone screen, which is the point of folding them. */
  .cv-acc__count-word,
  .cv-acc__hint {
    display: none;
  }

  .cv-acc__toggle {
    min-height: 48px;
    padding: 8px 0;
  }

  /* `.pj-savebar` fixes the bar at the bottom; stacked, full width. */
  .cv-editor__actions.pj-savebar {
    flex-direction: column;
    gap: 8px;
  }

  .cv-editor__actions .btn {
    width: 100%;
  }

  /* Three stacked buttons are taller than the one-button bar
     `.pj-has-savebar` makes room for (104px). */
  .cv-editor-host {
    padding-bottom: 190px;
  }
}

/* ── Preview (the rendered CV document) ─────────────────────────────────── */

.cv-preview__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cv-preview__actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.cv-preview__actions .btn {
  width: auto;
}

.cv-preview__note {
  margin: 0;
  font-size: 0.85rem;
}

/* Le CV tel que le serveur le dessine (E57) : un document dans un iframe
   bac à sable, dimensionné à son contenu par `mountCvDocument()`. Sa mise en
   forme est à l'intérieur ; d'ici on ne règle que le cadre. */
.cv-doc-frame {
  display: block;
  width: 100%;
  min-height: 240px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

@media (min-width: 640px) {
  .cv-list__body {
    gap: 16px;
  }

  .cv-pick__items {
    grid-template-columns: 1fr 1fr;
    gap: 2px 16px;
  }
}


/* ======================================================================== *
 *  M4 Company (E2-02) — mes entreprises, espace entreprise, page publique
 *  Mobile-first: everything is a single column at 360px and gains columns
 *  from 640px. Reuses the candidate/CV card vocabulary rather than inventing
 *  a third one; what is genuinely new here is the rights grid, which has to
 *  stay readable with seventeen checkboxes on a phone.
 * ======================================================================== */

/* `gap` sans `display` ne produit rien — voir la note sur `.cand-editor`. */
.co-list,
.co-create,
.co-space,
.co-public,
.co-invitation {
  display: grid;
  gap: 16px;
}

/* ── Mes entreprises ────────────────────────────────────────────────────── */

.co-list__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 22px;
}

.co-list__intro h1 {
  margin: 0;
  font-size: clamp(1.4rem, 3.5vw, 1.9rem);
}

.co-list__intro p {
  margin: 4px 0 0;
}

.co-list__body {
  display: grid;
  gap: 14px;
}

.co-card {
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.co-card--suspended {
  opacity: 0.72;
}

.co-card__head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.co-card__logo,
.co-space__logo {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  background: var(--connected-accent-soft);
  color: var(--connected-accent);
  font-size: 1.2rem;
  overflow: hidden;
}

.co-card__logo img,
.co-space__logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.co-card__ident {
  min-width: 0;
}

.co-card__name {
  margin: 0;
  font-size: 1.1rem;
  overflow-wrap: anywhere;
}

/* Le nom d'une entreprise ou d'un organisme ouvre sa gestion, au meme titre
   que le bouton « Ouvrir » (retour PO, 2026-09-19 : sur telephone les gens
   touchent le nom et sont surpris qu'il ne reagisse pas).

   C'est un `<button>`, donc il faut defaire ce que la regle `button, .btn`
   du haut de ce fichier lui impose — `width: 100%` en tete — et lui rendre
   l'apparence du titre qu'il etait. `text-align: left` parce qu'un bouton
   centre par defaut, et le nom doit rester aligne sur la ligne de meta
   juste en dessous. */
.co-card__name-btn {
  width: auto;
  /* La zone de frappe est agrandie par le rembourrage, et la marge negative
     annule le decalage qu'il causerait : a l'ecran, rien ne bouge.

     Elle s'etend vers le HAUT et les COTES, presque pas vers le bas : mesure
     faite, il n'y a que 2 px entre le nom et la ligne de lieu juste en
     dessous, donc descendre plus bas volerait les touchers destines a
     celle-ci. On obtient 34 px de haut sur toute la largeur du nom — moins
     que les 44 px d'un bouton, et c'est assume : c'est un titre cliquable,
     pas un bouton, et l'agrandir davantage desserrerait visiblement la
     carte sur la liste ou l'espace vertical compte le plus. */
  padding: 10px 8px 2px;
  margin: -10px -8px -2px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  overflow-wrap: anywhere;
  cursor: pointer;
}

.co-card__name-btn:hover,
.co-card__name-btn:focus-visible {
  color: var(--pj-orange-text);
  text-decoration: underline;
}

.co-card__meta {
  margin: 2px 0 0;
  font-size: 0.88rem;
}

.co-card__badges,
.co-space__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.co-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}

.co-badge--owner {
  background: var(--surface-chip);
  color: var(--color-primary);
}

.co-badge--verified {
  background: var(--pj-success-soft);
  color: var(--color-success);
}

/* ── L'examen de certification, en console (2026-10-02) ─────────────────
   Neuf lignes, chacune : un libellé coché, la valeur à confronter, une date.
   En grille à partir de 640px, empilées en dessous — l'administration se
   tient aussi depuis un téléphone, et une ligne de trois colonnes à 360px
   rend la valeur illisible, c'est-à-dire précisément ce qu'on vient vérifier.

   Pas de `.pj-*` ici : `.layout-admin` et `.pj-app` sont exclusifs. Les
   tokens, eux, sont disponibles — `prosyjob-app.css` remiroite l'échelle à
   `:root` pour les contrôles communs aux trois coquilles. */
.ac-certif__state {
  margin: 0 0 4px;
  font-size: var(--pj-fs-sm);
}

.ac-certif__warning {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
}

.ac-certif__section {
  display: grid;
  gap: 10px;
  margin-bottom: 18px;
}

.ac-certif__section h5 {
  margin: 0;
  font-size: var(--pj-fs-sm);
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--pj-muted);
}

.ac-certif__doc {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--pj-line);
  border-radius: 8px;
}

.ac-certif__doc-name {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: var(--pj-fs-sm);
}

/* `width: auto` contre la règle `button, .btn` de cette feuille, qui met tout
   bouton nu à 100 % : dans une rangée, un bouton pleine largeur pousse le nom
   du fichier hors du cadre. */
.ac-certif__doc-open {
  flex: 0 0 auto;
  width: auto;
}

/* Une case et une valeur, et plus de colonne de date : la péremption est
   globale à l'entreprise (PO, 2026-10-02). La valeur passe sous la case en
   dessous de 640px — à 360 px, un libellé et un extrait de registre côte à
   côte se coupent tous les deux. */
.ac-certif__field {
  display: grid;
  gap: 2px;
  padding: 8px 10px;
  border: 1px solid var(--pj-line);
  border-radius: 8px;
}

.ac-certif__check {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  /* 44px de cible (E10), mesurés et non supposés. */
  min-height: 44px;
  font-weight: 600;
  cursor: pointer;
}

.ac-certif__check input {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
}

.ac-certif__value {
  overflow-wrap: anywhere;
  font-size: var(--pj-fs-sm);
}


.ac-certif__count {
  margin-left: 6px;
  font-size: var(--pj-fs-2xs);
  font-variant-numeric: tabular-nums;
}

@media (min-width: 640px) {
  .ac-certif__field {
    grid-template-columns: minmax(0, 260px) minmax(0, 1fr);
    align-items: center;
    gap: 12px;
  }
}

/* « Certifiée » : la couleur de son SCEAU, et plus l'anneau vert d'hier.
   Depuis que les deux marques se montrent ensemble (PO, 2026-10-02), c'est le
   sceau qui porte la distinction — un anneau par-dessus ferait deux signaux
   pour une seule chose, et la pastille verte à côté de la verte ne se
   détachait de toute façon pas. */
.co-badge--certified {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

/* ── LES DEUX MARQUES DE CONFIANCE (PO, 2026-10-02) ─────────────────────
   Montrées ensemble et jamais l'une à la place de l'autre : la certification
   est un étage AU-DESSUS de la vérification, et c'est en les voyant côte à
   côte qu'on le comprend. Dessinées par `framework/utils/trustMarks.js`, une
   fois pour les trois surfaces qui les portent (carte d'annuaire, fiche
   publique, espace de l'entreprise).

   La VÉRIFICATION est une coche simple, en vert : « cette entreprise existe,
   un administrateur l'a constaté ». */
.pj-check {
  color: var(--pj-success);
}

/* La CERTIFICATION est un SCEAU : la rosette de Font Awesome avec la coche
   posée dessus, composée par `fa-stack` faute d'un glyphe unique dans la
   version Free. C'est la forme que tout le monde lit comme « certifié »
   depuis les réseaux sociaux, et elle porte deux choses que la coche n'a pas :
   une silhouette dentelée, qui se reconnaît avant même d'être lue, et la
   couleur de MARQUE — parce que ce qui donne sa valeur à la certification,
   c'est qu'elle vient de Prosyjob.

   Le vert dirait « encore un contrôle technique » ; l'orange dit qui l'a
   délivrée. */
.pj-seal {
  /* `fa-stack` vaut 2em de large par défaut, ce qui réserve une colonne vide
     à côté d'un texte. La ramener à sa hauteur rend un sceau qui se pose dans
     une ligne comme un caractère. */
  width: 1.25em;
  height: 1.25em;
  line-height: 1.25em;
  vertical-align: -0.2em;
}

/* Un cran plus grand que la coche voisine, et c'est délibéré : la hiérarchie
   se voit avant de se lire. */
.pj-seal .fa-stack-2x {
  font-size: 1.25em; /* fs-ok: la rosette du sceau, dimensionnee sur le texte qui la porte */
  color: var(--pj-orange);
}

/* La coche à l'intérieur du sceau est en RÉSERVE — la couleur du fond de
   carte, pas un blanc littéral, pour que le sceau tienne aussi en thème
   sombre. `--pj-orange` ne bouge pas en sombre, mais ce qui l'entoure si. */
.pj-seal .fa-stack-1x {
  font-size: 0.55em; /* fs-ok: la coche DANS la rosette, proportionnee a elle */
  color: var(--pj-card);
}

/* ── LES HORAIRES, sur la fiche publique (PO, 2026-10-02) ───────────────
   L'ÉTAT d'abord, en gros : c'est la question qu'on se pose devant une fiche
   — « est-ce ouvert là, maintenant ? ». La semaine vient après, pour quand la
   réponse est non. */
.pe-schedule__status {
  margin: 0 0 10px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

/* Ouvert : la couleur de la confirmation, celle des coches de vérification.
   Fermé reste en encre neutre — une boutique fermée la nuit n'est pas une
   anomalie, et la peindre en rouge en ferait une. */
.pe-schedule__status--open {
  color: var(--pj-success);
}

.pe-schedule__week {
  display: grid;
  gap: 2px;
  margin: 0;
}

/* `dt`/`dd` dans une grille à deux colonnes : le jour à gauche, la plage à
   droite, et les sept lignes alignées entre elles. `tabular-nums` parce que
   des heures qui ne s'alignent pas se lisent comme sept lignes sans rapport. */
.pe-schedule__day {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  padding: 3px 0;
  font-size: var(--pj-fs-sm);
}

.pe-schedule__day dt {
  margin: 0;
  color: var(--pj-muted);
  font-weight: 400;
}

.pe-schedule__day dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* Aujourd'hui se trouve sans compter les lignes. */
.pe-schedule__day--today dt,
.pe-schedule__day--today dd {
  color: var(--pj-ink);
  font-weight: 700;
}

/* La marque d'une information certifiée, sur la fiche publique (§6). Posée
   dans la famille `.pe-*` et non `.co-*` : elle vit dans `PublicEntityView`,
   que la fiche entreprise et celle d'un organisme partagent. */
/* Les deux marques par champ ne portent plus de couleur : le sceau qu'elles
   contiennent a la sienne. Elles ne règlent plus que la TAILLE — un sceau posé
   dans un libellé suit ce libellé, et `em` est le seul repère qui le fasse. */
.pe-certified {
  margin-left: 2px;
  font-size: 0.85em; /* fs-ok: sceau pose DANS un libelle, il suit sa taille */
}

/* La meme coche, sur le formulaire de fiche (§5) : « chaque champ verifie
   apparait avec un symbole vert ». Deux classes et non une, parce que les deux
   ecrans vivent sous des coquilles differentes -- mais la meme couleur, parce
   que c est le meme fait. */
.co-certif-mark {
  margin-left: 4px;
  font-size: 0.9em; /* fs-ok: sceau pose DANS un libelle, il suit sa taille */
}

.co-badge--suspended {
  background: var(--pj-danger-soft);
  color: var(--color-error);
}

/* Les rubriques d un organisme, sur sa carte (2026-09-27).

   Une rangee a part, entre les pastilles et les actions, et pas dans
   `.co-card__actions` : « Ouvrir » est une decision sur l organisme,
   « Formations » un deplacement vers une rubrique. Melangees, les deux se
   lisent comme six boutons egaux et on ne voit plus lequel est le principal.

   Plus discretes, donc, que `.btn` : trait fin, fond de page, libelle en
   poids normal. */
.co-card__links {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* `width: auto` est obligatoire : la regle `button, .btn` de cette feuille
   met TOUT bouton a 100 % dans la coque connectee, classe ou non — quatre
   barres empilees au lieu d une rangee. Et 44px de haut parce que ceci se
   touche avec un pouce. */
.co-card__link {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  border: 1px solid var(--pj-line);
  border-radius: 10px;
  background: var(--pj-bg);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  text-align: left;
}

.co-card__link i {
  color: var(--color-primary);
}

.co-card__link:hover,
.co-card__link:focus-visible {
  border-color: var(--color-primary);
}

.co-card__actions,
.co-form__actions,
.co-invitation__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}


/* When the actions row sits straight in a .co-section (no <form class="co-form">
   between them to supply its own grid gap — the event wizard's steps are like
   this), give it room of its own. The `>` keeps this off every .co-form__actions
   nested a level deeper, which already gets 14px from .co-form's grid gap and
   would otherwise double up. */
.co-section > .co-form__actions {
  margin-top: 16px;
}

/* Every tap target clears 44px — most of this is used on a phone. */
.co-card__actions .btn,
.co-member__actions .btn,
.co-invite-row .btn,
.co-form__actions .btn {
  min-height: 44px;
}

/* The base .btn is width:100%, which is right for a form's single call to
   action and wrong for a row of small ones — two full-width gradient bars
   stacked under a card read as two separate decisions. Paired row actions
   hug their label at every width; the page-level buttons stay full width on
   a phone and hug from 640px (see the breakpoint below). */
.co-card__actions .btn,
.co-member__actions .btn,
.co-invite-row .btn,
.co-invite__link .btn {
  width: auto;
}

.co-empty {
  padding: 28px 22px;
  text-align: center;
}

.co-empty h2 {
  margin: 0 0 6px;
  font-size: 1.15rem;
}

.co-empty .btn {
  margin-top: 14px;
}

/* ── Mes entreprises, maquette du 2026-09-27 ──────────────────────────────

   Tout est sous `.co-mine` : `.co-card`, `.co-badge` et `.co-card__actions`
   sont partagés avec « Mes organismes » (ProviderListPage), qui ne change pas.

   Un seul cadre blanc pour l'en-tête et les cartes ; les cartes, dedans, sont
   des boîtes à filet et non des `.pj-card` — une ombre dans une ombre. */
/* Sur téléphone le cadre n'a pas d'habillage : la maquette le dessine plein
   écran, et la piste centrale n'y fait que ~297px — un cadre ET une carte à
   filet y mangeaient 60px de marges, et le nom se cassait mot par mot.
   Deux classes : `.pj-card` (prosyjob.css) charge après cette feuille et
   imposerait son fond et son rembourrage à égalité de poids. */
.co-mine .co-mine__frame {
  display: grid;
  gap: 18px;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
}

.co-mine__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px 24px;
}

.co-mine__head .co-list__intro {
  flex: 1 1 280px;
  min-width: 0;
}

.co-mine .co-mine__new {
  width: 100%;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.co-mine__list {
  display: grid;
  gap: 16px;
}

/* Le formulaire de création, déplié dans le cadre (2026-09-27). Une boîte à
   filet comme les cartes, mais teintée d'orange : on lit tout de suite que ce
   n'est pas une entreprise de plus, c'est celle qu'on est en train de créer. */
.co-mine__create-host {
  padding: 16px 12px;
  border: 1px solid color-mix(in srgb, var(--pj-orange) 35%, var(--pj-line));
  border-radius: var(--pj-radius);
  background: color-mix(in srgb, var(--pj-orange-soft) 35%, var(--pj-card));
  /* La coque connectée a une barre du haut collante : sans marge, le
     `scrollIntoView` d'ouverture glisserait le titre dessous. */
  scroll-margin-top: calc(var(--pj-topbar-h) + 12px);
}

.co-mine__create {
  display: grid;
  gap: 14px;
}

.co-mine__create-title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.co-mine__create .co-create__points {
  margin-top: 8px;
}

.co-mine__create p {
  margin: 0;
}

.co-mine__create .co-form__actions .btn {
  min-height: 44px;
}

@media (min-width: 640px) {
  .co-mine__create-host {
    padding: 22px;
  }

  .co-mine__create .co-form__actions .btn {
    width: auto;
  }
}

.co-mine__card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
}

/* Logo, identité, menu ⋮ : le menu reste dans le coin quelle que soit la
   longueur du nom, qui passe à la ligne à sa place. */
.co-mine__top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 8px 12px;
}

/* Le logo couvre les deux rangées (identité, puis pastilles) : sinon sa
   hauteur fixait celle de la première, et les pastilles tombaient sous le
   logo, loin du lieu qu'elles suivent. */
.co-mine .co-mine__logo {
  grid-row: span 2;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: 1.4rem;
}

.co-mine__ident {
  min-width: 0;
  display: grid;
  gap: 6px;
}

.co-mine .co-card__name {
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  line-height: 1.25;
}

.co-mine__place {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.co-mine__place .fa-location-dot {
  margin-right: 4px;
}

/* Les pastilles forment leur propre rangée, sous le nom ET sous le menu ⋮ :
   à 360px la colonne du nom ne fait que ~170px, et « Propriétaire » et
   « Vérifiée » s'y empilaient. La rangée prend la largeur à droite du logo. */
.co-mine .co-mine__badges {
  grid-column: 2 / -1;
}

.co-mine .co-badge {
  gap: 6px;
  padding: 5px 12px;
  font-size: 0.8rem;
}

.co-mine .co-badge--owner {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.co-mine .co-badge--verified {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.co-mine .co-badge--certified {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

/* Le bouton ⋮ : une cible de 44px (E10) pour une icône de 16. Bouton nu, donc
   `width: auto` contre la règle `button, .btn` de cette feuille. */
.co-mine__kebab {
  width: 44px;
  height: 44px;
  margin: -8px -10px 0 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--pj-muted);
  cursor: pointer;
}

.co-mine__kebab:hover,
.co-mine__kebab:focus-visible,
.co-mine__kebab[aria-expanded="true"] {
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

.co-mine__menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.co-mine__menu .dropdown-item i {
  width: 14px;
  text-align: center;
}

.co-mine .co-card__actions .btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-inline: 14px;
}

/* « Ma galerie » et « Mes actualités » : des liens discrets, à l'orange du
   texte. `a.` dans le sélecteur : `.pj-app a { color: inherit }` est à
   (0,1,1) et battrait une classe seule (CLAUDE.md §9). */
.co-mine a.co-mine__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  align-self: flex-start;
  color: var(--pj-orange-text);
  font-weight: 600;
  text-decoration: none;
}

.co-mine a.co-mine__link:hover {
  text-decoration: underline;
}

.co-mine__gallery {
  display: grid;
  gap: 6px;
}

/* Quatre colonnes à toutes les largeurs — trois photos et le « +N » —, bornées
   à 132px chacune pour qu'elles ne deviennent pas des bannières sur ordinateur. */
.co-mine a.co-mine__thumbs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 132px));
  gap: 8px;
  color: var(--pj-ink);
  text-decoration: none;
}

.co-mine__thumb {
  aspect-ratio: 4 / 3;
  border-radius: 10px;
  overflow: hidden;
  background: var(--pj-card-2);
}

.co-mine__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.co-mine__thumb--more {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

@media (min-width: 640px) {
  .co-mine .co-mine__frame {
    padding: 28px;
    gap: 24px;
    background: var(--pj-card);
    border: 1px solid var(--pj-line);
    box-shadow: var(--pj-shadow);
  }

  .co-mine .co-mine__new {
    width: auto;
  }

  .co-mine__card {
    padding: 20px 22px;
  }

  .co-mine .co-mine__logo {
    width: 72px;
    height: 72px;
    font-size: 1.7rem;
  }

  .co-mine__top {
    column-gap: 18px;
  }

  .co-mine .co-card__name {
    font-size: var(--pj-fs-card);
  }
}

/* ── Mes organismes, maquette du 2026-10-03 ───────────────────────────────

   Deux vues sur une page : la liste (`.tp-mine`) et, à sa place, le
   formulaire de création (`.tp-new`, ProviderCreatePanel). Tout est sous ces
   deux familles : `.co-badge` et `.co-card__name-btn` sont partagés avec
   « Mes entreprises », qui ne doit pas changer avec elles. */

/* L'icône en tuile orange : en-tête, carte sans logo, intro de la création. */
.tp-mine__icon {
  flex: none;
  width: 52px;
  height: 52px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 14px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-card);
}

.tp-mine__icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tp-mine__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 14px 16px;
  padding: 18px 16px;
}

.tp-mine__intro h1 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.2;
}

.tp-mine__intro p {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.tp-mine .tp-mine__new {
  grid-column: 1 / -1;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.tp-mine__card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
}

/* Logo, identité, menu ⋮ : le menu reste dans le coin quelle que soit la
   longueur du nom ; les pastilles forment leur propre rangée, sous le nom ET
   sous le menu, à droite du logo — même grille que « Mes entreprises ». */
.tp-mine__top {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 8px 14px;
}

.tp-mine .tp-mine__logo {
  grid-row: span 2;
}

.tp-mine__ident {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.tp-mine__name {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  line-height: 1.25;
}

.tp-mine__place {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.tp-mine__place .fa-location-dot {
  margin-right: 4px;
}

.tp-mine .tp-mine__badges {
  grid-column: 2 / -1;
}

.tp-mine .co-badge {
  padding: 5px 12px;
  font-size: var(--pj-fs-xs);
}

.tp-mine .tp-mine__badge--owner {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

/* Le bouton ⋮ : une cible de 44px pour une icône de 16. Bouton nu, donc
   `width: auto` contre la règle `button, .btn` de cette feuille. */
.tp-mine__kebab {
  width: 44px;
  height: 44px;
  margin: -8px -10px 0 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--pj-muted);
  cursor: pointer;
}

.tp-mine__kebab:hover,
.tp-mine__kebab:focus-visible,
.tp-mine__kebab[aria-expanded="true"] {
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

.tp-mine__menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.tp-mine__menu .dropdown-item i {
  width: 14px;
  text-align: center;
}

/* Les rubriques : des tuiles, deux par ligne sur téléphone, quatre ensuite. */
.tp-mine__tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.tp-mine__tile {
  width: auto;
  min-width: 0;
  min-height: 48px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.tp-mine__tile span {
  min-width: 0;
}

/* Sur un petit téléphone la piste centrale ne laisse qu'une centaine de
   pixels par tuile : « Statistiques » à côté de son icône n'y tient pas et se
   cassait au milieu du mot. L'icône passe alors au-dessus du libellé. */
@media (max-width: 419px) {
  .tp-mine__tile {
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    padding: 8px 6px;
    font-size: var(--pj-fs-sm);
    text-align: center;
  }
}

.tp-mine__tile i {
  flex: none;
  color: var(--pj-blue);
  font-size: var(--pj-fs-lg);
}

.tp-mine__tile:hover,
.tp-mine__tile:focus-visible {
  border-color: var(--pj-blue);
}

.tp-mine__actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
}

.tp-mine__actions .btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

@media (min-width: 768px) {
  .tp-mine__icon {
    width: 72px;
    height: 72px;
    border-radius: 16px;
    font-size: var(--pj-fs-title);
  }

  .tp-mine__head {
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 20px 24px;
    padding: 24px 28px;
  }

  .tp-mine__intro p {
    font-size: var(--pj-fs-md);
  }

  .tp-mine .tp-mine__new {
    grid-column: auto;
    width: auto;
    padding-inline: 22px;
  }

  .tp-mine__card {
    padding: 22px 28px;
  }

  .tp-mine__top {
    column-gap: 20px;
  }

  .tp-mine__name {
    font-size: var(--pj-fs-card);
  }

  .tp-mine__tiles {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 14px;
  }

  .tp-mine__tile {
    min-height: 56px;
    padding: 12px 18px;
    font-size: var(--pj-fs-md);
  }

  .tp-mine__actions {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .tp-mine__actions .btn {
    width: auto;
    padding-inline: 20px;
  }
}

/* ── Créer un organisme, déplié au-dessus de la liste ───────────────────── */

/* La coque connectée a une barre du haut collante : sans marge, le
   `scrollIntoView` d'ouverture glisserait le titre dessous. */
.tp-mine__create {
  scroll-margin-top: calc(var(--pj-topbar-h) + 12px);
}

.tp-new__intro {
  display: grid;
  gap: 18px;
  padding: 18px 16px;
  background: color-mix(in srgb, var(--pj-orange-soft) 70%, var(--pj-card));
}

.tp-new__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 14px 16px;
}

.tp-new__titles h2 {
  margin: 0 0 6px;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.2;
}

.tp-new__titles p {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.tp-new__points {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

.tp-new__points li {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: var(--pj-fs-body);
}

.tp-new__point-icon {
  flex: none;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-lg);
}

.tp-new__source,
.tp-new__form-card {
  display: grid;
  gap: 14px;
  padding: 18px 16px;
}

.tp-new__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

/* Les portes : une ligne chacune sur téléphone (icône, texte, radio), des
   cartes côte à côte ensuite. Ce sont des <button> : `width: auto` et
   `text-align: left` contre la règle `button { width: 100% }` et le centrage
   par défaut d'un bouton. */
.tp-new__choices {
  display: grid;
  gap: 10px;
}

.tp-new__choice {
  width: auto;
  min-height: 44px;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  text-align: left;
  cursor: pointer;
}

.tp-new__choice-icon {
  color: var(--pj-blue);
  font-size: var(--pj-fs-card);
}

.tp-new__choice-text {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.tp-new__choice-text strong {
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

.tp-new__choice-text span {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tp-new__radio {
  width: 22px;
  height: 22px;
  border: 2px solid var(--pj-line);
  border-radius: 50%;
  background: var(--pj-card);
}

.tp-new__choice:hover,
.tp-new__choice:focus-visible {
  border-color: var(--pj-orange);
}

.tp-new__choice.is-chosen {
  border-color: var(--pj-orange);
  background: color-mix(in srgb, var(--pj-orange-soft) 60%, var(--pj-card));
}

.tp-new__choice.is-chosen .tp-new__choice-icon {
  color: var(--pj-orange-text);
}

.tp-new__choice.is-chosen .tp-new__radio {
  border-color: var(--pj-orange);
  background: var(--pj-orange);
  box-shadow: inset 0 0 0 4px var(--pj-card);
}

/* Le formulaire : deux colonnes à toutes les largeurs, comme la maquette ; le
   nom prend plus de place que le sigle, l'e-mail toute la ligne. Une grille à
   douze pour dire ces trois largeurs sans sous-boîte. */
.tp-new__grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 4px 12px;
}

.tp-new__grid > * {
  grid-column: span 6;
  min-width: 0;
}

.tp-new__grid > .tp-new__wide {
  grid-column: span 7;
}

.tp-new__grid > .tp-new__narrow {
  grid-column: span 5;
}

.tp-new__grid > .tp-new__full {
  grid-column: 1 / -1;
}

.tp-new__actions .btn {
  width: auto;
  padding-inline: 20px;
}

@media (min-width: 768px) {
  .tp-new__intro,
  .tp-new__source,
  .tp-new__form-card {
    padding: 24px 28px;
  }

  .tp-new__head {
    gap: 20px 24px;
  }

  .tp-new__titles p {
    font-size: var(--pj-fs-md);
  }

  .tp-new__choices {
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 14px;
  }

  .tp-new__choice {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "icon radio" "text text";
    align-items: start;
    align-content: start;
    padding: 18px;
  }

  .tp-new__choice-icon {
    grid-area: icon;
    font-size: var(--pj-fs-title);
  }

  .tp-new__radio {
    grid-area: radio;
  }

  .tp-new__choice-text {
    grid-area: text;
  }

  .tp-new__grid {
    column-gap: 18px;
  }

  .tp-new__grid > .tp-new__wide {
    grid-column: span 8;
  }

  .tp-new__grid > .tp-new__narrow {
    grid-column: span 4;
  }
}

@media (min-width: 992px) {
  .tp-new__points {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
  }

  .tp-new__points li {
    padding-inline: 20px;
  }

  .tp-new__points li:first-child {
    padding-left: 0;
  }

  .tp-new__points li + li {
    border-left: 1px solid color-mix(in srgb, var(--pj-orange) 20%, var(--pj-line));
  }
}

/* ── Catalogue de formations d'un organisme, maquette du 2026-10-03 ───────

   TrainingCatalogPanel : la rangée d'actions, « Recherche et filtres », les
   pastilles de statut, les cartes et le pied de liste. Tout est sous `tf-` :
   `.jo-status` et `.jo-chip` restent ceux de « Mes offres », restylés ici
   seulement à l'intérieur d'une carte de formation. Les cartes se nomment
   `.tf-cat .tf-…` : `.pj-card` (prosyjob.css, chargée après) impose sinon son
   propre rembourrage de 26px à égalité de poids. */

.tf-cat .tf-cat__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 20px;
  padding: 18px 16px;
}

.tf-cat__head h1 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-display);
  font-weight: 800;
}

.tf-cat__head p {
  margin: 0;
}

.tf-cat__head-links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tf-cat__head-links .btn {
  width: auto;
  min-height: 44px;
}

/* La rangée d'actions : deux boutons côte à côte puis « Nouvelle formation »
   sur toute la largeur sur téléphone ; une ligne, le dernier à droite, ensuite. */
.tf-cat__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.tf-cat__actions .btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding-inline: 14px;
  font-weight: 600;
}

.tf-cat__actions .tf-cat__new {
  grid-column: 1 / -1;
}

/* Deux classes : un `.btn` seul est peint par le §5 de prosyjob-app.css. */
.btn.tf-cat__describe,
.btn.tf-filters__toggle {
  background: var(--pj-card);
  border: 1px solid var(--pj-orange);
  color: var(--pj-orange-text);
}

.btn.tf-cat__select {
  background: var(--pj-card-2);
  border: 1px solid var(--pj-line);
  color: var(--pj-ink);
}

.btn.tf-cat__select i {
  color: var(--pj-orange-text);
}

/* Le mode sélection est ouvert : le bouton le dit (case cochée, teinte). */
.btn.tf-cat__select.is-active {
  background: var(--pj-orange-soft);
  border-color: var(--pj-orange);
  color: var(--pj-orange-text);
}

.btn.tf-cat__describe:hover,
.btn.tf-filters__toggle:hover,
.btn.tf-cat__select:hover {
  background: var(--pj-orange-soft);
  border-color: var(--pj-orange);
  color: var(--pj-orange-text);
}

/* ── Recherche et filtres ─────────────────────────────────────────────── */

.tf-cat .tf-filters {
  padding: 14px;
}

.tf-filters__form {
  display: grid;
  gap: 12px;
}

/* Le titre et « Recherche avancée » : écran large seulement — sur téléphone
   la maquette garde la seule ligne de recherche et son bouton « Filtres ». */
.tf-filters__head {
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.tf-filters__head h2 {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.tf-filters .tf-filters__toggle {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-inline: 14px;
  font-weight: 600;
}

.tf-filters__chevron {
  transition: transform 0.15s ease;
}

.tf-filters__toggle.is-open .tf-filters__chevron {
  transform: rotate(180deg);
}

.tf-filters__search-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
}

.tf-filters__search {
  position: relative;
  margin: 0;
  min-width: 0;
}

.tf-filters__search i {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--pj-muted);
  pointer-events: none;
}

.tf-filters__search .form-control {
  min-height: 44px;
  padding-left: 40px;
}

.tf-filters__adv {
  display: grid;
  gap: 12px;
}

.tf-filters__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 12px;
}

.tf-filters__grid .form-group {
  min-width: 0;
  margin: 0;
}

.tf-filters__grid label {
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.tf-filters__grid .form-control {
  min-height: 44px;
}

.tf-filters__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.tf-filters__buttons .btn {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-inline: 18px;
}

/* ── Les pastilles de statut ──────────────────────────────────────────────
   Elles défilent dans leur propre rangée sur téléphone : sept pastilles ne
   tiennent pas sur 360px, et la page ne doit pas déborder. */
.tf-pills {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: thin;
}

.tf-pill {
  flex: none;
  width: auto;
  min-height: 40px;
  padding: 8px 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.tf-pill:hover {
  border-color: var(--pj-navy);
}

.tf-pill.is-active {
  border-color: var(--pj-navy);
  background: var(--pj-navy);
  color: var(--pj-card);
}

/* ── Une carte de formation ──────────────────────────────────────────────
   Téléphone : vignette, identité et menu ; les pastilles sous le titre ; les
   trois boutons sur toute la largeur. Écran large : les actions s'alignent
   sous le texte, à droite de la vignette. */
.tf-cat .tf-card {
  position: relative;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  grid-template-areas:
    "thumb ident menu"
    "thumb chips chips"
    "actions actions actions";
  align-items: start;
  gap: 8px 12px;
  padding: 14px;
}

/* La case du mode sélection se pose sur la vignette plutôt que dans une
   colonne à elle : une colonne vide hors de ce mode laissait une marge morte
   à gauche de chaque carte. */
.tf-card > .pj-select__box {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 1;
}

.tf-card__thumb {
  grid-area: thumb;
  width: 64px;
  height: 64px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: 10px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-card);
}

.tf-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tf-card__ident {
  grid-area: ident;
  min-width: 0;
}

.tf-card__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-md);
  font-weight: 800;
  line-height: 1.3;
  overflow-wrap: break-word;
}

.tf-card__meta,
.tf-card__views {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* Le domaine et le type : écran large seulement, comme la maquette. */
.tf-card__meta .tf-card__meta-wide {
  display: none;
}

.tf-card__views i {
  margin-right: 4px;
}

.tf-card__chips {
  grid-area: chips;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.tf-card .jo-status {
  border-radius: var(--pj-radius-pill);
  padding: 4px 12px;
  font-size: var(--pj-fs-xs);
}

.tf-card .jo-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 1px solid currentColor;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.tf-card .jo-chip--quiz {
  color: var(--pj-blue);
}

.tf-card .jo-chip--cursus {
  color: var(--pj-orange-text);
}

.tf-card__menu {
  grid-area: menu;
}

.tf-card__kebab {
  width: 44px;
  height: 44px;
  margin: -8px -8px 0 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--pj-muted);
  cursor: pointer;
}

.tf-card__kebab:hover,
.tf-card__kebab:focus-visible,
.tf-card__kebab[aria-expanded="true"] {
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

.tf-card__menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.tf-card__menu .dropdown-item i {
  width: 16px;
  text-align: center;
  color: var(--pj-orange-text);
}

.tf-card__menu .tf-menu__danger,
.tf-card__menu .tf-menu__danger i {
  color: var(--pj-danger);
}

.tf-card__actions {
  grid-area: actions;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.tf-card .tf-act,
.tf-card .tf-act--solid {
  width: auto;
  min-width: 0;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 6px 10px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  white-space: nowrap;
}

.tf-card .tf-act span,
.tf-card .tf-act--solid span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.btn.tf-act {
  background: var(--pj-card-2);
  border: 1px solid var(--pj-line);
  color: var(--pj-ink);
}

.btn.tf-act i {
  color: var(--pj-orange-text);
}

.btn.tf-act:hover {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-ink);
}

.btn.tf-act.tf-act--danger i {
  color: var(--pj-danger);
}

.tf-act__count {
  flex: none;
  min-width: 24px;
  padding: 1px 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
}

/* Sur un petit téléphone, trois boutons côte à côte n'ont qu'environ 70px
   chacun : « Modifier » à côté de son icône s'y coupait en « Mod… ». L'icône
   passe alors au-dessus du libellé, et le nombre d'inscrits dans le coin. */
@media (max-width: 479px) {
  .tf-card .btn.tf-act,
  .tf-card .btn.tf-act--solid {
    position: relative;
    flex-direction: column;
    gap: 2px;
    min-height: 52px;
    padding: 6px 4px;
    font-size: var(--pj-fs-xs);
  }

  .tf-card .tf-act__count {
    position: absolute;
    top: 4px;
    right: 4px;
    min-width: 0;
    padding: 0 6px;
  }
}

/* Sur téléphone, les boutons secondaires passent dans le menu ⋮. Trois
   classes, pour la même raison que le bouton « Filtres ». */
.tf-card .btn.tf-act--secondary {
  display: none;
}

/* ── Le pied de liste ─────────────────────────────────────────────────── */

.tf-cat .tf-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  padding: 12px 14px;
}

.tf-foot__size {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tf-foot__size .form-control {
  width: auto;
  min-height: 40px;
}

.tf-foot__range {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tf-foot__pager:empty {
  display: none;
}

.tf-foot__pager .paginations {
  margin: 0;
}

@media (min-width: 576px) {
  .tf-filters__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 768px) {
  .tf-cat .tf-cat__head {
    padding: 24px 28px;
  }

  .tf-cat__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
  }

  .tf-cat__actions .btn {
    width: auto;
    padding-inline: 20px;
  }

  .tf-cat__actions .tf-cat__new {
    margin-left: auto;
  }

  .tf-cat .tf-filters {
    padding: 20px 22px;
  }

  .tf-filters__head {
    display: flex;
  }

  .tf-filters__search-row {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Trois classes : `.pj-app .btn` (prosyjob-app.css, chargée après) pose
     son propre `display` à (0,2,0). */
  .tf-filters .btn.tf-filters__toggle--narrow {
    display: none;
  }

  .tf-cat .tf-card {
    grid-template-columns: 96px minmax(0, 1fr) auto auto;
    grid-template-areas:
      "thumb ident chips menu"
      "thumb actions actions actions";
    gap: 10px 16px;
    padding: 16px 18px;
  }

  .tf-card__thumb {
    width: 96px;
    height: 80px;
  }

  .tf-card__title {
    font-size: var(--pj-fs-lg);
  }

  .tf-card__meta .tf-card__meta-wide {
    display: inline;
  }

  .tf-card__chips {
    justify-content: flex-end;
  }

  .tf-card__actions {
    display: flex;
    flex-wrap: wrap;
  }

  .tf-card .tf-act,
  .tf-card .tf-act--solid {
    min-height: 40px;
    padding: 6px 14px;
  }

  .tf-card .btn.tf-act--secondary {
    display: inline-flex;
  }

  /* Ce que le menu ne porte que pour le téléphone. */
  .tf-card__menu .tf-menu__phone,
  .tf-card__menu--phone {
    display: none;
  }
}

@media (min-width: 992px) {
  .tf-filters__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Le retour de l'éditeur de formation, quand il est ouvert à la place de la
   liste : sa propre ligne, en tête de la carte. `width: auto` contre la règle
   `button, .btn` de cette feuille. */
.jo-editor__head .jo-editor__back {
  flex-basis: 100%;
  width: auto;
  justify-self: start;
  align-self: flex-start;
  min-height: 44px;
  padding-inline: 0;
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
}

/* ── L'éditeur de formation, maquettes du 2026-10-03 ─────────────────────

   TrainingEditorPanel : les onglets à icône (des ronds légendés sur
   téléphone), les champs de la maquette, la carte « Options de publication »
   et ses trois groupes. Tout est sous `.tf-ed`, posé sur la section : l'éditeur
   d'offre partage `.jo-editor` et ne doit pas changer avec lui.

   Le bleu de l'onglet actif est `--pj-info-ink`, et son texte `--pj-card` :
   blanc sur bleu foncé en clair, sombre sur bleu pâle en sombre — les deux
   thèmes gardent leur contraste sans règle de plus. */

.tf-ed .jo-editor__head > div {
  min-width: 0;
}

/* Les onglets : pastilles légendées et soulignées sur écran large… */
.tf-ed__tabs {
  display: grid;
  grid-auto-columns: minmax(0, 1fr);
  grid-auto-flow: column;
  gap: 4px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--pj-line);
}

.tf-ed__tab {
  position: relative;
  width: auto;
  min-width: 0;
  min-height: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 0 2px;
  border: 0;
  background: none;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  cursor: pointer;
}

.tf-ed__tab-icon {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--pj-line);
  border-radius: 50%;
  background: var(--pj-card-2);
  color: var(--pj-navy);
  font-size: var(--pj-fs-md);
}

.tf-ed__tab-label {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tf-ed__long {
  display: none;
}

.tf-ed__tab.is-active {
  color: var(--pj-info-ink);
}

.tf-ed__tab.is-active .tf-ed__tab-icon {
  border-color: var(--pj-info-ink);
  background: var(--pj-info-ink);
  color: var(--pj-card);
}

/* Le trait sous l'onglet actif, posé sur la ligne de la barre. */
.tf-ed__tab.is-active::after {
  content: "";
  position: absolute;
  left: 25%;
  right: 25%;
  bottom: -9px;
  height: 3px;
  border-radius: 3px;
  background: var(--pj-info-ink);
}

.tf-ed__tab:focus-visible .tf-ed__tab-icon,
.tf-ed__tab:hover .tf-ed__tab-icon {
  border-color: var(--pj-info-ink);
}

/* Public cible et prérequis côte à côte à toutes les largeurs, comme la
   maquette : deux champs courts tiennent sur 360px. */
.tf-ed__pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px 12px;
}

.tf-ed__pair .form-group {
  min-width: 0;
}

/* Le lieu replié : l'épingle devant la phrase, « Modifier » en orange. */
.tf-ed .co-location--view .co-location__text {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--pj-muted);
}

.tf-ed .co-location--view .co-location__text::before {
  content: "\f3c5";
  font-family: "Font Awesome 7 Free", "Font Awesome 6 Free", "Font Awesome 5 Free";
  font-weight: 900;
  font-size: var(--pj-fs-lg);
  color: var(--pj-navy);
}

.tf-ed .co-location--view .btn {
  width: 100%;
  min-height: 44px;
}

/* Gratuite à gauche, prix à droite, devise dessous : la grille de la maquette
   sur écran large, une colonne sur téléphone. */
.tf-ed__price {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 4px 16px;
}

.tf-ed__price .form-group {
  min-width: 0;
}

.tf-ed .form-check.tf-ed__free {
  display: block;
  min-height: 0;
  text-align: left;
}

.tf-ed .tf-ed__free > label {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  margin: 0;
  font-weight: 500;
}

.tf-ed .tf-ed__free > small {
  display: block;
  margin-left: 32px;
  text-align: left;
}

/* Prix et devise grisés pour une formation gratuite : visiblement sans objet. */
.tf-ed__price .form-control:disabled {
  opacity: 0.6;
}

/* ── Options de publication ─────────────────────────────────────────────── */

.tf-ed .tf-ed__options {
  gap: 16px;
  padding: 0;
  border: 0;
}

.tf-ed__options-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px 14px;
  align-items: start;
}

.tf-ed__options-head > i {
  margin-top: 4px;
  color: var(--pj-navy);
  font-size: var(--pj-fs-card);
}

.tf-ed__options-head h2 {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.tf-ed__options-head p {
  margin: 4px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

/* Un groupe : l'icône à gauche, le titre, la phrase et le contenu alignés
   à sa droite. Trois classes : `.jo-optgroup` vit dans prosyjob-app.css,
   chargée après cette feuille. */
.tf-ed .jo-optgroup.tf-ed__group {
  position: relative;
  margin: 0;
  padding: 16px 16px 16px 56px;
  border: 0;
  background: var(--pj-card-2);
}

.tf-ed .tf-ed__group-icon {
  position: absolute;
  top: 18px;
  left: 18px;
  color: var(--pj-navy);
  font-size: var(--pj-fs-lg);
}

/* Une `legend` se dessine sur le cadre de son `fieldset` ; flottante, elle
   rentre dans la boîte comme un titre ordinaire. La phrase qui suit dégage. */
.tf-ed .jo-optgroup.tf-ed__group .jo-optgroup__title {
  float: left;
  width: 100%;
  margin: 0 0 2px;
  padding: 0;
  font-weight: 700;
}

.tf-ed .jo-optgroup.tf-ed__group .jo-optgroup__lead {
  clear: both;
}

.tf-ed .jo-optgroup.tf-ed__group .form-control {
  background: var(--pj-card);
}

.tf-ed__empty a {
  font-weight: 600;
}

/* Enregistrer et Annuler : un peu d'air au-dessus, pleine largeur sur
   téléphone, à leur taille ensuite. */
.tf-ed .jo-editor__actions {
  margin-top: 12px;
}

.tf-ed .jo-editor__actions .btn {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

@media (min-width: 768px) {
  .tf-ed__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    padding-bottom: 12px;
  }

  .tf-ed__tab {
    flex-direction: row;
    gap: 10px;
    min-height: 48px;
    padding: 8px 18px 8px 14px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card);
    color: var(--pj-ink);
    font-size: var(--pj-fs-md);
  }

  .tf-ed__tab-icon {
    width: auto;
    height: auto;
    border: 0;
    background: none;
    font-size: var(--pj-fs-lg);
  }

  .tf-ed__long {
    display: inline;
  }

  .tf-ed__short {
    display: none;
  }

  .tf-ed__tab.is-active {
    border-color: var(--pj-info-ink);
    background: var(--pj-info-ink);
    color: var(--pj-card);
  }

  .tf-ed__tab.is-active .tf-ed__tab-icon {
    background: none;
  }

  .tf-ed__tab.is-active::after {
    left: 0;
    right: auto;
    width: 60%;
    bottom: -14px;
  }

  .tf-ed__price {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tf-ed__currency {
    grid-column: 1;
  }

  .tf-ed .co-location--view .btn {
    width: auto;
  }

  .tf-ed .jo-editor__actions .btn {
    width: auto;
    padding-inline: 22px;
  }

  .tf-ed .jo-optgroup.tf-ed__group {
    padding: 20px 22px 20px 64px;
  }

  .tf-ed .tf-ed__group-icon {
    top: 22px;
    left: 22px;
  }
}

/* ── Creation ───────────────────────────────────────────────────────────── */

.co-create__intro {
  padding: 22px;
}

.co-create__intro h1 {
  margin: 0 0 6px;
  font-size: var(--pj-fs-display);
}

.co-create__points {
  list-style: none;
  margin: 16px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.co-create__points li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: var(--pj-fs-body);
}

.co-create__points i {
  margin-top: 3px;
  color: var(--connected-accent);
}

.co-form-card,
.co-section {
  padding: 20px;
}

.co-form {
  display: grid;
  gap: 14px;
}

/* A labelled sub-section inside a .co-section (2026-09-06) — the marketplace
   wizards' pricing step used to stack tarifs, delivery/access and payment
   methods with no visual boundary between them, so a lone "Ajouter une
   variante de prix" button on an empty list read as an orphan control rather
   than the start of a section. First child carries no divider: it already
   sits right under the card's own padding. */
.co-section__block {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--pj-line);
}

.co-section__block:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.co-section__title {
  margin: 0 0 12px;
  font-size: var(--pj-fs-md);
  font-weight: 600;
}

/* Multiple price-variant rows had no gap of their own — each row's own
   .co-form__grid only spaces its two fields, never the row above it. */
/* Ou la publication apparait : galerie Prosyjob, mini-site, ou les deux
   (demande PO, 2026-09-19). Trois choix exclusifs, donc trois lignes
   empilees plutot qu'une rangee — a 360 px trois libelles cote a cote se
   couperaient, et chacun porte une phrase d'explication sous son nom. */
.mk-visibility__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-md);
}

.mk-visibility__intro {
  margin-bottom: 10px;
}

.mk-visibility__choice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  /* 44 px de hauteur de frappe minimum : c'est un choix qu'on touche du
     pouce, et la ligne occupe toute la largeur pour qu'on n'ait pas a viser
     le petit rond. */
  min-height: 44px;
  margin-bottom: 6px;
  padding: 8px 10px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  cursor: pointer;
}

.mk-visibility__choice.is-active {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
}

.mk-visibility__label {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.mk-visibility__name {
  font-weight: 600;
}

.mk-visibility__hint {
  font-size: 0.85rem;
}

/* L'avertissement « vous n'avez pas encore de mini-site ». Il informe, il
   n'interdit pas : quelqu'un peut preparer son contenu avant son site. */
.mk-visibility__warning {
  margin-top: 8px;
  padding: 8px 10px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
}

.mk-prices {
  display: grid;
  gap: 16px;
}

.mk-prices:not(:empty) {
  margin-bottom: 16px;
}

.co-form__grid {
  display: grid;
  gap: 14px;
}

/* Webbuilder (E34 M6) — the company's own template picker
   (`MySitePage._galleryView()`). A template author's cover screenshot has
   no controlled size, so the frame — not the image — decides the card's
   footprint: a fixed aspect-ratio box, `object-fit: cover` cropping
   whatever comes in rather than letting it overflow or stretch. Photo on
   top, name and category below, exactly the reading order the markup
   already produces. */
.wbs-tpl-grid {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
}

/* A long unbroken name (or a code, back when one was shown here — see
   .co-form__grid's own note) could otherwise impose its width on the whole
   column. */
.wbs-package-card h3 {
  overflow-wrap: anywhere;
}

/* "What do I actually get" (2026-09-05) — plain-language content counts
   under the package name, framed as capacity rather than a ceiling. Small
   on purpose: a detail, not the headline. */
.wbs-package-limits {
  margin: 2px 0 0;
  font-size: var(--pj-fs-sm);
  line-height: 1.4;
  color: var(--pj-ink);
}

.wbs-tpl-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 8px;
  text-align: left;
  padding: 10px;
}

.wbs-tpl-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--pj-radius-sm, 12px);
  display: block;
}

/* The template a company's site actually renders with, right in the picker
   it would otherwise have to leave to find out (the status line lives on a
   different screen state entirely). */
.wbs-tpl-card--current {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
}

/* First-time site setup (E34, UX pass 2026-08-28) — a plain 4-step tracker
   shown only while the company has no live site yet (`!status.en_ligne`);
   the same gallery/preview/packages screens render through it unchanged,
   and it never appears once the site is live or when those same screens
   reopen from "Changer de X" on the live, advanced screen. */
.wbs-wizard {
  margin-bottom: 20px;
}

.wbs-wizard__intro {
  margin-bottom: 10px;
}

.wbs-wizard-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.wbs-wizard-step {
  display: flex;
  align-items: center;
  gap: 8px;
  opacity: 0.55;
}

.wbs-wizard-step--active,
.wbs-wizard-step--done {
  opacity: 1;
}

.wbs-wizard-step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid var(--pj-line);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  flex-shrink: 0;
}

.wbs-wizard-step--active .wbs-wizard-step__num {
  background: var(--pj-orange);
  border-color: var(--pj-orange);
  color: #fff;
}

.wbs-wizard-step--done .wbs-wizard-step__num {
  background: var(--pj-orange-soft);
  border-color: var(--pj-orange);
  color: var(--pj-orange);
}

.wbs-wizard-step__label {
  font-size: var(--pj-fs-body);
  font-weight: 600;
  white-space: nowrap;
}

/* One mailbox account (2026-09-09) — a real boxed card instead of a single
   flex-wrap row mixing the address, the status badge, the "use as company
   email" slot and up to four action buttons as siblings: on a narrow screen
   that row wrapped wherever it ran out of space, never where the content
   actually broke into groups, which is what "chaotic" meant here. Each
   sub-block below is its own row on purpose, so wrapping only ever happens
   *inside* the actions row, never between unrelated pieces of information. */
.wbs-mailbox-card {
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm, 8px);
  padding: 12px;
  margin-bottom: 10px;
}

.wbs-mailbox-card__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.wbs-mailbox-card__address {
  word-break: break-all;
}

.wbs-mailbox-card__meta {
  margin-top: 2px;
  color: var(--pj-muted);
  font-size: 0.85em;
}

.wbs-mailbox-card__row {
  margin-top: 8px;
}

/* Two-per-row on a phone by construction (min-width plus the card's own
   ~340px content width), one-per-row only when a button's label genuinely
   needs it — never the arbitrary wrap of same-sized flex items the old
   markup produced. */
.wbs-mailbox-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.wbs-mailbox-card__actions .btn {
  width: auto;
  flex: 1 1 100px;
}

/* Logo and banner sit above the identity fields, stacked on a phone and side
   by side from 640px — same breakpoint as .co-form__grid below. */
.co-form__images {
  display: grid;
  gap: 14px;
}

/* GPS picker (E32 M1): Leaflet needs an explicit height on its container or
   the map renders as a 0px sliver with broken tiles. */
.gps-picker {
  border-radius: var(--pj-radius-sm, 8px);
  overflow: hidden;
  border: 1px solid var(--color-border);
}

.gps-picker__map {
  height: 240px;
}

/* « Ma position actuelle » (PO, 2026-09-18) : sur telephone, partir du pays
   entier et pincer jusqu'a sa rue est penible, alors que la personne remplit
   sa fiche depuis son entreprise neuf fois sur dix.

   Le bouton vit DANS `.gps-picker`, qui porte `overflow: hidden` et une
   bordure : il se lit donc comme faisant partie du cadre de la carte, pas
   comme un bouton de formulaire perdu en dessous. */
/* Recherche d'adresse (PO, 2026-09-18) : le troisieme chemin, a cote du
   bouton de position et du repere pose au doigt. En HAUT de la carte, parce
   que c'est le premier geste quand on ne reconnait pas ce qu'on voit. */
.gps-picker__search {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px;
  border-bottom: 1px solid var(--color-border);
}

.gps-picker__search input {
  /* Le champ prend la place restante et retombe seul a la ligne sous 360px,
     ou le bouton ne tient plus a cote. */
  flex: 1 1 12rem;
  min-width: 0;
  min-height: 44px;
}

.gps-picker__find {
  width: auto;
  min-height: 44px;
}

.gps-picker__results {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 180px;
  overflow-y: auto;
  border-bottom: 1px solid var(--color-border);
}

.gps-picker__result {
  width: 100%;
  min-height: 44px;
  text-align: left;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--color-border);
  padding: 8px 12px;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
  cursor: pointer;
}

.gps-picker__result:hover,
.gps-picker__result:focus {
  background: var(--pj-neutral-soft);
}
.gps-picker__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px;
  border-top: 1px solid var(--color-border);
}

.gps-picker__locate {
  /* Tout `<button>` nu est `width: 100%` dans la coquille connectee (regle
     `button, .btn` en haut de cette feuille) — sans ceci il barrerait toute
     la largeur sous la carte. */
  width: auto;
  min-height: 44px;
}

.gps-picker__status {
  margin: 0;
  padding: 0 8px 8px;
  font-size: 0.85rem;
  color: var(--pj-muted);
}

.gps-picker__status--ok {
  color: var(--pj-ink);
}

/* Une position imprecise doit se voir : c'est la difference entre « votre
   adresse est enregistree » et « votre appareil a devine a 2 km pres ». */
.gps-picker__status--warn {
  color: var(--pj-orange-text);
  font-weight: 600;
}

/* Le cercle de precision. Volontairement discret : il informe, il ne doit pas
   masquer la carte sous laquelle l'utilisateur cherche son toit. */
.gps-picker__accuracy {
  stroke: var(--pj-orange-text);
  stroke-opacity: 0.6;
  stroke-width: 2;
  fill: var(--pj-orange-text);
  fill-opacity: 0.12;
}

/* EF-021 — la file de curation vue par un responsable de zone. */
.zd-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.zd-card__actions .btn {
  min-height: 44px;
  width: auto;
}

/* EF-001 — le tracé d'un quartier. Plus haut que le sélecteur de point : on y
   dessine une forme, pas un repère, et 240px ne laissent pas voir un quartier
   entier avec ses voisins. */
.polygon-picker {
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm, 8px);
  overflow: hidden;
}

.polygon-picker__map {
  height: 360px;
}

.rf-boundary__state {
  color: var(--pj-muted);
  margin: 8px 0 0;
}

.rf-boundary__error:empty {
  display: none;
}

.rf-boundary__tools {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0;
}

.rf-boundary__tools .btn {
  min-height: 44px;
  width: auto;
}

.rf-boundary__import summary {
  cursor: pointer;
  margin-bottom: 8px;
}

.rf-boundary__import .btn {
  margin-top: 8px;
  min-height: 44px;
  width: auto;
}

@media (max-width: 575px) {
  .polygon-picker__map {
    height: 280px;
  }
}

/* Lightweight rich-text editor (2026-08-24): a contenteditable box with a
   small toolbar, no editor library — see RichTextEditor.js. */
.rte {
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm, 8px);
  overflow: hidden;
}

.rte__toolbar {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  /* L'écart ENTRE groupes ; celui de l'intérieur vaut 4px (voir .rte__group).
     Le groupement se lit par cette différence — mise en forme / insertion /
     assistant — plutôt que par des traits, qui tombent en début de ligne dès
     que la barre se replie (2026-09-16). */
  gap: 16px;
  padding: 6px;
  background: var(--pj-card-2, var(--pj-bg));
  border-bottom: 1px solid var(--pj-line);
}

.rte__group {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Le groupe « assistant » porte une teinte à lui. Mesuré à 360px : la barre
   se replie sur trois lignes, et « lien / vidéo » finissait sur la même que
   « dictée / améliorer » — quatre icônes d'affilée, où la différence d'écart
   (16px contre 4) se voit mal. La teinte, elle, survit au retour à la ligne,
   et elle dit la seule chose qui distingue vraiment ces deux boutons des
   neuf autres : ils dépensent des crédits. */
.rte__group--ai {
  padding: 0 4px;
  border-radius: 8px;
  background: var(--pj-orange-soft);
}

/* Au-dessus de 576px la barre tient sur une ligne : un trait peut alors
   renforcer la séparation sans jamais se retrouver orphelin en début de
   ligne. */
@media (min-width: 577px) {
  .rte__group + .rte__group {
    padding-left: 16px;
    border-left: 1px solid var(--pj-line);
  }

  .rte__toolbar {
    gap: 0;
  }
}

/* 44px, not 32 (2026-09-08, found while measuring the mini-site publication
   flow on mobile) — CLAUDE.md's tap-target floor, and this toolbar is the
   busiest touch surface in the app: news posts, company description and
   réalisations all share it. */
.rte__btn {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--pj-radius-sm, 6px);
  background: transparent;
  color: var(--pj-ink);
  cursor: pointer;
}

.rte__btn:hover,
.rte__btn:focus-visible {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text, var(--pj-orange));
}

/* LE NIVEAU DE TITRE (option `headings`, 2026-10-03) — un <select> et non
   trois boutons, parce qu il montre le niveau COURANT : on clique dans le
   document, et la liste dit si on est dans un titre. Trois boutons ne
   peuvent pas le dire, et « revenir en paragraphe » en demanderait un
   quatrieme.

   44px de haut comme `.rte__btn` juste au-dessus : meme barre, meme
   plancher de cible tactile (CLAUDE.md), et un controle plus bas que ses
   voisins se lit comme un controle desactive.

   `width: auto` explicitement : ce <select> ne porte pas `.form-control`,
   mais la coquille connectee etire volontiers ce qui ne dit rien, et une
   liste deroulante en pleine largeur mangerait la barre entiere. */
.rte__block {
  height: 44px;
  width: auto;
  max-width: 170px;
  padding: 0 8px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm, 6px);
  background: transparent;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  cursor: pointer;
}

.rte__block:hover,
.rte__block:focus-visible {
  border-color: var(--pj-orange);
}

/* 70px empty, not 44px (2026-09-05) — a single-line tap-target height reads
   as "just a text field" and hides that a toolbar with six formatting
   buttons, including a video embed, sits above it. This value is echoed by
   `.rte .rte__editor` in prosyjob-app.css, which exists only to *win* on
   `.pj-app` pages — see that rule's own note — never to carry a different
   number than this one. */
.rte__editor {
  min-height: 70px;
  padding: 10px 12px;
  border: none;
  border-radius: 0;
  overflow-y: auto;
}

.rte__editor:focus {
  outline: none;
  box-shadow: none;
}

.rte__editor:empty::before {
  content: attr(data-placeholder);
  color: var(--color-muted);
  pointer-events: none;
}

.rte__editor ul,
.rte__editor ol {
  margin: 0 0 0 1.2em;
  padding: 0;
}

/* AI assistant buttons (E35-07): dictée + améliorer, only rendered when the
   editor was given an api client — see RichTextEditor.js's own note. */
.rte__btn.is-active {
  background: var(--pj-danger);
  color: #fff;
}

/* Text/background colour pickers (2026-09-07): a `<label>`, not a `<button>`,
   wrapping a real `<input type="color">` so the browser's own picker opens —
   RichTextEditor.js's `_runCommand()` deliberately never calls
   `preventDefault()` on these. The input sits transparent but on top (not
   `pointer-events:none`), covering the full label so the click actually
   lands on it; the swatch bar underneath the icon is the only visible trace
   of it, and is the one part JS repaints after a colour is picked. */
.rte__color-btn {
  position: relative;
  flex-direction: column;
  gap: 1px;
  padding-bottom: 4px;
}

.rte__color-swatch {
  display: block;
  width: 16px;
  height: 3px;
  border-radius: 2px;
  border: 1px solid var(--pj-line);
}

.rte__color-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
}

.rte__status-bar {
  height: 4px;
  background: var(--pj-line);
  overflow: hidden;
}

.rte__status-bar__fill {
  height: 100%;
  width: 0;
  background: var(--pj-orange);
}

.rte__status {
  margin: 0;
  padding: 6px 12px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
  border-top: 1px solid var(--pj-line);
}

.rte__status--error {
  color: var(--pj-danger);
}

.rte__status-link {
  margin-left: 6px;
  font-weight: 600;
  color: var(--pj-orange);
}

.rte__menu {
  position: absolute;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  margin-top: 4px;
  padding: 6px;
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm, 8px);
  box-shadow: var(--pj-shadow-sm);
}

.rte__menu-item {
  padding: 8px 10px;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: var(--pj-radius-sm, 6px);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  cursor: pointer;
}

.rte__menu-item:hover,
.rte__menu-item:focus-visible {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text, var(--pj-orange));
}

.rte__preview {
  padding: 10px 12px;
  background: var(--pj-card-2, var(--pj-bg));
  border-top: 1px solid var(--pj-line);
}

.rte__preview-label {
  margin: 0 0 4px;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pj-muted);
}

.rte__preview-text {
  margin: 0 0 10px;
  font-size: var(--pj-fs-body);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.rte__preview-actions {
  display: flex;
  gap: 8px;
}

.rte__preview-actions .btn {
  width: auto;
}

/* ExtractionValidationPanel (E35 V3.1, chapitres 5-7) — "Décrire brièvement"
   describe/analyse box, then the écran de validation grouped by confidence. */
.aiv-consent {
  margin-top: 10px;
  font-size: 0.85rem;
  color: var(--pj-muted);
}

.aiv-describe-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
}

.aiv-describe-actions .btn {
  width: auto;
}

.aiv-describe-status {
  font-size: 0.85rem;
  color: var(--pj-muted);
}

/* Deux chemins, deux onglets (2026-09-16). Ils remplacent un « — ou — »
   entre deux blocs empilés : le PO a constaté que les gens croyaient devoir
   faire les deux, saisir un texte ET joindre un fichier. Un séparateur
   n'informe que ceux qui le lisent ; un onglet ne montre jamais les deux à
   la fois, donc la question ne se pose plus. */
/* L'assistant de publication : trois onglets sur une seule rangee.
   Meme forme que `.aiv-tabs`, dont il reprend le vocabulaire visuel — ce
   sont les memes onglets pour l'utilisateur, seule leur portee change, et
   deux apparences pour une meme idee se lisent comme deux mecanismes.
   `flex-wrap` parce qu'a 360 px trois intitules ne tiennent pas toujours
   sur une ligne : ils passent en dessous plutot que de deborder. */
.pa-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
  padding: 4px;
  border-radius: 10px;
  background: var(--pj-card-2);
}

.pa-tab {
  flex: 1 1 110px;
  min-width: 0;
  min-height: 44px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.pa-tab.is-active {
  background: var(--pj-card);
  color: var(--pj-ink);
  box-shadow: 0 1px 3px rgba(9, 14, 20, 0.12);
}

/* Sur telephone la barre ne fait que 239 px de large (mesure a 360 px de
   fenetre, carte et gouttieres deduites), soit 73 px par onglet. Avec la
   base de 110 px, le troisieme passait seul sur une deuxieme ligne et s'y
   etalait sur toute la largeur — ce qui se lit comme une erreur de mise en
   page plutot que comme un choix. On resserre juste assez pour que les trois
   tiennent sur une ligne, sans descendre sous les 44 px de hauteur de
   frappe. `flex-wrap` reste le filet si une traduction s'allonge. */
@media (max-width: 560px) {
  .pa-tab {
    flex: 1 1 calc(33.333% - 4px);
    padding: 8px 4px;
    font-size: var(--pj-fs-sm);
  }
}

/* La phrase sous la barre : elle dit ce qui va se passer, la ou l'intitule
   ne dit que ce qu'on choisit. Notamment qu'un tableau cree PLUSIEURS
   brouillons, ce qu'aucun mot d'onglet ne peut porter. */
.pa-assistant__hint {
  margin-bottom: 16px;
}

.pa-assistant__intro {
  margin-bottom: 14px;
}

/* L'assistant porte deja ses propres onglets : ceux du panneau d'extraction
   sont alors supprimes cote JS (`ownTabs: false`), et ce qui reste ne doit
   pas garder la marge que la barre laissait au-dessus de lui. */
.pa-pane > .aiv-describe > .aiv-pane:first-child {
  margin-top: 0;
}

.aiv-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
  padding: 4px;
  border-radius: 10px;
  background: var(--pj-card-2);
}

.aiv-tab {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.aiv-tab.is-active {
  background: var(--pj-card);
  color: var(--pj-ink);
  box-shadow: 0 1px 3px rgba(9, 14, 20, 0.12);
}

.aiv-describe-file {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.aiv-describe-file-label {
  display: block;
  margin: 0 0 8px;
  font-size: 0.85rem;
  color: var(--pj-muted);
}

.aiv-describe-file input[type="file"] {
  flex: 1 1 auto;
  min-width: 0;
}

.aiv-describe-file .btn {
  width: auto;
}

.aiv-result {
  margin-top: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.aiv-result-intro {
  margin: 0;
  color: var(--pj-muted);
}

.aiv-fields {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.aiv-field {
  display: grid;
  grid-template-columns: 24px 1fr;
  grid-template-areas: "icon label" "icon input" "icon raw";
  column-gap: 10px;
  row-gap: 4px;
  padding: 10px 12px;
  border-radius: var(--pj-radius-sm, 8px);
  border: 1px solid var(--pj-line);
  border-left: 4px solid var(--pj-line);
}

.aiv-field-icon {
  grid-area: icon;
  font-weight: 700;
  text-align: center;
}

.aiv-field-label {
  grid-area: label;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-muted);
}

.aiv-field input,
.aiv-field textarea,
.aiv-field select {
  grid-area: input;
}

.aiv-field-raw {
  grid-area: raw;
  margin: 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  font-style: italic;
}

.aiv-score--ok {
  border-left-color: var(--pj-success);
}

.aiv-score--ok .aiv-field-icon {
  color: var(--pj-success);
}

.aiv-score--confirm {
  border-left-color: var(--pj-warning-ink);
  background: var(--pj-warning-soft);
}

.aiv-score--confirm .aiv-field-icon {
  color: var(--pj-warning-ink);
}

.aiv-score--correct {
  border-left-color: var(--pj-danger);
  background: var(--pj-danger-soft);
}

.aiv-score--correct .aiv-field-icon {
  color: var(--pj-danger);
}

.aiv-sections {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.aiv-section {
  font-size: var(--pj-fs-body);
}

.aiv-result-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.aiv-result-actions .btn {
  width: auto;
}

.aiv-fallback {
  margin: 0;
  font-size: var(--pj-fs-body);
}

.aiv-error {
  color: var(--pj-danger);
  font-size: var(--pj-fs-body);
}

/* "Recharger mes crédits Assistant" (`.aic-`, 2026-09-15, maquette
   2026-09-29) — the recharge view of the history page (`?vue=recharger`):
   a header card (title, balance, a link back to the history) then one card
   per pack. Three columns once the column is wide enough, one below; the
   cards stretch to a common height so the three « Acheter » line up. Named
   for its own feature rather than shared with `.sub-plan*`: two unrelated
   purchases that look alike today should not have to change together. */
.aic-head { display: grid; gap: 8px; }
.aic-head__balance { margin: 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.aic-history-link {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  margin-top: 16px;
  padding: 12px 20px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
  font-size: var(--pj-fs-body);
  text-decoration: none;
}
/* Classe doublée : `.pj-app a { color: inherit }` (prosyjob.css) pèse (0,1,1)
   et se charge après cette feuille ; (0,2,0) l'emporte. */
.aic-history-link.aic-history-link,
.aic-history-link.aic-history-link:hover { color: var(--pj-info-ink); }
.aic-history-link:hover { text-decoration: underline; }
.aic-history-link > .fa-clock { font-size: 1.3rem; }
.aic-history-link__chevron { margin-left: auto; }

.aic-state { display: grid; gap: 10px; }
.aic-state .btn { width: auto; justify-self: start; }

.aic-packs {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
}
.aic-packs[hidden] { display: none; }

.aic-pack { display: flex; flex-direction: column; gap: 0; }
.aic-pack__name {
  margin: 0;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--pj-line);
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.2;
  color: var(--pj-ink);
}
.aic-pack__price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 16px; margin: 24px 0 0; }
.aic-pack__money { font-size: var(--pj-fs-display); font-weight: 800; line-height: 1.1; color: var(--pj-orange-text); }
.aic-pack__miles { font-size: var(--pj-fs-body); color: var(--pj-muted); }
.aic-pack__perks { list-style: none; margin: 28px 0 0; padding: 0; display: grid; gap: 16px; }
.aic-pack__perks li { display: flex; align-items: flex-start; gap: 14px; color: var(--pj-ink); font-size: var(--pj-fs-body); line-height: 1.35; }
.aic-pack__perks .fa-circle-check { flex: 0 0 auto; margin-top: 1px; font-size: 1.5rem; color: var(--pj-orange); }
.aic-pack .aic-pack__buy.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  min-height: 60px;
  margin-top: auto;
  font-size: var(--pj-fs-card);
}
/* `margin-top: auto` pins the button to the bottom of a stretched card; the
   perks list still needs a floor between it and the button. */
.aic-pack__perks { margin-bottom: 36px; }

@media (min-width: 768px) {
  .aic-packs { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
}

@media (max-width: 767px) {
  .aic-head__balance { font-size: var(--pj-fs-body); }
  .aic-history-link { margin-top: 8px; min-height: 48px; padding: 10px 14px; gap: 10px; font-size: var(--pj-fs-body); }
  .aic-history-link > .fa-clock { font-size: 1.1rem; }
  .aic-packs { gap: 12px; }
  .aic-pack__name { padding-bottom: 0; border-bottom: 0; font-size: var(--pj-fs-lg); }
  .aic-pack__price { margin-top: 6px; gap: 2px 12px; }
  .aic-pack__money { font-size: var(--pj-fs-title); }
  .aic-pack__miles { font-size: var(--pj-fs-body); }
  .aic-pack__perks { margin: 10px 0 14px; gap: 8px; }
  .aic-pack__perks li { gap: 10px; font-size: var(--pj-fs-body); color: var(--pj-muted); }
  .aic-pack__perks .fa-circle-check { font-size: 1.1rem; }
  .aic-pack .aic-pack__buy.btn { min-height: 48px; font-size: var(--pj-fs-md); }
}

/* DiscussionPanel (2026-09-07): a bottom sheet on mobile, a centred panel on
   desktop — the same shape `.ap-drawer` already uses for a candidate's
   detail view, generalised under its own name rather than reused directly:
   a second consumer of the pattern, not a reason for this framework
   component to reach into the Application module's CSS. */
.disc-backdrop {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(22, 35, 59, 0.45);
}

.disc-drawer {
  width: 100%;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--pj-card);
  border-radius: var(--connected-radius-lg, 22px) var(--connected-radius-lg, 22px) 0 0;
}

.disc-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--pj-line);
  flex: 0 0 auto;
}

.disc-drawer__head h2 {
  margin: 0;
  font-size: var(--pj-fs-lg);
}

.disc-drawer__close {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: var(--pj-muted, #657085);
}

.disc-messages {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 16px 20px;
  min-height: 120px;
}

.disc-message {
  margin-bottom: 16px;
}

.disc-message__meta {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 4px;
}

.disc-message__author {
  font-weight: 700;
  font-size: var(--pj-fs-body);
}

.disc-message__time {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted, #657085);
}

.disc-message__body {
  font-size: var(--pj-fs-body);
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.disc-message__body ul,
.disc-message__body ol {
  margin: 0 0 0 1.2em;
  padding: 0;
}

.disc-composer {
  flex: 0 0 auto;
  border-top: 1px solid var(--pj-line);
  padding: 12px 20px 16px;
}

.disc-composer__error {
  margin: 8px 0 0;
  font-size: var(--pj-fs-body);
}

.disc-composer__actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 8px;
}

.disc-composer__actions .btn {
  width: auto;
}

@media (min-width: 768px) {
  .disc-backdrop { align-items: center; }

  .disc-drawer {
    width: auto;
    min-width: 480px;
    max-width: 640px;
    border-radius: var(--connected-radius-lg, 22px);
  }
}

@media (min-width: 1200px) {
  .disc-drawer { max-width: 760px; }
}

.co-gps__hint {
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
}

/* La suggestion « votre mini-site est ailleurs » sous le champ Site web
   (2026-09-17). Discrète par demande : une ligne sourdine sous le champ, pas
   une bannière — garder son ancien site est un choix légitime.

   `display: flex` + `wrap` plutôt qu'un bouton en flux : à 360px le domaine
   et le bouton ne tiennent pas sur une ligne, et un `<button>` nu est
   `width: 100%` dans cette coquille (règle `button, .btn` du haut de cette
   feuille), donc il prendrait toute la largeur sous le texte. */
.co-site-suggest {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
}

.co-site-suggest__btn {
  width: auto;
  min-height: 44px;
  padding: 0 4px;
  font-size: var(--pj-fs-body);
  /* `--pj-orange-text` et non le bleu : c'est la couleur des boutons-liens
     depuis l'harmonisation du 2026-09-08 (voir `.cv-linkbtn`). */
  color: var(--pj-orange-text);
  font-weight: 600;
}

.co-gps__coords {
  display: grid;
  gap: 14px;
  margin-top: 10px;
}

/* Web presence (E31-02): the drag-and-drop section list. */
.wp-section-list {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: grid;
  gap: 8px;
}

.wp-section-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: grab;
}

.wp-section-item:active {
  cursor: grabbing;
}

.wp-section-item i {
  color: var(--pj-muted);
}

/* Menu personnalisable du mini-site (2026-08-25) — même liste/ligne que
   les rubriques de la présence web (.wp-section-list/.wp-section-item),
   avec une étiquette extensible et deux cases à cocher alignées à droite. */
.wp-menu-item__label {
  flex: 1;
}

.wp-menu-unavailable {
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.wp-menu-check {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--pj-fs-body);
  white-space: nowrap;
  cursor: pointer;
}

/* Separates the two numbered steps sharing one card on WebPresencePage
   (2026-08-28) — plain <hr> can't take a token border colour by itself. */
.wp-step-sep {
  margin: 24px 0;
  border: none;
  border-top: 1px solid var(--pj-line);
}

/* Opening hours (E32 M1): a {debut,fin} pair per day rather than the E31
   free-text field, so the RDV module can parse it reliably. */
.co-hours {
  display: grid;
  gap: 10px;
}

.co-hours__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

.co-hours__day {
  flex: 0 0 100px;
  font-weight: 600;
  font-size: var(--pj-fs-body);
}

.co-hours__row input[type="time"] {
  flex: 1 1 110px;
  min-width: 100px;
}

.co-hours__sep {
  color: var(--color-muted);
  font-size: var(--pj-fs-body);
}

.co-hours__hint {
  margin: 4px 0 0;
  font-size: var(--pj-fs-body);
}

/* ── Accordion sections (fiche entreprise, Présence Web M1) ────────────── */

.co-accordion {
  border: 1px solid var(--color-border);
  border-radius: var(--pj-radius-sm, 12px);
  overflow: hidden;
}

.co-accordion + .co-accordion {
  margin-top: 0; /* spacing comes from .co-form's own gap, not a margin here */
}

.co-accordion__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
  padding: 12px 16px;
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  background: var(--pj-card-2);
}

.co-accordion__summary::-webkit-details-marker {
  display: none;
}

/* A drawn chevron rather than an icon font glyph: the two vendored icon sets
   (admin FontAwesome 5, user-template's older FontAwesome) don't share one
   font-family, and this avoids depending on either. */
.co-accordion__summary::after {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--color-muted);
  border-bottom: 2px solid var(--color-muted);
  transform: rotate(45deg);
  transition: transform 0.2s ease;
  flex-shrink: 0;
}

.co-accordion[open] > .co-accordion__summary::after {
  transform: rotate(-135deg);
}

.co-accordion__summary:hover,
.co-accordion__summary:focus-visible {
  filter: brightness(0.97);
}

.co-accordion__body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
}

.co-req {
  color: var(--color-error);
}

/* ── Media upload control (.mu) ─────────────────────────────────────────── */

.mu {
  display: grid;
  gap: 8px;
}

.mu__preview {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: 1px dashed var(--color-border);
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--pj-card-2);
  cursor: pointer;
}

/* Tapping the box opens the same picker as "Choisir une image" below it
   (2026-09-07) — the outline only needs to show up for keyboard/switch
   navigation, not for the mouse/touch click that already has its own
   visible feedback (the native file dialog opening). */
.mu__preview:focus-visible {
  outline: 2px solid var(--pj-orange, #ef5a28);
  outline-offset: 2px;
}

/* A logo is square, a banner is wide: the box states the aspect the image will
   be shown at, so what is uploaded is judged against where it will land. */
.mu--square .mu__preview {
  aspect-ratio: 1 / 1;
  max-width: 160px;
}

.mu--wide .mu__preview {
  aspect-ratio: 3 / 1;
}

.mu__preview img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* "Retour à la fiche" on NewsPage/GalleryPage — a plain .btn is width:100%,
   right for a form's one call to action and wrong for a small back link
   sitting above the hero card on its own. */
.wp-back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: auto;
  margin-bottom: 12px;
  padding-left: 0;
}

/* The web presence cluster's lateral nav (2026-08-27) — a sibling of
   .wp-back-link inside .connected-page, so its own gap:20px is the only
   thing spacing it from the hero card above and below; no margin here. */
.wpnav {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.wpnav__group-label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pj-muted);
}

.wpnav__group-items {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Classe doublee : `.pj-app a { color: inherit }` (prosyjob.css) pese
   (0,1,1) et battait cette regle (0,1,0), donc le lien heritait de la
   couleur de son parent au lieu de la sienne. Voir check-link-colors.mjs. */
.wpnav__item.wpnav__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  width: auto;
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  white-space: nowrap;
  text-decoration: none;
  /* No `href` on this anchor — the SPA router acts on `data-nav-to` instead —
     so it never matches `:link` and the browser falls back to the text
     cursor over its label. */
  cursor: pointer;
}

.wpnav__item.is-active {
  background: var(--pj-orange);
  border-color: var(--pj-orange);
  color: #fff;
}

/* News cover thumbnail (E31-03) inside an .ss-card, and the gallery grid
   (E31-04) — a fixed square thumbnail either way, the drag affordance
   reusing .wp-section-item's cursor treatment from E31-02. */
.wn-cover-thumb {
  width: 100%;
  max-width: 220px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--pj-radius-sm);
  margin-bottom: 8px;
}

.wp-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 14px;
  margin-bottom: 14px;
}

.wp-gallery-item {
  display: grid;
  gap: 6px;
  padding: 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: grab;
}

.wp-gallery-item:active {
  cursor: grabbing;
}

.wp-gallery-item img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--pj-radius-sm);
}

.wp-gallery-add {
  max-width: 220px;
}

.wp-gallery-item__visibility {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: 44px;
  padding: 4px 8px;
  border: 1px solid var(--color-border);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--color-muted);
  font-size: var(--pj-fs-sm);
  cursor: pointer;
}

.wp-gallery-item__visibility.is-public {
  color: var(--color-primary);
  border-color: var(--color-primary);
}

.mu__empty {
  display: grid;
  justify-items: center;
  gap: 6px;
  color: var(--color-muted);
  font-size: 0.875rem;
}

.mu__empty-icon {
  font-size: 2rem;
}

.mu__pick,
.mu__gallery-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.mu__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* The picker is a <label> wrapping a hidden <input type=file>, so it needs the
   button's own affordances — `.btn` alone leaves it feeling inert. */
.mu__pick {
  cursor: pointer;
  margin: 0;
}

/* Both escape the `button, .btn { width: 100% }` rule near the top of this
   sheet; a row of two full-width buttons is not a row. */
.mu__pick,
.mu__clear,
.mu__gallery-toggle {
  width: auto;
}

.mu__hint {
  margin: 0;
  font-size: var(--pj-fs-sm);
}

.mu__gallery-panel {
  margin-top: 8px;
  padding: 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.mu__gallery-status {
  margin: 0;
}

.mu__gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 8px;
  max-height: 240px;
  overflow-y: auto;
}

.mu__gallery-thumb {
  width: 100%;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
  cursor: pointer;
  background: none;
}

.mu__gallery-thumb:hover {
  border-color: var(--color-primary);
}

.mu__gallery-thumb img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* ── Photo gallery (.pg) — a grid of thumbnails fed by one multi-select
   picker (2026-09-14) — replaces the earlier "one .mu slot per photo" row,
   uncomfortable on a phone (N native file dialogs to add N photos). */

.pg__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}

.pg__thumb {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--pj-card-2);
}

.pg__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A bare <button> is width:100% by default (prosyjob-components.css's own
   rule, near the top of this file) — this class-selector width wins on
   specificity, same fix already documented for any inline button row. */
.pg__thumb-remove {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: rgba(20, 20, 20, 0.65);
  color: #fff;
  font-size: var(--pj-fs-card);
  line-height: 1;
  cursor: pointer;
}

.pg__add {
  max-width: 160px;
}

.pg__max-hint {
  margin: 8px 0 0;
  font-size: var(--pj-fs-sm);
}

/* ── Marketplace review preview (.mp-preview) — main photo + thumbnails ──── */

.mp-preview {
  margin-bottom: 16px;
}

.mp-preview__main {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--surface-chip);
}

.mp-preview__main img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.mp-preview__thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

/* Explicit width overrides the `button, .btn { width:100% }` rule near the
   top of this sheet — a row of thumbnails is not a row of full-width bars. */
.mp-preview__thumb {
  width: 64px;
  height: 64px;
  flex: 0 0 auto;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--pj-radius-sm, 8px);
  overflow: hidden;
  cursor: pointer;
  background: none;
}

.mp-preview__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.mp-preview__thumb.is-active {
  border-color: var(--color-primary);
}

/* ── Rendez-vous picker (.bk) — a "sur rendez-vous" service's buy step ───── */

.bk-picker {
  margin-top: 4px;
}

.bk-cal {
  margin-bottom: 12px;
}

.bk-cal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.bk-cal-label {
  font-weight: 700;
  text-transform: capitalize;
}

/* Explicit width overrides the `button, .btn { width:100% }` rule near the
   top of this sheet — a nav arrow is not a full-width bar. */
.bk-cal-nav {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  border-radius: var(--pj-radius-sm, 8px);
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: var(--pj-fs-card);
  line-height: 1;
  cursor: pointer;
}

.bk-cal-nav:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.bk-cal-weekdays,
.bk-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 3px;
}

.bk-cal-weekdays {
  margin-bottom: 4px;
  text-align: center;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  color: var(--color-muted);
}

/* Explicit width overrides the `button, .btn { width:100% }` rule near the
   top of this sheet — a calendar cell is a grid item, not a full-width bar. */
.bk-cal-day {
  width: auto;
  aspect-ratio: 1;
  min-height: 40px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--pj-radius-sm, 8px);
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  cursor: pointer;
}

.bk-cal-day--empty {
  background: none;
  cursor: default;
}

.bk-cal-day.has-slots {
  font-weight: 700;
}

.bk-cal-day.is-today {
  color: var(--color-primary);
}

.bk-cal-day.is-selected {
  border-color: var(--color-primary);
}

.bk-cal-day.is-disabled,
.bk-cal-day:disabled {
  opacity: 0.35;
  cursor: not-allowed;
  font-weight: 600;
}

.bk-slots {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.bk-slot {
  flex: 0 0 auto;
  width: auto;
  min-width: 44px;
  min-height: 44px;
  padding: 6px 14px;
  border: 2px solid transparent;
  border-radius: var(--pj-radius-sm, 8px);
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  cursor: pointer;
}

.bk-slot.is-selected {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* ── Listing management cards (.ml-card) — "Mes publications" ────────────── */

.ml-card {
  display: flex;
  gap: 12px;
  align-items: center;
  cursor: pointer;
  text-align: left;
}

.ml-card__cover {
  flex: 0 0 auto;
  width: 64px;
  height: 64px;
  border-radius: var(--pj-radius-sm, 8px);
  overflow: hidden;
  background: var(--surface-chip);
  display: flex;
  align-items: center;
  justify-content: center;
}

.ml-card__cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.ml-card__placeholder {
  font-size: 0.7rem;
  color: var(--color-muted);
  text-align: center;
  padding: 0 4px;
}

/* The catalogue's own header when narrowed to one company (?entreprise=). */
.mc-company-header__link {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  color: inherit;
}

.mc-company-header__logo {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: 1.4rem;
  overflow: hidden;
  flex: none;
}

.mc-company-header__logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mc-company-header__name {
  font-size: var(--pj-fs-card);
  font-weight: 600;
}

.ml-card__body {
  min-width: 0;
}

.ml-card__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-md);
  display: flex;
  align-items: center;
  gap: 8px;
}

/* The seller's own logo, rounded, ahead of the item title — distinct from
   .mc-company-header__logo (square, page-level) because this one sits inline
   in a title of unknown length rather than beside a lone name. */
.ml-card__company-avatar {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: 0.7rem;
  overflow: hidden;
  flex: none;
}

.ml-card__company-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ml-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}

/* The company-name chip becomes a link back to "?entreprise=" — keep the
   .co-readonly look, just make the intent (a place to click) visible. */
.ml-card__company-link {
  text-decoration: none;
  cursor: pointer;
}

.ml-card__company-link:hover {
  text-decoration: underline;
}

/* Inline management actions (edit/publish/duplicate/delete) directly on a
   "Mes publications" card, so a click doesn't need to open the listing
   first. A modifier, not a change to .ml-card itself: the other three
   consumers of that class (public/read-only contexts) never carry it. */
.ml-card--manageable {
  flex-wrap: wrap;
}

.ml-card__actions {
  flex: 1 0 100%;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 4px;
}

.ml-card__actions .btn {
  width: auto;
}

/* ── File upload control (.fu) ──────────────────────────────────────────── */

/* Sibling of .mu for a file that is not necessarily an image — a payment
   receipt is a screenshot or a PDF (E16-06). No preview box: half of what it
   accepts cannot be previewed, and a box that is empty for PDFs reads as a
   failed upload. */
.fu {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.fu__pick {
  cursor: pointer;
  margin: 0;
}

/* Both escape the `button, .btn { width: 100% }` rule near the top of this
   sheet. */
.fu__pick,
.fu__clear {
  width: auto;
}

.fu__name {
  font-size: var(--pj-fs-body);
  /* A phone screenshot is called something like
     Screenshot_20260805-141233_Orange Money.jpg — long enough to push the
     clear button off a 360px row if it is allowed to. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
  min-width: 0;
  flex: 1 1 120px;
}

.fu__hint {
  margin: 6px 0 0;
  font-size: var(--pj-fs-sm);
}

/* ── Espace entreprise ──────────────────────────────────────────────────── */

.co-space__head {
  display: grid;
  gap: 16px;
  padding: 22px;
}

.co-space__ident {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.co-space__ident h1 {
  margin: 0;
  font-size: var(--pj-fs-display);
  overflow-wrap: anywhere;
}

.co-space__ident p {
  margin: 2px 0 8px;
  font-size: var(--pj-fs-body);
}

.co-space__switcher {
  display: grid;
  gap: 6px;
}

.co-space__switcher label {
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  color: var(--color-muted);
}

.co-space__switcher select {
  width: 100%;
  min-height: 44px;
}

/* Tabs: a horizontal scroller on a phone rather than a wrapped pile — the
   same choice the admin console makes. */
.co-tabs {
  display: flex;
  gap: 6px;
  /* Two tabs never reach the point where this matters. The shell no longer
     stretches to a wide row (prosyjob-app.css §2 gives it `width: 100%`), so
     such a row now overflows its own track instead — see .jo-tabs, which
     wraps for that reason. */
  min-width: 0;
  flex-wrap: wrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 4px;
}

.co-tab.is-active {
  background: var(--primary-fill);
  border-color: var(--primary-fill);
  color: #fff;
}

.co-space__body {
  display: grid;
  gap: 16px;
}

/* Overview tab (2026-08-27) — the task menu a phone-first, non-technical
   owner lands on instead of the edit form. Its own grid+gap, nested inside
   #co-space-body's: two spacing mechanisms, one per level, never a margin
   filling in for either (CLAUDE.md's .pj-card lesson). */
.co-task-list {
  display: grid;
  gap: 10px;
}

.co-task {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  text-align: left;
  width: 100%;
  /* The `<a>` variant carries no `href` (the router acts on `data-nav-to`
     instead), so it never matches `:link` and the browser falls back to the
     text cursor over its label — same cause as `.wpnav__item`. */
  cursor: pointer;
}

/* A secondary shortcut nested inside an already-clickable `.co-task` (its
   own click target resolves first via the delegator's `closest()`, so this
   never double-navigates) — visually distinct so it reads as its own link
   rather than more status text. */
.co-task__link {
  color: var(--pj-orange-dark);
  text-decoration: underline;
  cursor: pointer;
}

.co-task__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-dark);
}

.co-task__body {
  flex: 1;
  min-width: 0;
}

.co-task__title {
  font-weight: 700;
  font-size: var(--pj-fs-md);
}

.co-task__status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 3px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.co-chip {
  font-size: 0.72rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: var(--pj-radius-pill);
}

/* The brand's own accessible red-orange is already the platform's
   semantic warning colour (see CLAUDE.md §9 on .cpd-error) — nothing new
   to mirror into prosyjob.css. */
.co-chip--warn {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.co-chip--ok {
  background: var(--pj-success-soft);
  color: var(--color-success, #1e8e5a);
}

.co-chip--muted {
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.co-task__cta {
  color: var(--pj-orange-dark);
  font-weight: 700;
}

.co-task__chevron {
  flex-shrink: 0;
  color: var(--pj-muted);
}

.co-task--secondary {
  background: var(--pj-card-2);
  border: 1px dashed var(--pj-line);
  box-shadow: none;
}

.co-task--secondary .co-task__icon {
  background: var(--pj-card);
  color: var(--pj-muted);
}

.co-overview-eyebrow {
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pj-muted);
}

.co-section__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

/* ── Espace entreprise, maquette du 2026-09-27 ───────────────────────────

   Tout est sous `.co-space--company` : `.co-space__head`, `__ident`,
   `__switcher` et `__badges` sont partagés avec l'espace organisme
   (ProviderSpacePage), qui ne change pas avec celui-ci.

   L'en-tête : l'identité, puis le sélecteur et les deux réglages ; sous eux,
   la rangée de raccourcis, qui défile à l'horizontale sur téléphone (icône
   au-dessus du libellé) et passe à la ligne sur ordinateur (icône à côté). */
.co-space--company .co-space__head {
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  padding: 16px;
}

.co-space__top {
  display: grid;
  gap: 12px;
}

.co-space--company .co-space__ident {
  align-items: flex-start;
}

.co-space--company .co-space__logo {
  width: 64px;
  height: 64px;
  border-radius: 16px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: 1.5rem;
}

.co-space__ident-text {
  min-width: 0;
  display: grid;
  gap: 6px;
}

.co-space--company .co-space__ident h1 {
  font-weight: 800;
  line-height: 1.15;
}

.co-space--company .co-space__place {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.co-space__place .fa-location-dot {
  margin-right: 4px;
}

.co-space--company .co-badge {
  padding: 5px 12px;
  font-size: var(--pj-fs-sm);
}

.co-space--company .co-badge--role {
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

.co-space--company .co-badge--owner {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.co-space--company .co-badge--verified {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.co-space--company .co-badge--certified {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.co-space__side {
  display: grid;
  gap: 10px;
  align-content: start;
}

.co-space__tools {
  display: flex;
  gap: 10px;
}

/* Deux pastilles rondes de 44px (E10). `width: auto` n'est pas utile ici —
   la largeur est posée — mais le `button` nu de ce fichier est à 100 %, donc
   la largeur DOIT être posée. `a.` pour la couleur : `.pj-app a` (0,1,1). */
.co-space--company .co-space__tool,
.co-space--company a.co-space__tool {
  width: 44px;
  height: 44px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--pj-card-2);
  color: var(--pj-navy);
  cursor: pointer;
  text-decoration: none;
}

.co-space--company .co-space__tool:hover,
.co-space--company .co-space__tool[aria-expanded="true"] {
  color: var(--pj-orange-text);
}

/* Le réglage ouvert sur place : la même marque qu'un raccourci actif. */
.co-space--company .co-space__tool.is-active {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  box-shadow: inset 0 0 0 1px var(--pj-orange);
}

.co-space--company .co-space__tool[hidden] {
  display: none;
}

/* Les raccourcis. Une rangée qui défile plutôt qu'une pile sur téléphone : six
   pavés empilés repousseraient les onglets sous la ligne de flottaison. */
.co-shortcuts {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
}

.co-shortcuts::-webkit-scrollbar {
  display: none;
}

.co-space--company .co-shortcut,
.co-space--company a.co-shortcut {
  flex: 0 0 auto;
  width: 76px;
  min-height: 68px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 8px 4px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-2xs);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.co-space--company .co-shortcut i {
  font-size: 18px;
  color: var(--pj-orange-text);
}

.co-space--company .co-shortcut:hover {
  border-color: var(--pj-orange);
}

.co-space--company .co-shortcut.is-active {
  background: var(--pj-orange-soft);
  border-color: var(--pj-orange);
  color: var(--pj-orange-text);
}

/* Les cartes de l'Aperçu : pastille plus grande et titre plus présent. */
.co-space--company .co-task {
  gap: 14px;
  padding: 14px 16px;
}

.co-space--company .co-task__icon {
  width: 48px;
  height: 48px;
  font-size: 1.15rem;
}

.co-space--company .co-task__title {
  font-size: var(--pj-fs-md);
  color: var(--pj-ink);
}

.co-space--company .co-task--secondary {
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
}

.co-space--company .co-task--secondary .co-task__icon {
  background: var(--pj-card-2);
  color: var(--pj-navy);
}

@media (min-width: 640px) {
  .co-space--company .co-space__head {
    grid-template-columns: minmax(0, 1fr);
    padding: 22px;
  }

  .co-space__top {
    grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
    align-items: start;
    gap: 20px;
  }

  .co-space--company .co-space__logo {
    width: 88px;
    height: 88px;
    font-size: 2rem;
  }

  .co-space__tools {
    justify-content: flex-end;
  }

  .co-shortcuts {
    flex-wrap: wrap;
    overflow: visible;
  }

  .co-space--company .co-shortcut,
  .co-space--company a.co-shortcut {
    width: auto;
    min-height: 44px;
    flex-direction: row;
    gap: 8px;
    padding: 8px 14px;
    font-size: var(--pj-fs-sm);
  }

  .co-space--company .co-shortcut i {
    font-size: 16px;
  }
}


.co-section__head h2 {
  margin: 0;
  font-size: var(--pj-fs-lg);
}

/* One glance, one icon (2026-08-28) — `MySitePage`'s own kitchen-sink
   screen (status/branding/domain/mailboxes) is a stack of otherwise
   identical white cards; the icon is what lets someone scrolling past
   tell them apart without reading each heading. */
.co-section__icon {
  color: var(--pj-orange);
  font-size: 0.95em;
  margin-right: 8px;
}

.co-section__note {
  margin: -4px 0 14px;
  font-size: var(--pj-fs-body);
}

/* Classe doublee : `.pj-app a { color: inherit }` (prosyjob.css) pese
   (0,1,1) et battait cette regle (0,1,0), donc le lien heritait de la
   couleur de son parent au lieu de la sienne. Voir check-link-colors.mjs. */
.co-readonly.co-readonly {
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
}

/* ── Fiche completion (Présence Web M1) ─────────────────────────────────── */

.co-completion-mini {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

.co-completion-mini__bar {
  flex: 1;
  min-width: 60px;
  height: 6px;
  border-radius: 999px;
  background: var(--pj-card-2);
  overflow: hidden;
}

.co-completion-mini__bar span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--color-primary, #2563eb);
  transition: width 0.3s ease;
}

.co-completion-mini__pct {
  font-size: var(--pj-fs-xs);
  color: var(--color-muted);
}

.co-completion-mini__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  color: var(--color-muted);
  flex: none;
}

.co-completion-mini__icon.is-ready {
  background: var(--surface-chip);
  color: var(--color-primary);
}

/* Le libellé du bandeau : ce que la barre veut dire, en toutes lettres, parce
   que l'attribut `title` qui le portait ne s'ouvre qu'au survol — donc jamais
   sur un téléphone (retour PO, 2026-09-16). C'est un bouton : il mène au
   détail, sur l'onglet où sont les champs. */
.co-completion-mini__label {
  width: auto;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-orange);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  text-decoration: underline;
  white-space: nowrap;
}

/* ── Ce qu'il reste à compléter (`.co-todo`, 2026-09-16) ────────────────── */

.co-todo__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.co-todo__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
}

.co-todo__pct {
  flex: none;
  font-size: var(--pj-fs-lg);
  color: var(--pj-orange);
  /* Mesuré à 360px : sans cela, « 65 % » se coupe entre le nombre et le
     signe et s'écrit sur deux lignes. */
  white-space: nowrap;
}

.co-todo__bar {
  height: 8px;
  margin: 10px 0;
  border-radius: 999px;
  background: var(--pj-card-2);
  overflow: hidden;
}

.co-todo__bar span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--pj-orange);
  transition: width 0.3s ease;
}

.co-todo__goal {
  margin: 0 0 12px;
  font-size: var(--pj-fs-body);
}

.co-todo__list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Chaque manque est une cible tactile pleine largeur : sur 360px, une liste
   de liens serrés est une liste qu'on rate. */
.co-todo__go {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--pj-line);
  border-radius: 8px;
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: 0.9rem;
  text-align: left;
}

.co-todo__item--info {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px dashed var(--pj-line);
  border-radius: 8px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.co-todo__pts {
  flex: none;
  font-weight: 700;
  color: var(--pj-orange);
}

/* L'indication en tête d'une section du formulaire (réseaux sociaux :
   identifiant ou adresse, les deux marchent — 2026-09-16). */
.co-form__hint {
  margin: 0 0 12px;
  font-size: 0.85rem;
}

.co-form__subhead {
  margin: 8px 0 0;
  font-size: var(--pj-fs-md);
}

/* ── Advanced settings (transfer + close, merged behind one toggle) ─────── */

.co-advanced-panel {
  display: grid;
  gap: 16px;
}

.co-advanced-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--pj-card-2);
  color: var(--color-muted);
  cursor: pointer;
}

.co-advanced-toggle:hover,
.co-advanced-toggle[aria-expanded="true"] {
  background: var(--surface-chip);
  color: var(--color-primary);
}

.co-advanced {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px;
}

.co-advanced__section h3 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-lg);
}

.co-advanced__section--danger h3 {
  color: var(--color-error);
}

.co-advanced__section + .co-advanced__section {
  padding-top: 20px;
  border-top: 1px solid var(--color-border);
}

.co-danger {
  padding: 20px;
  border: 1px solid color-mix(in srgb, var(--pj-danger) 35%, transparent);
}

.co-danger h2 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-lg);
  color: var(--color-error);
}

/* `.co-danger__btn` a quitte cette regle : c'est un `.btn btn-outline-secondary`,
   donc il doit battre la definition du secondaire, qui vit en fin de cascade
   dans prosyjob-app.css §5. Une regle a une classe posee ici ne peut pas y
   arriver, quel que soit ce qu'elle declare. */
.co-action--danger {
  color: var(--color-error);
}

/* ── Transfer ownership ─────────────────────────────────────────────────── */

.co-transfer {
  padding: 20px;
}

.co-transfer h2 {
  margin: 0 0 4px;
  font-size: 1.05rem;
}

.co-transfer__row {
  display: flex;
  align-items: flex-end;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 12px;
}

.co-transfer__row .field {
  flex: 1 1 240px;
  margin: 0;
}

.co-transfer__btn {
  width: auto;
  white-space: nowrap;
}

/* ── Collaborateurs ─────────────────────────────────────────────────────── */

.co-members {
  display: grid;
  gap: 12px;
}

.co-member {
  display: grid;
  gap: 10px;
  padding: 14px;
  border: 1px solid var(--connected-border);
  border-radius: var(--radius);
  background: var(--surface-sunken);
}

.co-member--suspended {
  opacity: 0.7;
}

.co-member__ident {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.co-member__avatar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--surface-chip);
  color: var(--chip-ink);
  overflow: hidden;
}

.co-member__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.co-member__name {
  overflow-wrap: anywhere;
}

.co-member__contact {
  margin: 2px 0 0;
  font-size: var(--pj-fs-sm);
  overflow-wrap: anywhere;
}

.co-member__role {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.co-member__custom {
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  color: var(--color-warning);
}

.co-member__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* ── Droits (RG012) ─────────────────────────────────────────────────────── */

.co-rights__frame {
  margin-top: 16px;
  padding: 16px;
  border: 1px solid var(--connected-border);
  border-radius: var(--radius);
  background: var(--surface-sunken);
}

.co-rights__frame h3 {
  margin: 0 0 12px;
  font-size: var(--pj-fs-md);
}

.co-rights__who {
  color: var(--color-muted);
  font-weight: 600;
}

.co-rights__row {
  display: grid;
  gap: 12px;
}

.co-rights__role-desc {
  margin: 6px 0 0;
  font-size: var(--pj-fs-sm);
}

.co-rights__hint {
  margin: 12px 0;
  font-size: var(--pj-fs-body);
}

.co-rights__groups {
  display: grid;
  gap: 12px;
}

.co-rights__group {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--connected-border);
  border-radius: var(--radius);
  background: var(--color-surface);
}

.co-rights__group legend {
  padding: 0 6px;
  font-size: var(--pj-fs-sm);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-muted);
}

.co-rights__perm-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: var(--pj-fs-body);
  cursor: pointer;
}

.co-rights__perm {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}

.co-rights__deviation {
  margin-left: auto;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  font-style: normal;
  color: var(--color-warning);
  white-space: nowrap;
}

/* ── Invitations ────────────────────────────────────────────────────────── */

.co-invite__heading {
  margin: 20px 0 10px;
  font-size: var(--pj-fs-md);
}

.co-invites {
  display: grid;
  gap: 10px;
}

.co-invite-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px;
  border: 1px dashed var(--connected-border);
  border-radius: var(--radius);
}

.co-invite-row p {
  margin: 2px 0 0;
  font-size: var(--pj-fs-sm);
}

.co-invite__empty {
  margin: 0;
  font-size: var(--pj-fs-body);
}

.co-invite__link {
  margin-top: 14px;
  padding: 14px;
  border-radius: var(--radius);
  background: var(--connected-accent-soft);
  display: grid;
  gap: 8px;
}

.co-invite__link p {
  margin: 0;
  font-size: var(--pj-fs-body);
}

.co-invite__link input {
  width: 100%;
  font-size: 0.82rem;
}

/* The box is a grid, and a grid item stretches whatever its width says. */
.co-invite__link .btn {
  justify-self: start;
}

/* ── Page publique ──────────────────────────────────────────────────────── */

/* The only route here a signed-out visitor reaches, so it renders in the
   guest layout — whose #content is a centring flex box that would otherwise
   shrink the page to its widest card. */
.layout-guest .co-public {
  width: 100%;
  max-width: 900px;
  align-content: start;
}

/* Les regles de la fiche publique (.co-public__head, .co-fact, .co-contact)
   sont parties avec la refonte : les deux pages passent par le composant
   partage `PublicEntityView` et sa famille `.pe-`. `.co-public` reste juste
   au-dessus, comme conteneur de la page. */

/* ── Invitation ─────────────────────────────────────────────────────────── */

.co-invitation__card {
  padding: 28px 22px;
  text-align: center;
  display: grid;
  gap: 12px;
  justify-items: center;
}

.co-invitation__mark {
  display: grid;
  place-items: center;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: var(--connected-accent-soft);
  color: var(--connected-accent);
  font-size: 1.5rem;
}

.co-invitation__card h1 {
  margin: 0;
  font-size: var(--pj-fs-display);
}

.co-invitation__lead {
  margin: 0;
}

.co-invitation__facts {
  margin: 6px 0 0;
  display: grid;
  gap: 10px;
  width: 100%;
  text-align: left;
}

.co-invitation__facts div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--connected-border);
}

.co-invitation__facts dt {
  font-size: var(--pj-fs-body);
  color: var(--color-muted);
}

.co-invitation__facts dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
  overflow-wrap: anywhere;
}

.co-invitation__message {
  margin: 4px 0 0;
  padding: 12px 14px;
  border-left: 3px solid var(--connected-accent);
  background: var(--surface-sunken);
  text-align: left;
  font-style: italic;
}

.co-invitation__blocked {
  margin: 0;
  color: var(--color-error);
  font-size: var(--pj-fs-body);
}

/* ── 640px and up: room for two columns ─────────────────────────────────── */

@media (min-width: 640px) {
  /* `minmax(0, 1fr)` et non `1fr` : le minimum implicite d'un `1fr` est
     `auto`, donc une piste ne peut pas descendre sous la largeur min-content
     de son contenu. Un seul mot insécable suffit alors à élargir la grille,
     puis la carte, puis la colonne centrale — le 2026-08-30, les codes de
     forfait affichés en titre (`WEBBUILDER.PACKAGE.MAXI`) ont poussé la carte
     de « Mon site web » de 765 à 871 px, soit 82 px passés SOUS le rail de
     droite. Mesuré, pas supposé. Le shell applique déjà cette règle à ses
     trois colonnes (prosyjob-app.css §2) ; elle manquait un niveau plus bas,
     là où le contenu arrive vraiment. */
  .co-form__grid,
  .co-gps__coords {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  /* The banner gets the wider track — it is a 3:1 image next to a 1:1 one. */
  .co-form__images {
    grid-template-columns: 160px 1fr;
    align-items: start;
  }

  .co-list__new,
  .co-empty .btn,
  .co-danger__btn,
  .co-form__actions .btn,
  .co-invitation__actions .btn {
    width: auto;
  }

  .co-space__head {
    grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
    align-items: center;
  }

  .co-member {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) auto;
    align-items: center;
  }

  .co-rights__row {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
  }

  .co-rights__groups {
    grid-template-columns: 1fr 1fr;
  }

}

/* ── 1200px and up: keep long text readable rather than edge-to-edge ────── */

@media (min-width: 1200px) {
  .co-rights__groups {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .co-create__points {
    max-width: 78ch;
  }
}

/* ======================================================================== *
 *  M5 JobOffer (E2-05) — recherche publique, fiche d'offre, mes offres,
 *  éditeur.
 *  Mobile-first: one column at 360px, two from 640px, three for the result
 *  grid from 1200px. Reuses the company card vocabulary rather than adding a
 *  fourth; what is new is the result card, which has to stay scannable when
 *  there are forty of them.
 * ======================================================================== */

/* `gap` sans `display` ne produit rien — voir la note sur `.cand-editor`. */
.jo-search,
.jo-public,
.jo-mine,
.jo-editor {
  display: grid;
  gap: 16px;
}

/* Visually hidden but read aloud — the search input's label. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── Recherche ──────────────────────────────────────────────────────────── */

.jo-search__head {
  display: grid;
  gap: 16px;
  padding: 22px;
}

.jo-search__head h1 {
  margin: 0;
  font-size: clamp(1.4rem, 3.5vw, 1.9rem);
}

.jo-search__head p {
  margin: 4px 0 0;
}

.jo-search__bar {
  display: grid;
  gap: 10px;
}

.jo-search__bar input {
  width: 100%;
  min-height: 48px;
}

.jo-search__bar .btn {
  min-height: 48px;
}

.jo-filters {
  border-top: 1px solid var(--connected-border);
  padding-top: 12px;
}

.jo-filters > summary {
  cursor: pointer;
  font-weight: 700;
  font-size: var(--pj-fs-body);
  min-height: 44px;
  display: flex;
  align-items: center;
}

.jo-filters__grid {
  display: grid;
  gap: 14px;
  margin: 12px 0;
}

/* A field meant to take the full row (a chip list, a picker) regardless of
   how many grid columns the breakpoint currently has — CVthèque's skills and
   language pickers are the first to need it (2026-09-10). Harmless at the
   single-column width `.jo-filters__grid` starts from; `1 / -1` only does
   something once the 640px rule below gives the grid a second column. */
.field--wide {
  grid-column: 1 / -1;
}

/* Groups inside any .jo-filters advanced-filters panel — first written for
   CVthèque (who the candidate is / where they are / what they can do,
   2026-09-10), reused as-is by TrainingSearchPage (2026-09-11): a native
   <fieldset> rather than a styled <div>, so the browser's own accessibility
   tree announces each group's name. No border on the fieldset itself (every
   UA draws one by default); the divider is the top rule on every group after
   the first, kept deliberately plain — a label and a line, nothing heavier.
   Named after the shared `.jo-filters`/`.jo-filters__grid` shell it lives
   inside, not after either page — one definition, not a copy per page. */
.jo-filter-group {
  border: 0;
  padding: 0;
  margin: 0;
}

.jo-filter-group + .jo-filter-group {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
}

.jo-filter-group legend {
  padding: 0;
  margin: 0 0 4px;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pj-muted);
}

/* Import CSV's "accepted reference values" panel (Lot 5) — closed by default,
   same disclosure pattern as .jo-filters, so it never competes with the file
   picker above it. */
/* Le mode d'emploi et le plafond de lignes (PO, 2026-09-18). « CSV » ne dit
   rien a la majorite du public vise : le format n'est pas cache — il faut le
   mot au moment de cliquer « Enregistrer sous » — il est explique une fois,
   ici, avant le choix du fichier. */
.imp-howto {
  margin: 0 0 16px;
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

/* Sous le champ, la ou on le lit avant d'envoyer plutot qu'apres le refus. */
.imp-limit {
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
}
.imp-ref-panel {
  border: 1px solid var(--pj-line);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 16px;
}

.imp-ref-panel > summary {
  cursor: pointer;
  font-weight: 700;
  font-size: var(--pj-fs-body);
  min-height: 44px;
  display: flex;
  align-items: center;
}

.imp-ref-panel__intro {
  margin: 8px 0 12px;
  font-size: var(--pj-fs-body);
}

.imp-ref-group + .imp-ref-group {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--pj-line);
}

.imp-ref-group__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pj-muted);
}

.imp-ref-group__list {
  max-height: 160px;
  overflow-y: auto;
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.jo-search__count {
  margin: 0 2px;
  font-size: var(--pj-fs-body);
}

.jo-search__subbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 4px 0 2px;
}

.jo-save-search {
  white-space: nowrap;
}

/* The sort control shares .jo-search__subbar with the result count (job
   search's "save this search" button sits there too) — this override just
   drops the vendor .form-group's own margin so it doesn't add space below a
   row that's otherwise a plain flex line, and keeps the <select> from
   collapsing to its content width. */
.jo-search__sort {
  margin: 0;
  min-width: 200px;
}

.jo-results {
  display: grid;
  gap: 14px;
}

/* .ss- : ne de « recherches sauvegardees », reutilise par Webbuilder
   (sections, blocs) et Marketplace — la page des alertes a ses .oa- */
.ss-list {
  display: grid;
  gap: 14px;
}

.ss-card {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.ss-card__main {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.ss-card__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
}

.ss-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ss-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.05);
  font-size: var(--pj-fs-sm);
}

.ss-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  font-weight: 600;
}

.ss-badge--on { color: #1a7f4b; }
.ss-badge--off { color: #7a7a7a; }

.ss-card__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.ss-card__actions .btn { width: auto; }
.ss-danger { color: #b4231f; }

.ss-form__grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  margin: 12px 0;
}

.ss-form__actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.ss-form__actions .btn { width: auto; }

/* Mes alertes sur les offres (M12, ex-« recherches sauvegardées »), maquette
   « alerte_offres » du 2026-10-01. Trois cartes : l'en-tete, le formulaire,
   la liste. Une carte d'alerte porte l'icone et la couleur de son secteur
   (support/sectorIcons.js) ; sur telephone, ses boutons cedent la place a un
   chevron et la carte entiere ouvre le formulaire. */
.oa-hero {
  display: flex;
  align-items: flex-start;
  gap: 24px;
}

.oa-hero__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 96px;
  height: 96px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-display);
}

.oa-hero__body {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.oa-hero__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.15;
  color: var(--pj-ink);
}

.oa-hero__lead {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

.oa-hero .oa-hero__new.btn,
.oa-form__actions .btn,
.oa-card__actions .btn {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.oa-hero .oa-hero__new.btn {
  justify-self: start;
  margin-top: 6px;
}

.oa-section-title {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

/* Le formulaire */
.oa-form-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
}

.oa-form-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* Le replier n'existe que sur telephone. */
.oa-form-card__toggle {
  display: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-ink);
  cursor: pointer;
}

.oa-form {
  display: grid;
  gap: 14px;
}

.oa-field {
  display: grid;
  gap: 6px;
  margin: 0;
}

.oa-form label {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

/* Quatre colonnes seulement quand la colonne centrale les tient (au-dela de
   1400 px) ; en dessous, deux — a 1366 px les libelles passaient a la ligne
   et desalignaient les champs. */
.oa-form__grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.oa-form__grid .oa-field {
  align-content: start;
}

.oa-form .form-control,
.oa-form .form-select {
  min-height: 44px;
}

@media (min-width: 1400px) {
  .oa-form__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.oa-form__checks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 40px;
}

.oa-check {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  margin: 0;
  cursor: pointer;
}

.oa-check .form-check-input {
  width: 20px;
  height: 20px;
  margin: 0;
}

.oa-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* La liste */
/* minmax(0, 1fr) : sans lui, la piste grandit a la largeur de la plus
   longue rangee de pastilles et la carte deborde (mesure a 360 px). */
.oa-list-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
}

.oa-list {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.oa-list__note {
  margin: 0;
}

.oa-card {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: pointer;
}

.oa-card:hover,
.oa-card:focus-visible {
  border-color: var(--pj-orange);
}

.oa-card__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 60px;
  height: 60px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-title);
}

.oa-tone--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.oa-tone--success { background: var(--pj-success-soft); color: var(--pj-success); }
.oa-tone--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.oa-tone--accent { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.oa-tone--orange { background: var(--pj-orange-soft); color: var(--pj-orange); }
.oa-tone--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.oa-card__main {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  min-width: 0;
}

.oa-card__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.oa-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.oa-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-neutral-soft);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.oa-chip i {
  flex: 0 0 auto;
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-xs);
}

/* Une pastille tient sur une ligne : un nom de secteur long s'abrege plutot
   que de faire une pastille de trois lignes. */
.oa-chip {
  max-width: 100%;
  min-width: 0;
}

.oa-chip__text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.oa-card__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.oa-card__status--on { color: var(--pj-success); }
.oa-card__status--off { color: var(--pj-neutral-ink); }

.oa-card__actions {
  flex: 0 0 auto;
  display: flex;
  gap: 10px;
}

.oa-card__chevron {
  display: none;
  color: var(--pj-ink);
}

/* Telephone : en-tete compact, formulaire en une colonne et repliable, cartes
   sans boutons — le toucher ouvre l'alerte, le chevron le dit. */
@media (max-width: 720px) {
  .oa-hero {
    gap: 14px;
  }

  .oa-hero__icon {
    width: 60px;
    height: 60px;
    font-size: var(--pj-fs-title);
  }

  .oa-hero__title {
    font-size: var(--pj-fs-card);
  }

  .oa-hero__lead {
    font-size: var(--pj-fs-sm);
  }

  .oa-form-card__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .oa-form-card__chevron {
    transition: transform 0.2s ease;
  }

  .oa-form-card.is-folded .oa-form-card__chevron {
    transform: rotate(180deg);
  }

  .oa-form-card.is-folded .oa-form {
    display: none;
  }

  .oa-form__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .oa-form__checks {
    flex-direction: column;
    gap: 0;
  }

  .oa-card {
    gap: 10px;
    padding: 10px;
  }

  .oa-card__icon {
    width: 42px;
    height: 42px;
    font-size: var(--pj-fs-md);
  }

  .oa-card__status {
    font-size: var(--pj-fs-xs);
    white-space: nowrap;
  }

  .oa-card__title {
    font-size: var(--pj-fs-body);
  }

  .oa-card__chips {
    gap: 6px;
  }

  .oa-chip {
    gap: 5px;
    padding: 3px 8px;
    font-size: var(--pj-fs-xs);
  }

  .oa-card__actions {
    display: none;
  }

  .oa-card__chevron {
    display: inline-block;
  }
}

/* Account / avatar (M Media) --------------------------------------------- */
.md-avatar-card__head h2 {
  margin: 0 0 4px;
  font-size: 1.05rem;
}

.md-avatar {
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  margin-top: 16px;
}

.md-avatar__preview {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  overflow: hidden;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.06);
  color: #9a9a9a;
  font-size: 2rem;
}

.md-avatar__preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.md-avatar__controls {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.md-avatar__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.md-avatar__actions .btn { width: auto; }
.md-danger { color: var(--color-error); }

.jo-loading {
  margin: 0;
  padding: 20px;
}

.jo-card {
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.jo-card:hover,
.jo-card:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 18px 34px rgba(22, 35, 59, 0.10);
  outline: none;
}

.jo-card:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.jo-card__head {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.jo-card__logo,
.jo-public__logo {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  background: var(--connected-accent-soft);
  color: var(--connected-accent);
  overflow: hidden;
}

.jo-card__logo img,
.jo-public__logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.jo-card__ident {
  min-width: 0;
}

.jo-card__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  overflow-wrap: anywhere;
}

.jo-card__company {
  margin: 2px 0 0;
  font-size: var(--pj-fs-body);
  overflow-wrap: anywhere;
}

.jo-card__badges,
.jo-card__chips,
.jo-public__badges,
.jo-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.jo-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  white-space: nowrap;
}

.jo-badge--tender {
  background: var(--connected-accent-soft);
  color: var(--connected-accent);
}

.jo-badge--verified {
  background: var(--pj-success-soft);
  color: var(--color-success);
}

.jo-badge--salary {
  background: var(--surface-chip);
  color: var(--color-primary);
}

.jo-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--connected-border);
  font-size: var(--pj-fs-xs);
}

.jo-chip--required {
  border-color: color-mix(in srgb, var(--pj-info-ink) 35%, transparent);
  background: var(--pj-info-soft);
}

.jo-chip em {
  font-style: normal;
  font-size: var(--pj-fs-2xs);
  color: var(--color-muted);
}

.jo-card__salary {
  margin: 0;
  font-weight: 700;
  font-size: var(--pj-fs-body);
}

.jo-card__meta {
  margin: 0;
  font-size: var(--pj-fs-sm);
}

/* The training card's "next session" line (2026-09-11) — a training's own
   date/seats teaser, distinct enough from a plain meta line to want its own
   color and icon gap rather than inheriting jo-card__meta's bare text. */
.jo-card__meta--session {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--pj-muted);
}

.jo-empty {
  padding: 28px 22px;
  text-align: center;
}

.jo-empty h2 {
  margin: 0 0 6px;
  font-size: var(--pj-fs-lg);
}

.jo-empty .btn {
  margin-top: 14px;
  width: auto;
}

.jo-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.jo-pager .btn {
  width: auto;
  min-height: 44px;
}

/* ── Fiche d'offre publique ─────────────────────────────────────────────── */

/* The only route here a signed-out visitor reaches renders in the guest
   layout, whose #content is a centring flex box that would otherwise shrink
   the page to its widest card. */
.layout-guest .jo-public,
.layout-guest .jo-search {
  width: 100%;
  max-width: 900px;
  align-content: start;
}

.jo-public__head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 24px 22px;
}

.jo-public__logo {
  width: 60px;
  height: 60px;
  font-size: 1.4rem;
}

.jo-public__ident h1 {
  margin: 0;
  font-size: var(--pj-fs-display);
  overflow-wrap: anywhere;
}

.jo-public__ident p {
  margin: 4px 0 8px;
}

.jo-public__apply {
  padding: 20px 22px;
  display: grid;
  gap: 10px;
  justify-items: start;
}

.jo-public__apply p {
  margin: 0;
}

.jo-public__apply .btn {
  width: auto;
}

.jo-public__soon,
.jo-public__closed {
  font-size: var(--pj-fs-body);
}

.jo-public__closed {
  color: var(--color-error);
  font-weight: 600;
}

.jo-public__facts {
  display: grid;
  gap: 12px;
  padding: 20px 22px;
}

.jo-fact {
  display: grid;
  gap: 2px;
}

.jo-fact span {
  font-size: var(--pj-fs-sm);
}

.jo-public__block {
  padding: 20px 22px;
}

.jo-public__block h2 {
  margin: 0 0 8px;
  font-size: var(--pj-fs-lg);
}

.jo-public__block h2 + h2 {
  margin-top: 16px;
}

.jo-public__block p {
  margin: 0;
  white-space: pre-line;
}

.jo-public__block-text {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.jo-public__block .btn {
  width: auto;
}

.jo-public__back {
  margin: 0;
  font-weight: 600;
}

.jo-public__back-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.jo-public__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.jo-public__bar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.jo-public__bar .btn {
  width: auto;
}

.jo-public__preview-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

/* ── Fiche d'une offre : maquette `apercu_offre_emploi.png` (2026-10-01) ──
   Famille `jov-` et non `jo-public__` : la fiche formation partage encore
   ces dernières. Tout est préfixé par `.jov` parce que `prosyjob.css` charge
   APRÈS cette feuille et pose `.pj-card { padding: 26px }` à (0,1,0) : une
   règle à une seule classe sur la carte perdrait. Mobile d'abord ; la grille
   de faits passe de 2 à 4 colonnes et le chevron disparaît à 768px. */

.jov {
  gap: 14px;
}

.jov .jov-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.jov .jov-bar__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.jov .jov-bar .btn {
  width: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

/* Trois classes : `.jov .jov-bar .btn` ci-dessus en a trois aussi et
   repeindrait le bouton en `inline-flex` sur téléphone. */
.jov .jov-bar .jov-bar__apply,
.jov .jov-wide {
  display: none;
}

.jov .jov-preview {
  justify-self: start;
}

.jov .jov-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 14px;
  padding: 18px;
}

.jov .jov-head__logo {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
  overflow: hidden;
}

.jov .jov-head__logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.jov .jov-head h1 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.2;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.jov .jov-head__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  margin: 6px 0 10px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.jov .jov-head__meta a {
  color: var(--pj-muted);
}

.jov .jov-head__place i {
  color: var(--pj-navy);
  margin-right: 4px;
}

.jov .jov-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* `inline-block` et surtout pas `inline-flex` : en flex, « Publié le » et la
   balise `<time>` deviennent deux éléments, et l'espace final du premier est
   supprimé — on lisait « Publié le1er octobre 2026 » (mesuré : 0 px). */
.jov .jov-pill {
  display: inline-block;
  padding: 4px 12px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.jov .jov-pill--verified {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.jov .jov-pill--date {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.jov .jov-pill--tender {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

/* Le bandeau : la seule surface teintée de la page, parce que c'est la
   seule qui demande un geste. */
.jov .jov-apply {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 12px 14px;
  padding: 16px 18px;
  background: var(--pj-orange-soft);
  border-color: transparent;
}

.jov .jov-apply p {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.jov .jov-apply__icon {
  color: var(--pj-orange);
  font-size: var(--pj-fs-card);
  transform: rotate(-12deg);
}

.jov .jov-apply__cta {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
  width: 100%;
}

.jov .jov-apply--closed {
  display: block;
  background: var(--pj-card);
}

.jov .jov-apply--closed p {
  color: var(--pj-danger);
  font-weight: 600;
}

.jov .jov-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  padding: 6px 4px;
}

.jov .jov-fact {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px;
  min-width: 0;
}

.jov .jov-fact__icon {
  flex: 0 0 auto;
  width: 22px;
  margin-top: 2px;
  text-align: center;
  color: var(--pj-navy);
  font-size: var(--pj-fs-lg);
}

.jov .jov-fact__label {
  display: block;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.jov .jov-fact__value {
  display: block;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.jov .jov-sec {
  padding: 18px;
}

.jov .jov-sec__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.jov .jov-sec__title {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.jov .jov-sec__title i {
  width: 22px;
  text-align: center;
  color: var(--pj-orange);
}

.jov .jov-sec__toggle {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -10px -10px -10px 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--pj-ink);
}

.jov .jov-sec__toggle i {
  transition: transform 0.2s ease;
}

.jov .jov-sec.is-collapsed .jov-sec__toggle i {
  transform: rotate(-90deg);
}

.jov .jov-sec.is-collapsed .jov-sec__body {
  display: none;
}

/* Le texte s'aligne sous le titre, pas sous l'icône. */
.jov .jov-sec__body {
  padding-left: 34px;
  margin-top: 8px;
}

.jov .jov-sec__text {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.jov .jov-sec__text p {
  margin: 0 0 6px;
}

/* Les puces se posent sur le `li` : le thème vendu déclare
   `ul li { list-style: none }`, qu'une règle sur le `ul` ne reprend pas. */
.jov .jov-sec__text ul,
.jov .jov-sec__text ol {
  margin: 0;
  padding-left: 18px;
}

.jov .jov-sec__text ul > li {
  display: list-item;
  list-style: disc;
}

.jov .jov-sec__text ol > li {
  display: list-item;
  list-style: decimal;
}

.jov .jov-sec__text li::marker {
  color: var(--pj-orange);
}

.jov .jov-sec__btn {
  width: auto;
  margin-top: 10px;
}

/* Compétences et langues, sous un filet dans la carte du profil. */
.jov .jov-tags {
  display: grid;
  gap: 12px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--pj-line);
}

.jov .jov-sec > .jov-tags:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

.jov .jov-tags__row {
  display: grid;
  gap: 8px;
}

.jov .jov-tags__row h3 {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 800;
  color: var(--pj-ink);
}

.jov .jov-tags__row h3 i {
  width: 22px;
  text-align: center;
  color: var(--pj-orange);
}

.jov .jov-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.jov .jov-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-sm);
}

.jov .jov-chip--optional {
  background: transparent;
  border: 1px dashed var(--pj-info-ink);
}

.jov .jov-chip span {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

@media (min-width: 768px) {
  .jov .jov-wide,
  .jov .jov-bar__apply {
    display: inline;
  }

  .jov .jov-bar .jov-bar__apply {
    display: inline-flex;
  }

  .jov .jov-narrow {
    display: none;
  }

  .jov .jov-head {
    gap: 22px;
    padding: 20px 24px;
  }

  .jov .jov-head__logo {
    width: 96px;
    height: 96px;
    font-size: var(--pj-fs-display);
  }

  .jov .jov-head h1 {
    font-size: var(--pj-fs-display);
  }

  .jov .jov-apply {
    grid-template-columns: auto minmax(0, 1fr) auto;
    padding: 14px 22px;
  }

  .jov .jov-apply__cta {
    grid-column: auto;
    width: auto;
  }

  .jov .jov-facts {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    padding: 8px 6px;
  }

  /* Un filet entre les colonnes, pas autour des cases. */
  .jov .jov-fact + .jov-fact:not(:nth-child(4n + 1)) {
    border-left: 1px solid var(--pj-line);
  }

  .jov .jov-sec {
    padding: 20px 24px;
  }

  .jov .jov-sec__toggle {
    display: none;
  }

  .jov .jov-sec.is-collapsed .jov-sec__body {
    display: block;
  }

  .jov .jov-tags__row {
    grid-template-columns: 160px minmax(0, 1fr);
    align-items: center;
  }
}

/* ── Fiche d'une formation : maquette `formation_apercu.png` (2026-10-03) ──
   Famille `tfv-`, sœur de `jov-` ci-dessus et préfixée par `.tfv` pour la
   même raison (`prosyjob.css` charge après et pose `.pj-card { padding }`).
   Chaque bloc est une ligne : pastille d'icône teintée, titre, texte. Mobile
   d'abord : un bloc long y est replié en extrait de trois lignes, que le
   chevron déplie ; à 768px tout est ouvert et le chevron disparaît. */

.tfv {
  gap: 12px;
}

.tfv .tfv-bar .btn,
.tfv .tfv-actions .btn,
.tfv .tfv-cta .btn {
  width: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
}

.tfv .tfv-bar {
  display: flex;
}

/* La bande d'aperçu : le bandeau seul sur téléphone, bandeau + actions sur
   ordinateur. Sans bandeau (fiche publique) elle n'existe que là. */
.tfv .tfv-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
}

.tfv .tfv-strip--bare {
  display: none;
}

.tfv .tfv-preview {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1 1 100%;
  margin: 0;
  padding: 10px 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.tfv .tfv-preview i {
  color: var(--pj-orange);
}

.tfv .tfv-actions {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 8px;
}

.tfv .tfv-actions--wide {
  display: none;
}

.tfv .tfv-actions--narrow .btn {
  padding: 8px 10px;
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

/* ── En-tête ── */

.tfv .tfv-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 14px;
  padding: 16px;
}

.tfv .tfv-head__logo {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-card);
  overflow: hidden;
}

.tfv .tfv-head__logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.tfv .tfv-head h1 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.2;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.tfv .tfv-head__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 8px;
  margin: 6px 0 8px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tfv .tfv-head__meta a {
  color: var(--pj-orange-text);
}

.tfv .tfv-head__sep {
  margin-right: 4px;
}

.tfv .tfv-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tfv .tfv-pill {
  display: inline-block;
  padding: 3px 12px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.tfv .tfv-pill--price {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.tfv .tfv-pill--free,
.tfv .tfv-pill--cert {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

/* ── Pastilles d'icône ── */

.tfv .tfv-ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-md);
}

.tfv .tfv-ico--orange  { background: var(--pj-orange-soft);  color: var(--pj-orange); }
.tfv .tfv-ico--info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.tfv .tfv-ico--accent  { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.tfv .tfv-ico--success { background: var(--pj-success-soft); color: var(--pj-success); }
.tfv .tfv-ico--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }
.tfv .tfv-ico--danger  { background: var(--pj-danger-soft);  color: var(--pj-danger); }

/* ── Faits : deux colonnes sur téléphone, trois à filets sur ordinateur ── */

.tfv .tfv-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  padding: 6px;
}

.tfv .tfv-fact {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px;
  min-width: 0;
}

.tfv .tfv-facts .tfv-ico {
  width: 32px;
  height: 32px;
  font-size: var(--pj-fs-body);
}

.tfv .tfv-fact__text {
  min-width: 0;
}

.tfv .tfv-fact__label {
  display: block;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

/* `break-word` et non `anywhere` : un mot ne se coupe que s'il ne tient
   sur aucune ligne — « professionnell / e » se lisait à 375px. */
.tfv .tfv-fact__value {
  display: block;
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  overflow-wrap: break-word;
  hyphens: auto;
}

/* ── Blocs ── */

.tfv .tfv-sec {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 12px;
  padding: 14px 8px 14px 14px;
}

.tfv .tfv-sec__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-body);
  font-weight: 700;
  color: var(--pj-ink);
}

.tfv .tfv-sec__text {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.tfv .tfv-sec__text--plain {
  white-space: pre-line;
}

.tfv .tfv-sec__text p {
  margin: 0;
}

/* Les puces se posent sur le `li` : le thème vendu déclare
   `ul li { list-style: none }`, qu'une règle sur le `ul` ne reprend pas. */
.tfv .tfv-sec__text ul,
.tfv .tfv-sec__text ol {
  margin: 0;
  padding-left: 18px;
}

.tfv .tfv-sec__text ul > li {
  display: list-item;
  list-style: disc;
}

.tfv .tfv-sec__text ol > li {
  display: list-item;
  list-style: decimal;
}

.tfv .tfv-sec__toggle {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -4px 0 -4px 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--pj-muted);
}

.tfv .tfv-sec__toggle i {
  transition: transform 0.2s ease;
}

.tfv .tfv-sec__toggle[aria-expanded="true"] i {
  transform: rotate(90deg);
}

.tfv .tfv-sec.is-short {
  grid-template-columns: auto minmax(0, 1fr);
  padding-right: 14px;
}

.tfv .tfv-sec.is-short .tfv-sec__toggle {
  display: none;
}

/* L'extrait : trois lignes de texte, fondues plutôt que coupées net. */
.tfv .tfv-sec.is-collapsed .tfv-sec__body {
  max-height: 4.8em;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, var(--pj-ink) 60%, transparent);
  mask-image: linear-gradient(to bottom, var(--pj-ink) 60%, transparent);
}

.tfv .tfv-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}

.tfv .tfv-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

/* Un lien : un contour plutôt qu'un fond, comme la maquette. Élément nommé,
   l'ancre perdant sinon sa couleur face à `.pj-app a` (voir §5). */
.tfv a.tfv-chip--link {
  min-height: 32px;
  background: transparent;
  border: 1.5px solid var(--pj-info-ink);
  color: var(--pj-info-ink);
  text-transform: uppercase;
}

.tfv .tfv-pair {
  display: grid;
  gap: 12px;
}

.tfv .tfv-sessions {
  display: grid;
  gap: 8px;
  margin-top: 4px;
}

.tfv .tfv-session {
  display: grid;
  gap: 2px;
  padding: 8px 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.tfv .tfv-session__title {
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.tfv .tfv-session__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2px 16px;
}

/* ── Inscription ── */

.tfv .tfv-cta {
  display: grid;
  gap: 10px;
  padding: 12px;
}

.tfv .tfv-cta .btn {
  width: 100%;
}

/* ── Avis ── */

.tfv .tfv-reviews {
  padding: 14px 16px;
}

.tfv .tfv-reviews__title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.tfv .tfv-reviews__avg {
  margin-left: 6px;
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-sm);
}

.tfv .tfv-reviews__list {
  display: grid;
}

.tfv .tfv-review {
  padding: 10px 0;
  border-bottom: 1px solid var(--pj-line);
  font-size: var(--pj-fs-sm);
}

.tfv .tfv-review:last-child {
  border-bottom: 0;
}

.tfv .tfv-review p {
  margin: 0;
}

.tfv .tfv-review__stars {
  color: var(--pj-warning-ink);
  letter-spacing: 1px;
}

.tfv .tfv-review__role {
  color: var(--pj-muted);
}

.tfv .tfv-review__comment {
  color: var(--pj-ink);
}

@media (min-width: 768px) {
  .tfv {
    gap: 14px;
  }

  .tfv .tfv-strip,
  .tfv .tfv-strip--bare {
    display: flex;
    justify-content: flex-end;
  }

  .tfv .tfv-strip:not(.tfv-strip--bare) {
    padding: 8px;
    border-radius: var(--pj-radius);
    background: var(--pj-card);
    justify-content: space-between;
  }

  .tfv .tfv-preview {
    flex: 0 1 auto;
  }

  .tfv .tfv-actions--wide {
    display: flex;
    gap: 10px;
  }

  .tfv .tfv-actions--narrow {
    display: none;
  }

  .tfv .tfv-head {
    gap: 22px;
    padding: 20px 24px;
  }

  .tfv .tfv-head__logo {
    width: 80px;
    height: 80px;
    font-size: var(--pj-fs-display);
  }

  .tfv .tfv-head h1 {
    font-size: var(--pj-fs-display);
  }

  .tfv .tfv-head__meta {
    font-size: var(--pj-fs-md);
  }

  .tfv .tfv-ico,
  .tfv .tfv-facts .tfv-ico {
    width: 48px;
    height: 48px;
    font-size: var(--pj-fs-card);
  }

  .tfv .tfv-facts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0;
    padding: 10px 8px;
  }

  .tfv .tfv-fact {
    gap: 18px;
    padding: 10px 16px;
  }

  /* Un filet entre les colonnes, pas autour des cases. */
  .tfv .tfv-fact:not(:nth-child(3n + 1)) {
    border-left: 1px solid var(--pj-line);
  }

  .tfv .tfv-fact__label {
    color: var(--pj-ink);
    font-size: var(--pj-fs-md);
    font-weight: 700;
  }

  .tfv .tfv-fact__value {
    font-size: var(--pj-fs-md);
    font-weight: 400;
  }

  .tfv .tfv-sec {
    grid-template-columns: auto minmax(0, 1fr);
    gap: 20px;
    padding: 16px 24px;
  }

  .tfv .tfv-sec__title {
    font-size: var(--pj-fs-md);
  }

  .tfv .tfv-sec__text {
    font-size: var(--pj-fs-md);
  }

  .tfv .tfv-sec__toggle {
    display: none;
  }

  .tfv .tfv-sec.is-collapsed .tfv-sec__body {
    max-height: none;
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }

  .tfv .tfv-pair {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tfv .tfv-pair--single {
    grid-template-columns: minmax(0, 1fr);
  }

  .tfv .tfv-session {
    padding: 10px 16px;
    font-size: var(--pj-fs-sm);
  }

  .tfv .tfv-session__title {
    font-size: var(--pj-fs-md);
  }

  .tfv .tfv-cta {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    padding: 14px 16px;
  }

  .tfv .tfv-cta .btn {
    width: auto;
    padding-left: 28px;
    padding-right: 28px;
  }

  .tfv .tfv-reviews {
    padding: 16px 20px;
  }

  .tfv .tfv-reviews__title {
    font-size: var(--pj-fs-lg);
  }

  /* En colonnes à filets, comme les faits. */
  .tfv .tfv-reviews__list {
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }

  .tfv .tfv-review {
    padding: 4px 16px;
    border-bottom: 0;
    border-left: 1px solid var(--pj-line);
  }

  .tfv .tfv-review:first-child {
    padding-left: 4px;
    border-left: 0;
  }
}

/* ── S'inscrire à une formation : maquette `formation_inscription.png` ──
   (2026-10-04) Le formulaire monté dans la fiche à la place de ses deux
   boutons (`EnrollPanel`, M17). Trois étapes numérotées ; chaque choix est une
   carte entière cliquable, cochée quand son radio l'est (`:has`). Mobile
   d'abord : à 768px les deux choix passent côte à côte et les étapes
   s'alignent sous leur titre. La carte se nomme `article.tev`, `prosyjob.css`
   chargeant après et posant `.pj-card { padding }` — et non `.pj-card.tev` :
   `check-card-gaps` prête alors son `gap` à toutes les `.pj-card`. */

article.tev {
  display: grid;
  gap: 18px;
  padding: 18px 16px;
}

.tev .tev-title {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.tev .tev-title__ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-md);
}

.tev .tev-form {
  display: grid;
  gap: 22px;
}

.tev .tev-step {
  display: grid;
  gap: 10px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.tev .tev-step__head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 0;
  font-size: var(--pj-fs-body);
  font-weight: 700;
  color: var(--pj-ink);
}

/* Une légende n'est pas un enfant de grille : son écart se donne à la main. */
.tev legend.tev-step__head {
  margin-bottom: 10px;
}

.tev .tev-num {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--pj-info-ink);
  color: var(--pj-card);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.tev .tev-step__hint {
  margin: -4px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tev .tev-choices,
.tev .tev-sessions {
  display: grid;
  gap: 10px;
}

.tev .tev-choice {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: pointer;
}

.tev .tev-choice:has(input:checked) {
  border-color: var(--pj-info-ink);
  background: var(--pj-info-soft);
}

.tev .tev-choice:has(input:focus-visible) {
  outline: 2px solid var(--pj-info-ink);
  outline-offset: 2px;
}

.tev .tev-choice .form-check-input {
  width: 20px;
  height: 20px;
  margin: 0;
  float: none;
}

.tev .tev-choice__ico {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-lg);
}

.tev .tev-choice:has(input:checked) .tev-choice__ico {
  background: var(--pj-card);
}

.tev .tev-choice__text {
  display: grid;
  gap: 2px;
  min-width: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 400;
}

.tev .tev-choice__text strong {
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.tev .tev-pill {
  justify-self: start;
  margin-top: 4px;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

/* Sur une carte cochée le fond est déjà bleu pâle : la pastille passe au blanc. */
.tev .tev-choice:has(input:checked) .tev-pill {
  background: var(--pj-card);
}

.tev .tev-pill--full {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.tev .tev-note {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tev .tev-actions {
  display: flex;
  gap: 12px;
}

.tev .tev-actions .btn {
  width: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
  padding-left: 22px;
  padding-right: 22px;
}

.tev .tev-actions .btn-primary {
  flex: 1 1 auto;
}

.tev .tev-done {
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 8px 0;
  text-align: center;
}

.tev .tev-done__ico {
  color: var(--pj-success);
  font-size: var(--pj-fs-display);
}

.tev .tev-done__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.tev .tev-done__text {
  margin: 0 0 8px;
  color: var(--pj-muted);
}

@media (min-width: 768px) {
  article.tev {
    gap: 22px;
    padding: 24px 28px;
  }

  /* L'échelle de la fiche autour (bloc `tfv-sec`) : titre de carte comme
     « Avis », titre d'étape comme un titre de bloc, aide comme un texte de
     bloc. Le formulaire est une carte de la page, pas une page. */
  .tev .tev-title {
    font-size: var(--pj-fs-lg);
  }

  .tev .tev-title__ico {
    width: 48px;
    height: 48px;
    font-size: var(--pj-fs-card);
  }

  .tev .tev-step__head {
    font-size: var(--pj-fs-md);
  }

  .tev .tev-step__hint {
    font-size: var(--pj-fs-md);
  }

  /* Le contenu d'une étape s'aligne sous son titre, pas sous sa pastille. */
  .tev .tev-step > :not(.tev-step__head) {
    margin-left: 40px;
  }

  .tev .tev-choices {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .tev .tev-choice {
    gap: 16px;
    padding: 14px 18px;
  }

  .tev .tev-choice__ico {
    width: 48px;
    height: 48px;
  }

  .tev .tev-choice__text {
    font-size: var(--pj-fs-sm);
  }

  .tev .tev-choice__text strong {
    font-size: var(--pj-fs-md);
  }

  .tev .tev-actions .btn-primary {
    flex: 0 0 auto;
  }
}

/* ── Inscrits d'une formation : maquettes `inscrit_formation.png` et
   `inscrit_formation_detail.png` (2026-10-04) ──
   `/formations/inscrits`. Préfixé par `.tei` (deux classes) pour passer
   devant `.pj-card { padding }` que `prosyjob.css` pose après cette feuille.
   Le tableau ou les cartes se décident sur la largeur de la CARTE, pas de
   l'écran (`container-type`) : au centre de la coquille à trois colonnes, un
   écran de 1366px ne laisse que 700px — huit colonnes n'y tiennent pas. */

.tei .btn {
  width: auto;
}

/* ── En-tête ── */

.tei .tei-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  padding: 14px 16px;
}

.tei .tei-head__back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

.tei .tei-head__ico {
  display: none;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-lg);
}

.tei .tei-head__title {
  flex: 1 1 100%;
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.tei .tei-head__discussion:empty {
  display: none;
}

/* ── Recherche ── */

.tei .tei-search {
  display: grid;
  gap: 14px;
  padding: 14px 16px;
}

.tei .tei-search__form {
  display: grid;
  gap: 12px;
}

.tei .tei-search__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.tei .tei-search__head h2 {
  margin: 0;
  font-size: var(--pj-fs-body);
  font-weight: 700;
  color: var(--pj-ink);
}

.tei .tei-search__toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: auto;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: transparent;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.tei .tei-search__toggle i {
  transition: transform 0.2s ease;
}

.tei .tei-search__toggle[aria-expanded="true"] i {
  transform: rotate(180deg);
}

.tei .tei-search__q {
  position: relative;
  display: block;
  margin: 0;
}

.tei .tei-search__q i {
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  color: var(--pj-muted);
}

.tei .tei-search__q .form-control {
  min-height: 44px;
  padding-left: 40px;
}

.tei .tei-adv {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 12px 16px;
}

.tei .tei-adv .form-group {
  margin: 0;
}

.tei .tei-adv label,
.tei .tei-label {
  display: block;
  margin-bottom: 6px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.tei .tei-adv .form-control {
  min-height: 44px;
}

/* Deux dates dans une seule boîte, « Du → Au ». */
.tei .tei-range {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
}

.tei .tei-range__input {
  flex: 1 1 0;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.tei .tei-range__arrow {
  font-size: var(--pj-fs-xs);
}

.tei .tei-search__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

/* Rechercher d'abord sur téléphone, comme la maquette. */
.tei .tei-search__actions .btn-primary {
  order: -1;
}

.tei .tei-search__actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
}

/* ── Pastilles de statut ── */

.tei .tei-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tei .tei-chip {
  width: auto;
  min-height: 40px;
  padding: 6px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.tei .tei-chip.is-active {
  border-color: var(--pj-navy);
  background: var(--pj-navy);
  color: var(--pj-card);
}

.tei .tei-chip--more {
  display: none;
}

/* ── Liste ── */

.tei .tei-list {
  container-type: inline-size;
  display: grid;
  gap: 12px;
  padding: 14px 12px;
}

.tei .tei-list__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
}

.tei .tei-list__count {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.tei .tei-list__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
}

.tei .tei-list__tool {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.tei .tei-list__tool .form-control {
  width: auto;
  min-height: 44px;
}

.tei .tei-list__export {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

.tei .tei-list__note {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tei .tei-list__body {
  display: grid;
  gap: 0;
}

.tei .tei-list__empty {
  padding: 24px 8px;
  text-align: center;
}

.tei .tei-list__empty-title {
  margin: 0 0 4px;
  font-weight: 700;
  color: var(--pj-ink);
}

.tei .tei-wide {
  display: none;
}

.tei .tei-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border: 1px solid transparent;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  white-space: nowrap;
}

.tei .tei-status--preregistered { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.tei .tei-status--info_request  { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.tei .tei-status--awaiting_payment { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.tei .tei-status--paid,
.tei .tei-status--enrolled,
.tei .tei-status--certified     { background: var(--pj-success-soft); color: var(--pj-success); }
.tei .tei-status--waitlisted    { background: var(--pj-orange-soft);  color: var(--pj-orange-text); border-color: var(--pj-orange); }
.tei .tei-status--cancelled     { background: var(--pj-danger-soft);  color: var(--pj-danger); }
.tei .tei-status--attended,
.tei .tei-status--completed     { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.tei .tei-status--refunded      { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.tei .tei-name {
  display: block;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.tei .tei-sub {
  display: block;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.tei .tei-contact {
  display: block;
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
  overflow-wrap: anywhere;
}

/* Une adresse coupée n'importe où ne se lit plus : une ligne, « … », et
   l'adresse entière au survol (`title`). */
.tei .tei-contact--clip {
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tei .tei-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tei .tei-details {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 6px 14px;
  font-size: var(--pj-fs-sm);
}

.tei .tei-kebab {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
}

.tei .tei-menu .dropdown-item {
  width: 100%;
  min-height: 40px;
  font-size: var(--pj-fs-sm);
}

.tei .tei-menu .tei-menu__danger {
  color: var(--pj-danger);
}

/* Les cartes : téléphone et colonne étroite. */
.tei .tei-table-wrap {
  display: none;
}

.tei .tei-cards {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tei .tei-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.tei .tei-card__main {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.tei .tei-card__top,
.tei .tei-card__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.tei .tei-card__date {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  white-space: nowrap;
}

.tei .tei-card__who {
  min-width: 0;
}

.tei .form-check-input {
  width: 20px;
  height: 20px;
  margin: 0;
  float: none;
}

.tei .tei-list__foot {
  display: grid;
  justify-items: center;
  gap: 8px;
}

.tei .tei-list__range {
  order: 1;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  text-align: center;
}

/* Le tableau dès 640px de carte ; « # », « Contact » et « Session » n'y
   entrent qu'à 840px — la colonne centrale de la coquille plafonne à 900. */
@container (min-width: 640px) {
  .tei .tei-table-wrap {
    display: block;
    overflow-x: auto;
  }

  .tei .tei-cards {
    display: none;
  }

  .tei .tei-wide {
    display: inline;
  }

  .tei .tei-list__foot {
    grid-template-columns: minmax(0, 1fr) auto;
    justify-items: stretch;
    align-items: center;
  }

  .tei .tei-list__range {
    order: 0;
    text-align: left;
  }

  .tei .tei-col-extra {
    display: none;
  }
}

@container (min-width: 840px) {
  .tei .tei-col-extra {
    display: table-cell;
  }
}

.tei .tei-table {
  width: 100%;
  border-collapse: collapse;
}

.tei .tei-table th {
  padding: 10px 8px;
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-align: left;
  white-space: nowrap;
}

.tei .tei-table td {
  padding: 8px;
  border-top: 1px solid var(--pj-line);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  vertical-align: middle;
}

.tei .tei-table .tei-num,
.tei .tei-table .tei-date {
  color: var(--pj-muted);
  white-space: nowrap;
}

/* Plus petit de texte, pas de cible : une tablette touche ce tableau aussi. */
.tei .tei-table .tei-details {
  padding: 4px 12px;
  font-size: var(--pj-fs-xs);
}

/* ── Détails ── */

.tei .tei-modal .modal-content {
  border: 0;
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.tei .tei-modal .modal-header {
  align-items: center;
  border-bottom: 0;
  padding: 18px 20px 8px;
}

.tei .tei-modal__title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.tei .tei-modal__close {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-left: auto;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--pj-muted);
  font-size: var(--pj-fs-lg);
}

.tei .tei-modal__body {
  display: grid;
  gap: 14px;
  padding: 8px 16px 16px;
}

.tei .tei-modal__foot {
  gap: 10px;
  border-top: 0;
  padding: 0 16px 18px;
}

.tei .tei-modal__foot .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  margin: 0;
  padding-left: 22px;
  padding-right: 22px;
}

.tei .tei-modal__foot .btn-primary {
  flex: 1 1 auto;
}

.tei .tei-person {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px 14px;
  padding: 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.tei .tei-person__avatar {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

.tei .tei-person__ident p {
  margin: 0;
}

.tei .tei-person__name {
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

.tei .tei-person__role {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tei .tei-person__contact {
  display: grid;
  gap: 4px;
  margin-top: 6px;
  font-size: var(--pj-fs-sm);
}

.tei .tei-person__contact i {
  width: 16px;
  margin-right: 6px;
  color: var(--pj-muted);
}

.tei .tei-person__contact a {
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.tei .tei-person__status {
  grid-column: 2;
  justify-self: start;
  padding: 4px 12px;
  font-size: var(--pj-fs-sm);
}

.tei .tei-letter {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  padding: 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
}

.tei .tei-letter__ico {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-ink);
  color: var(--pj-card);
  font-size: var(--pj-fs-sm);
}

.tei .tei-letter__title {
  margin: 0 0 4px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 700;
}

.tei .tei-letter__text {
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

.tei .tei-letter__text p {
  margin: 0;
}

.tei .tei-certs {
  display: grid;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.tei .tei-certs__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.tei .tei-certs__title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 700;
}

.tei .tei-certs__count {
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-success-soft);
  color: var(--pj-success);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.tei .tei-certs__empty {
  display: grid;
  justify-items: center;
  gap: 4px;
  padding: 16px 12px;
  border: 1px dashed var(--pj-line);
  border-radius: var(--pj-radius-sm);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  text-align: center;
}

.tei .tei-certs__empty i {
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-card);
}

.tei .tei-certs__empty p {
  margin: 0;
}

.tei .tei-certs__empty-title {
  color: var(--pj-ink);
  font-weight: 600;
}

.tei .tei-certs__list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tei .tei-cert {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  font-size: var(--pj-fs-sm);
}

.tei .tei-cert__revoke {
  min-height: 40px;
  color: var(--pj-danger);
  font-size: var(--pj-fs-xs);
}

.tei .tei-deposit {
  display: grid;
  gap: 10px;
  padding: 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
}

.tei .tei-deposit .form-group {
  margin: 0;
}

.tei .tei-deposit label {
  display: block;
  margin-bottom: 6px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.tei .tei-deposit .form-control {
  min-height: 44px;
  background: var(--pj-card);
}

.tei .tei-deposit__title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

.tei .tei-deposit__title i {
  color: var(--pj-orange);
}

.tei .tei-required {
  color: var(--pj-danger);
}

.tei .tei-url {
  position: relative;
}

.tei .tei-url i {
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  color: var(--pj-muted);
}

.tei .tei-url .form-control {
  padding-left: 40px;
}

.tei .tei-deposit__hint {
  margin: 6px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tei .tei-modal__discussion:empty {
  display: none;
}

/* Le dépôt en lot : à qui il s'adresse, dit avant le formulaire. */
.tei .tei-batch-sub {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.tei .tei-batch-names {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tei .tei-batch-names li {
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-xs);
}

@media (min-width: 768px) {
  .tei .tei-head {
    flex-wrap: nowrap;
    padding: 14px 20px;
  }

  .tei .tei-head__ico {
    display: grid;
  }

  .tei .tei-head__title {
    flex: 1 1 auto;
    font-size: var(--pj-fs-title);
  }

  .tei .tei-search {
    padding: 16px 20px;
  }

  .tei .tei-search__actions {
    display: flex;
    justify-content: flex-end;
  }

  .tei .tei-search__actions .btn-primary {
    order: 0;
  }

  .tei .tei-chip--more {
    display: inline-block;
  }

  .tei .tei-chip--toggle {
    display: none;
  }

  .tei .tei-list {
    padding: 16px 20px;
  }

  .tei .tei-modal .modal-header {
    padding: 22px 28px 8px;
  }

  .tei .tei-modal__title {
    font-size: var(--pj-fs-title);
  }

  .tei .tei-modal__body {
    gap: 16px;
    padding: 8px 28px 20px;
  }

  .tei .tei-modal__foot {
    padding: 0 28px 24px;
  }

  .tei .tei-modal__foot .btn-primary {
    flex: 0 0 auto;
  }

  .tei .tei-person {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    padding: 18px 20px;
  }

  .tei .tei-person__avatar {
    width: 72px;
    height: 72px;
    font-size: var(--pj-fs-card);
  }

  .tei .tei-person__contact {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 28px;
  }

  .tei .tei-person__status {
    grid-column: 3;
    grid-row: 1;
  }

  .tei .tei-letter,
  .tei .tei-certs,
  .tei .tei-deposit {
    padding: 16px 20px;
  }
}

/* ── Mes offres ─────────────────────────────────────────────────────────── */

.jo-mine__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 16px;
  padding: 22px;
}

.jo-mine__intro h1 {
  margin: 0;
  font-size: var(--pj-fs-display);
}

.jo-mine__intro p {
  margin: 4px 0 0;
}

.jo-mine__company-picker {
  max-width: 320px;
  margin: 8px 0 0;
}

.jo-mine__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.jo-mine__actions .btn {
  width: auto;
  min-height: 44px;
}

/* Seven status filters, and they wrap rather than scroll.
   Written when the shell still sized itself to the page's max-content, where
   one unwrappable row of seven tabs stretched the whole layout past the
   viewport at 768px — the sidebar included. prosyjob-app.css §2 has since
   pinned the shell to `width: 100%`, so the same row would now overflow its
   own track rather than the page. Either way wrapping is the right answer:
   it removes the pressure at the source, a horizontal scroller only caps how
   much is *shown*, and seven short chips read perfectly well on two lines. */
.jo-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
  padding-bottom: 4px;
}

.jo-tab {
  flex: 0 0 auto;
  width: auto;
  min-height: 44px;
  padding: 8px 14px;
  border: 1px solid var(--connected-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.jo-tab.is-active {
  background: var(--primary-fill);
  border-color: var(--primary-fill);
  color: #fff;
}

.jo-mine__body {
  display: grid;
  gap: 14px;
}

.jo-mine-card {
  padding: 18px 20px;
  display: grid;
  gap: 12px;
}

.jo-mine-card--archived,
.jo-mine-card--expired {
  opacity: 0.75;
}

.jo-mine-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px 12px;
}

.jo-mine-card__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  overflow-wrap: anywhere;
}

.jo-mine-card__meta {
  margin: 2px 0 0;
  font-size: var(--pj-fs-body);
}

/* The status is the card's headline fact: it decides what can be done next. */
.jo-status {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  white-space: nowrap;
}

.jo-status--published {
  background: var(--pj-success-soft);
  color: var(--color-success);
}

.jo-status--pending_payment,
.jo-status--pending_validation {
  background: var(--pj-warning-soft);
  color: var(--color-warning);
}

.jo-status--suspended {
  background: var(--pj-danger-soft);
  color: var(--color-error);
}

.jo-mine-card__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  margin: 0;
}

.jo-mine-card__stats div {
  display: grid;
  gap: 1px;
}

.jo-mine-card__stats dt {
  font-size: var(--pj-fs-xs);
  color: var(--color-muted);
}

.jo-mine-card__stats dd {
  margin: 0;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.jo-mine-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--connected-border);
}

.jo-mine-card__actions .btn {
  width: auto;
  min-height: 44px;
}

.jo-action--danger {
  color: var(--color-error);
}

/* ── Éditeur ────────────────────────────────────────────────────────────── */

.jo-editor__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 22px;
}

.jo-editor__head h1 {
  margin: 0;
  font-size: var(--pj-fs-display);
}

.jo-editor__head p {
  margin: 4px 0 0;
}

/* A moderator's refusal is the first thing to read on the page. */
.jo-editor__banner {
  padding: 16px 20px;
  border-left: 4px solid var(--color-warning);
  background: var(--pj-warning-soft);
}

.jo-editor__banner p {
  margin: 4px 0 0;
}

.jo-form {
  display: grid;
  gap: 16px;
}

.jo-section {
  padding: 20px;
}

.jo-section h2 {
  margin: 0 0 14px;
  font-size: var(--pj-fs-lg);
}

.jo-form__grid {
  display: grid;
  gap: 14px;
}

.jo-req {
  color: var(--color-error);
}

.jo-hint {
  display: block;
  margin-top: 4px;
  font-size: var(--pj-fs-sm);
}

/* La forme du salaire (PO, 2026-10-01) : trois pastilles exclusives. De vrais
   boutons radio, pas des `.btn` — un choix affiché n'est pas un bouton de
   l'échelle (CLAUDE.md §9, les préréglages de Miles). La pastille cochée se
   lit à sa bordure ET à son fond, jamais à la bordure seule. */
.jo-salary {
  margin: 4px 0 14px;
  padding: 0;
  border: 0;
  min-width: 0;
}

.jo-salary__legend {
  float: none;
  width: auto;
  margin-bottom: 8px;
  font-size: var(--pj-fs-body);
  font-weight: 600;
  color: var(--pj-ink);
}

.jo-salary__types {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.jo-salary__type {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin: 0;
  padding: 0 16px;
  border: 2px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  cursor: pointer;
}

.jo-salary__type input {
  margin: 0;
  accent-color: var(--pj-orange);
}

.jo-salary__type:has(input:checked) {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  font-weight: 600;
}

/* La devise, lue et non saisie : une mention sous son libellé, alignée sur
   la hauteur d'un champ voisin pour que la grille ne saute pas. */
.jo-salary__currency-label {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
  color: var(--pj-ink);
}

.jo-salary__currency {
  margin: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.jo-salary__currency--missing {
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-sm);
}

.jo-salary__type:has(input:focus-visible) {
  outline: 2px solid var(--pj-orange);
  outline-offset: 2px;
}

/* L'encadre « Options de publication » de l'editeur de formation.

   Retour PO (2026-09-20) : la case « Afficher sur mon mini-site » etait
   posee au bas de la grille des tarifs, sous « Devise », sans titre. Elle
   fonctionnait a toutes les couches — c'est a l'oeil qu'elle manquait,
   parce qu'on la cherche la ou l'editeur d'offre la met : sous un titre.

   Un bloc encadre et non une `pj-card.jo-section` comme sur l'offre : ce
   formulaire-la est decoupe en plusieurs cartes, celui-ci n'en est qu'une
   seule, et imbriquer une carte dans une carte doublerait le chrome pour
   dire la meme chose. Meme titre, meme taille de titre, meme place — juste
   avant d'enregistrer. */
.jo-editor__options {
  display: grid;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm, 8px);
}

.jo-editor__options h2 {
  margin: 0;
  font-size: var(--pj-fs-lg);
}

.jo-editor__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.jo-editor__actions .btn {
  min-height: 44px;
}

/* The company space header gained a second link when M5 landed. */
.co-space__links {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.co-space__link {
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

/* Company fiche: the same three links as icon buttons, so the row of prose
   ("Offres d'emploi", "Pondérations du matching", "Page publique") stops
   competing with the completion bar right underneath it for space. The
   label survives as the button's title/tooltip. Scoped to this modifier
   rather than restyling .co-space__link itself, which the training
   provider space still renders as text. */
.co-space__links--icons {
  gap: 10px;
}

.co-space__links--icons .co-space__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: var(--pj-card-2);
  color: var(--color-muted);
  font-size: 1.05rem;
}

.co-space__links--icons .co-space__link:hover {
  background: var(--surface-chip);
  color: var(--color-primary);
}

/* ── 640px and up ───────────────────────────────────────────────────────── */

@media (min-width: 640px) {
  .jo-search__bar {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .jo-filters__grid,
  .jo-form__grid,
  .jo-public__facts {
    grid-template-columns: 1fr 1fr;
  }

  .jo-editor__actions .btn,
  .jo-mine__actions .btn {
    width: auto;
  }
}

/* ── 1200px and up: a result grid rather than one long column ───────────── */

@media (min-width: 1200px) {
  .jo-results {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .jo-public__facts {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .jo-public__block p {
    max-width: 78ch;
  }

  .jo-public__block-text {
    max-width: 78ch;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   M7 Matching — score badges, the breakdown, and the weight editor
   ═══════════════════════════════════════════════════════════════════════════

   Mobile-first at 360px, like the rest: the recommendation card stacks, the
   weight editor is one column of rows, and the two drawers are full-height
   sheets rather than centred dialogs — a modal you cannot scroll past is a
   trap on a phone.

   The four compatibility levels of §5.7 get four colours and they are the only
   place in this file that invents any: green for "très compatible" down to a
   neutral grey for "faible". A score of "—" (nothing was comparable) is
   deliberately colourless — it is not a bad score, it is no score.
   ═════════════════════════════════════════════════════════════════════════ */

/* Aliases onto the status scale (2026-09-10). These names are the vocabulary
   the matching screens speak, and every rule below keeps using them; what
   changed is that they now resolve through `--pj-*-soft` / `-ink`, which have
   a dark value. Before, they were declared here and nowhere else, so the
   chips kept their light tint under dark text — and already failed AA in
   light: `--mt-partial` measured 3,33:1 on its own tint. */
:root {
  --mt-very: var(--pj-success);
  --mt-very-soft: var(--pj-success-soft);
  --mt-ok: var(--pj-info-ink);
  --mt-ok-soft: var(--pj-info-soft);
  --mt-partial: var(--pj-warning-ink);
  --mt-partial-soft: var(--pj-warning-soft);
  --mt-low: var(--pj-neutral-ink);
  --mt-low-soft: var(--pj-neutral-soft);
}

/* ── The badge ──────────────────────────────────────────────────────────── */

.mt-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--mt-low-soft);
  color: var(--mt-low);
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}

.mt-badge--very_compatible { background: var(--mt-very-soft); color: var(--mt-very); }
.mt-badge--compatible      { background: var(--mt-ok-soft);   color: var(--mt-ok); }
.mt-badge--partially_compatible { background: var(--mt-partial-soft); color: var(--mt-partial); }
.mt-badge--low             { background: var(--mt-low-soft);  color: var(--mt-low); }

/* No score is not a low score: no colour, and the title attribute explains. */
.mt-badge--none {
  background: transparent;
  color: var(--connected-muted, #657085);
  border: 1px dashed var(--connected-border);
}

.mt-badge__score { font-size: var(--pj-fs-lg); }
.mt-badge__level { font-size: var(--pj-fs-sm); font-weight: 500; }

.mt-badge--sm { padding: 3px 10px; }
.mt-badge--sm .mt-badge__score { font-size: var(--pj-fs-md); }
.mt-badge--sm .mt-badge__level { font-size: var(--pj-fs-xs); }

/* ── The recommendations page ───────────────────────────────────────────── */

.mt-page { display: grid; gap: 16px; }

.mt-page__head {
  display: grid;
  gap: 12px;
  padding: 20px 22px;
}

.mt-page__eyebrow {
  margin: 0 0 2px;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.mt-page__title { margin: 0; font-size: var(--pj-fs-card); }

.mt-page__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Every bare <button> is width:100% in this stylesheet; a row of them needs
   to say otherwise (the same note as .jo-tabs and .co-tabs). */
.mt-page__actions .btn,
.mt-drawer__actions .btn,
.mt-pager .btn,
.mt-card__actions .btn {
  width: auto;
}

.mt-filters {
  display: grid;
  gap: 10px;
  padding: 16px 20px;
}

.mt-filters__count { margin: 0; font-weight: 600; }

.mt-list { display: grid; gap: 12px; }

.mt-card {
  display: grid;
  gap: 12px;
  padding: 18px 20px;
}

.mt-card__title { margin: 0; font-size: var(--pj-fs-lg); }
.mt-card__cv { margin: 2px 0 0; font-size: var(--pj-fs-body); }

.mt-card__gap {
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
  font-weight: 600;
  color: var(--mt-partial);
}

.mt-card__actions { display: flex; flex-wrap: wrap; gap: 8px; }

.mt-empty { padding: 28px 22px; text-align: center; }
.mt-empty h2 { margin: 0 0 6px; font-size: var(--pj-fs-lg); }

.mt-loading { padding: 20px 4px; }

.mt-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.mt-pager__state { font-weight: 600; }

/* ── The breakdown ──────────────────────────────────────────────────────── */

.mt-crits {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

.mt-crit__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.mt-crit__name { font-weight: 600; }
.mt-crit__weight { font-size: var(--pj-fs-sm); }

.mt-crit__bar {
  height: 8px;
  margin: 6px 0 4px;
  border-radius: 999px;
  background: var(--mt-low-soft);
  overflow: hidden;
}

.mt-crit__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--mt-ok);
}

.mt-crit__detail { margin: 0; font-size: var(--pj-fs-body); }

.mt-skipped {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--connected-border);
}

.mt-skipped__title { margin: 0 0 8px; font-size: var(--pj-fs-md); }

.mt-skipped__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 4px;
}

.mt-skipped__list li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px;
  font-size: var(--pj-fs-body);
}

.mt-skipped__note { margin: 10px 0 0; font-size: var(--pj-fs-sm); }

.mt-stale {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: var(--radius, 10px);
  background: var(--mt-partial-soft);
  color: var(--mt-partial);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

/* ── The drawers ────────────────────────────────────────────────────────── */

.mt-drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(22, 35, 59, 0.45);
}

.mt-drawer__panel {
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px;
  border-radius: var(--connected-radius-lg, 22px) var(--connected-radius-lg, 22px) 0 0;
}

.mt-drawer__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}

.mt-drawer__title { margin: 0; font-size: var(--pj-fs-lg); }

.mt-drawer__close {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: var(--connected-muted, #657085);
}

.mt-drawer__sub { margin: 0 0 14px; }

.mt-drawer__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 18px;
}

/* ── The weight editor (both the admin console and the offer drawer) ─────── */

.mt-weights__head { margin-bottom: 12px; }
.mt-weights__title { margin: 0 0 4px; font-size: var(--pj-fs-md); }
.mt-weights__hint { margin: 0; font-size: var(--pj-fs-body); }

.mt-weights__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 14px;
}

.mt-weight {
  display: grid;
  gap: 8px;
  padding: 12px;
  border: 1px solid var(--connected-border);
  border-radius: var(--radius, 10px);
}

/* A criterion at zero is switched off, not merely small. */
.mt-weight--off { opacity: 0.62; }

.mt-weight__name { display: block; font-weight: 600; }
.mt-weight__help { margin: 2px 0 0; font-size: var(--pj-fs-sm); }

.mt-weight__controls {
  display: flex;
  align-items: center;
  gap: 12px;
}

.mt-weight__range {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px; /* tap target, not the visual height of the track */
  accent-color: var(--connected-primary, #264A78);
}

.mt-weight__number {
  flex: 0 0 84px;
  width: 84px;
  text-align: center;
}

.mt-weight__state { margin: 0; font-size: var(--pj-fs-xs); min-height: 1em; }

.mt-weights__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin: 16px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--connected-border);
  font-size: var(--pj-fs-body);
}

.mt-weights__total strong { font-size: var(--pj-fs-card); }

.mt-thresholds { margin-top: 22px; }

.mt-thresholds__list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.mt-threshold {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.mt-threshold__label { margin: 0; }
.mt-threshold__input { flex: 0 0 84px; width: 84px; text-align: center; }

/* ── The admin console ──────────────────────────────────────────────────── */

.mt-scope-card .form-control { max-width: 420px; }
.mt-scope-note { margin: 8px 0 0; }

.mt-actions {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
  display: grid;
  gap: 12px;
}

.mt-note { margin: 0; }

.mt-actions__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.mt-history__title { margin: 0 0 4px; font-size: var(--pj-fs-md); }

.mt-history__list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.mt-history__item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 10px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius, 10px);
  font-size: var(--pj-fs-body);
}

.mt-history__item--active { border-color: var(--mt-very); background: var(--mt-very-soft); }

.mt-history__version { font-weight: 700; }
.mt-history__note { font-weight: 600; }
.mt-history__by,
.mt-history__at { grid-column: 2; font-size: var(--pj-fs-sm); }

.mt-history__badge {
  grid-column: 2;
  justify-self: start;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--mt-very);
  color: #fff;
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

/* ── 768px and up ───────────────────────────────────────────────────────── */

@media (min-width: 768px) {
  .mt-page__head {
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .mt-filters {
    grid-template-columns: auto 1fr;
    align-items: end;
  }

  .mt-filters__count { text-align: right; }

  .mt-card {
    grid-template-columns: auto 1fr auto;
    align-items: center;
  }

  .mt-weight {
    grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
    align-items: center;
    gap: 8px 18px;
  }

  .mt-weight__state { grid-column: 2; text-align: right; }

  /* Centred dialog once there is room for one. */
  .mt-drawer { align-items: center; }

  .mt-drawer__panel {
    max-width: 640px;
    border-radius: var(--connected-radius-lg, 22px);
  }

  .mt-actions {
    grid-template-columns: 1fr auto;
    align-items: end;
  }

  .mt-history__item {
    grid-template-columns: auto minmax(0, 1fr) auto auto auto;
    align-items: center;
  }

  .mt-history__by,
  .mt-history__at,
  .mt-history__badge { grid-column: auto; }
}

/* ── 1200px and up ──────────────────────────────────────────────────────── */

@media (min-width: 1200px) {
  .mt-weights__list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mt-drawer__panel { max-width: 760px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   M6 Application — postuler, mes candidatures, le pipeline entreprise
   ═══════════════════════════════════════════════════════════════════════════

   Mobile-first at 360px like the rest. Two things drive the layout:

   The pipeline is **tabs, not kanban columns**. Seven statuses side by side
   need horizontal room this platform does not have, and a board that only
   works on a laptop is a board most recruiters will not use. The counts sit on
   the tabs so nothing hides behind one, and the bar wraps — the same lesson as
   `.jo-tabs`, where an unwrappable row stretched the whole shell.

   Each status has one colour, used identically on both sides of the
   relationship: the candidate's "Consultée" and the recruiter's "Consultée"
   are the same fact and read as the same chip.
   ═════════════════════════════════════════════════════════════════════════ */

/* Same aliasing as `--mt-*` above. Seven application states, six of which
   failed AA in the light theme on their own tint before this. */
:root {
  --ap-submitted: var(--pj-neutral-ink);
  --ap-submitted-soft: var(--pj-neutral-soft);
  --ap-viewed: var(--pj-info-ink);
  --ap-viewed-soft: var(--pj-info-soft);
  --ap-shortlisted: var(--pj-accent-ink);
  --ap-shortlisted-soft: var(--pj-accent-soft);
  --ap-interview: var(--pj-warning-ink);
  --ap-interview-soft: var(--pj-warning-soft);
  --ap-hired: var(--pj-success);
  --ap-hired-soft: var(--pj-success-soft);
  --ap-rejected: var(--pj-danger);
  --ap-rejected-soft: var(--pj-danger-soft);
  --ap-withdrawn: var(--pj-neutral-ink);
  --ap-withdrawn-soft: var(--pj-neutral-soft);
}

/* ── Status chip ────────────────────────────────────────────────────────── */

.ap-status {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--ap-submitted-soft);
  color: var(--ap-submitted);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  white-space: nowrap;
}

.ap-status--submitted   { background: var(--ap-submitted-soft);   color: var(--ap-submitted); }
.ap-status--viewed      { background: var(--ap-viewed-soft);      color: var(--ap-viewed); }
.ap-status--shortlisted { background: var(--ap-shortlisted-soft); color: var(--ap-shortlisted); }
.ap-status--interview   { background: var(--ap-interview-soft);   color: var(--ap-interview); }
.ap-status--hired       { background: var(--ap-hired-soft);       color: var(--ap-hired); }
.ap-status--rejected    { background: var(--ap-rejected-soft);    color: var(--ap-rejected); }
.ap-status--withdrawn   { background: var(--ap-withdrawn-soft);   color: var(--ap-withdrawn); }

/* ── Shared shells ──────────────────────────────────────────────────────── */

.ap-apply,
.ap-mine,
.ap-pipeline {
  display: grid;
  gap: 16px;
}

.ap-list { display: grid; gap: 12px; }

.ap-empty { padding: 28px 22px; text-align: center; }
.ap-empty h2 { margin: 0 0 6px; font-size: var(--pj-fs-lg); }

.ap-loading { padding: 20px 4px; }

/* Every bare <button> is width:100% in this stylesheet; rows of them say so. */
.ap-apply__actions .btn,
.ap-mine__head .btn,
.ap-pipeline__actions .btn,
.ap-row__actions .btn,
.ap-card__actions .btn,
.ap-drawer__actions .btn,
.ap-pager .btn,
.ap-empty .btn {
  width: auto;
}

.ap-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.ap-pager__state { font-weight: 600; }

/* ── Tabs (both screens) ────────────────────────────────────────────────── */

.ap-tabs {
  display: flex;
  flex-wrap: wrap; /* seven short chips read fine on two lines */
  gap: 6px;
  padding-bottom: 4px;
}

.ap-tab {
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--connected-border);
  border-radius: 999px;
  background: var(--connected-surface);
  color: var(--connected-text);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  cursor: pointer;
}

.ap-tab--active {
  border-color: var(--primary-fill);
  background: var(--primary-fill);
  color: #fff;
}

.ap-tab__count {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.08);
  font-size: var(--pj-fs-xs);
}

.ap-tab--active .ap-tab__count { background: rgba(255, 255, 255, 0.22); }

/* ── Apply ──────────────────────────────────────────────────────────────── */

/* Maquette `Postuler.png` (2026-10-01). Préfixé `.ap-apply` partout : la
   carte porte aussi `.pj-card`, que `prosyjob.css` charge APRÈS cette
   feuille avec `padding: 26px` à (0,1,0) — une classe seule perdrait. */

.ap-apply .ap-apply__offer,
.ap-apply .ap-apply__form,
.ap-apply .ap-apply__blocked { padding: 18px; }

/* Deux classes : `button, .btn { width: 100% }` vaut aussi pour un `<a>`. */
.ap-apply .ap-apply__back {
  justify-self: start;
  width: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

.ap-apply .ap-apply__offer {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 14px;
}

.ap-apply .ap-apply__offer[hidden] { display: none; }

.ap-apply .ap-apply__logo {
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
  overflow: hidden;
}

.ap-apply .ap-apply__logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.ap-apply .ap-apply__eyebrow {
  margin: 0 0 4px;
  font-size: var(--pj-fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ap-apply .ap-apply__title {
  margin: 0 0 6px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.2;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.ap-apply .ap-apply__meta {
  display: grid;
  gap: 4px;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.ap-apply .ap-apply__meta i {
  width: 18px;
  margin-right: 6px;
  text-align: center;
  color: var(--pj-navy);
}

/* Une section du formulaire : icône orange, titre, et le texte aligné sous
   le titre plutôt que sous l'icône. */
.ap-apply .ap-apply__section {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  align-items: start;
  gap: 12px;
  margin-bottom: 14px;
}

.ap-apply .ap-apply__section-icon {
  margin-top: 2px;
  color: var(--pj-orange);
  font-size: var(--pj-fs-card);
  text-align: center;
}

.ap-apply .ap-apply__step {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.ap-apply .ap-apply__step label { margin: 0; font: inherit; }

.ap-apply .ap-apply__hint { margin: 4px 0 0; font-size: var(--pj-fs-body); }

.ap-apply .ap-apply__letter {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--pj-line);
}

.ap-apply .ap-apply__counter { margin: 6px 0 0; font-size: var(--pj-fs-sm); text-align: right; }

.ap-apply .ap-apply__actions {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px;
  margin-top: 16px;
}

.ap-apply .ap-apply__actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
}

.ap-apply .ap-cvs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.ap-apply .ap-cv__label {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0;
  padding: 14px 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: pointer;
}

/* Le CV retenu est la décision de l'écran : bordure ET fond, jamais l'une seule. */
.ap-apply .ap-cv__label:has(input:checked) {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
}

.ap-apply .ap-cv__label input {
  width: 22px;
  height: 22px;
  margin: 0;
  flex: 0 0 22px;
  accent-color: var(--pj-orange);
}

/* Bootstrap peint `.form-check-input:checked` en bleu par son propre fond,
   que `accent-color` ne touche pas : on reprend fond et bordure. */
.ap-apply .ap-cv__label .form-check-input:checked {
  background-color: var(--pj-orange);
  border-color: var(--pj-orange);
}

.ap-apply .ap-cv__label input:focus-visible {
  outline: 2px solid var(--pj-orange);
  outline-offset: 2px;
}

/* La vignette « CV » : un fichier, ses initiales dedans. */
.ap-apply .ap-cv__icon {
  position: relative;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-navy);
  font-size: var(--pj-fs-title);
}

.ap-apply .ap-cv__icon b {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding-top: 6px;
  font-size: var(--pj-fs-2xs);
  font-weight: 800;
}

.ap-apply .ap-cv__label:has(input:checked) .ap-cv__icon {
  background: var(--pj-card);
  color: var(--pj-orange);
}

.ap-apply .ap-cv__body { display: grid; gap: 2px; min-width: 0; }

.ap-apply .ap-cv__name {
  font-weight: 700;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.ap-apply .ap-cv__default {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-success-soft);
  color: var(--pj-success);
  font-size: var(--pj-fs-xs);
  font-style: normal;
  font-weight: 600;
}

.ap-apply .ap-cv__summary { font-size: var(--pj-fs-body); }

@media (min-width: 768px) {
  .ap-apply .ap-apply__offer,
  .ap-apply .ap-apply__form,
  .ap-apply .ap-apply__blocked { padding: 24px 28px; }

  .ap-apply .ap-apply__offer { gap: 26px; }

  .ap-apply .ap-apply__logo {
    width: 112px;
    height: 112px;
    font-size: var(--pj-fs-display);
  }

  .ap-apply .ap-apply__title { font-size: var(--pj-fs-display); }

  .ap-apply .ap-apply__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 28px;
  }

  .ap-apply .ap-apply__step { font-size: var(--pj-fs-card); }

  .ap-apply .ap-cv__label { padding: 16px 22px; gap: 22px; }

  .ap-apply .ap-apply__actions {
    display: flex;
    justify-content: flex-start;
  }

  .ap-apply .ap-apply__actions .btn { width: auto; padding-inline: 28px; }
}

/* ── My applications ────────────────────────────────────────────────────── */

.ap-mine__head,
.ap-pipeline__head {
  display: grid;
  gap: 12px;
  padding: 20px 22px;
}

.ap-mine__title,
.ap-pipeline__title { margin: 0; font-size: var(--pj-fs-card); }

.ap-pipeline__eyebrow {
  margin: 0 0 2px;
  font-size: var(--pj-fs-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ap-pipeline__actions { display: flex; flex-wrap: wrap; gap: 8px; }

.ap-row,
.ap-card {
  display: grid;
  gap: 12px;
  padding: 18px 20px;
}

.ap-row__title,
.ap-card__name { margin: 0; font-size: var(--pj-fs-lg); }

.ap-row__meta,
.ap-row__cv,
.ap-row__date,
.ap-row__help,
.ap-card__headline,
.ap-card__cv,
.ap-card__date { margin: 2px 0 0; font-size: var(--pj-fs-body); }

.ap-row__gap,
.ap-card__gap {
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
  font-weight: 600;
  color: var(--ap-interview);
}

.ap-row__state,
.ap-card__state { display: grid; gap: 4px; align-content: start; }

.ap-row__score { display: grid; gap: 4px; align-content: start; }

.ap-row__actions,
.ap-card__actions { display: flex; flex-wrap: wrap; gap: 8px; }

.ap-action--danger { color: var(--ap-rejected); }

.ap-card__contact {
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
  word-break: break-word;
}

.ap-card__rating {
  margin: 0;
  color: var(--ap-interview);
  letter-spacing: 2px;
}

/* A decided candidature recedes: the working set is what is still open. */
.ap-card--rejected,
.ap-card--withdrawn { opacity: 0.72; }

/* ── Drawer (shared with the detail panels) ─────────────────────────────── */

.ap-drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(22, 35, 59, 0.45);
}

.ap-drawer__panel {
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  padding: 20px;
  border-radius: var(--connected-radius-lg, 22px) var(--connected-radius-lg, 22px) 0 0;
}

.ap-drawer__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.ap-drawer__title { margin: 0; font-size: var(--pj-fs-lg); }

.ap-drawer__close {
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  color: var(--connected-muted, #657085);
}

.ap-drawer__sub { margin: 4px 0 16px; }

.ap-drawer__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0 4px;
}

.ap-detail__score {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 16px;
}

.ap-detail__frozen { margin: 0; font-size: var(--pj-fs-sm); }

/* E19-02 — the two scores, and the sort that chooses between them.
   `score` is what the candidature scored the day it arrived and is never
   rewritten (RG018); `score_actuel` is the same CV under the weights in force
   now, computed at read time. They are only both drawn when they differ. */
.ap-scores {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.ap-scores__row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.ap-scores__label { font-size: var(--pj-fs-xs); }

/* The live one is the actionable number when the recruiter sorts on it, so it
   reads as the primary and the frozen one as the reference beside it. */
.ap-scores__row--live .ap-scores__label { color: var(--pj-ink); }

.ap-detail__live {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-basis: 100%;
  padding-top: 10px;
  border-top: 1px solid var(--pj-line);
}

.ap-detail__live p { margin: 0; font-size: var(--pj-fs-sm); }

.ap-pipeline__sort {
  display: grid;
  gap: 8px;
}

.ap-pipeline__sort-hint { margin: 0; font-size: var(--pj-fs-sm); }

.ap-pipeline__truncated {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-warning-text, var(--pj-text));
}

/* E19-03 — a scope an admin may read and not write. The controls stay visible
   and disabled: seeing what an offer is ranked on is the point of the screen. */
.mt-scope-readonly {
  margin: 8px 0 0;
  font-weight: 600;
}

.mt-weights--readonly { opacity: 0.85; }

/* E19-04 — the inverted criterion, announced above the training form. The
   editor renders whatever vocabulary it is handed and cannot know that one of
   these sliders rewards a candidate for *lacking* something; left unsaid, the
   number reads as broken. */
.mt-inverted-note {
  margin: 8px 0 0;
  padding: 10px 12px;
  border-left: 3px solid var(--pj-orange);
  background: var(--pj-card-2);
  border-radius: 4px;
  font-size: var(--pj-fs-body);
}

.ap-detail__heading {
  margin: 20px 0 8px;
  font-size: var(--pj-fs-md);
}

.ap-detail__letter {
  margin: 0;
  white-space: pre-line; /* a letter typed with paragraphs keeps them */
}

.ap-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.ap-timeline__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: var(--pj-fs-body);
}

.ap-timeline__note {
  flex: 1 0 100%;
  padding-left: 2px;
  font-style: italic;
}

/* ── 768px and up ───────────────────────────────────────────────────────── */

@media (min-width: 768px) {
  .ap-mine__head,
  .ap-pipeline__head {
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .ap-row {
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: start;
  }

  .ap-row__actions { grid-column: 1 / -1; }

  .ap-card {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
  }

  .ap-card__actions { grid-column: 1 / -1; }

  .ap-drawer { align-items: center; }

  .ap-drawer__panel {
    max-width: 640px;
    border-radius: var(--connected-radius-lg, 22px);
  }

  /* Plus de `.ap-apply__form { max-width: 720px }` : la maquette
     `Postuler.png` aligne le formulaire sur la carte de l'offre. */
}

/* ── 1200px and up ──────────────────────────────────────────────────────── */

@media (min-width: 1200px) {
  .ap-drawer__panel { max-width: 760px; }

  .ap-detail__letter,
  .ap-apply__hint { max-width: 78ch; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   M8 Payment — the tunnel and the buyer's history (connected design system),
   plus a few touches for the admin channels/desk (Bootstrap admin template).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Same aliasing again. Note these six solids are also used as plain text on
   a card (`.pay-method__warn`), not only as ink on a tint — the `-ink` values
   were chosen to clear AA in both roles, so the repointing is safe there too. */
:root {
  --pay-initiated: var(--pj-neutral-ink); --pay-initiated-soft: var(--pj-neutral-soft);
  --pay-pending:   var(--pj-warning-ink); --pay-pending-soft:   var(--pj-warning-soft);
  --pay-succeeded: var(--pj-success);     --pay-succeeded-soft: var(--pj-success-soft);
  --pay-failed:    var(--pj-danger);      --pay-failed-soft:    var(--pj-danger-soft);
  --pay-cancelled: var(--pj-neutral-ink); --pay-cancelled-soft: var(--pj-neutral-soft);
  --pay-refunded:  var(--pj-info-ink);    --pay-refunded-soft:  var(--pj-info-soft);
}

/* ── Status pill (used on every payment screen) ─────────────────────────────── */
/* Shared field controls used by the tunnel and the history scope switch. */
.pay-checkout .field__label {
  display: block;
  font-size: var(--pj-fs-body);
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--connected-text);
}
.pay-checkout .field__control {
  width: 100%;
  padding: 11px 13px;
  border: 1px solid var(--connected-border);
  border-radius: 12px;
  background: var(--connected-surface);
  color: var(--connected-text);
  font: inherit;
  min-height: 44px;
}
.pay-checkout .field__control:focus {
  outline: none;
  border-color: var(--connected-primary);
  box-shadow: 0 0 0 3px rgba(38, 74, 120, 0.12);
}

/* ── Shared shells ──────────────────────────────────────────────────────────── */
.pay-checkout { display: grid; gap: 16px; }

.pay-checkout__body { display: grid; gap: 16px; }
.pay-loading { padding: 20px 4px; }
.pay-empty { padding: 28px 22px; text-align: center; }
.pay-empty h2 { margin: 0 0 6px; font-size: var(--pj-fs-lg); }

/* Bare <button> is width:100% in this stylesheet — rows of them opt out. */
.pay-result__actions .btn,
.pay-pager .btn,
.pay-empty .btn { width: auto; }

/* Le retour d'un prestataire hébergé (Stripe, PayPal, Monetbil). Même rythme
   que le tunnel : c'est la même tâche vue de l'autre côté de la redirection. */
/* Maquette paiements_retour.png (2026-10-08) : la tuile portefeuille et le
   titre dans une carte, puis une carte de résultat centrée. */
.pay-return { display: grid; gap: 16px; }
.pay-return__head { display: flex; align-items: center; gap: 16px; }
.pay-return__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}
.pay-return__heading { min-width: 0; }
.pay-return__title { margin: 0; font-size: var(--pj-fs-title); font-weight: 700; color: var(--pj-ink); }
.pay-return__sub { margin: 2px 0 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }

.pay-return__result {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 32px 22px 36px;
  text-align: center;
}
.pay-return__result-title { margin: 8px 0 6px; font-size: var(--pj-fs-card); font-weight: 700; color: var(--pj-ink); }
.pay-return__result-text { max-width: 440px; margin: 0; color: var(--pj-muted); font-size: var(--pj-fs-md); }
.pay-return .pay-return__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: auto;
  min-width: 220px;
  min-height: 44px;
  margin-top: 24px;
}

/* L'illustration : une carte bancaire et une pastille. Le ton de la pastille
   est la seule chose qui change d'un état à l'autre. */
.pay-ill { width: 200px; max-width: 70%; height: auto; }
.pay-ill__halo { fill: var(--pj-orange-soft); }
.pay-ill__dot { fill: var(--pj-orange); }
.pay-ill__dot--pale { fill: var(--pj-orange-soft); }
.pay-ill__spark { fill: none; stroke: var(--pj-muted); stroke-width: 4; stroke-linecap: round; opacity: .6; }
.pay-ill__card { fill: var(--pj-orange); }
.pay-ill__stripe { fill: var(--pj-orange-dark); opacity: .55; }
.pay-ill__chip { fill: var(--pj-card); opacity: .85; }
.pay-ill__line { fill: none; stroke: var(--pj-card); stroke-width: 4; stroke-linecap: round; opacity: .55; }
.pay-ill__badge > circle { stroke: var(--pj-card); stroke-width: 5; }
.pay-ill__glyph { fill: none; stroke: var(--pj-card); stroke-width: 4.5; stroke-linecap: round; stroke-linejoin: round; }
.pay-ill--error .pay-ill__badge > circle { fill: var(--pj-orange-fill); }
.pay-ill--success .pay-ill__badge > circle { fill: var(--pj-success-fill); }
.pay-ill--wait .pay-ill__badge > circle { fill: var(--pj-navy); }

@media (max-width: 575.98px) {
  .pay-return__icon { width: 44px; height: 44px; font-size: var(--pj-fs-card); }
  .pay-return__title { font-size: var(--pj-fs-card); }
  .pay-return .pay-return__cta { width: 100%; min-width: 0; }
}
/* L'attente a une forme : trois points qui respirent, pas un écran figé. */
.pay-return__spinner {
  margin: 10px 0 0;
  color: var(--pj-muted);
  font-size: 1.6rem;
  letter-spacing: 4px;
  animation: pay-return-pulse 1.4s ease-in-out infinite;
}
@keyframes pay-return-pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .pay-return__spinner { animation: none; opacity: .7; }
}

.pay-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
/* ── Mes paiements (`.pm-`, maquette 2026-09-29) ─────────────────────────────
   One card: title and account picker, the status tabs with their counts, a
   table, and the pager beside « Affichage de … ». Below 768px the table's
   rows become stacked cards — one markup, the CSS decides — and the tab row
   shows three chips plus a button unfolding the rest. Every bare button of
   this shell is `width: 100%` (the `button, .btn` rule at the top of this
   sheet), hence the `width: auto` on each small one. */
.pm-card { display: grid; grid-template-columns: minmax(0, 1fr); gap: 20px; }
.pm-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 16px; }
.pm-head__title { margin: 0; font-size: var(--pj-fs-display); font-weight: 800; line-height: 1.1; color: var(--pj-ink); }
.pm-head__count { margin: 6px 0 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.pm-scope { display: grid; gap: 6px; min-width: 260px; margin: 0; }
.pm-scope__label { font-weight: 600; color: var(--pj-ink); }
.pm-scope .form-select { width: 100%; min-height: 48px; border-radius: var(--pj-radius-sm); }

.pm-tabs { display: flex; flex-wrap: wrap; gap: 10px; }
.pm-tabs .pm-tab {
  width: auto;
  min-height: 44px;
  padding: 8px 20px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.pm-tabs .pm-tab--active { border-color: var(--pj-navy); background: var(--pj-navy); color: var(--pj-card); }
.pm-tabs .pm-tabs__more { display: none; }

.pm-table { width: 100%; border-collapse: separate; border-spacing: 0; border: 1px solid var(--pj-line); border-radius: var(--pj-radius-sm); overflow: hidden; }
.pm-table th {
  padding: 12px 16px;
  background: var(--pj-bg);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  text-align: left;
}
.pm-table td { padding: 12px 16px; border-top: 1px solid var(--pj-line); vertical-align: middle; }
.pm-table .pm-table__num { text-align: center; }
.pm-table .pm-table__action { text-align: center; }
.pm-row__desc { display: grid; gap: 2px; }
.pm-row__title { color: var(--pj-ink); font-weight: 700; }
.pm-row__meta { color: var(--pj-muted); font-size: var(--pj-fs-body); }
.pm-row__instructions {
  margin-top: 6px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--pay-pending-soft);
  color: var(--pay-pending);
  font-size: var(--pj-fs-body);
}
.pm-row__account { color: var(--pj-muted); }
/* La ligne qu'une notification a nommée (`?paiement=`, 2026-10-08). */
.pm-table tr.pm-row--focus > td { background: var(--pj-orange-soft); }
.pm-row__amount { color: var(--pj-ink); font-weight: 700; white-space: nowrap; }
.pm-none { color: var(--pj-muted); }

.pm-table .pm-receipt.btn {
  width: auto;
  min-height: 44px;
  gap: 8px;
  padding: 8px 18px;
  border: 1px solid var(--pj-orange);
  background: var(--pj-card);
  color: var(--pj-orange-text);
  white-space: nowrap;
}
.pm-table .pm-receipt.btn:hover { background: var(--pj-orange-soft); }
.pm-table .pm-more {
  width: 44px;
  min-height: 44px;
  border: 0;
  border-radius: var(--pj-radius-pill);
  background: transparent;
  color: var(--pj-muted);
  cursor: pointer;
}
.pm-table .pm-more:hover,
.pm-table .pm-more[aria-expanded="true"] { background: var(--pj-neutral-soft); color: var(--pj-ink); }
.pm-detail td { border-top: 0; padding-top: 0; }
.pm-detail__line { margin: 0 0 4px; padding: 8px 12px; border-radius: 10px; background: var(--pj-neutral-soft); color: var(--pj-ink); font-size: var(--pj-fs-body); }

.pm-empty { padding: 28px 22px; text-align: center; }
.pm-empty h2 { margin: 0 0 6px; font-size: var(--pj-fs-lg); }
.pm-loading { padding: 20px 4px; }

.pm-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.pm-foot__range { margin: 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.pm-foot__range:empty { display: none; }

@media (max-width: 767px) {
  .pm-card { gap: 14px; }
  .pm-head { display: grid; gap: 12px; }
  .pm-scope { min-width: 0; }

  /* Three chips, then « ≡ » unfolds the rest. The chosen tab is always shown. */
  .pm-tabs { flex-wrap: nowrap; gap: 8px; }
  .pm-tabs.pm-tabs--open { flex-wrap: wrap; }
  .pm-tabs .pm-tab { padding: 6px 12px; font-size: var(--pj-fs-body); }
  .pm-tabs:not(.pm-tabs--open) .pm-tab:nth-child(n+4):not(.pm-tab--active) { display: none; }
  .pm-tabs .pm-tabs__more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 44px;
    min-height: 44px;
    margin-left: auto;
    border: 1px solid var(--pj-line);
    border-radius: 50%;
    background: var(--pj-card);
    color: var(--pj-ink);
  }

  /* The table becomes cards: title and meta on the left, the badge top
     right, the amount under the text, the action bottom right. */
  .pm-table, .pm-table tbody { display: block; border: 0; }
  .pm-table thead { display: none; }
  .pm-table tr.pm-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "desc   status"
      "amount action";
    align-items: center;
    gap: 6px 12px;
    margin-top: 10px;
    padding: 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
  }
  .pm-table td { padding: 0; border-top: 0; }
  .pm-row__desc { grid-area: desc; }
  .pm-row__account { display: none; }
  .pm-table .pm-row__amount { grid-area: amount; text-align: left; font-size: var(--pj-fs-md); }
  .pm-row__status { grid-area: status; justify-self: end; align-self: start; }
  .pm-table .pm-row__action { grid-area: action; justify-self: end; }
  .pm-table .pm-receipt.btn { padding: 6px 14px; }
  .pm-none { display: none; }
  .pm-table tr.pm-detail { display: block; }
  .pm-table tr.pm-detail[hidden] { display: none; }
  .pm-detail td { display: block; padding: 6px 0 0; }

  .pm-foot { justify-content: center; }
  .pm-foot__range { display: none; }
}

/* 360px, measured: three chips and « ≡ » came to ~370px in a 268px column,
   and the unwrapped row pushed the whole card past the screen's edge. Two
   chips then, and the card's padding given back — as on the other pages. */
@media (max-width: 480px) {
  .pm-page .pm-card.pj-card { padding: 18px 14px; }
  .pm-tabs:not(.pm-tabs--open) .pm-tab:nth-child(n+3):not(.pm-tab--active) { display: none; }
}


/* ── Historique des crédits Assistant (2026-09-15, maquette 2026-09-29) ─
   Deux cartes : l'en-tête (titre + encadré du solde et « Recharger »), puis
   le journal (compteur, filtres Date/Type, lignes). Une ligne est une grille
   icône | texte | date | montant ; sous 768px la date passe sous le détail,
   au format court, et le « solde après » s'efface comme sur la maquette
   mobile. Tout `.btn` de cette coquille est pleine largeur par défaut (règle
   `button, .btn` en tête de cette feuille), d'où les `width: auto`. */
.aih-coin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: 2.3rem;
}
.aih-coin--on-soft { width: 72px; height: 72px; font-size: 1.9rem; background: var(--pj-card); }

.aih-head { display: grid; gap: 20px; }
.aih-head__intro { display: flex; align-items: center; gap: 20px; }
.aih-head__title { margin: 0; font-size: var(--pj-fs-display); font-weight: 800; line-height: 1.15; color: var(--pj-ink); }
.aih-head__lead { margin: 8px 0 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }

.aih-balance {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 12px 20px;
  padding: 16px 20px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
}
.aih-balance[hidden] { display: none; }
.aih-balance__text { margin: 0; display: grid; gap: 2px; color: var(--pj-ink); }
.aih-balance__label { font-size: var(--pj-fs-body); }
.aih-balance__line { font-size: var(--pj-fs-lg); }
.aih-balance__value { font-size: var(--pj-fs-display); font-weight: 800; line-height: 1; color: var(--pj-orange-text); margin-right: 4px; }
.aih-balance .aih-balance__cta.btn {
  width: auto;
  min-height: 52px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 22px;
  font-size: var(--pj-fs-md);
}

.aih-journal { display: grid; gap: 16px; }
.aih-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.aih-toolbar__count { margin: 0; font-size: var(--pj-fs-body); color: var(--pj-muted); }
.aih-toolbar__filters { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 16px; }
.aih-filter { display: flex; align-items: center; gap: 12px; margin: 0; position: relative; }
.aih-filter__label { color: var(--pj-muted); }
.aih-filter .form-select { min-height: 48px; min-width: 190px; border-radius: var(--pj-radius-sm); }
.aih-filter--period .form-select { min-width: 256px; padding-left: 48px; }
.aih-filter__icon { position: absolute; left: 18px; color: var(--pj-muted); pointer-events: none; font-size: 1.1rem; }

.aih-state { padding: 12px 16px; border-radius: var(--pj-radius-sm); background: var(--pj-danger-soft); color: var(--pj-danger); }

.aih-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.aih-list__note { padding: 16px 4px; }

.aih-row {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) minmax(0, 15rem) auto;
  grid-template-areas: "icon body date amount";
  align-items: center;
  gap: 4px 28px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}
.aih-row__icon {
  grid-area: icon;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  border-radius: 18px;
  font-size: 1.6rem;
  background: var(--pj-success-soft);
  color: var(--pj-success);
}
.aih-row--usage .aih-row__icon { background: var(--pj-danger-soft); color: var(--pj-danger); }
.aih-row__body { grid-area: body; min-width: 0; }
.aih-row__title { margin: 0; font-size: var(--pj-fs-md); font-weight: 700; color: var(--pj-ink); }
.aih-row__detail,
.aih-row__balance { margin: 4px 0 0; color: var(--pj-muted); }
.aih-row__date { grid-area: date; margin: 0; align-self: start; padding-top: 6px; color: var(--pj-muted); }
.aih-row__when i { margin-right: 10px; }
.aih-row__date-short,
.aih-row__date-balance { display: none; }
.aih-row__amount {
  grid-area: amount;
  justify-self: end;
  min-width: 80px;
  padding: 8px 14px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-card);
  font-weight: 700;
  text-align: center;
  white-space: nowrap;
}
.aih-row__amount--credit { background: var(--pj-success-soft); color: var(--pj-success); }
.aih-row__amount--debit { background: var(--pj-danger-soft); color: var(--pj-danger); }

.aih-more { margin: 0; text-align: center; }
.aih-more[hidden], .aih-more:has(.btn[hidden]) { display: none; }
.aih-more .btn { width: auto; min-height: 44px; }

@media (max-width: 991px) {
  .aih-balance { grid-template-columns: auto 1fr; }
  .aih-balance .aih-balance__cta.btn { grid-column: 1 / -1; justify-content: center; width: 100%; }
}

@media (max-width: 767px) {
  .aih-coin { width: 64px; height: 64px; font-size: 1.7rem; }
  .aih-head__intro { align-items: flex-start; gap: 14px; }
  .aih-head__lead { font-size: var(--pj-fs-body); }
  .aih-balance { padding: 14px 16px; gap: 12px 14px; }
  .aih-coin--on-soft { width: 56px; height: 56px; font-size: 1.5rem; }
  .aih-balance__label { font-size: var(--pj-fs-body); }
  .aih-balance__value { font-size: var(--pj-fs-display); }
  .aih-balance__line { font-size: var(--pj-fs-md); }
  .aih-balance .aih-balance__cta.btn { font-size: var(--pj-fs-md); }

  .aih-toolbar { flex-direction: column-reverse; align-items: stretch; }
  .aih-toolbar__count { font-size: var(--pj-fs-body); }
  .aih-toolbar__filters { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); gap: 10px; }
  .aih-filter { gap: 8px; min-width: 0; }
  .aih-filter .form-select,
  .aih-filter--period .form-select { min-width: 0; width: 100%; font-size: var(--pj-fs-body); }
  .aih-filter--period .form-select { padding-left: 40px; }
  .aih-filter__icon { left: 14px; }
  .aih-filter__label { font-size: var(--pj-fs-body); }
}

/* The row folds on the journal's own width, not the viewport's: at 768px
   the journal is 705px wide, and the four-column row measured a
   141px text column there. */
.aih-journal { container: aih-journal / inline-size; }
@container aih-journal (max-width: 720px) {
  .aih-row {
    grid-template-columns: 52px minmax(0, 1fr) auto;
    grid-template-areas:
      "icon body amount"
      "icon date amount";
    gap: 2px 14px;
    padding: 12px;
  }
  .aih-row__icon { width: 52px; height: 52px; border-radius: 14px; font-size: 1.2rem; }
  .aih-row__title { font-size: var(--pj-fs-md); }
  .aih-row__detail { font-size: var(--pj-fs-body); margin-top: 2px; }
  .aih-row__balance { display: none; }
  /* The date and the balance share one line when it fits and break between
     the two when it does not — never inside « Solde : 40 », never between
     the calendar icon and its date. */
  .aih-row__date { padding-top: 0; font-size: var(--pj-fs-sm); }
  .aih-row__when { margin-right: 10px; }
  .aih-row__when i { margin-right: 6px; }
  .aih-row__date-long { display: none; }
  .aih-row__date-short { display: inline; }
  .aih-row__date-balance { display: inline-block; white-space: nowrap; }
  .aih-row__amount { min-width: 56px; padding: 6px 10px; font-size: var(--pj-fs-md); }
}

/* 360px, measured: at the 767px settings a row's text column was 81px wide
   and each select showed nine characters. The journal gives back its card
   padding, the filters stack (a label beside each would leave neither
   readable), and the icon and the amount shrink. */
@media (max-width: 480px) {
  .aih-head,
  .aih-journal { padding: 16px 12px; }
  .aih-coin { width: 48px; height: 48px; font-size: 1.3rem; }
  .aih-coin--on-soft { width: 44px; height: 44px; font-size: 1.15rem; }
  .aih-balance { padding: 12px; }
  .aih-toolbar__filters { grid-template-columns: minmax(0, 1fr); }
  .aih-filter__label { display: none; }
}
@container aih-journal (max-width: 360px) {
  .aih-row {
    grid-template-columns: 40px minmax(0, 1fr) auto;
    gap: 2px 10px;
    padding: 10px;
  }
  .aih-row__icon { width: 40px; height: 40px; border-radius: 12px; font-size: 1rem; }
  .aih-row__amount { min-width: 0; padding: 5px 8px; font-size: var(--pj-fs-md); }
}

/* ── Acheter des Miles (E16-07) ─────────────────────────────────────────
   Un écran qui ne fait qu'une chose : demander une quantité et en montrer
   le prix. Le taux n'est écrit nulle part ici — il vient du serveur à
   chaque frappe, sans quoi ce serait une seconde source de vérité. */
.bm-card {
  display: grid;
  gap: 18px;
}

.bm-balance {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--color-border);
}

.bm-balance__label {
  color: var(--connected-muted);
  font-weight: 600;
}

.bm-balance__value {
  font-size: var(--pj-fs-card);
  font-weight: 800;
}

.bm-form {
  display: grid;
  gap: 16px;
}

.bm-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Échappe au `button, .btn { width: 100% }` du haut de cette feuille : une
   rangée de trois boutons pleine largeur n'est pas une rangée. */
.bm-preset {
  width: auto;
  /* 44 px de cible tactile — la règle du projet, mesurée et pas devinée. */
  min-height: 44px;
}

.bm-quote {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 16px;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--surface-sunken);
}

.bm-quote__label {
  color: var(--connected-muted);
  font-weight: 600;
}

.bm-quote__price {
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--connected-primary);
}

.bm-form__submit {
  min-height: 44px;
}

.bm-note {
  margin: 0;
  font-size: var(--pj-fs-body);
}

/* ── Tunnel: summary, method picker, result ─────────────────────────────────── */
.pay-checkout__title { margin: 0; font-size: var(--pj-fs-card); }

.pay-summary {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.pay-summary__label { color: var(--connected-muted); font-weight: 600; }
.pay-summary__price { font-size: var(--pj-fs-card); font-weight: 700; color: var(--connected-primary); }
.pay-summary__or { color: var(--connected-muted); font-weight: 500; font-size: var(--pj-fs-md); }

/* ── Prix : argent d'abord, miles à côté (E15-04) ───────────────────────
   « Tous les prix doivent s'afficher en vrai argent et en équivalent
   miles », et « la valeur en miles doit s'écrire à côté du prix normal,
   mais en plus petits caractères ». Le montant est le prix ; les miles
   l'annotent. Rendu par `framework/utils/price.js`, partout. */
.pj-price__main {
  font-weight: 600;
}

.pj-price__miles {
  margin-left: 8px;
  font-size: 0.8em;
  font-weight: 500;
  color: var(--color-muted);
  white-space: nowrap;
}

.pay-form__legend { margin: 0 0 12px; font-size: var(--pj-fs-lg); }
.pay-methods { display: grid; gap: 10px; }

.pay-method {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--connected-border);
  border-radius: 14px;
  cursor: pointer;
  min-height: 44px;
}
.pay-method:has(input:checked) {
  border-color: var(--connected-primary);
  box-shadow: 0 0 0 2px rgba(38, 74, 120, 0.16);
  background: var(--surface-chip);
}
.pay-method--disabled { opacity: 0.55; cursor: not-allowed; }
.pay-method input { width: 20px; height: 20px; flex: 0 0 auto; }
/* La portee d'un canal dans la console (E46) : mondial ou par pays. Une puce
   discrete, pas un etat — `pc-state` est deja pris par actif/operationnel et
   les confondre ferait lire « mondial » comme un probleme. */
.pc-scope {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  border: 1px solid var(--color-border);
  color: var(--connected-muted);
}
.pc-scope--global { border-color: var(--connected-primary); color: var(--connected-primary); }
.pc-readonly { font-size: var(--pj-fs-sm); }

/* Le genre du fournisseur, sous sa cle (E48) : `monetbil` seul ne dit pas ce
   qu'est ce fournisseur ni pourquoi la ligne d'a cote est en lecture seule.
   En bloc, pour ne pas allonger la colonne sur un telephone. */
.pc-kind {
    display: block;
    font-size: var(--pj-fs-xs);
    line-height: 1.3;
    color: var(--pj-muted);
}

.pay-method__body { display: grid; gap: 2px; min-width: 0; }
.pay-method__title { font-weight: 600; }
/* Ce que CE canal debiterait, quand il differe du prix de l'en-tete (E46).
   `margin-left: auto` le pousse a droite de la ligne flex sans ajouter de
   colonne ; `white-space: nowrap` empeche « 7,60 EUR » de se couper en deux. */
.pay-method__amount {
  margin-left: auto;
  flex: 0 0 auto;
  font-weight: 700;
  white-space: nowrap;
}
.pay-method__sub { font-size: var(--pj-fs-body); }
.pay-method__warn { font-size: var(--pj-fs-sm); color: var(--pay-failed); font-weight: 600; }

.pay-form__phone { margin-top: 14px; }
.pay-form__phone-error { margin: 6px 0 0; font-size: var(--pj-fs-sm); color: var(--pay-failed); font-weight: 600; }
.pay-form__submit { width: 100%; margin-top: 18px; min-height: 48px; }

.pay-result { text-align: center; padding: 32px 22px; }
.pay-result__icon {
  width: 64px; height: 64px; line-height: 64px;
  margin: 0 auto 14px;
  border-radius: 50%;
  font-size: 1.8rem;
}
.pay-result--ok .pay-result__icon { background: var(--pay-succeeded-soft); color: var(--pay-succeeded); }
.pay-result--pending .pay-result__icon { background: var(--pay-pending-soft); color: var(--pay-pending); }
.pay-result--failed .pay-result__icon { background: var(--pay-failed-soft); color: var(--pay-failed); }
.pay-result__title { margin: 0 0 6px; font-size: var(--pj-fs-card); }
.pay-result__amount { margin: 0 0 10px; font-weight: 600; }
.pay-result__text { margin: 0 auto 16px; max-width: 46ch; }
/* « vous en aviez deja un » : une note, pas une alerte — rien n'a echoue. */
.pay-result__resumed {
    margin: 0 auto 16px;
    max-width: 46ch;
    padding: 10px 14px;
    border-radius: 8px;
    border: 1px solid var(--pj-line);
    background: var(--pj-info-soft);
    color: var(--pj-info-ink);
    font-size: var(--pj-fs-body);
}
.pay-result__instructions {
  margin: 0 auto 18px;
  max-width: 46ch;
  text-align: left;
  background: var(--pay-pending-soft);
  color: var(--pay-pending);
  padding: 12px 14px;
  border-radius: 12px;
  white-space: pre-wrap;
}
.pay-result__actions {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}

/* ── Admin (Bootstrap template) touches ─────────────────────────────────────── */
.pc-scope-card, .pc-filters-card, .pa-filters-card { margin-bottom: 16px; }
.pc-editor-card { margin-top: 16px; }
.pc-editor__title { margin: 0 0 14px; }
.pc-editor__actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 10px; }
.pc-active { margin: 6px 0 14px; }
/* Ce que l'administrateur doit encore remplir avant d'activer un canal, et
   l'état du coffre à secrets. Un avertissement, pas une erreur. */
.pc-creds__warning {
  margin: 0 0 14px;
  padding: 10px 12px;
  border-left: 3px solid var(--pj-orange);
  background: var(--pj-orange-soft);
  border-radius: 6px;
}
.pc-creds__warning p { margin: 0; }
.pc-creds__warning p + p { margin-top: 4px; }
.pc-table__actions, .pa-table__actions, .ic-table__actions { white-space: nowrap; }

/* Dix colonnes ne tiennent pas dans la boite : 1434px pour 1203, et c'est la
   colonne d'actions qui tombait hors champ — la table defile bien, mais un
   bouton qu'il faut aller chercher a chaque ligne se lit comme un defaut
   d'affichage. Elle reste collee au bord droit ; le reste glisse dessous.
   Reservee au grand format : sous 768px la table devient des cartes, ou tout
   est deja visible. Meme correctif que `.alv-col-actions` et `.dup-col-actions`,
   pour la meme raison. */
@media (min-width: 768px) {
  .pa-table__actions, .ic-table__actions {
    position: sticky;
    right: 0;
    z-index: 1;
    background: var(--pj-card);
    box-shadow: -10px 0 10px -10px rgba(0, 0, 0, 0.28);
  }
}

.pc-state {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}
.pc-state--on { background: var(--pay-succeeded-soft); color: var(--pay-succeeded); }
.pc-state--off { background: var(--pay-cancelled-soft); color: var(--pay-cancelled); }
/* Active in the console, unusable at the till: a credential is missing. */
.pc-state--warn { background: var(--pay-pending-soft); color: var(--pay-pending); margin-left: 6px; }

/* Les pays desservis, dans le tableau. Des puces `inline-block` ne se coupent
   pas : repliee en carte, la cellule fait 269px et trois noms de pays en
   sortiraient. Meme correctif, pour la meme raison, que `.pa-payer-cell`. */
.pc-countries-cell {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  min-width: 0;
}

.pc-country {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--pj-bg);
  /* `--pj-line` et non `--color-border` : ce dernier n'est pas defini sur la
     pile admin, et un `var()` sans valeur ne retombe pas sur un defaut — la
     declaration entiere devient `inherit`, donc la bordure disparait sans que
     rien ne le signale (CLAUDE.md §9). Mesurer, pas regarder. */
  border: 1px solid var(--pj-line);
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

/* Les cases a cocher pays de l'editeur.
   Chacune est un <label> pleine largeur d'au moins 44px : une case nue fait
   ~13px de haut, tres en deca de ce qu'une cible tactile demande sur les
   telephones qui font ~90% de l'audience. Mesurer plutot que se fier au nom
   d'une classe — `.btn--sm` est reste a 38px pendant cinq jalons. */
.pc-countries__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 4px;
  margin-bottom: 6px;
}

.pc-country-check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  margin: 0;
  padding: 4px 10px;
  border: 1px solid var(--pj-line);
  border-radius: 8px;
  cursor: pointer;
  font-weight: 500;
}

.pc-country-check input { margin: 0; flex: none; }
.pc-country-check span { min-width: 0; overflow-wrap: anywhere; }
.pc-country-check small { margin-left: auto; text-align: right; }
/* Un pays hors perimetre : montre et coche, mais intouchable. */
.pc-country-check:has(input:disabled) { cursor: default; opacity: 0.75; }

.pc-scope-field {
  border: 0;
  margin: 0 0 14px;
  padding: 0;
}

.pc-scope-field legend { float: none; width: auto; font-size: inherit; }
.pc-provider-other { margin-top: 6px; }

.pa-payer__email { font-size: var(--pj-fs-sm); }
/* Le nom et l'email tiennent dans un seul item : en mode carte la cellule
   est une boite flex, et deux voisins y seraient deux colonnes serrees. */
.pa-payer-cell { min-width: 0; }
.pa-pager, .pc-pager, .ic-pager { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 14px; }

/* La rangee sous les filtres : la taille de page a gauche, la remise a zero a
   droite. Elle vit hors de la grille des champs parce qu'elle ne filtre rien —
   l'une regle l'affichage, l'autre efface. */
.pa-filters-actions, .pc-filters-actions, .ic-filters-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 12px;
  margin-top: 4px;
}

.pa-size, .pc-size {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 600;
}

.pa-size .form-control, .pc-size .form-control {
  width: auto;
  min-width: 88px;
}

.pa-filters-actions .btn, .pc-filters-actions .btn, .ic-filters-actions .btn { width: auto; }

/* Le pied du tableau : le nombre de lignes de l'ensemble filtre, et **un
   montant par devise**. Jamais un total unique — francs et euros n'ont pas de
   parite ici, et un paiement en Miles porte une devise nulle : les additionner
   ferait un chiffre faux qui aurait l'air juste. */
.pa-total th {
  border-top: 2px solid var(--color-border);
  font-weight: 700;
  white-space: nowrap;
}

.pa-total th:last-child { text-align: right; }

.pa-total__amount + .pa-total__amount { margin-left: 16px; }
.pa-pager__state, .pc-pager__state { font-weight: 600; }

/* ── Mobile: rows and admin tables become stacked cards ─────────────────────── */
@media (max-width: 767px) {
  .pc-table thead, .pa-table thead, .ic-table thead { display: none; }
  .pc-table tr, .pa-table tr, .ic-table tr {
    display: block;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    padding: 8px 12px;
    margin-bottom: 10px;
  }
  .pc-table td, .pa-table td, .ic-table td {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    border: none;
    padding: 6px 0;
    text-align: right;
    /* Les deux lignes qui font tenir la carte dans 360px.

       Le theme pose `white-space: nowrap` sur les cellules du tableau, ce qui
       est juste tant qu'on est un tableau : une colonne s'elargit. Repliee en
       carte, la cellule fait toute la largeur, et une valeur qui refuse de se
       couper elargit alors la boite — mesure ici : 396px de contenu dans une
       carte de 269, donc chaque valeur sortait du champ pendant que son
       intitule restait visible. Un ecran qui montre les etiquettes et cache
       les donnees.

       `normal` seul ne suffit pas : un email n'a aucune espace ou se couper.
       `anywhere` agit sur la taille min-content, la ou `break-word` ne
       l'aurait pas fait — c'est ce dont un item flex a besoin pour retrecir.
       Meme correctif que `.alv-table td`, meme cause. */
    white-space: normal;
    overflow-wrap: anywhere;
  }

  /* `tbody td` et non `td` : cette feuille se charge **avant** le theme du
     vendeur, donc a specificite egale c'est lui qui gagne (CLAUDE.md SS9, et
     c'est deliberé). Son `.table td { white-space: nowrap }` reprenait donc la
     main sur la declaration ci-dessus — `overflow-wrap` passait, `white-space`
     non, et la carte continuait de deborder sans que la regle ait l'air
     fautive. Un selecteur d'un cran plus precis tranche quel que soit l'ordre. */
  .pc-table tbody td, .pa-table tbody td, .ic-table tbody td { white-space: normal; }

  .pc-table td::before, .pa-table td::before, .ic-table td::before {
    content: attr(data-label);
    /* L'intitule ne se replie pas, la valeur si : c'est un libelle court dont
       la largeur est connue, et c'est a la valeur de ceder la place. */
    flex: none;
    white-space: nowrap;
    font-weight: 600;
    color: var(--color-muted);
    text-align: left;
  }
  .pc-table__actions, .pa-table__actions, .ic-table__actions { justify-content: flex-end; flex-wrap: wrap; }

  /* Le panneau de decision n'est pas une donnee : il n'a pas d'intitule a
     poser en face, et le `display: flex` des cellules l'ecraserait contre
     le bord droit comme une valeur. Il reprend toute la largeur de sa
     carte, ce qu'un champ de saisie demande de toute facon. */
  .ic-table .ic-decision td {
    display: block;
    text-align: left;
  }
  .ic-table .ic-decision td::before { content: none; }

  /* Le pied devient une carte comme les autres : `th` n'herite pas du
     `display: flex` pose sur `td`, il resterait donc une cellule de tableau
     dans une pile de blocs. */
  .pa-total th {
    display: block;
    padding: 6px 0;
    text-align: left;
    white-space: normal;
  }

  .pa-total th:last-child { text-align: left; }

  .pa-total__amount { display: block; }
  .pa-total__amount + .pa-total__amount { margin-left: 0; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   M9 Subscription — the company forfait page (connected) + the admin desk.
   ═══════════════════════════════════════════════════════════════════════════ */

.sub-page { display: grid; gap: 16px; }
.sub-page__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.sub-page__title { margin: 0; font-size: var(--pj-fs-card); }
.sub-page__scope-field { min-width: 220px; }

/* ── Current-state card ─────────────────────────────────────────────────────── */
.sub-state { display: grid; gap: 6px; }
.sub-state--active { border-left: 4px solid var(--pay-succeeded); }
.sub-state__badge {
  justify-self: start;
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  background: var(--pay-succeeded-soft);
  color: var(--pay-succeeded);
}
.sub-state__badge--none { background: var(--pay-cancelled-soft); color: var(--pay-cancelled); }
.sub-state__plan { margin: 4px 0 0; font-size: var(--pj-fs-lg); }
.sub-state__until { margin: 0; font-weight: 600; }
.sub-state__none { margin: 0; }

/* ── Plan cards ─────────────────────────────────────────────────────────────── */
.sub-plans__title { margin: 4px 0 12px; font-size: var(--pj-fs-lg); }
.sub-plans__grid {
  display: grid;
  gap: 12px;
  grid-template-columns: 1fr;
}
.sub-plan { display: grid; gap: 6px; align-content: start; }
.sub-plan .btn { width: auto; justify-self: start; margin-top: 6px; }
.sub-plan__period {
  justify-self: start;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--connected-accent);
}
.sub-plan__name { margin: 0; font-size: var(--pj-fs-lg); }
.sub-plan__price { margin: 0; font-size: var(--pj-fs-card); font-weight: 700; color: var(--connected-primary); }
.sub-plan__days { margin: 0; font-size: var(--pj-fs-body); }
.sub-plan__noperm { margin: 6px 0 0; font-size: var(--pj-fs-body); }

/* ── Billing row ────────────────────────────────────────────────────────────── */
.sub-billing {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.sub-billing .btn { width: auto; }
.sub-billing__title { margin: 0 0 2px; font-size: var(--pj-fs-lg); }

/* ── Admin desk (Bootstrap template) ────────────────────────────────────────── */
.sa-grant-card, .sa-filters-card { margin-bottom: 16px; }
.sa-grant__title { margin: 0 0 14px; }
.sa-grant__actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 6px; }

/* Rechercher une entreprise, puis la choisir : le champ et son bouton sur une
   ligne, les resultats juste dessous. `width: auto` sur le bouton parce que
   tout <button> nu vaut 100% dans la couche connectee (CLAUDE.md §9). */
.sa-picker { display: flex; gap: 8px; align-items: center; }
.sa-picker .btn { width: auto; flex: 0 0 auto; }
.sa-results {
  margin-top: 8px;
  border: 1px solid var(--pj-line);
  border-radius: 8px;
  overflow: hidden;
  max-height: 260px;
  overflow-y: auto;
}
.sa-results p { margin: 0; padding: 10px 12px; }
/* `.sa-results .sa-result` et non `.sa-result` seul : cette feuille se charge
   AVANT le theme fournisseur (CLAUDE.md §9), donc une regle `button` de meme
   specificite l'emporte et rendait le resultat en inline-block, les entreprises
   cote a cote sur une ligne. Deux classes suffisent a reprendre la main. */
.sa-results .sa-result {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-bottom: 1px solid var(--pj-line);
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  /* 44px minimum : cette console se consulte aussi sur telephone. */
  min-height: 44px;
}
.sa-results .sa-result:last-child { border-bottom: 0; }
.sa-results .sa-result:hover, .sa-results .sa-result:focus { background: var(--pj-orange-soft); }
.sa-results .sa-result__name { font-weight: 600; }
.sa-results .sa-result__meta { color: var(--pj-muted); font-size: var(--pj-fs-body); }
.sa-chosen {
  margin: 8px 0 0;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--pay-succeeded-soft);
  color: var(--pay-succeeded);
  font-weight: 600;
}
.sa-table__actions { white-space: nowrap; }
.sa-pager { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 14px; }
.sa-pager__state { font-weight: 600; }

.sa-state {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}
.sa-state--active { background: var(--pay-succeeded-soft); color: var(--pay-succeeded); }
.sa-state--expired { background: var(--pay-cancelled-soft); color: var(--pay-cancelled); }
.sa-state--cancelled { background: var(--pay-failed-soft); color: var(--pay-failed); }

@media (min-width: 768px) {
  .sub-plans__grid { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
}

@media (max-width: 767px) {
  .sa-table thead { display: none; }
  .sa-table tr {
    display: block;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    padding: 8px 12px;
    margin-bottom: 10px;
  }
  .sa-table td {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    border: none;
    padding: 6px 0;
    text-align: right;
  }
  .sa-table td::before {
    content: attr(data-label);
    font-weight: 600;
    color: var(--color-muted);
    text-align: left;
  }
  .sa-table__actions { justify-content: flex-end; }
}

/* ------------------------------------------------------------------ *
 * M15 TrainingProvider — validation status badges and the fiche banner.
 * Reuses the connected `co-*` design system; only the status colours and
 * the submit banner are specific.
 * ------------------------------------------------------------------ */
.tp-status--draft { background: var(--surface-chip); color: var(--chip-ink); }
.tp-status--submitted { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.tp-status--validated { background: var(--pj-success-soft); color: var(--color-success); }
.tp-status--needs_correction { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.tp-status--suspended { background: var(--pj-danger-soft); color: var(--color-error); }
.tp-status--rejected { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.tp-status--archived { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.tp-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border-left: 4px solid #c9d3e0;
  flex-wrap: wrap;
}
.tp-banner--submitted { border-left-color: #f0a500; }
.tp-banner--validated { border-left-color: var(--color-success); }
.tp-banner--needs_correction { border-left-color: var(--pj-info-ink); }
.tp-banner--rejected { border-left-color: var(--pj-accent-ink); }
.tp-banner--suspended { border-left-color: var(--color-error); }
.tp-banner__main { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.tp-banner__hint { margin: 0; color: var(--color-muted); }
.tp-banner__note {
  margin: 0;
  padding: 8px 12px;
  background: var(--pj-warning-soft);
  border-radius: 8px;
  font-size: var(--pj-fs-body);
}
.tp-banner .btn { width: auto; flex: 0 0 auto; }

.tp-docs { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.tp-docs li { display: flex; align-items: center; gap: 8px; }

/* ── Entreprise link (Présence Web M2) ──────────────────────────────────── */

.tp-linked-field {
  background: var(--pj-card-2);
  color: var(--color-muted);
  cursor: default;
  min-height: 44px;
  display: flex;
  align-items: center;
}

.tp-linked-image img {
  max-width: 160px;
  max-height: 90px;
  border-radius: var(--pj-radius-sm, 12px);
}

.tp-linked-social { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.tp-linked-social li { display: flex; gap: 8px; }
.tp-linked-social span { color: var(--color-muted); }

.tp-link-notice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 14px;
  margin-bottom: 14px;
  background: var(--pj-card-2);
  border-radius: var(--pj-radius-sm, 12px);
}
.tp-link-notice p { margin: 0; }
.tp-link-notice .btn { width: auto; flex: 0 0 auto; }

.tp-link-picker { margin-bottom: 14px; }
.tp-link-picker__row { display: flex; gap: 10px; flex-wrap: wrap; }
.tp-link-picker__row select { flex: 1 1 220px; }
.tp-link-picker__row .btn { width: auto; flex: 0 0 auto; }

@media (max-width: 640px) {
  .tp-banner { flex-direction: column; align-items: flex-start; }
  .tp-banner .btn { width: 100%; }
}

/* ============================================================
   M17 TrainingEnrollment (§28.8/§28.11/§28.12/§28.15)
   Reuses the connected-* / ap-* / jo-* system; only the genuinely
   new bits get a te-* rule.
   ============================================================ */

/* Head action rows (catalogue, my-enrolments, certificates) */
.te-mine__head-actions, .jo-mine__head-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.te-mine__head-actions .btn, .jo-mine__head-actions .btn { width: auto; }

/* Review rating grid */
.te-rate { display: grid; gap: 10px; margin: 8px 0 16px; }
.te-rate__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.te-rate__select { width: 88px; }

/* Statistiques d'un organisme : maquette `statistiques.png` (2026-10-04).
   Trois cartes : les neuf chiffres en tuiles à pastille, les examens et
   parcours, la répartition par statut en barres. La grille se décide sur la
   largeur de la SECTION (un conteneur) : trois colonnes dès 640px, deux
   en-dessous — au centre de l'espace organisme, un écran de 1366px ne laisse
   que 700px. Les cartes portent leur propre fond, comme les panneaux quiz. */
.te-stats { display: grid; gap: 16px; container: tsv / inline-size; }

.tsv-card {
  display: grid;
  gap: 14px;
  padding: 18px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
}

.tsv-title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.tsv-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

/* Deux colonnes de 130px : la pastille et les marges se resserrent, ou le
   libellé n'avait plus que 50px et passait sur quatre lignes (mesuré). */
@container tsv (max-width: 639px) {
  /* `.te-stats` devant : ce bloc précède les règles de base des tuiles, qui
     l'emporteraient à spécificité égale. */
  .te-stats .tsv-tile {
    gap: 8px;
    padding: 10px 8px;
  }

  .te-stats .tsv-ico {
    width: 34px;
    height: 34px;
    font-size: var(--pj-fs-md);
  }

  .te-stats .tsv-tile__value {
    font-size: var(--pj-fs-lg);
  }
}

@container tsv (min-width: 640px) {
  .tsv-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
  }
}

.tsv-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.tsv-ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-lg);
}

.tsv-ico--info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.tsv-ico--success { background: var(--pj-success-soft); color: var(--pj-success); }
.tsv-ico--orange  { background: var(--pj-orange-soft);  color: var(--pj-orange); }
.tsv-ico--accent  { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.tsv-ico--danger  { background: var(--pj-danger-soft);  color: var(--pj-danger); }
.tsv-ico--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }

.tsv-tile__text {
  display: grid;
  min-width: 0;
}

.tsv-tile__value {
  color: var(--pj-ink);
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.2;
}

.tsv-tile__label {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  overflow-wrap: anywhere;
}

/* Ce qui attend une décision : une porte, pas un chiffre. */
.tsv-wait {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: 10px;
  width: auto;
  min-height: 44px;
  padding: 0 16px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.tsv-bars {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tsv-bar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  min-height: 36px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.tsv-bar + .tsv-bar {
  border-top: 1px solid var(--pj-line);
}

.tsv-bar__dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
}

.tsv-bar__n {
  min-width: 2ch;
  font-weight: 600;
  text-align: right;
}

.tsv-bar__track {
  height: 10px;
  overflow: hidden;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-neutral-soft);
}

.tsv-bar__fill {
  display: block;
  height: 100%;
  border-radius: var(--pj-radius-pill);
}

@container tsv (min-width: 640px) {
  .tsv-bar {
    grid-template-columns: auto minmax(0, 2fr) auto minmax(0, 1.5fr);
    gap: 14px;
  }
}

/* Une couleur par statut, dans l'ordre de vie d'une inscription. */
.tsv-tone--info_request     { background: var(--pj-blue); }
.tsv-tone--preregistered    { background: var(--pj-orange); }
.tsv-tone--awaiting_payment { background: var(--pj-warning-ink); }
.tsv-tone--paid             { background: var(--pj-success); }
.tsv-tone--enrolled         { background: var(--pj-accent-ink); }
.tsv-tone--waitlisted       { background: var(--pj-orange-text); }
.tsv-tone--attended         { background: var(--pj-info-ink); }
.tsv-tone--completed        { background: var(--pj-navy); }
.tsv-tone--certified        { background: var(--pj-danger); }
.tsv-tone--cancelled        { background: var(--pj-neutral-ink); }
.tsv-tone--refunded         { background: var(--pj-muted); }


/* M18 TrainingMatching — recommended trainings (§28.10) */
.tr-reco__gaps { margin-bottom: 16px; }
.tr-reco-card { margin-bottom: 12px; }
.tr-reco-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.tr-reco-card__title { margin: 0; font-size: var(--pj-fs-lg); }
.tr-reco-card__score { color: var(--connected-primary); font-weight: 700; white-space: nowrap; }
.tr-reco-card__meta { margin: 4px 0 8px; }
.tr-reco-card__covers { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0 0 10px; }
.tr-reco-card__actions { display: flex; }
.tr-reco-card__actions .btn { width: auto; }
.jo-chip--sm { font-size: var(--pj-fs-xs); padding: 2px 8px; }

/* M19 Content — blog / actualités / conseils (§4.12) */
/* Pas de marge : ces blocs sont des enfants directs de `.connected-page`, dont
   le `gap` de 20px les espace déjà. Une marge s'y AJOUTE — 36px et 40px
   mesurés là où 20 étaient voulus, exactement le cumul décrit dans
   prosyjob-app.css §2 pour la console admin. */
.cms-list__filters { display: flex; flex-wrap: wrap; gap: 8px; }
.cms-chip {
    width: auto;
    border: 1px solid var(--connected-border, var(--color-border));
    /* Was `var(--connected-surface-bg, #fff)` — a token that is declared
       nowhere, so the chip was hard white whatever the theme, with `color:
       inherit` turning pale on top of it in dark. E7-15: the name it meant. */
    background: var(--connected-surface);
    color: inherit;
    border-radius: 999px;
    padding: 6px 14px;
    font-size: var(--pj-fs-body);
    cursor: pointer;
    min-height: 36px;
}
.cms-chip.is-active { background: var(--primary-fill); border-color: var(--primary-fill); color: #fff; }
.cms-list__grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
.cms-card { padding: 0; overflow: hidden; cursor: pointer; display: flex; flex-direction: column; }
.cms-card:hover { transform: translateY(-2px); transition: transform 0.15s ease; }
.cms-card__cover { aspect-ratio: 16 / 9; overflow: hidden; background: var(--surface-track); }
.cms-card__cover img { width: 100%; height: 100%; object-fit: cover; }
.cms-card__body { padding: 16px; display: flex; flex-direction: column; gap: 8px; }
.cms-card__meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: var(--pj-fs-sm); }
.cms-card__cat { background: var(--ap-hired-soft); color: var(--connected-primary); border-radius: 4px; padding: 2px 8px; font-weight: 600; }
.cms-card__title { margin: 0; font-size: var(--pj-fs-lg); line-height: 1.3; }
.cms-card__excerpt { margin: 0; font-size: var(--pj-fs-body); }
.cms-card__more { color: var(--connected-primary); font-weight: 600; font-size: var(--pj-fs-body); margin-top: auto; }
.cms-list__more { display: flex; justify-content: center; }

/* Article page */
.cms-article__back { width: auto; margin-bottom: 12px; }
.cms-article__doc { max-width: 760px; margin: 0 auto; }
.cms-article__cover { margin: -4px 0 16px; border-radius: 8px; overflow: hidden; }
.cms-article__cover img { width: 100%; height: auto; display: block; }
.cms-article__meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: var(--pj-fs-sm); margin-bottom: 8px; }
.cms-article__title { margin: 0 0 12px; font-size: var(--pj-fs-title); line-height: 1.25; }
.cms-article__lead { font-size: var(--pj-fs-body); font-weight: 500; margin: 0 0 16px; }
.cms-article__body { line-height: 1.7; }
.cms-article__body p { margin: 0 0 14px; }
.cms-article__subtitle { font-size: var(--pj-fs-lg); margin: 22px 0 10px; }
.cms-article__pimg { max-width: 100%; height: auto; border-radius: 6px; margin: 8px 0; }
.cms-article__block { margin-bottom: 8px; }

@media (min-width: 640px) { .cms-list__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .cms-list__grid { grid-template-columns: repeat(3, 1fr); } }

/* M20 Metier — the métier encyclopedia (§4.12) */
/* Fiches métiers, maquette « listes_des_metiers.png » (2026-10-02) : une
   carte d'en-tête qui porte aussi les filtres, l'alphabet et le compte, puis
   une grille de cartes à illustration. */
.mtl-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
}

.mtl-head__top {
  display: flex;
  align-items: center;
  gap: 24px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--pj-line);
}

.mtl-head__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-display);
}

.mtl-head__text {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.mtl-head__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.15;
  color: var(--pj-ink);
}

.mtl-head__lead {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

.mtl-filters {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1.3fr) minmax(0, 1.3fr);
  gap: 14px;
}

.mtl-field {
  position: relative;
  display: block;
  margin: 0;
  min-width: 0;
}

.mtl-field__icon {
  position: absolute;
  top: 50%;
  left: 16px;
  transform: translateY(-50%);
  color: var(--pj-muted);
  pointer-events: none;
}

.mtl-field .form-control,
.mtl-field .form-select {
  min-height: 48px;
  padding-left: 46px;
}

/* L'alphabet DÉFILE plutôt que de se replier : vingt-six pastilles sur trois
   lignes mangeraient l'écran d'un téléphone avant la première fiche. Le
   défilement horizontal est borné à cette bande — jamais à la page. */
.mtl-alpha-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.metier-alpha {
  flex: 1 1 auto;
  display: flex;
  gap: 6px;
  min-width: 0;
  overflow-x: auto;
  padding-bottom: 4px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.metier-alpha::-webkit-scrollbar {
  display: none;
}

/* 36px de côté : sous le plancher tactile de 44, et c'est assumé — vingt-sept
   cibles de 44px feraient une bande qu'on ne finit jamais de parcourir. Les
   8px d'écart portent la différence, comme dans tous les index alphabétiques. */
.metier-alpha__letter {
  flex: 0 0 auto;
  width: auto;
  min-width: 34px;
  height: 34px;
  padding: 0 8px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
}

.metier-alpha__letter:hover { border-color: var(--pj-navy); }

.metier-alpha__letter.is-active {
  background: var(--pj-navy);
  border-color: var(--pj-navy);
  color: var(--pj-card);
}

.mtl-alpha-next {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: 50%;
  background: var(--pj-card);
  color: var(--pj-ink);
  cursor: pointer;
}

.metier-list__count { margin: 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }

/* Un bouton nu est en pleine largeur dans la coquille connectée (§5) : celui-ci
   vit dans une phrase, il déclare donc sa largeur. */
.metier-list__reset {
  width: auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-navy);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}

/* La grille. Les colonnes se comptent sur la place REELLE, pas sur la
   fenetre : la coquille connectee entoure la page de deux rails, et une regle
   « 3 colonnes au-dela de 1100 px » y faisait des cartes de 220 px. Une carte
   veut au moins 300 px et jamais moins d'un tiers de la place — donc trois
   par rangee au plus, comme la maquette ; `min(100%, …)` la laisse tenir sur
   un telephone (mesure a 360, 768, 1280, 1440 et 1920 px). */
.mtl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, max(300px, calc((100% - 32px) / 3))), 1fr));
  gap: 16px;
}

.mtl-empty {
  margin: 0;
  grid-column: 1 / -1;
}

.mtl-card {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  cursor: pointer;
}

.mtl-card:hover,
.mtl-card:focus-visible {
  outline: 2px solid var(--pj-orange);
  outline-offset: -2px;
}

.mtl-card__media {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 110px;
  height: 110px;
  overflow: hidden;
  border-radius: var(--pj-radius);
  font-size: var(--pj-fs-display);
}

.mtl-card__media--img {
  background: var(--pj-neutral-soft);
}

.mtl-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mtl-tone--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.mtl-tone--success { background: var(--pj-success-soft); color: var(--pj-success); }
.mtl-tone--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.mtl-tone--accent { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.mtl-tone--orange { background: var(--pj-orange-soft); color: var(--pj-orange); }
.mtl-tone--danger { background: var(--pj-danger-soft); color: var(--pj-danger); }
.mtl-tone--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.mtl-card__body {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.mtl-card__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 800;
  line-height: 1.25;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

/* Six lignes d'extrait, comme la maquette : une fiche plus bavarde ne pousse
   pas sa rangée vers le bas. */
.mtl-card__excerpt {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.45;
}

.mtl-card__more {
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-body);
  font-weight: 700;
}

.mtl-more {
  display: flex;
  justify-content: center;
}

.mtl-more .mtl-more__btn.btn {
  width: auto;
  min-width: 160px;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

@media (max-width: 720px) {
  .mtl-head__top {
    align-items: flex-start;
    gap: 14px;
  }

  .mtl-head__icon {
    width: 60px;
    height: 60px;
    font-size: var(--pj-fs-title);
  }

  .mtl-head__title {
    font-size: var(--pj-fs-card);
  }

  .mtl-head__lead {
    font-size: var(--pj-fs-sm);
  }

  .mtl-filters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }

  .mtl-field--search {
    grid-column: 1 / -1;
  }

  .mtl-field .form-control,
  .mtl-field .form-select {
    min-height: 44px;
    padding-left: 38px;
    font-size: var(--pj-fs-sm);
  }

  .mtl-field__icon {
    left: 12px;
  }

  .mtl-card {
    gap: 12px;
  }

  .mtl-card__media {
    width: 84px;
    height: 84px;
    font-size: var(--pj-fs-title);
  }

  .mtl-card__title {
    font-size: var(--pj-fs-body);
  }

  .mtl-card__excerpt {
    -webkit-line-clamp: 4;
    font-size: var(--pj-fs-sm);
  }

  .mtl-card__more {
    font-size: var(--pj-fs-sm);
  }

  .mtl-more .mtl-more__btn.btn {
    width: 100%;
  }
}
/* Fiche métier, maquette « detail_metier.png » (2026-10-02). Une carte qui
   tient le retour, la fiche et deux encarts. La grille se décide sur la place
   RÉELLE (requête de conteneur), pas sur la fenêtre : dans la coquille
   connectée, deux rails entourent la page et 1024 px de fenêtre ne laissent
   pas la place d'une colonne de 320 px à côté de la fiche. */
.mf-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  container-type: inline-size;
}

.mf-back {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.mf-back .mf-back__btn.btn {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.mf-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

@container (min-width: 860px) {
  .mf-grid {
    grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
  }
}

.mf-doc {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  padding: 18px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.mf-head {
  display: flex;
  align-items: flex-start;
  gap: 20px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--pj-line);
}

.mf-head__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 88px;
  height: 88px;
  overflow: hidden;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-fill);
  color: var(--pj-card);
  font-size: var(--pj-fs-display);
}

.mf-head__icon--img {
  background: var(--pj-neutral-soft);
}

.mf-head__icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mf-head__text {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.mf-head__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.15;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.mf-head__lead p {
  margin: 0 0 6px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

.mf-head__lead p:last-child {
  margin-bottom: 0;
}

/* Les rubriques */
.mf-secs {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.mf-sec {
  border-bottom: 1px solid var(--pj-line);
}

.mf-sec:last-child {
  border-bottom: 0;
}

.mf-sec__head {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 0 4px;
  list-style: none;
  cursor: default;
}

.mf-sec__head::-webkit-details-marker {
  display: none;
}

.mf-sec__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-lg);
}

.mf-sec__title {
  flex: 1 1 auto;
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.mf-sec__chev {
  display: none;
  color: var(--pj-ink);
  transition: transform 0.2s ease;
}

.mf-sec[open] .mf-sec__chev {
  transform: rotate(180deg);
}

/* Le texte s'aligne sous le titre, pas sous l'icône : 48 px d'icône + 16 px. */
.mf-sec__body {
  padding: 0 0 14px 64px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.55;
}

.mf-sec__body p {
  margin: 0 0 6px;
}

.mf-sec__body p:last-child {
  margin-bottom: 0;
}

.mf-bullets {
  display: grid;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mf-bullets li {
  position: relative;
  padding-left: 18px;
}

.mf-bullets li::before {
  content: "";
  position: absolute;
  top: 0.6em;
  left: 2px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--pj-orange);
}

/* Les deux encarts */
.mf-aside {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.mf-box {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 4px;
  padding: 0 0 14px;
  overflow: hidden;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.mf-box__head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
}

.mf-box--offers .mf-box__head { background: var(--pj-info-soft); }
.mf-box--trainings .mf-box__head { background: var(--pj-orange-soft); }

.mf-box__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  font-size: var(--pj-fs-lg);
}

.mf-box--offers .mf-box__icon { color: var(--pj-info-ink); }
.mf-box--trainings .mf-box__icon { color: var(--pj-orange); }

.mf-box__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.mf-box__list {
  display: grid;
  margin: 0;
  padding: 0 16px 0 74px;
  list-style: none;
}

.mf-item {
  border-bottom: 1px solid var(--pj-line);
}

.mf-item:last-child {
  border-bottom: 0;
}

.mf-item--empty {
  padding: 10px 0;
  font-size: var(--pj-fs-body);
}

.mf-item__link,
.mf-item__link:hover {
  display: grid;
  gap: 2px;
  padding: 10px 0;
  text-decoration: none;
}

.mf-item__title {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.mf-item__link:hover .mf-item__title {
  color: var(--pj-orange-text);
}

.mf-item__sub {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* Deux classes : un lien coloré par une seule classe ne tient pas dans cette
   coquille (`.pj-app a { color: inherit }`, CLAUDE.md §9). */
.mf-box .mf-box__all {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  margin: 8px 16px 0;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  text-decoration: none;
}

.mf-box--offers .mf-box__all { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.mf-box--trainings .mf-box__all { background: var(--pj-orange-soft); color: var(--pj-orange-text); }

/* Téléphone : rubriques en accordéon, repliées à l'arrivée (décision PO) ;
   au large, le titre ne replie rien et le chevron n'existe pas. */
@media (max-width: 720px) {
  .mf-doc {
    padding: 12px;
  }

  .mf-head {
    gap: 14px;
  }

  .mf-head__icon {
    width: 64px;
    height: 64px;
    font-size: var(--pj-fs-title);
  }

  .mf-head__title {
    font-size: var(--pj-fs-card);
  }

  .mf-head__lead p {
    font-size: var(--pj-fs-sm);
  }

  .mf-sec__head {
    min-height: 52px;
    padding: 6px 0;
    gap: 12px;
    cursor: pointer;
  }

  .mf-sec__icon {
    width: 36px;
    height: 36px;
    font-size: var(--pj-fs-md);
  }

  .mf-sec__title {
    font-size: var(--pj-fs-md);
  }

  .mf-sec__chev {
    display: inline-block;
  }

  .mf-sec__body {
    padding: 0 0 12px 48px;
    font-size: var(--pj-fs-sm);
  }

  .mf-box__list {
    padding-left: 16px;
  }

  .mf-box--offers .mf-item:nth-child(n + 4),
  .mf-box--trainings .mf-item:nth-child(n + 3) {
    display: none;
  }
}

@media (min-width: 721px) {
  .mf-sec__head {
    pointer-events: none;
  }
}

/* M21 Dashboard — the post-login multi-profile landing (§4) */
@media (min-width: 640px) { .dash__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .dash__grid { grid-template-columns: repeat(3, 1fr); } }

/* ── /profil : l'en-tête du compte et ses trois vues (2026-10-01) ────────
   D'après `mon_profil_info_perso.png` et ses trois sœurs. L'en-tête reste ;
   ses trois boutons choisissent ce qui s'affiche dessous (`?vue=`) : la fiche,
   l'email et le téléphone, le mot de passe.

   Mobile d'abord : tout ce qui suit est la forme à 360 px — portrait à gauche
   du titre, boutons empilés avec leur chevron. Les requêtes sont des requêtes
   de **conteneur** et non de viewport : la colonne centrale de la coque
   connectée mesure 600 px à 1200 px d'écran et 820 à 1440, selon que la
   colonne de droite est là ou non, et c'est elle qui décide si trois boutons
   tiennent sur une ligne.

   Tokens partout. Le seul blanc écrit en clair est le libellé du bouton actif,
   posé sur le même orange plein que `.btn-primary`, qui l'écrit de la même
   façon (prosyjob-app.css §5). */
.pfh {
  container: pfh / inline-size;
  display: grid;
  gap: 16px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: linear-gradient(135deg, var(--pj-orange-soft) 0%, var(--pj-card) 80%);
}

.pfh__top {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: start;
  gap: 14px;
}

.pfh__avatar {
  position: relative;
  width: 72px;
  height: 72px;
}

.pfh__portrait {
  display: block;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border-radius: 50%;
  background: var(--pj-card);
  box-shadow: 0 0 0 3px var(--pj-card);
}

.pfh__img,
.pfh__initials {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
  object-fit: cover;
}

.pfh__initials {
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-card);
  font-weight: 700;
}

/* 44 px de cible pour un rond qui en paraît 32 : le cercle est un
   pseudo-élément, la zone de tap est le bouton entier. `button { width: 100% }`
   s'applique dans la coque connectée, d'où la largeur posée ici. */
.pfh__pick {
  position: absolute;
  right: -12px;
  bottom: -12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-ink);
  cursor: pointer;
}

.pfh__pick::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: 1px solid var(--pj-line);
  border-radius: 50%;
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
}

.pfh__pick i {
  position: relative;
  font-size: var(--pj-fs-sm);
}

.pfh__pick:hover::before {
  background: var(--pj-card-2);
}

.pfh__title {
  margin: 0 0 6px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-title);
  font-weight: 800;
  line-height: 1.15;
}

.pfh__intro {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

/* L'illustration n'existe pas sur téléphone : la maquette mobile n'en a pas,
   et 200 px de dessin sur une colonne de 330 repousseraient les boutons sous
   la ligne de flottaison. */
.pfh__art {
  display: none;
}

.pfh-art__blob {
  fill: var(--pj-card);
  opacity: 0.7;
}

.pfh-art__card-back,
.pfh-art__tab {
  fill: var(--pj-card-2);
}

.pfh-art__card {
  fill: var(--pj-card);
  stroke: var(--pj-line);
  stroke-width: 2;
}

.pfh-art__head {
  fill: var(--pj-info-ink);
  opacity: 0.45;
}

.pfh-art__line {
  fill: var(--pj-info-ink);
  opacity: 0.3;
}

.pfh-art__gear {
  fill: var(--pj-orange);
}

.pfh-art__gear .pfh-art__gear-hole {
  fill: var(--pj-card);
}

.pfh__nav {
  display: grid;
  gap: 10px;
}

.pfh__link {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 60px;
  padding: 10px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
  color: var(--pj-ink);
  text-align: left;
  cursor: pointer;
}

.pfh__link:hover {
  border-color: var(--pj-orange);
}

.pfh__ico {
  display: inline-flex;
  flex: 0 0 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--pj-card-2);
  color: var(--pj-navy);
  font-size: var(--pj-fs-lg);
}

.pfh__label {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.pfh__label-t {
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

.pfh__label-s {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.pfh__chev {
  color: var(--pj-muted);
}

.pfh__link.is-active {
  border-color: var(--pj-orange-fill);
  background: linear-gradient(90deg, var(--pj-orange-fill) 0%, var(--pj-orange-dark) 100%);
  color: #fff;
}

.pfh__link.is-active .pfh__label-s,
.pfh__link.is-active .pfh__chev {
  color: inherit;
}

.pfh__link.is-active .pfh__ico {
  background: rgb(255 255 255 / 18%);
  color: inherit;
}

@container pfh (min-width: 560px) {
  .pfh__top {
    grid-template-columns: 104px minmax(0, 1fr);
    align-items: center;
    gap: 20px;
  }

  .pfh__avatar {
    width: 104px;
    height: 104px;
  }

  .pfh__pick {
    right: -6px;
    bottom: -6px;
  }

  .pfh__title {
    font-size: var(--pj-fs-display);
  }

  .pfh__intro {
    font-size: var(--pj-fs-md);
  }
}

@container pfh (min-width: 760px) {
  .pfh {
    gap: 20px;
    padding: 24px;
  }

  .pfh__top {
    grid-template-columns: 104px minmax(0, 1fr) 190px;
  }

  .pfh__art {
    display: block;
    width: 190px;
    height: auto;
  }

  .pfh__nav {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .pfh__chev {
    display: none;
  }
}

/* ── Les deux vues en panneau : titre commun ─────────────────────────── */
.pf-view-head {
  display: grid;
  gap: 6px;
}

.pf-view-title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-title);
  font-weight: 800;
  line-height: 1.2;
}

.pf-view-intro {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

#pf-view-panel {
  container: pfview / inline-size;
}

/* ── Email et téléphone (?vue=verification) ──────────────────────────────
   Était /verifier, variante « compte ». Deux panneaux côte à côte quand la
   colonne le permet, l'un sous l'autre sinon. */
.ct-grid {
  display: grid;
  gap: 16px;
}

@container pfview (min-width: 760px) {
  .ct-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }
}

.ct-panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.ct-panel__head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.ct-panel__ico {
  display: inline-flex;
  flex: 0 0 52px;
  height: 52px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  font-size: var(--pj-fs-card);
}

.ct-panel__ico--email {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.ct-panel__ico--phone {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.ct-panel__id {
  min-width: 0;
}

.ct-panel__title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.ct-panel__title h3 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
}

.ct-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.ct-badge--ok {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.ct-badge--todo {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.ct-current {
  margin: 2px 0 0;
  overflow-wrap: anywhere;
}

.ct-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.ct-form > .field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.ct-form label {
  margin: 0;
  font-weight: 600;
}

/* `.field input` (plus haut dans cette feuille) peint sa bordure avec
   `var(--color-border)`, un token hérité que la coque `pj` ne déclare pas : la
   déclaration entière devient invalide au calcul et la bordure tombe à `none`,
   ce qui battait la règle du thème par sa spécificité (0,1,1). Mesuré sur la
   variante « compte » de /verifier, qui l'avait déjà. (0,2,0) ici, et le token
   de Bootstrap, qui suit le thème sombre. */
.ct-form .form-control {
  border: 1px solid var(--bs-border-color);
}

.ct-input {
  position: relative;
}

.ct-input__ico {
  position: absolute;
  top: 50%;
  left: 14px;
  color: var(--pj-muted);
  transform: translateY(-50%);
  pointer-events: none;
}

/* (0,3,1), pas (0,2,0) : `.field input:not([type="checkbox"]):not([type="radio"])`
   plus haut pèse (0,3,1) et remettait `padding: 10px 12px`, si bien que le
   texte démarrait sous l'icône (mesuré : padding-left 12px, icône jusqu'à 34px).
   Même spécificité et plus bas dans la feuille, celle-ci gagne. */
.field .ct-input > input.form-control {
  padding-left: 42px;
}

.ct-hint {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.ct-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* La règle `button, .btn` du haut de cette feuille met tout bouton en
   `width: 100%` ; une rangée d'actions doit reprendre sa largeur elle-même. */
.ct-actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

.ct-confirm {
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
}

.ct-sent {
  margin: 0 0 14px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* ── Mot de passe (?vue=mot-de-passe) ─────────────────────────────────────
   Était /mon-compte/mot-de-passe. Les boutons gardent la pleine largeur sur
   téléphone, comme la maquette, et la reprennent en ligne au-delà. */
.pw-head {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 18px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--pj-line);
}

.pw-head__ico {
  display: inline-flex;
  width: 64px;
  height: 64px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--pj-warning-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}

.pw-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.pw-form .input-block {
  margin: 0;
}

.pw-form label {
  font-weight: 600;
}

.pw-hint {
  display: flex;
  gap: 8px;
  margin: 8px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.pw-hint i {
  margin-top: 3px;
  color: var(--pj-info-ink);
}

.pw-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 18px;
  border-top: 1px solid var(--pj-line);
}

.pw-actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
}

@container pfview (min-width: 600px) {
  .pw-head {
    flex-direction: row;
    align-items: center;
    gap: 20px;
  }

  .pw-head__ico {
    flex: 0 0 80px;
    height: 80px;
  }

  .pw-actions {
    flex-direction: row;
    flex-wrap: wrap;
  }

  .pw-actions .btn {
    width: auto;
  }
}

/* ── Scanner de QR code (E16-05) ────────────────────────────────────────── */

.sc-panel {
  display: grid;
  gap: 14px;
}

.sc-camera {
  position: relative;
  display: grid;
  gap: 10px;
  justify-items: center;
}

/* Capped rather than full-bleed: a viewfinder the width of a desktop card is
   harder to aim, not easier, and this is a phone-first feature. */
.sc-camera video {
  width: 100%;
  max-width: 360px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--pj-card-2);
}

.sc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* The `button, .btn { width: 100% }` opt-out, and E10-01's 44px floor. */
.sc-btn,
.sc-camera__stop {
  width: auto;
  min-height: 44px;
}

.sc-manual input {
  max-width: 46ch;
}

.sc-result__amount {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 700;
  color: var(--color-success);
}

/* =====================================================================
   Profile hero — `.ph-` (shared by /profil and /candidat/profil)
   =====================================================================
   Cover band, portrait laid over it, identity, tab bar. Both screens were
   redesigned from mockups that share this whole head and differ only in what
   they put under the tabs, so it is one component and one family of rules.

   Tokens only, never a raw hex: that is what keeps dark mode an override block
   rather than a second pass over these rules (CLAUDE.md §9). The cover's own
   fallback is a token gradient for the same reason — the mockups are light-only
   and a painted band had to follow the theme without being redrawn.

   Mobile first: everything below is the 360px layout, and the two media
   queries only enrich it. */
.ph-hero {
  padding: 0;
  overflow: hidden;
}

.ph-cover {
  position: relative;
  height: 120px;
  background-color: var(--pj-card-2);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* No picture is a normal state, not a broken one: a quiet band in the brand's
   own colours rather than an empty grey rectangle or a stock photograph. */
.ph-cover--empty {
  background-image: linear-gradient(135deg, var(--pj-navy) 0%, var(--pj-navy-dark) 55%, var(--pj-orange-dark) 160%);
}

/* The camera buttons. `button, .btn { width: 100% }` applies in the connected
   shell (CLAUDE.md §9), so every one of these has to opt out itself — and the
   44px floor is the measured tap target, not the class name's promise. */
.ph-pick {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  min-height: 44px;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  box-shadow: var(--pj-shadow-sm);
  cursor: pointer;
}

.ph-pick:hover {
  background: var(--pj-card-2);
}

.ph-pick--banner {
  top: 12px;
  right: 12px;
}

.ph-pick--avatar {
  right: -4px;
  bottom: -4px;
}

.ph-identity {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 0 16px 16px;
  text-align: center;
}

/* Half the portrait sits on the cover, which is the whole point of the shape.
   A negative top margin rather than absolute positioning, so the text below it
   still flows and the card grows with a long name instead of overlapping it. */
.ph-avatar {
  position: relative;
  width: 96px;
  height: 96px;
  margin-top: -48px;
  border-radius: 50%;
  background: var(--pj-card);
  box-shadow: 0 0 0 4px var(--pj-card);
}

.ph-avatar__img,
.ph-avatar__initials {
  display: flex;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  object-fit: cover;
}

.ph-avatar__initials {
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.ph-identity__text {
  min-width: 0;
  flex: 1 1 auto;
}

.ph-name {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.ph-headline,
.ph-location,
.ph-meta {
  margin: 4px 0 0;
  color: var(--pj-muted);
  overflow-wrap: anywhere;
}

.ph-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

.ph-actions .btn {
  width: auto;
  min-height: 44px;
}

/* The tab bar **wraps**, it does not scroll. A row that cannot wrap sizes the
   connected shell's centre column on its own max-content, and `overflow-x`
   only bounds what is shown, not what was measured — the `.jo-filters` lesson
   from E2-05. Five tabs at 360px take two lines and cost nothing. */
.ph-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 0 8px;
  border-top: 1px solid var(--pj-line);
}

/* Icone puis libelle, sur une ligne. L'icone est optionnelle : `/profil` n'en
   passe aucune et le bouton n'a alors rien a espacer. */
.ph-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding: 10px 14px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--pj-ink);
  font-weight: 600;
  cursor: pointer;
}

/* L'icone est bleue et le libelle encre tant que l'onglet dort, tous deux
   orange quand il est actif — meme traitement que `.gm-tab` et `.tj-tab`, pour
   que les trois barres d'onglets du produit se lisent de la meme facon.
   L'inactif etait `--pj-muted` : un onglet est une commande, pas du texte
   secondaire, et le passer en encre ne fait que gagner du contraste. */
.ph-tab__icon {
  color: var(--pj-navy);
  font-size: 0.95rem;
}

.ph-tab:hover {
  color: var(--pj-orange-text);
}

.ph-tab.is-active {
  border-bottom-color: var(--pj-orange-fill);
  color: var(--pj-orange-text);
}

.ph-tab.is-active .ph-tab__icon {
  color: var(--pj-orange-text);
}

/* Sur telephone, la barre defile horizontalement plutot que de se replier.

   Trois etats mesures a 357 px, dans l'ordre ou ils ont ete essayes :
   les cinq onglets replies chacun sur sa ligne font une barre de 237 px de
   haut pour une colonne de 289 ; l'icone au-dessus du libelle la ramene a
   62 px mais coupe les mots en plein milieu (« Expérien/ce », « Paramèt/res »)
   parce qu'un mot seul ne se replie pas ; le defilement garde l'affichage
   demande — icone A COTE du libelle — et ne tronque rien. C'est deja le
   traitement des puces de « Mes CV » et de « Mes candidatures », deux
   panneaux plus loin.

   `scrollbar-width: none` parce que la barre native s'afficherait par-dessus
   le libelle sur 44 px de haut ; le debordement se devine au libelle coupe
   net par le bord, comme partout ailleurs dans ce produit. */
@media (max-width: 575px) {
  .ph-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 0;
    padding: 0 4px;
    scrollbar-width: none;
  }

  .ph-tabs::-webkit-scrollbar {
    display: none;
  }

  .ph-tab {
    flex: 0 0 auto;
    gap: 6px;
    padding: 10px 10px;
    font-size: var(--pj-fs-sm);
    white-space: nowrap;
  }
}
/* ── /profil : one row per field ─────────────────────────────────────────
   The whole-page read/edit swap is gone; a row edits in place. Mobile first,
   so this is the 360px shape — label over value, the action on the right as
   the mockup draws it — and the 768px query turns it into the four-column
   line. While a row is edited, its form and buttons take the width under the
   label. */
.pf-rows {
  padding: 4px 0;
}

.pf-row {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--pj-line);
}

.pf-row:last-child {
  border-bottom: 0;
}

.pf-row__icon {
  grid-row: span 2;
  color: var(--pj-muted);
  text-align: center;
}

.pf-row__label {
  grid-column: 2;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.pf-row__value {
  grid-column: 2;
  grid-row: 2;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* The trailing action. Text buttons, not `.btn`: the mockup draws them as an
   orange link with a pencil and a chevron. `button { width: 100% }` applies
   in the connected shell and a grid item needs `justify-self` on top of
   `width: auto` (CLAUDE.md §9); 44px is the measured tap target. */
.pf-row__edit,
.pf-row__lock {
  display: inline-flex;
  grid-column: 3;
  grid-row: 1 / span 2;
  align-items: center;
  justify-self: end;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding: 0 2px;
  border: 0;
  background: none;
  font-weight: 600;
  cursor: pointer;
}

.pf-row__edit {
  color: var(--pj-orange-text);
}

.pf-row__lock {
  color: var(--pj-muted);
}

.pf-row__lock-ico {
  color: var(--pj-orange-text);
}

.pf-row__lock.is-ok .pf-row__lock-ico {
  color: var(--pj-success);
}

.pf-row__chev {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

/* A verification state, shared by the rows, the Sécurité tab and the
   sessions list. */
.pf-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  white-space: nowrap;
}

.pf-pill--ok {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.pf-pill--todo {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.pf-row.is-editing {
  background: var(--pj-card-2);
}

.pf-row__form {
  display: flex;
  flex-wrap: wrap;
  grid-column: 2 / -1;
  gap: 8px;
}

.pf-row__form .form-control {
  flex: 1 1 180px;
  min-width: 0;
}

.pf-row__form .form-text {
  flex: 1 0 100%;
}

/* The location row holds three labelled fields (E56): pays, ville, quartier.
   Each field takes the flex basis the bare controls take in other rows, so
   they sit side by side from ~600px and stack below it. */
.pf-row__field {
  display: flex;
  flex: 1 1 180px;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.pf-row__field > label {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.pf-row__actions {
  display: flex;
  flex-wrap: wrap;
  grid-column: 2 / -1;
  gap: 8px;
}

.pf-row__actions .btn {
  width: auto;
  min-height: 44px;
}

.pf-row__error {
  grid-column: 2 / -1;
  margin: 0;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
}

@media (min-width: 768px) {
  .pf-row {
    grid-template-columns: 28px minmax(140px, 200px) minmax(0, 1fr) auto;
    gap: 8px 16px;
  }

  .pf-row__icon {
    grid-row: auto;
  }

  .pf-row__label {
    font-size: var(--pj-fs-body);
  }

  .pf-row__value {
    grid-column: 3;
    grid-row: 1;
  }

  .pf-row__edit,
  .pf-row__lock {
    grid-column: 4;
    grid-row: 1;
  }

  .pf-row__form {
    grid-column: 3;
  }

  .pf-row__actions {
    grid-column: 4;
  }

  .pf-row__error {
    grid-column: 3 / -1;
  }
}

/* ── /profil, onglet Sécurité ─────────────────────────────────────────────
   Trois cartes, chacune une tuile d'icône à gauche et son contenu à droite :
   le mot de passe, l'état des vérifications, les connexions (E16-02). */
.pf-sec {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  align-items: start;
  gap: 14px;
}

.pf-sec__ico {
  display: inline-flex;
  width: 48px;
  height: 48px;
  align-items: center;
  justify-content: center;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-lg);
}

.pf-sec__ico--orange {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.pf-sec__ico--blue {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.pf-sec__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
}

.pf-sec__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

.pf-sec__intro {
  margin: 4px 0 0;
  color: var(--pj-muted);
}

.pf-sec__cta,
.pf-sessions__all {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

.pf-sec__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
}

.pf-checks {
  display: grid;
  gap: 8px;
  width: 100%;
}

.pf-check {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 8px 14px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  text-align: left;
  cursor: pointer;
}

.pf-check--static {
  cursor: default;
}

.pf-check__ico {
  width: 18px;
  color: var(--pj-navy);
  text-align: center;
}

.pf-check__label {
  flex: 1 1 auto;
  min-width: 0;
}

.pf-check__value {
  font-weight: 700;
}

.pf-session-list {
  width: 100%;
}

.pf-session {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--pj-line);
}

.pf-session:last-child {
  border-bottom: 0;
}

.pf-session__ico {
  color: var(--pj-muted);
  text-align: center;
}

.pf-session__text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow-wrap: anywhere;
}

.pf-session__meta {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.pf-session__close {
  width: auto;
  min-height: 44px;
  padding: 0 8px;
  border: 0;
  background: none;
  color: var(--pj-danger);
  font-weight: 600;
  cursor: pointer;
}

/* ── /candidat/profil : les paliers de compétence ───────────────────────
   La maquette montrait des pourcentages ; `candidate_skills.level` n'a que
   quatre valeurs, alors la barre a quatre crans et le libellé les nomme. Un
   90 % affiché sur une donnée à quatre paliers annoncerait une précision que
   personne n'a saisie. */
.cand-skill {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
  padding: 12px 0;
  border-bottom: 1px solid var(--pj-line);
}

.cand-skill:last-child {
  border-bottom: 0;
}

.cand-skill__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.cand-skill__name {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.cand-skill__level {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.cand-skill__track {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}

.cand-skill__notch {
  height: 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-line);
}

.cand-skill__notch.is-on {
  background: var(--pj-orange-fill);
}

.cand-skill__select {
  max-width: 22ch;
  min-height: 44px;
}

/* The completion meter opens the "À propos" tab now, on its own card. */
.cand-completion {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* "Votre métier est-il [X] ?" (2026-09-16) — outside the tab panels, so it
   shows regardless of which one is open. */
.cand-occ-suggestion {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cand-occ-suggestion__text {
  margin: 0;
  font-weight: 600;
}

.cand-occ-suggestion__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

@media (min-width: 768px) {
  .cand-skill {
    grid-template-columns: minmax(0, 1fr) 22ch;
    align-items: center;
    gap: 6px 16px;
  }

  .cand-skill__head,
  .cand-skill__track {
    grid-column: 1;
  }

  .cand-skill__select {
    grid-column: 2;
    grid-row: 1 / span 2;
  }
}

/* =====================================================================
   Fiche publique d'un organisme — `.pe-` (entreprise et organisme)
   =====================================================================
   Une seule maquette pour les deux pages, donc une seule famille de règles et
   un seul composant (`framework/components/PublicEntityView`). Les anciennes
   `.co-public__*` sont parties avec la refonte : `ProviderPublicPage` les
   portait sans en déclarer une, ce qui était le motif que `PermissionMatrix`
   puis `ProfileHero` ont déjà refermé ailleurs.

   Jetons `--pj-*` uniquement : la maquette est en clair, et le sombre suit
   sans qu'on repasse sur une règle. Mobile d'abord — ce qui suit est le
   dessin à 360 px, les deux media queries enrichissent. */
.pe-head {
  padding: 0;
  overflow: hidden;
}

.pe-cover {
  height: 120px;
  background-color: var(--pj-card-2);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}

/* Pas d'image est un état normal, pas une panne : une bande sobre aux couleurs
   de la marque plutôt qu'un rectangle gris ou une photo d'agence. */
.pe-cover--empty {
  background-image: linear-gradient(135deg, var(--pj-navy) 0%, var(--pj-navy-dark) 55%, var(--pj-orange-dark) 160%);
}

.pe-identity {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 0 16px 16px;
  text-align: center;
}

/* Le logo chevauche la couverture de moitié. Marge négative plutôt que
   position absolue : le texte dessous continue de couler, donc un nom long
   fait grandir la carte au lieu de passer dessous. */
.pe-logo {
  display: grid;
  width: 88px;
  height: 88px;
  margin-top: -44px;
  place-items: center;
  border-radius: 20px;
  background: var(--pj-card);
  box-shadow: 0 0 0 4px var(--pj-card), var(--pj-shadow-sm);
  color: var(--pj-muted);
  font-size: var(--pj-fs-display);
  overflow: hidden;
}

.pe-logo__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pe-identity__text {
  min-width: 0;
}

.pe-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  overflow-wrap: anywhere;
}

/* Le sigle, sous le nom sur une fiche publique. Discret : c est un rappel
   du nom, pas une seconde identite. */
.pe-sigle {
  margin: 2px 0 0;
  font-size: var(--pj-fs-md);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--pj-muted);
}

.pe-verified {
  color: var(--pj-orange-fill);
  font-size: 0.9em;
}

.pe-badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 6px;
}

.pe-badge {
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.pe-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 16px;
  margin: 8px 0 0;
  color: var(--pj-muted);
}

.pe-meta__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: inherit;
  overflow-wrap: anywhere;
}

a.pe-meta__item:hover {
  color: var(--pj-orange-text);
}

/* Le bandeau de chiffres. Il **enveloppe** : une rangée qui ne peut pas passer
   à la ligne dimensionne la colonne centrale de la coquille sur son propre
   max-content, et `overflow-x` ne borne que ce qui est montré, jamais ce qui a
   été mesuré (la barre de filtres de E2-05). */
.pe-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--pj-line);
}

.pe-fact {
  display: grid;
  gap: 2px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--pj-line);
  text-align: center;
}

.pe-fact:nth-child(odd) {
  border-right: 1px solid var(--pj-line);
}

/* Une cellule seule (ou la derniere d'une rangee impaire) ne trace pas un bord
   contre du vide : `nth-child(odd)` le posait meme quand il n'y a personne a
   droite, ce qui se voit des qu'une entite ne renseigne qu'un chiffre. */
.pe-fact:last-child {
  border-right: 0;
}

.pe-fact__label {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.pe-fact__value {
  overflow-wrap: anywhere;
}

.pe-body {
  display: grid;
  gap: 16px;
}

.pe-body__main,
.pe-body__side {
  display: grid;
  gap: 16px;
  align-content: start;
}

.pe-block__title {
  margin: 0 0 10px;
  font-size: var(--pj-fs-lg);
}

.pe-block__text {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* AddressLocationField (2026-09-06) — the three publication wizards' "where"
   step, read-only by default with a "Modifier" button, instead of three
   always-editable fields and a map for an address that is already correct
   nine times out of ten. `--pj-card-2` is the same nested-surface token the
   theme already uses for a sunken panel inside a card. */
.co-location--view {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  background: var(--pj-card-2);
  border-radius: var(--pj-radius-sm);
}

.co-location__text {
  margin: 0;
}

/* "Vous gérez cette entreprise" banner (2026-09-06) — prepended into the
   same .pj-stack as PublicEntityView's own header card, so it takes its
   spacing from the stack's own gap like every other child; no margin of its
   own, same reasoning check-card-gaps.mjs enforces elsewhere. */
.co-public-manage {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--pj-orange-soft);
}

.co-public-manage__text {
  margin: 0;
  color: var(--pj-orange-text);
  font-weight: 600;
}

/* Company/provider public page content sections (E31-05) — actualités,
   galerie, marketplace, offres, formations, appended after PublicEntityView
   rather than folded into it (it knows no vocabulary for any of these). */
.co-public-section {
  margin-top: 16px;
}

.co-public-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
  margin-bottom: 14px;
}

.co-public-card {
  cursor: pointer;
  display: grid;
  gap: 6px;
  align-content: start;
}

.co-public-news__cover {
  width: 100%;
  max-width: 320px;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--pj-radius-sm);
  margin-bottom: 8px;
}

.co-public-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}

.co-public-photo {
  margin: 0;
}

.co-public-photo img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--pj-radius-sm);
}

.co-public-photo figcaption {
  margin-top: 4px;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.pe-info {
  display: grid;
  gap: 2px;
  padding: 10px 0;
  border-bottom: 1px solid var(--pj-line);
}

.pe-info:last-of-type {
  border-bottom: 0;
}

.pe-info__label {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.pe-info__value {
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* Un numero et une adresse e-mail sont **les** gestes de cette page, sur une
   plateforme ou ~90 % des visiteurs arrivent au telephone. Mesures a 360 px :
   ces liens sortaient a 20 px, l'ancienne `.co-contact` portant le plancher que
   la nouvelle regle avait perdu. La cible grandit, pas la typographie. */
a.pe-info__value {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

a.pe-info__value:hover {
  color: var(--pj-orange-text);
}

/* Les icônes de réseaux : seul l'organisme en a (`social_links`), une
   entreprise n'a pas la colonne. 44 px, comme toute cible tactile. */
.pe-social {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

/* Classe doublee : `.pj-app a { color: inherit }` (prosyjob.css) pese
   (0,1,1) et battait cette regle (0,1,0), donc le lien heritait de la
   couleur de son parent au lieu de la sienne. Voir check-link-colors.mjs. */
.pe-social__link.pe-social__link {
  display: inline-flex;
  width: 44px;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

.pe-social__link:hover {
  background: var(--pj-orange-fill);
  color: #fff;
}

@media (min-width: 768px) {
  .pe-cover {
    height: 180px;
  }

  .pe-identity {
    flex-direction: row;
    align-items: flex-end;
    padding: 0 24px 20px;
    text-align: left;
  }

  .pe-logo {
    width: 112px;
    height: 112px;
    margin-top: -56px;
  }

  .pe-name,
  .pe-badges,
  .pe-meta {
    justify-content: flex-start;
  }

  .pe-facts {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .pe-fact {
    border-bottom: 0;
    border-right: 1px solid var(--pj-line);
  }

  .pe-fact:last-child,
  .pe-fact:nth-child(odd) {
    border-right: 1px solid var(--pj-line);
  }

  .pe-fact:last-child {
    border-right: 0;
  }
}

@media (min-width: 1200px) {
  /* Deux colonnes, pas les trois de la maquette : « Domaines d'activité » et
     « Nos valeurs » n'ont aucune colonne derrière eux et le PO a tranché de ne
     pas en inventer (2026-08-11). */
  .pe-body {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    align-items: start;
  }

  /* Une seule des deux colonnes a du contenu : elle prend toute la largeur
     plutot que de laisser un tiers de page vide a cote. Le composant pose la
     classe, parce qu'une grille ne peut pas savoir qu'un de ses elements est
     vide — un `<div>` sans enfant reste un element de grille. */
  .pe-body--single {
    grid-template-columns: minmax(0, 1fr);
  }

  .pe-block__text {
    max-width: 78ch;
  }
}

/* Le petit menu du bouton appareil-photo du hero : changer ou retirer.
   `position: fixed` parce que `.ph-hero` doit couper son propre contenu (la
   couverture a besoin d'`overflow: hidden`) et couperait un menu place en
   absolu dedans. Le fond ferme au clic — un fond qui meurt avec le balisage
   plutot qu'un ecouteur sur `document` qui survivrait a la page (§9). */
.ph-menu {
  position: fixed;
  z-index: 1070;
  display: grid;
  min-width: 200px;
  padding: 6px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow);
}

.ph-menu__item {
  width: 100%;
  min-height: 44px;
  padding: 0 12px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: none;
  color: var(--pj-ink);
  text-align: left;
  cursor: pointer;
}

.ph-menu__item:hover {
  background: var(--pj-card-2);
}

.ph-menu__item--danger {
  color: var(--pj-orange-text);
}

.ph-menu__backdrop {
  position: fixed;
  z-index: 1069;
  inset: 0;
}

/* ── Page de resultats de la recherche globale (`.sr-`) ─────────────────── */

.sr-head {
  display: grid;
  gap: 8px;
}

.sr-head__title {
  margin: 0;
  font-size: var(--pj-fs-card);
  overflow-wrap: anywhere;
}

.sr-scope {
  display: grid;
  gap: 4px;
  max-width: 22rem;
  margin: 4px 0 0;
}

.sr-scope > span {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.sr-scope .form-control {
  min-height: 44px;
}

.sr-group__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
}

.sr-group__head h2 {
  margin: 0;
  font-size: var(--pj-fs-lg);
}

/* Chaque resultat est un lien entier, pas un titre cliquable dans une carte :
   la cible tactile est la ligne, ce qui vaut mieux sur un telephone. */
.sr-hit {
  display: grid;
  gap: 2px;
  min-height: 44px;
  padding: 10px 0;
  border-bottom: 1px solid var(--pj-line);
  color: inherit;
}

.sr-hit:last-of-type {
  border-bottom: 0;
}

.sr-hit:hover .sr-hit__title {
  color: var(--pj-orange-text);
}

.sr-hit__title {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.sr-hit__meta {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  overflow-wrap: anywhere;
}

.sr-group__rest {
  margin: 10px 0 0;
  font-size: var(--pj-fs-body);
}

/* ================================================================== *
 * M22 « Vos annonces » — la famille .ads-
 *
 * Mobile d'abord : chaque grille commence en une colonne et gagne des
 * pistes quand la place existe. Les valeurs viennent des jetons
 * `--pj-*` sans exception — c'est ce qui fait du thème sombre un bloc
 * de surcharge et non une seconde passe sur ces règles.
 * ================================================================== */

/* --- la liste ---------------------------------------------------- */

/* Tout `<button>` nu fait 100 % de large dans la mise en page connectée
   (`button, .btn` en haut de cette feuille). Une rangée d'actions doit
   donc le dire elle-même, sinon chaque bouton prend une ligne. */
.ads-wizard-actions .btn,
.ads-action {
    width: auto;
}

.ads-card__head {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: flex-start;
    justify-content: space-between;
}

.ads-card__title {
    font-size: var(--pj-fs-lg);
    margin: 0 0 4px;
}

.ads-card__meta {
    color: var(--pj-muted);
    display: flex;
    flex-wrap: wrap;
    font-size: var(--pj-fs-sm);
    gap: 10px;
    margin: 0;
}

.ads-card__kpis {
    display: grid;
    gap: 12px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin: 16px 0 0;
}

.ads-card__kpis dt {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-weight: 500;
}

.ads-card__kpis dd {
    font-size: var(--pj-fs-lg);
    font-weight: 700;
    margin: 0;
}

/* L'état porte toujours son libellé en plus de sa couleur : un badge
   qui ne se distingue que par sa teinte ne dit rien à qui ne la voit
   pas, et rien du tout sur une capture d'écran en noir et blanc. */
.ads-badge {
    border-radius: var(--pj-radius-pill);
    font-size: var(--pj-fs-xs);
    font-weight: 600;
    padding: 4px 12px;
    white-space: nowrap;
}

.ads-badge--info    { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.ads-badge--ok      { background: var(--pj-success-soft); color: var(--pj-success); }
.ads-badge--ended   { background: var(--pj-orange-soft); color: var(--pj-orange-text); }
.ads-badge--warn    { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.ads-badge--bad     { background: var(--pj-danger-soft); color: var(--pj-danger); }
.ads-badge--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.ads-hint {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    margin: 6px 0 0;
}

/* Le poids d'un emailing proche du plafond (E60-02) : une alerte, pas encore
   un refus. */
.ads-hint.ads-hint--warn {
    color: var(--pj-danger);
    font-weight: 600;
}

.ads-empty {
    color: var(--pj-muted);
    padding: 24px 0;
    text-align: center;
}

/* --- la liste « Vos annonces » (maquette vos_annonces.png) ---------- *
 * `adsx` : l'en-tete a icone et trois entrees, les filtres, puis une
 * seule carte qui porte les lignes et le pied de pagination. Une ligne
 * n'est pas une `.pj-card` : la maquette les separe d'un filet, pas d'un
 * espace, et c'est ce qui les lit comme une liste plutot qu'un mur.
 * ------------------------------------------------------------------- */

/* Les seuils suivent la colonne de contenu, pas l'ecran : a 1280 px, la
   coque connectee ne laisse qu'environ 600 px a cette page entre la barre
   laterale et la colonne de droite. */
.adsx {
    container: adsx / inline-size;
}

.adsx .adsx-hero {
    display: grid;
    gap: 16px;
    padding: 16px;
}

.adsx-hero__head {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

.adsx-hero__icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: var(--pj-radius);
    background: var(--pj-orange-soft);
    color: var(--pj-orange);
    font-size: 26px; /* fs-ok: pictogramme de l'en-tete */
}

.adsx-hero__text h1 {
    margin: 0;
    font-size: var(--pj-fs-title);
    font-weight: 800;
    color: var(--pj-ink);
}

.adsx-hero__text p {
    margin: 4px 0 0;
    color: var(--pj-muted);
}

/* Sur un telephone, les trois entrees s'empilent en pleine largeur : c'est
   la maquette, et c'est la seule facon de garder 44 px de cible a 360 px. */
.adsx-hero__actions {
    display: grid;
    gap: 10px;
}

.adsx-hero__actions .btn,
.adsx-filters__actions .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
}

.adsx .adsx-filters {
    display: grid;
    gap: 12px;
    padding: 16px;
}

.adsx-filters__row {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.adsx-filters__row .field {
    margin: 0;
    min-width: 0;
}

.adsx-filters__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.adsx-filters__actions .btn {
    width: auto;
    padding-inline: 18px;
}

.adsx .adsx-results {
    display: grid;
    gap: 0;
    padding: 0;
    overflow: hidden;
}

.adsx-list {
    display: grid;
}

.adsx-row {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr);
    grid-template-areas: "thumb main" "thumb side";
    gap: 10px 12px;
    align-items: start;
    padding: 14px 16px;
    border-bottom: 1px solid var(--pj-line);
}

.adsx-row:last-child {
    border-bottom: 0;
}

.adsx-row .adsx-row__thumb {
    width: 56px;
    height: 56px;
    padding: 0;
    border: 0;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
    overflow: hidden;
    cursor: pointer;
}

.adsx-row__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.adsx-row__icon {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    background: var(--pj-orange-soft);
    color: var(--pj-orange);
    font-size: 24px; /* fs-ok: pictogramme du type d'annonce */
}

.adsx-row__icon--whatsapp {
    background: var(--pj-success-soft);
    color: var(--pj-success);
}

.adsx-row__icon--email {
    background: var(--pj-info-soft);
    color: var(--pj-info-ink);
}

.adsx-row .adsx-row__thumb { grid-area: thumb; }

.adsx-row__main {
    grid-area: main;
    min-width: 0;
}

.adsx-row__title {
    margin: 0;
    font-size: var(--pj-fs-body);
    font-weight: 800;
    line-height: 1.3;
}

.adsx-row .adsx-row__link {
    width: auto;
    padding: 0;
    border: 0;
    background: none;
    color: var(--pj-ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.adsx-row .adsx-row__link:hover,
.adsx-row .adsx-row__link:focus-visible {
    color: var(--pj-orange-text);
    text-decoration: underline;
}

.adsx-row__meta {
    display: flex;
    flex-wrap: wrap;
    margin: 2px 0 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

.adsx-row__meta span + span::before {
    content: "|";
    margin: 0 8px;
    color: var(--pj-line);
}

.adsx-row__progress {
    height: 6px;
    margin-top: 10px;
    border-radius: var(--pj-radius-pill);
    background: var(--pj-card-2);
    overflow: hidden;
}

.adsx-row__progress span {
    display: block;
    height: 100%;
    background: var(--pj-orange-fill);
}

/* Les chiffres : sur un telephone, l'icone et la valeur seulement — le
   libelle reste lu par un lecteur d'ecran, il n'a pas la place d'etre vu. */
.adsx-row__kpis {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
    margin: 10px 0 0;
}

.adsx-row__kpis div {
    display: flex;
    align-items: center;
    gap: 4px;
}

.adsx-row__kpis dt {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-weight: 500;
}

.adsx-row__kpis dd {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-sm);
    font-weight: 700;
}

.adsx-row__side {
    grid-area: side;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.adsx-row__status {
    display: flex;
    align-items: center;
    gap: 2px;
}

.adsx-row .adsx-row__kebab {
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: var(--pj-muted);
    cursor: pointer;
}

.adsx-row .adsx-row__kebab:hover,
.adsx-row .adsx-row__kebab[aria-expanded="true"] {
    background: var(--pj-card-2);
    color: var(--pj-ink);
}

.adsx-row__more .dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
}

.adsx-row__more .dropdown-item i {
    width: 16px;
    text-align: center;
}

.adsx-row .btn.adsx-row__cta {
    width: auto;
    min-height: 44px;
    padding-inline: 14px;
    white-space: nowrap;
}

.adsx-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    border-top: 1px solid var(--pj-line);
}

.adsx-footer__size {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.adsx-footer__size select {
    width: auto;
    min-height: 44px;
}

.adsx-footer__count {
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.adsx-footer__pages .paginations {
    margin: 0;
}

@container adsx (max-width: 559px) {
    /* La maquette mobile n'affiche ni le libelle des filtres ni celui des
       chiffres : visuellement masques, pas retires. */
    .adsx-filters__row .field > span,
    .adsx-row__kpis dt span {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    .adsx-footer {
        justify-content: center;
    }
}

@container adsx (min-width: 560px) {
    .adsx .adsx-hero,
    .adsx .adsx-filters {
        padding: 22px 26px;
    }

    .adsx-hero__icon {
        width: 72px;
        height: 72px;
        font-size: 34px; /* fs-ok: pictogramme de l'en-tete */
    }

    .adsx-hero__text h1 {
        font-size: var(--pj-fs-display);
    }

    .adsx-hero__actions {
        display: flex;
        flex-wrap: wrap;
    }

    .adsx-hero__actions .btn {
        width: auto;
        padding-inline: 16px;
    }

    .adsx-row {
        grid-template-columns: 96px minmax(0, 1fr) auto;
        grid-template-areas: "thumb main side";
        gap: 20px;
        padding: 16px 26px;
    }

    .adsx-row__side {
        display: grid;
        justify-items: end;
    }

    .adsx-row .adsx-row__thumb {
        width: 96px;
        height: 80px;
    }

    .adsx-row__title {
        font-size: var(--pj-fs-md);
    }

    .adsx-row__meta {
        font-size: var(--pj-fs-sm);
    }

    .adsx-row__progress {
        max-width: 720px;
    }

    .adsx-row__kpis {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 140px));
        gap: 12px;
    }

    .adsx-row__kpis div {
        display: grid;
        gap: 2px;
    }

    .adsx-footer {
        padding: 14px 26px;
    }
}

@container adsx (min-width: 760px) {
    .adsx-filters__row {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

@container adsx (min-width: 1000px) {
    .adsx .adsx-hero {
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
    }

    .adsx-hero__actions {
        justify-content: flex-end;
    }
}

/* « Rechercher » : le bloc de recherche est replie par defaut. Le bouton
   dit s'il est ouvert (le chevron tourne) et porte une pastille quand un
   filtre est actif, pour qu'une liste raccourcie dise pourquoi. */
.adsx-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 14px;
}

.adsx .btn.adsx-toolbar__toggle {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    width: auto;
    min-height: 44px;
    padding-inline: 18px;
}

.adsx-toolbar__caret {
    transition: transform .15s ease;
}

.adsx-toolbar__toggle.is-open .adsx-toolbar__caret {
    transform: rotate(180deg);
}

.adsx-toolbar__toggle.has-filters::after {
    content: "";
    position: absolute;
    top: 6px;
    right: 6px;
    width: 9px;
    height: 9px;
    border: 2px solid var(--pj-card);
    border-radius: 50%;
    background: var(--pj-orange-fill);
}

.adsx-toolbar__desk {
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

@media (prefers-reduced-motion: reduce) {
    .adsx-toolbar__caret {
        transition: none;
    }
}

/* --- le detail d'une annonce (maquette detail_annonce.png) ---------- *
 * `adsd` : l'en-tete (visuel, titre, etat, actions, retour), puis une
 * carte par sujet, chacune sous une tuile d'icone. Monte dans « Vos
 * annonces » a la place de la liste, donc sous le conteneur `adsx`.
 * ------------------------------------------------------------------- */

.adsx .adsd-head {
    display: grid;
    gap: 16px;
    padding: 16px;
}

.adsd-head__art {
    display: grid;
    align-self: start;
    overflow: hidden;
    max-width: 280px;
    border-radius: var(--pj-radius);
}

.adsd-head__art img {
    display: block;
    width: 100%;
    max-height: 180px;
    object-fit: cover;
}

.adsd-head__icon {
    display: grid;
    place-items: center;
    width: 100%;
    height: 140px;
    background: var(--pj-orange-soft);
    color: var(--pj-orange);
    font-size: 44px; /* fs-ok: pictogramme du format, en l'absence de visuel */
}

.adsd-head__icon--whatsapp { background: var(--pj-success-soft); color: var(--pj-success); }
.adsd-head__icon--email    { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.adsd-head__icon--text     { background: var(--pj-info-soft); color: var(--pj-blue); }

.adsd-head__body {
    display: grid;
    align-content: start;
    gap: 12px;
    min-width: 0;
}

.adsd-head__body h2 {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-title);
    font-weight: 800;
    overflow-wrap: anywhere;
}

.adsd-head__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0;
    color: var(--pj-muted);
}

.adsd-chip {
    padding: 3px 10px;
    border-radius: var(--pj-radius-pill);
    background: var(--pj-orange-soft);
    color: var(--pj-orange-text);
    font-size: var(--pj-fs-xs);
    font-weight: 600;
}

.adsd-head__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.adsd-head__actions:empty {
    display: none;
}

.adsd-head__actions .btn,
.adsx .btn.adsd-back,
.adsx .btn.adsd-head-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: auto;
    min-height: 44px;
    padding-inline: 16px;
}

/* Sur un telephone, « Payer » prend la ligne entiere : c'est l'action qui
   fait avancer l'annonce, les autres la rangent ou la copient. */
.adsd-head__actions .btn-primary {
    flex: 1 1 100%;
}

/* Les autres, deux par ligne : un bouton par ligne allongeait l'en-tete
   d'autant sans rien dire de plus. */
.adsd-head__actions .btn:not(.btn-primary) {
    flex: 1 1 calc(50% - 4px);
    padding-inline: 10px;
}

/* Une carte de sujet. */
.adsx .adsd-card {
    display: grid;
    gap: 14px;
    padding: 16px;
}

.adsd-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
}

.adsd-card__icon {
    display: grid;
    flex: none;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-orange-soft);
    color: var(--pj-orange);
    font-size: 17px; /* fs-ok: pictogramme de carte */
}

.adsd-card__head h2 {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-card);
    font-weight: 800;
}

.adsx .btn.adsd-head-btn {
    margin-left: auto;
}

.adsd-card > p {
    margin: 0;
}

.adsd-text {
    white-space: pre-wrap;
}

/* Les faits d'une carte : libelle puis valeur. */
.adsd-facts {
    display: grid;
    gap: 12px 24px;
    margin: 0;
}

.adsd-facts > div {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.adsd-facts dt {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    font-weight: 400;
}

.adsd-facts dd {
    margin: 0;
    color: var(--pj-ink);
    font-weight: 600;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

/* Les tuiles de chiffres. */
.adsd-tiles {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
    margin: 0;
}

.adsd-tile {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px;
    border-radius: var(--pj-radius);
}

.adsd-tile > i {
    flex: none;
    font-size: 20px; /* fs-ok: pictogramme de chiffre */
}

.adsd-tile dt {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-weight: 500;
}

.adsd-tile dd {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-card);
    font-weight: 800;
}

.adsd-tile--blue   { background: var(--pj-info-soft); }
.adsd-tile--blue > i { color: var(--pj-blue); }
.adsd-tile--green  { background: var(--pj-success-soft); }
.adsd-tile--green > i { color: var(--pj-success); }
.adsd-tile--orange { background: var(--pj-orange-soft); }
.adsd-tile--orange > i { color: var(--pj-orange); }
.adsd-tile--navy   { background: var(--pj-neutral-soft); }
.adsd-tile--navy > i { color: var(--pj-navy); }
.adsd-tile--red    { background: var(--pj-danger-soft); }
.adsd-tile--red > i { color: var(--pj-danger); }

.adsd-note {
    display: flex;
    align-items: center;
    gap: 8px;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.adsd-note i {
    color: var(--pj-blue);
}

/* Les commandes. */
.adsd-orders {
    display: grid;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.adsd-order {
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr);
    grid-template-areas: "icon what" "icon price";
    column-gap: 12px;
    row-gap: 6px;
    align-items: center;
    padding: 12px 14px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
}

.adsd-order.is-pending {
    background: var(--pj-orange-soft);
}

.adsd-order__icon {
    grid-area: icon;
    color: var(--pj-orange);
    font-size: 18px; /* fs-ok: pictogramme de commande */
    text-align: center;
}

.adsd-order__what {
    grid-area: what;
    display: grid;
    min-width: 0;
}

.adsd-order__price {
    grid-area: price;
    display: grid;
}

.adsd-order strong {
    color: var(--pj-ink);
    font-weight: 700;
}

.adsd-order__price strong {
    color: var(--pj-orange-text);
}

.adsd-order small {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

/* L'historique, en frise : un point par etape, relies d'un trait. */
.adsd-timeline {
    margin: 0;
    padding: 0;
    list-style: none;
}

.adsd-timeline li {
    position: relative;
    display: grid;
    gap: 2px;
    padding: 0 0 14px 26px;
}

.adsd-timeline li + li {
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
}

.adsd-timeline li::before {
    content: "";
    position: absolute;
    top: 6px;
    left: 4px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--pj-orange-fill);
}

.adsd-timeline li + li::before {
    top: 18px;
}

.adsd-timeline strong {
    color: var(--pj-ink);
    font-weight: 700;
}

.adsd-timeline small {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

.adsd-timeline p {
    margin: 2px 0 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-sm);
}

@container adsx (min-width: 560px) {
    .adsx .adsd-head {
        grid-template-columns: minmax(150px, 220px) minmax(0, 1fr);
        gap: 24px;
        padding: 22px 26px;
    }

    .adsd-head__body h2 {
        font-size: var(--pj-fs-display);
    }

    .adsd-head__actions .btn-primary,
    .adsd-head__actions .btn:not(.btn-primary) {
        flex: 0 0 auto;
        padding-inline: 16px;
    }

    .adsx .adsd-card {
        padding: 22px 26px;
    }

    .adsd-facts {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .adsd-facts > div {
        grid-template-columns: 110px minmax(0, 1fr);
        gap: 12px;
    }

    .adsd-order {
        grid-template-columns: 32px minmax(0, 1fr) auto;
        grid-template-areas: "icon what price";
    }

    .adsd-order__price {
        text-align: right;
    }
}

/* --- « Base de données des contacts » (maquette importer_des_contacts.png)
 * `adsl` : l'en-tete, le formulaire d'import, puis « Mes bases de
 * contacts » en tableau — qui devient une liste a deux lignes sur un
 * telephone, la ou ses colonnes du milieu n'ont pas la place.
 * ------------------------------------------------------------------- */

.adsl {
    container: adsl / inline-size;
}

.adsl .adsl-hero {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px;
}

.adsl-hero__icon {
    position: relative;
    flex: none;
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    border-radius: var(--pj-radius);
    background: var(--pj-info-soft);
    color: var(--pj-blue);
    font-size: 32px; /* fs-ok: pictogramme de l'en-tete */
}

.adsl-hero__badge {
    position: absolute;
    right: 4px;
    bottom: 4px;
    display: grid;
    place-items: center;
    width: 24px;
    height: 24px;
    border: 2px solid var(--pj-card);
    border-radius: 50%;
    background: var(--pj-orange-fill);
    color: var(--pj-card);
    font-size: 11px; /* fs-ok: pastille de l'icone */
}

.adsl-hero__text h1 {
    margin: 0;
    font-size: var(--pj-fs-title);
    font-weight: 800;
    color: var(--pj-ink);
}

.adsl-hero__text p {
    margin: 4px 0 0;
    color: var(--pj-muted);
}

.adsl .adsl-import,
.adsl .adsl-mine {
    display: grid;
    gap: 16px;
    padding: 16px;
}

.adsl-import .field {
    margin: 0;
}

.adsl-head {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

.adsl-head__icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-info-soft);
    color: var(--pj-blue);
    font-size: 18px; /* fs-ok: pictogramme de section */
}

.adsl-head h2 {
    margin: 0;
    font-size: var(--pj-fs-card);
    font-weight: 800;
    color: var(--pj-ink);
}

.adsl-head p {
    margin: 2px 0 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.adsl-pair {
    display: grid;
    gap: 12px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.adsl-pair .field {
    min-width: 0;
}

.adsl .adsl-preview {
    min-height: 120px;
    background: var(--pj-card-2);
    color: var(--pj-ink);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--pj-fs-sm);
    line-height: 1.5;
    white-space: pre;
    overflow-x: auto;
}

.adsl .btn.adsl-model,
.adsl .btn.adsl-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: auto;
    min-height: 44px;
    padding-inline: 18px;
}

/* « Mes bases de contacts » */
.adsl-mine__head {
    display: grid;
    gap: 12px;
}

.adsl-search {
    position: relative;
    display: block;
    margin: 0;
}

.adsl-search i {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--pj-muted);
    pointer-events: none;
}

.adsl-search input {
    width: 100%;
    min-height: 44px;
    padding: 10px 12px 10px 40px;
    border: 1px solid var(--color-field-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
}

.adsl-search input:focus {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.adsl-table-host {
    min-width: 0;
}

.adsl-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--pj-fs-sm);
}

.adsl-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
}

.adsl-table tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    padding: 12px 0;
    border-bottom: 1px solid var(--pj-line);
}

.adsl-table tbody tr:last-child {
    border-bottom: 0;
}

.adsl-table td {
    padding: 0;
    border: 0;
    color: var(--pj-ink);
}

.adsl-table__name strong {
    display: block;
    font-weight: 700;
}

.adsl-table__meta {
    display: block;
    margin-top: 2px;
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

.adsl-table .adsl-table__col {
    display: none;
}

.adsl-table__actions {
    display: flex;
    align-items: center;
    gap: 6px;
}

.adsl .btn.adsl-view {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    width: auto;
    min-height: 44px;
    padding-inline: 14px;
}

.adsl .adsl-kebab {
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card);
    color: var(--pj-muted);
    cursor: pointer;
}

.adsl .adsl-kebab:hover,
.adsl .adsl-kebab[aria-expanded="true"] {
    background: var(--pj-card-2);
    color: var(--pj-ink);
}

.adsl-more .dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
}

.adsl-more .dropdown-item i {
    width: 16px;
    text-align: center;
}

.adsl-more .dropdown-item.adsl-danger {
    color: var(--pj-danger);
}

.adsl-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.adsl-footer__count {
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.adsl-footer .paginations {
    margin: 0;
}

/* Le dialogue d'une base */
.adsl-fiche {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin: 0 0 14px;
}

.adsl-fiche dt {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-weight: 500;
}

.adsl-fiche dd {
    margin: 0;
    color: var(--pj-ink);
    font-weight: 600;
    overflow-wrap: anywhere;
}

.adsl-attestation {
    margin: 0 0 16px;
    padding: 12px 14px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
    font-size: var(--pj-fs-sm);
}

.adsl-attestation p {
    margin: 0;
}

.adsl-attestation .adsl-attestation__head {
    margin-bottom: 4px;
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

.adsl-fiche__title {
    margin: 0 0 8px;
    font-size: var(--pj-fs-body);
    font-weight: 700;
}

.adsl-contacts {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--pj-fs-sm);
}

.adsl-contacts th,
.adsl-contacts td {
    padding: 8px 10px;
    border-bottom: 1px solid var(--pj-line);
    text-align: left;
    overflow-wrap: anywhere;
}

.adsl-contacts th {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-weight: 600;
}

.adsl-modal-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
    margin-top: 16px;
}

.adsl-modal-actions .btn {
    width: auto;
    min-height: 44px;
}

@container adsl (min-width: 560px) {
    .adsl .adsl-hero,
    .adsl .adsl-import,
    .adsl .adsl-mine {
        padding: 22px 26px;
    }

    .adsl-hero__icon {
        width: 84px;
        height: 84px;
        font-size: 42px; /* fs-ok: pictogramme de l'en-tete */
    }

    .adsl-hero__text h1 {
        font-size: var(--pj-fs-display);
    }

    .adsl-mine__head {
        grid-template-columns: minmax(0, 1fr) minmax(220px, 300px);
        align-items: center;
    }
}

/* Le tableau, des que ses cinq colonnes tiennent. */
@container adsl (min-width: 580px) {
    .adsl-table thead {
        position: static;
        width: auto;
        height: auto;
        overflow: visible;
        clip: auto;
    }

    .adsl-table th {
        padding: 10px 12px;
        background: var(--pj-card-2);
        color: var(--pj-ink);
        font-weight: 700;
        text-align: left;
        white-space: nowrap;
    }

    .adsl-table tbody tr {
        display: table-row;
        padding: 0;
    }

    .adsl-table td {
        padding: 8px 12px;
        border-bottom: 1px solid var(--pj-line);
        vertical-align: middle;
    }

    .adsl-table tbody tr:last-child td {
        border-bottom: 0;
    }

    .adsl-table .adsl-table__col {
        display: table-cell;
        white-space: nowrap;
    }

    .adsl-table__meta {
        display: none;
    }

    .adsl-table__name strong {
        font-weight: 600;
    }

    .adsl-table td.adsl-table__actions {
        display: table-cell;
        white-space: nowrap;
    }

    .adsl-table__actions .dropdown {
        display: inline-block;
        margin-left: 6px;
    }
}

/* --- l'assistant -------------------------------------------------- */

/* La barre d'etapes (maquettes creer_annonce_*.png) : un cercle numerote
   et son libelle par etape, l'etape en cours dans une pastille orange, un
   filet entre les autres. Sur un telephone les quatre tiennent sur une
   ligne en petit ; si la place manque malgre tout, la barre defile sur
   elle-meme plutot que d'elargir la page. */
.ads-steps {
    display: flex;
    align-items: center;
    gap: 4px;
    min-width: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-x: auto;
}

.ads-steps li {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    gap: 6px;
    padding: 4px 8px 4px 4px;
    border: 1px solid transparent;
    border-radius: var(--pj-radius-sm);
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    white-space: nowrap;
}

.ads-steps li span {
    display: grid;
    flex: 0 0 22px;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--pj-card-2);
    color: var(--pj-ink);
    font-size: var(--pj-fs-2xs);
    font-weight: 700;
}

.ads-steps li strong {
    font-weight: 500;
}

.ads-steps li.is-current {
    border-color: var(--pj-orange-fill);
    background: var(--pj-orange-soft);
    color: var(--pj-orange-text);
}

.ads-steps li.is-current span {
    background: var(--pj-orange-fill);
    color: var(--pj-card);
}

.ads-steps li.is-done span {
    background: var(--pj-orange-soft);
    color: var(--pj-orange-text);
}

/* Un forfait, sur l'assistant comme sur le panneau « Prolonger » de la
   fiche : l'icone du format, le libelle, le prix en grand, les Miles en
   dessous, la duree — et le bouton radio qui dit lequel est choisi. */
.ads-forfaits {
    display: grid;
    gap: 12px;
    grid-template-columns: 1fr;
    margin: 0;
}

.ads-forfait {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 14px;
    width: 100%;
    padding: 16px 44px 16px 16px;
    border: 1px solid var(--color-field-border);
    border-radius: var(--pj-radius);
    background: var(--pj-card);
    color: var(--pj-ink);
    text-align: left;
    cursor: pointer;
}

.ads-forfait.is-picked {
    border-color: var(--pj-orange-fill);
    background: var(--pj-orange-soft);
}

.ads-forfait.is-unavailable {
    opacity: .55;
    cursor: not-allowed;
}

.ads-forfait__art {
    display: grid;
    flex: none;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-orange-soft);
    color: var(--pj-orange);
    font-size: 22px; /* fs-ok: pictogramme du format */
}

.ads-forfait.is-picked .ads-forfait__art {
    background: var(--pj-card);
}

.ads-forfait__body {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.ads-forfait__body strong {
    font-size: var(--pj-fs-body);
    font-weight: 700;
    line-height: 1.3;
}

.ads-forfait__price {
    margin-top: 4px;
    color: var(--pj-orange-text);
    font-size: var(--pj-fs-card);
    font-weight: 800;
}

.ads-forfait small {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.ads-forfait__details {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin-top: 6px;
    font-size: var(--pj-fs-sm);
}

.ads-forfait__details i {
    color: var(--pj-muted);
}

.ads-forfait em {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-style: normal;
}

/* Le bouton radio d'une carte de choix — format comme forfait. */
.adsw-radio {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 20px;
    height: 20px;
    border: 2px solid var(--color-field-border);
    border-radius: 50%;
    background: var(--pj-card);
}

.is-picked > .adsw-radio {
    border-color: var(--pj-orange-fill);
    background: var(--pj-orange-fill);
    box-shadow: inset 0 0 0 3px var(--pj-card);
}

/* --- l'assistant : la carte d'une etape ----------------------------- */

.adsw .adsw-card {
    display: grid;
    gap: 16px;
    padding: 16px;
}

.adsw-card .field {
    margin: 0;
}

.adsw-head {
    display: flex;
    align-items: flex-start;
    gap: 14px;
}

.adsw-head__icon,
.adsw-sub__icon,
.adsw-summary__icon {
    display: grid;
    flex: none;
    place-items: center;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-orange-soft);
    color: var(--pj-orange);
}

.adsw-head__icon {
    width: 48px;
    height: 48px;
    font-size: 22px; /* fs-ok: pictogramme d'etape */
}

.adsw-head h2 {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-title);
    font-weight: 800;
}

.adsw-head p {
    margin: 2px 0 0;
    color: var(--pj-muted);
}

.adsw-choose {
    margin: 4px 0 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-md);
    font-weight: 700;
}

.adsw-req {
    color: var(--pj-danger);
    font-weight: 700;
}

/* Les formats : des cartes de choix a bouton radio. */
.adsw-options {
    display: grid;
    gap: 12px;
    grid-template-columns: 1fr;
}

.adsw .adsw-option {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 14px;
    width: 100%;
    padding: 16px 44px 16px 16px;
    border: 1px solid var(--color-field-border);
    border-radius: var(--pj-radius);
    background: var(--pj-card);
    color: var(--pj-ink);
    text-align: left;
    cursor: pointer;
}

.adsw .adsw-option.is-picked {
    border-color: var(--pj-orange-fill);
    background: var(--pj-orange-soft);
}

.adsw .adsw-option.is-unavailable {
    opacity: .55;
    cursor: not-allowed;
}

.adsw-option__art {
    display: grid;
    flex: none;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: var(--pj-radius-sm);
    font-size: 26px; /* fs-ok: pictogramme du format */
}

.adsw-tone--orange { background: var(--pj-orange-soft); color: var(--pj-orange); }
.adsw-tone--blue   { background: var(--pj-info-soft); color: var(--pj-blue); }
.adsw-tone--green  { background: var(--pj-success-soft); color: var(--pj-success); }
.adsw-tone--red    { background: var(--pj-danger-soft); color: var(--pj-danger); }

.adsw-option.is-picked .adsw-option__art {
    background: var(--pj-card);
}

.adsw-option__body {
    display: grid;
    gap: 4px;
    min-width: 0;
}

.adsw-option__body strong {
    font-size: var(--pj-fs-body);
    font-weight: 700;
    line-height: 1.3;
}

.adsw-option__body small {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

/* Ou l'emplacement s'affiche reellement, dit avant l'achat plutot que
   decouvert apres. Un acheteur qui choisit « Banniere verticale » et la
   cherche dans le rail connecte conclut que la plateforme est cassee. */
.adsw-option__body em {
    margin-top: 4px;
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-style: normal;
    line-height: 1.45;
}

/* Un champ precede d'une icone : le lien, l'epingle, l'enveloppe. */
.adsw-input {
    position: relative;
    display: block;
}

.adsw-input > i {
    position: absolute;
    top: 50%;
    left: 14px;
    color: var(--pj-muted);
    transform: translateY(-50%);
    pointer-events: none;
}

/* `.field .adsw-input > input` : la règle générique `.field input:not(…):not(…)`
   pèse (0,3,1) et l'emportait sur (0,2,1), le texte passant sous l'icône. */
.adsw .adsw-input > input,
.adsw .adsw-input > select,
.adsw .field .adsw-input > input {
    width: 100%;
    padding-left: 40px;
}

.adsw-count {
    align-self: flex-end;
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

.adsw-notice {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin: 0;
    padding: 12px 14px;
    border-radius: var(--pj-radius-sm);
    font-size: var(--pj-fs-sm);
    line-height: 1.5;
}

.adsw-notice > i {
    margin-top: 3px;
}

.adsw-notice--warn {
    background: var(--pj-orange-soft);
    color: var(--pj-orange-text);
}

.adsw-notice--info {
    background: var(--pj-info-soft);
    color: var(--pj-info-ink);
}

/* « Repondre a », « Zone de diffusion » : une icone, un titre, une phrase,
   puis le controle. */
.adsw-sub {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    gap: 14px;
    align-items: start;
}

.adsw-sub__icon {
    width: 44px;
    height: 44px;
    font-size: 18px; /* fs-ok: pictogramme de section */
}

.adsw-sub__body {
    display: grid;
    gap: 10px;
    min-width: 0;
}

.adsw-sub h3 {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-md);
    font-weight: 700;
}

.adsw-sub .adsw-sub__hint {
    margin: -6px 0 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.adsw-zone-target {
    display: grid;
    gap: 10px;
}

.adsw-zone-target:empty {
    display: none;
}

/* Le visuel : une zone en pointilles tant qu'il n'y en a pas. */
.adsw-visual {
    display: grid;
    gap: 14px;
}

.adsw-visual__preview {
    display: grid;
    place-items: center;
    min-height: 150px;
    overflow: hidden;
    border: 2px dashed var(--color-field-border);
    border-radius: var(--pj-radius);
    background: var(--pj-card-2);
}

.adsw-visual__preview img {
    display: block;
    max-width: 100%;
    max-height: 240px;
    object-fit: contain;
}

.adsw-visual__empty {
    display: grid;
    justify-items: center;
    gap: 4px;
    padding: 20px;
    color: var(--pj-muted);
    text-align: center;
}

.adsw-visual__empty i {
    color: var(--pj-blue);
    font-size: 30px; /* fs-ok: pictogramme du visuel absent */
}

.adsw-visual__empty strong {
    color: var(--pj-ink);
    font-weight: 600;
}

.adsw-visual__empty small {
    font-size: var(--pj-fs-xs);
}

.adsw-visual__side {
    display: grid;
    align-content: start;
    gap: 8px;
}

.adsw-visual__side .ads-hint {
    margin: 0;
}

.adsw .btn.adsw-soft {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    justify-self: start;
    gap: 8px;
    width: auto;
    min-height: 44px;
    padding-inline: 18px;
}

.adsw-tools {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* La validation : une ligne par fait, icone, libelle, valeur. */
.adsw-summary {
    margin: 0;
    padding: 0 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--pj-radius);
}

.adsw-summary__row {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr);
    grid-template-areas: "icon label" "icon value";
    column-gap: 14px;
    align-items: center;
    padding: 12px 0;
    border-bottom: 1px solid var(--color-border);
}

.adsw-summary__row:last-child {
    border-bottom: 0;
}

.adsw-summary__icon {
    grid-area: icon;
    width: 40px;
    height: 40px;
    font-size: 17px; /* fs-ok: pictogramme du recapitulatif */
}

.adsw-summary dt {
    grid-area: label;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    font-weight: 400;
}

.adsw-summary dd {
    grid-area: value;
    margin: 0;
    color: var(--pj-ink);
    font-weight: 700;
    overflow-wrap: anywhere;
}

.adsw-summary dd small {
    display: block;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    font-weight: 400;
}

/* Le bas de chaque etape : le retour a gauche, la suite a droite. */
.adsw-actions {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    margin-top: 4px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}

.adsw-actions .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: auto;
    min-height: 44px;
    padding-inline: 22px;
}

.adsw-actions .btn-primary {
    flex: 1 1 auto;
}

.adsw .ads-forfaits {
    grid-template-columns: 1fr;
}

@container adsx (min-width: 560px) {
    .adsw .adsw-card {
        padding: 22px 26px;
    }

    .ads-steps {
        justify-content: space-between;
        gap: 8px;
    }

    .ads-steps li {
        flex: 1 1 0;
        gap: 10px;
        padding: 8px 12px 8px 8px;
        font-size: var(--pj-fs-body);
    }

    /* Le filet entre deux etapes, dans la place que l'etape laisse. */
    .ads-steps li:not(:last-child):not(.is-current)::after {
        content: "";
        flex: 1;
        height: 1px;
        margin-left: 8px;
        background: var(--color-border);
    }

    .ads-steps li span {
        flex-basis: 32px;
        width: 32px;
        height: 32px;
        font-size: var(--pj-fs-body);
    }

    .adsw-options,
    .adsw .ads-forfaits {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .adsw-visual {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        align-items: start;
    }

    .adsw-summary {
        padding: 0 18px;
    }

    .adsw-summary__row {
        grid-template-columns: 40px minmax(140px, 220px) minmax(0, 1fr);
        grid-template-areas: "icon label value";
    }

    .adsw-actions .btn-primary {
        flex: 0 0 auto;
    }
}

/* Sous 380 px, les quatre libelles ne tiennent pas (mesure : 355 px pour
   297) : seuls les numeros restent visibles, sauf pour l'etape en cours.
   Les libelles sont masques a l'oeil, pas retires — un lecteur d'ecran les
   lit toujours. */
@container adsx (max-width: 379px) {
    .ads-steps {
        justify-content: space-between;
    }

    .ads-steps li:not(.is-current) {
        padding-right: 4px;
    }

    .ads-steps li:not(.is-current) strong {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }
}

@container adsx (min-width: 820px) {
    .adsw-options,
    .adsw .ads-forfaits {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.ads-forfait__price {
    font-size: var(--pj-fs-lg);
    font-weight: 700;
}

.ads-wizard-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 20px;
}

.ads-visual {
    align-items: flex-start;
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
}

.ads-visual__preview {
    align-items: center;
    background: var(--pj-card-2);
    border: 1px dashed var(--pj-line);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-muted);
    display: flex;
    font-size: var(--pj-fs-sm);
    justify-content: center;
    min-height: 120px;
    overflow: hidden;
    width: 100%;
}

.ads-visual__preview img {
    display: block;
    height: auto;
    max-width: 100%;
}

/* --- la fiche ----------------------------------------------------- */

.ads-summary {
    display: grid;
    gap: 12px;
    grid-template-columns: 1fr;
    margin: 0;
}

.ads-summary dt {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

.ads-summary dd {
    margin: 2px 0 0;
    font-weight: 600;
    /* Une destination est une URL, qui n'a pas de point de coupure
       naturel : sans ceci elle élargit la carte et la page défile
       horizontalement. */
    overflow-wrap: anywhere;
}

.ads-reason {
    border-left: 3px solid var(--pj-orange-fill);
}

.ads-orders,
.ads-history {
    list-style: none;
    margin: 0;
    padding: 0;
}

.ads-orders li {
    border-bottom: 1px solid var(--pj-line);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: space-between;
    padding: 12px 0;
}

.ads-history li {
    border-bottom: 1px solid var(--pj-line);
    padding: 10px 0;
}

.ads-orders li:last-child,
.ads-history li:last-child {
    border-bottom: 0;
}

.ads-orders__price {
    text-align: right;
}

.ads-orders small,
.ads-history small {
    color: var(--pj-muted);
    display: block;
    font-size: var(--pj-fs-xs);
}

.ads-history p {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    margin: 4px 0 0;
}

/* --- le graphique ------------------------------------------------- */

/* Le SVG déborde de sa propre boîte plutôt que d'élargir la colonne :
   une série de 30 jours est plus large qu'un rail sur téléphone, et
   c'est le conteneur qui défile, pas la page. */
.ads-chart {
    margin-top: 16px;
    overflow-x: auto;
}

.ads-chart svg {
    height: 120px;
    min-width: 100%;
}

.ads-chart__impressions { fill: var(--pj-blue); }
.ads-chart__clicks      { fill: var(--pj-orange-fill); }

.ads-chart__legend {
    color: var(--pj-muted);
    display: flex;
    align-items: center;
    font-size: var(--pj-fs-xs);
    gap: 6px;
    margin: 8px 0 0;
}

.ads-chart__key {
    border-radius: 2px;
    display: inline-block;
    height: 10px;
    margin-left: 12px;
    width: 10px;
}

.ads-chart__key--impressions { background: var(--pj-blue); }
.ads-chart__key--clicks      { background: var(--pj-orange-fill); }

/* Même patron que .ads-chart (Advertising) — un site déborde de sa boîte
   plutôt que d'élargir la colonne, c'est le conteneur qui défile. */
.wbs-chart {
    margin-top: 16px;
    overflow-x: auto;
}

.wbs-chart svg {
    height: 120px;
    min-width: 100%;
}

.wbs-chart__visits { fill: var(--pj-blue); }
.wbs-chart__unique  { fill: var(--pj-orange-fill); }

/* The live site itself, scaled down — real content, not a screenshot
   service or a new dependency. `width/height: 400%` + `scale(0.25)`
   keeps this responsive to whatever width the card actually renders at
   (no magic pixel constants): the iframe's own internal viewport is
   always 4x the frame, so it renders at a desktop-like width even on a
   narrow admin screen. `pointer-events: none` on the iframe lets a click
   land on the wrapping <a> instead — this is a preview, not the site. */
.wbs-preview {
    display: block;
    margin: 12px 0;
}

.wbs-preview__frame {
    display: block;
    position: relative;
    width: 100%;
    max-width: 480px;
    aspect-ratio: 16 / 10;
    overflow: hidden;
    border: 1px solid var(--pj-line);
    border-radius: 8px;
    background: var(--pj-bg);
}

.wbs-preview__frame iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 400%;
    height: 400%;
    border: 0;
    transform: scale(0.25);
    transform-origin: 0 0;
    pointer-events: none;
}

.wbs-chart__legend {
    color: var(--pj-muted);
    display: flex;
    align-items: center;
    font-size: var(--pj-fs-xs);
    gap: 6px;
    margin: 8px 0 0;
}

.wbs-chart__key {
    border-radius: 2px;
    display: inline-block;
    height: 10px;
    margin-left: 12px;
    width: 10px;
}

.wbs-chart__key--visits { background: var(--pj-blue); }
.wbs-chart__key--unique { background: var(--pj-orange-fill); }

/* --- au-delà du téléphone ----------------------------------------- */

@media (min-width: 720px) {
    .ads-card__kpis    { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .ads-summary       { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ads-formats,
    .ads-forfaits      { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ads-visual__preview { width: 300px; }
}

@media (min-width: 1100px) {
    .ads-formats,
    .ads-forfaits      { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* La vignette de la fiche, par opposition à celle de l'assistant.
 *
 * L'assistant montre un emplacement à remplir : une boîte fixe, avec un
 * cadre en pointillés quand elle est vide. La fiche montre le visuel tel
 * qu'il est — un 140×420 vertical et un 728×90 horizontal n'ont rien à
 * faire dans la même boîte de 300px, où le premier devient une colonne
 * de 900px de haut. D'où une largeur qui suit l'image, plafonnée par la
 * carte, et une hauteur bornée pour qu'une bannière verticale ne pousse
 * pas le reste de la page hors de l'écran. */
.ads-visual__preview--wide {
    border-style: solid;
    display: inline-flex;
    min-height: 0;
    padding: 8px;
    width: auto;
    max-width: 100%;
}

.ads-visual__preview--wide img {
    max-height: 320px;
    width: auto;
}

@media (min-width: 720px) {
    /* La règle de base fixe 300px pour l'assistant ; la fiche s'en
       affranchit, sinon le média-query la rattrape. */
    .ads-visual__preview--wide { width: auto; }
}


/* Un prix programmÃ© â€” dans l'historique, et en toutes lettres au-dessus du
 * formulaire.
 *
 * Les jetons `--pj-*` plutÃ´t que des valeurs brutes : `prosyjob-app.css` les
 * miroite sur `:root`, donc ils existent aussi sur la console. La ligne
 * voisine `.rf-origin--base` porte encore ses couleurs en dur ; ce n'est pas
 * une raison d'en ajouter.
 *
 * Le mot Â« programmÃ© Â» est Ã©crit, pas seulement suggÃ©rÃ© par une teinte : une
 * ligne qui ne se distingue que par sa couleur ne dit rien Ã  qui ne la voit
 * pas, et rien du tout sur une capture d'Ã©cran. */
.layout-admin .rf-history__line.is-scheduled {
    border-left: 3px solid var(--pj-orange-fill);
    padding-left: 8px;
}

.layout-admin .rf-origin--scheduled {
    background: var(--pj-orange-soft);
    color: var(--pj-orange-text);
}

.layout-admin .rf-scheduled-notice {
    background: var(--pj-orange-soft);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-orange-text);
    font-size: var(--pj-fs-sm);
    margin: 12px 0 0;
    padding: 10px 12px;
}


/* ------------------------------------------------------------------ *
 * M22/E23 — le ciblage de diffusion et son compteur
 *
 * Le chiffre est la raison d'etre de ce bloc : c'est sur lui que
 * l'annonceur choisit son forfait, donc il est gros, et il est juste
 * au-dessus des forfaits plutot qu'ailleurs sur la page.
 * ------------------------------------------------------------------ */
.ads-targeting {
    margin-bottom: 16px;
}

/* La grille porte sur les champs, pas sur la section : depuis E23-10 celle-ci
   a un titre et une phrase au-dessus, et les mettre dans la grille les
   collerait en colonne a cote d'un menu deroulant. */
.ads-targeting__fields {
    display: grid;
    gap: 12px;
    grid-template-columns: 1fr;
}

.ads-reach {
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-sm);
    margin-bottom: 16px;
    padding: 14px 16px;
}

.ads-reach__count {
    color: var(--pj-ink);
    font-size: var(--pj-fs-md);
    margin: 0;
}

.ads-reach__count strong {
    font-size: var(--pj-fs-title);
    line-height: 1.1;
    margin-right: 6px;
}

/* Une audience trop petite n'est pas une erreur de l'annonceur : c'est un
   fait qu'on lui dit, en gris, pas en rouge. */
.ads-reach__none {
    color: var(--pj-muted);
    margin: 0;
}

.ads-reach__capped {
    color: var(--pj-orange-text);
    margin: 8px 0 0;
}

/* L'avertissement du gabarit WhatsApp : ce que l'annonceur ne pourra pas
   changer, dit avant qu'il ecrive plutot qu'apres. */
.ads-notice {
    background: var(--pj-orange-soft);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-orange-text);
    font-size: var(--pj-fs-sm);
    margin: 0 0 16px;
    padding: 10px 12px;
}

/* L'exemple de fichier. Recopiable, donc en chasse fixe et selectionnable. */
.ads-example {
    margin-bottom: 16px;
}

.ads-example__code {
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-ink);
    font-size: var(--pj-fs-sm);
    margin: 8px 0;
    overflow-x: auto;
    padding: 12px;
    white-space: pre;
}

@media (min-width: 768px) {
    .ads-targeting__fields {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* Les consentements publicitaires, sur l'ecran des preferences.
   Mis a part visuellement parce qu'ils le sont aussi dans le modele :
   au-dessus on choisit comment etre prevenu de ce qui vous concerne,
   ici on autorise qu'on vous sollicite. */
.notif-offers {
    display: grid;
    gap: 12px;
    margin-bottom: 8px;
}

.notif-offer {
    align-items: center;
    display: flex;
    gap: 10px;
    margin: 0;
}

.notif-offer input {
    flex: 0 0 auto;
    /* Cible tactile : une case de 16px est sous le plancher du projet, et
       c'est le label entier qui la declenche — d'ou la hauteur ici. */
    min-height: 20px;
    min-width: 20px;
}

/* L'opt-in du formulaire d'inscription, sous les conditions. */
.pj-optin {
    margin-top: 8px;
}

/* La phrase qui remplace les deux cases retirées (E27) : sous les conditions,
   dans le gris secondaire — elle informe, elle ne demande rien. */
.pj-optin-notice {
    margin: 8px 0 0;
    font-size: var(--pj-fs-sm);
    line-height: 1.5;
    color: var(--pj-muted);
}

/* Les réponses de l'assistant de première connexion (E43) : des cibles, pas
   des liens. Empilées sous 768px, côte à côte au-dessus.

   Pas de `min-height` ici : le thème en pose déjà un à 44px, le seuil que
   le projet s'est donné (E10), et cette feuille chargeant AVANT le thème
   une règle de spécificité égale y perdrait. Mesuré à 44px sur l'écran. */
.onb-choices {
    display: grid;
    gap: 12px;
    margin-top: 16px;
}

/* The objective question and the three journey cards under it (2026-09-29):
   one gap, no margins, the cards' own layout decided by `dash-lanes`. */
.onb-goal { display: grid; gap: 16px; }
.onb-goal > h2 { margin: 0; }

.onb-choices .btn {
    width: 100%;
    text-align: left;
}

/* La carte « prochaine etape » du tableau de bord (E43, lot 3).

   Aucune marge : la carte est un enfant direct de la pile de la page, et
   l'espacement vient entierement du `gap` du conteneur (CLAUDE.md §9). Le
   bouton est un `<a>`, donc il est ecrit `.btn.btn-primary` en deux classes —
   `.pj-app a { color: inherit }` est a (0,1,1) et battrait une classe seule.
   Il ne prend que sa largeur : la regle `button, .btn` de cette feuille met
   tout bouton a 100 % dans la coque connectee. */
.dash-next__text {
    margin: 8px 0 0;
    font-size: var(--pj-fs-lg);
    color: var(--pj-ink);
}

.dash-next__gauge {
    margin-top: 12px;
    height: 8px;
    border-radius: 999px;
    background: var(--pj-line);
    overflow: hidden;
}

.dash-next__bar {
    display: block;
    height: 100%;
    border-radius: 999px;
    background: var(--pj-orange-fill);
}

/* La jauge et son pourcentage sur une ligne (maquette du 2026-09-27). La
   marge passe du rail au conteneur, qui porte desormais les deux. */
.dash-next__progress {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
}

.dash-next__progress .dash-next__gauge {
    flex: 1;
    min-width: 0;
    margin-top: 0;
}

.dash-next__pct {
    flex: none;
    min-width: 3ch;
    text-align: right;
    font-weight: 700;
    font-size: var(--pj-fs-body);
    color: var(--pj-ink);
}

.dash-next__cta {
    width: auto;
    justify-self: start;
    margin-top: 16px;
    /* Le seuil de zone tactile que le projet s'est donne (E10) : mesure, pas
       confiance dans le nom de la classe. */
    min-height: 44px;
    display: inline-flex;
    align-items: center;
}

/* La miniature du certificat d un cursus (2026-09-26).

   `ac-vignette` et non `ac-cert` : ce dernier est pris plus bas par la liste
   des certificats DETENUS de l accueil de l Academie. Les deux regles
   s appliquaient ensemble, et la mienne ajoutait une marge a chaque ligne de
   cette liste. Un prefixe de module ne garantit pas l unicite d un nom. */

.ac-vignette {
    margin: 12px 0 0;
}

/* Le cadre porte la taille FINALE, et `overflow: hidden` n est pas
   decoratif : un element transforme occupe toujours sa place d origine dans
   le flux, donc sans cette coupe la miniature pousserait 794px de vide sous
   elle. La hauteur vient du JS, qui la calcule sur l echelle courante.

   Un `<button>`, pas un `<div>` : on clique dessus pour agrandir, et un
   bouton est atteignable au clavier sans rien ajouter. D ou aussi
   `width: auto`, la regle `button, .btn` de cette feuille mettant tout bouton
   a 100 % dans la coque connectee — elle ecraserait la largeur calculee. */
.ac-vignette__cadre {
    position: relative;
    overflow: hidden;
    padding: 0;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    /* Pas de fond : l iframe couvre exactement le cadre et peint le sien. Un
       blanc ecrit ici serait un hexa brut (le papier reste blanc dans les deux
       themes, donc aucun jeton ne convient) pour une surface qu on ne voit
       pas. */
    cursor: zoom-in;
    display: block;
}

/* `!important` nulle part : c est la specificite a deux classes qui bat la
   regle `button, .btn` a (0,0,1). */
.ac-vignette .ac-vignette__cadre {
    width: auto;
    min-height: 0;
}

/* `top left` et non le centre par defaut : on veut que le document reduise
   VERS le coin du cadre, sinon il se centre sur son milieu et deborde des
   quatre cotes. */
.ac-vignette__doc {
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: top left;
    border: 0;
    /* Le document est deja inerte (sandbox vide) ; ceci evite en plus qu un
       clic aille a l iframe au lieu du bouton qui l entoure. */
    pointer-events: none;
}

.ac-vignette__note {
    margin-top: 6px;
    font-size: var(--pj-fs-xs);
    color: var(--pj-muted);
}

/* La grille de l editeur de formation (2026-09-26).

   Elle etait ecrite dans le gabarit depuis le debut et n existait dans aucune
   feuille : `display: block`, mesure dans le navigateur. Tous les champs se
   suivaient donc sur une colonne interminable, ce qui est une bonne part du
   desordre signale.

   Une seule colonne jusqu a 768px — la regle mobile-first du projet, ou deux
   champs cote a cote sur un telephone n en laissent lire aucun. */
.jo-editor__grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px 16px;
}

@media (min-width: 768px) {
    .jo-editor__grid {
        /* `minmax(0, 1fr)` et non `1fr` : une colonne de grille prend sinon sa
           largeur de contenu minimale, et un champ au contenu long elargit la
           page au lieu de se borner. */
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Un champ peut demander toute la ligne — une description, un editeur
       riche — sans quitter la grille. */
    .jo-editor__grid > .form-group--large {
        grid-column: 1 / -1;
    }
}

/* Les sessions d une formation (2026-09-26).

   Elles n avaient aucune regle : les classes vivaient dans le JS et nulle
   part ailleurs. */

.tf-sessions {
    display: grid;
    gap: 10px;
    margin-bottom: 20px;
}

/* `--pj-bg` et non `--pj-card` : une carte blanche bordee de `--pj-line` sur
   un panneau blanc ne se detache de rien. Mesure faite — la bordure etait
   bien appliquee, elle ne se voyait pas. `--pj-bg` est le jeton de « ce qui
   n est pas une carte », et il suit le theme sombre tout seul. */
.tf-session {
    padding: 12px 14px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-bg);
}

/* Le titre et le statut sur une ligne, et le statut ne se comprime pas :
   c est le mot qu on cherche en parcourant la liste. */
.tf-session__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.tf-session__titre {
    margin: 0;
    font-size: var(--pj-fs-md);
    font-weight: 700;
    min-width: 0;
}

.tf-session__head .jo-status {
    flex: 0 0 auto;
}

/* Quand d abord, en plus lisible : c est par la date qu on reconnait une
   session. Le reste — lieu, places, formateur — vient en dessous. */
.tf-session__quand {
    margin: 6px 0 0;
    font-size: var(--pj-fs-body);
    font-weight: 600;
}

.tf-session__meta {
    margin: 3px 0 0;
    font-size: var(--pj-fs-sm);
    color: var(--pj-muted);
}

/* `width: auto` : sans cela les trois actions s empilent sur toute la
   largeur, ce qui faisait l essentiel du desordre signale. */
.tf-session__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
}

.tf-session__actions .btn {
    width: auto;
}

/* Le selecteur de transition : aussi haut que les boutons a cote, et borne
   — un `.form-control` prend 100 % sinon, et repousse la suppression a la
   ligne suivante. */
.tf-session__move {
    width: auto;
    max-width: 220px;
    min-height: 44px;
    padding: 4px 10px;
    font-size: var(--pj-fs-sm);
}

/* Les groupes du formulaire. `<fieldset>` arrive avec une bordure et des
   marges d agent utilisateur qu on remplace, pas qu on subit. */
.tf-groupe {
    margin: 0 0 20px;
    padding: 0;
    border: 0;
    border-top: 1px solid var(--pj-line);
    padding-top: 14px;
}

.tf-groupe > legend {
    float: none;
    width: auto;
    margin: 0 0 10px;
    padding: 0;
    font-size: var(--pj-fs-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--pj-muted);
}

/* L ecran des flyers A5 (2026-09-26). */

/* Deux colonnes sur grand ecran, une seule en dessous — et la liste PASSE
   AU-DESSUS de l editeur sur telephone, parce que c est par elle qu on
   choisit ce qu on modifie. `gap` et `display` sont ici obligatoires : la
   boite porte deux `.pj-card`, et `.pj-card` n a aucune marge propre. */
.fl-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    align-items: start;
}

@media (min-width: 992px) {
    .fl-layout {
        /* `minmax(0, 1fr)` et non `1fr` : une colonne de grille prend par
           defaut sa largeur de contenu minimale, et l apercu — qui porte un
           document de 559px — elargirait la page au lieu de se reduire. */
        grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
    }
}

.fl-liste__titre {
    margin: 0 0 12px;
    font-size: var(--pj-fs-md);
    font-weight: 700;
}

/* `minmax(0, 1fr)` ET `min-width: 0` sur les items : les deux, et aucun ne
   suffit seul.

   Une piste de grille `auto` se dimensionne sur son MAX-CONTENT, et un item
   de grille a `min-width: auto` par defaut, c est-a-dire « jamais plus etroit
   que mon contenu ». La liste debordait donc de sa carte : mesure, une ligne
   de 287px dans une colonne de 200px, et le `text-overflow` interieur ne se
   declenchait jamais puisque rien ne manquait de place.

   C est le meme piege que `minmax(0, 1fr)` sur `.fl-layout` quelques regles
   plus haut, pour la meme raison. */
.fl-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
}

.fl-items > li {
    min-width: 0;
}

/* Un `<button>` et non un `<div>` : on clique dessus pour changer de flyer,
   et un bouton est atteignable au clavier sans rien ajouter. Pleine largeur
   est ici ce qu on veut — c est une ligne de liste. */
/* UNE SEULE LIGNE, et le NOM a la priorite sur le genre.
 *
 * Deux reglages ont ete essayes, et le second est le bon :
 *
 * 1. a l origine, `flex` avec `.fl-item__genre` en `flex: 0 0 auto` : le
 *    genre ne se reduisait JAMAIS, « Page composee par l IA » prenait toute
 *    la largeur et le nom sortait a « Prosyg… », coupe a six caracteres,
 *    dans la colonne qui sert justement a CHOISIR ce qu on modifie ;
 *
 * 2. puis le nom et le genre empiles sur deux lignes. Le nom etait enfin
 *    lisible, mais chaque entree gagnait une ligne et la colonne allongeait
 *    la page — refuse par le PO : on prefere couper un nom trop long que
 *    d allonger la liste.
 *
 * D ou ceci : une ligne unique ou les DEUX se coupent, mais ou le nom sert
 * en premier. Le genre est plafonne a 40 % de la largeur et s abrege ;
 * le nom prend tout le reste et ne s abrege que s il le faut vraiment. */
.fl-item {
    display: flex;
    align-items: center;
    gap: 8px;
    /* `width: 100%` sur un BOUTON : sans cela il se dimensionne sur son
       contenu (`max-content`) et deborde de sa carte — mesure : 287px de
       ligne dans une colonne de 200px. Et tant que le bouton n est pas
       contraint, aucun `text-overflow` interieur ne se declenche, puisque
       rien ne manque de place. */
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card);
    text-align: left;
    /* 44px : le plancher tactile du projet, mesure et non suppose. */
    min-height: 44px;
}

.fl-item--actif {
    border-color: var(--pj-orange);
    box-shadow: inset 0 0 0 1px var(--pj-orange);
}

.fl-item__puce {
    flex: 0 0 auto;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 1px solid var(--pj-line);
}

.fl-item__nom {
    /* `1 1 auto` : il prend la place laissee par le genre, et se coupe
       seulement quand il n y en a plus. */
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

/* TOUT LE CORRECTIF TIENT DANS LE `1` DU MILIEU.
 *
 * Le defaut d origine etait `flex: 0 0 auto` : un facteur de retrecissement
 * a ZERO, donc un genre qui ne cede jamais un pixel. « Page composee par
 * l IA » prenait toute la colonne et le nom sortait a « Prosyg… ».
 *
 * `0 1 auto` avec `min-width: 0` le rend compressible, et `max-width` lui
 * pose un plafond ferme : le nom garde au moins 60 % quoi qu il arrive.
 *
 * Essaye avant, et refuse : la meme chose en grille. Une piste `auto` se
 * dimensionne sur son CONTENU, et `max-width` sur l element ne retrecit pas
 * la piste — le nom tombait a 0px et on ne lisait plus que le genre. */
.fl-item__genre {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 40%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--pj-fs-xs);
    color: var(--pj-muted);
}

/* LE GENRE DISPARAIT QUAND LA COLONNE SE RETRECIT, et le seuil est a
   l envers de l habitude parce que cette colonne l est aussi.

   Sur telephone `.fl-layout` tient sur UNE colonne : la carte de la liste
   prend toute la largeur, le nom et le genre y tiennent ensemble. A partir de
   992px la liste passe en colonne laterale de 200px, soit 147px utiles — et
   la mesure est sans appel : a deux, le nom tombe a 45px, c est-a-dire
   « Pros… ». On ne choisit rien dans une liste ou les trois entrees se
   ressemblent.

   Le genre cede donc la place : la pastille de couleur et le NOM sont ce par
   quoi on choisit, et la disposition se lit en toutes lettres dans l editeur
   des qu on ouvre le flyer. */
@media (min-width: 992px) {
    .fl-item__genre {
        display: none;
    }
}

.fl-vide,
.fl-quota {
    margin: 10px 0 0;
    font-size: var(--pj-fs-sm);
    color: var(--pj-muted);
}

.fl-quota--plein {
    color: var(--pj-danger);
}

/* Le bloc « offre » de l editeur (2026-09-27).

   Il n apparait que pour la disposition « offre ». Un cadre plutot qu une
   suite de champs : ces cinq-la ne servent qu a cette disposition, et rien
   ne le dirait s ils se melaient aux autres. */
.fl-offre {
  margin: 18px 0;
  padding: 16px 18px 18px;
  border: 1px solid var(--pj-line);
  border-radius: 12px;
  background: var(--pj-bg);
}

.fl-offre > legend {
  padding: 0 8px;
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--pj-muted);
  width: auto;
}

/* Le libelle et le montant vont de pair : les separer sur deux lignes
   ferait lire deux reglages la ou il y en a un. */
@media (min-width: 560px) {
  .fl-offre__prix {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 16px;
    align-items: end;
  }
}

.fl-offre__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

/* `width: auto` est obligatoire : la regle `button, .btn` de cette feuille
   met TOUT bouton a 100 % dans la coque connectee. 44px parce que ceci se
   touche avec un pouce. */
.fl-offre__actions .btn {
  width: auto;
  min-height: 44px;
}

.fl-offre__source {
  margin-top: 10px;
}

.fl-articles__vide {
  margin: 8px 0 0;
  font-size: var(--pj-fs-body);
}

/* ── L ETAPE DE DISPOSITION ────────────────────────────────────────────────

   Une grille de vignettes, chacune portant le VRAI document rendu par le
   serveur avec le brouillon deja saisi. Pas de requete media : ce composant vit
   dans une colonne a cote d une liste, et une requete media regarde la fenetre.
   `auto-fill` avec un minimum de 150px s adapte a la place reelle, ce qu une
   bascule a 640px ne sait pas faire. */
.fl-dispos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
  margin-top: 14px;
}

.fl-dispo {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: var(--color-surface);
  cursor: pointer;
  text-align: left;
}

.fl-dispo:hover,
.fl-dispo:focus-visible {
  border-color: var(--pj-orange);
}

/* La disposition en cours quand on rouvre la galerie depuis l editeur : on
   doit retrouver ou l on en est sans avoir a s en souvenir. */
.fl-dispo[aria-pressed="true"] {
  border-color: var(--pj-orange);
  box-shadow: inset 0 0 0 1px var(--pj-orange);
}

/* Le cadre coupe : la vignette rend le document a sa taille NATURELLE puis le
   reduit par transform, et ce qui depasse ne doit pas pousser la grille. */
.fl-dispo__cadre {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  border-radius: 4px;
  background: var(--surface-sunken);
}

.fl-dispo__cadre > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.fl-dispo__cadre > iframe {
  position: absolute;
  top: 0;
  left: 0;
  border: 0;
  transform-origin: top left;
  pointer-events: none;
}

/* La mention des vignettes qui se ressemblent. Discrete : elle explique, elle
   n avertit pas — rien n est casse, et la ressemblance disparait des qu une
   image est choisie. */
.fl-dispo__note {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  line-height: 1.3;
}

.fl-dispo__nom {
  font-size: var(--pj-fs-body);
  font-weight: 600;
  color: var(--pj-ink);
}

/* La disposition en cours, dans l editeur : son nom, et le bouton qui rouvre
   la galerie. */
.fl-dispo-courante {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.fl-dispo-courante__nom {
  font-weight: 600;
}

/* UN APERCU QUI A ECHOUE le dit, au lieu de garder le rendu precedent.

   Discret : c est un cadre vide avec une phrase, pas une alerte. Un apercu
   manquant pendant qu on tape n en merite pas, mais un apercu qui MENT sur la
   disposition choisie est une panne qu on ne sait pas lire. */
.fl-apercu__panne {
  margin: 0;
  padding: 16px;
  border: 1px dashed var(--color-border);
  border-radius: 6px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  text-align: center;
}

/* CE QUI NE SERA PAS IMPRIME, dit sous la liste.

   Un avertissement, pas une aide : ce qu il annonce est une perte, et il
   apparait au moment ou l on peut encore l eviter. D ou le filet lateral
   plutot que la couleur seule — la couleur seule ne se voit pas sur un ecran
   de telephone en plein jour, et c est exactement la ou ce flyer se compose. */
.fl-articles__tenus {
  margin: 8px 0 0;
  padding: 8px 10px;
  border-left: 3px solid var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  line-height: 1.4;
}

/* Une ligne d article : intitule et detail sur toute la largeur, puis le prix
   et le bouton qui la retire sur la derniere ligne.

   AUCUNE requete media, et c est le point. Le premier jet passait a quatre
   colonnes au-dela de 640 px de fenetre ; mesure a l ecran, le formulaire vit
   dans une colonne de ~330 px a cote de l apercu, et l intitule s y retrouvait
   a 72 px. Une requete media regarde la FENETRE ; ce composant vit dans une
   colonne, et les deux n ont rien a voir. Cette disposition-ci est la meme a
   360 px et a 1920, et elle est juste dans les deux cas. */
.fl-article {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 44px;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--pj-line);
}

.fl-article > input:nth-child(1),
.fl-article > input:nth-child(2) {
  grid-column: 1 / -1;
}

.fl-article:last-child {
  border-bottom: 0;
  margin-bottom: 0;
}

.fl-article .btn {
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  justify-self: start;
}

.fl-ajouter {
    margin-top: 12px;
}

/* L editeur : les champs d un cote, l apercu de l autre. Il bascule en une
   colonne plus tot que la page elle-meme, un formulaire a 300px n etant plus
   un formulaire. */
/* UN BLOC SUR TELEPHONE, une grille a partir de 1200px.
 *
 * Ce n etait pas le choix d origine, et la raison est precise : un element
 * `position: sticky` a pour bloc conteneur sa RANGEE de grille. L apercu
 * collant repartait donc au premier defilement — verifie a l ecran, pas
 * deduit. En bloc ordinaire, son conteneur est la colonne entiere et il
 * tient. */
.fl-editeur__grille {
    display: block;
}

.fl-editeur__grille > * + * {
    margin-top: 20px;
}

/* L APERCU PASSE EN TETE SUR TELEPHONE.
 *
 * Il etait le dernier bloc de la page : mesure du 2026-10-07, le bouton
 * d enregistrement a y=2359 et l apercu a y=2450 — on voyait donc le
 * resultat APRES avoir enregistre. Pour un coiffeur ou un peintre, qui
 * n est pas graphiste, c est le seul retour qui compte : il modifie, il
 * regarde, il recommence.
 *
 * IL NE COLLE PAS, ET IL NE PEUT PAS. C etait l intention, et la mesure l a
 * refusee : la coque enveloppe les pages dans un conteneur en
 * `overflow-y: auto` aussi HAUT que son contenu. C est lui le scrollport de
 * tout element de page, il ne defile jamais lui-meme, donc un
 * `position: sticky` y a une course nulle — constate a l ecran, deux fois.
 * Aucun contenu de page ne peut coller dans cette application ; c est
 * d ailleurs pourquoi `.pj-side` utilise `position: fixed`.
 *
 * Le plafond de hauteur devient alors ESSENTIEL plutot que confortable : une
 * A5 a la largeur d un telephone fait ~550px, et sans plafond le premier
 * champ naitrait sous la ligne de flottaison. Il vit dans le JS
 * (`_plafondApercu`), qui calcule l echelle du document — plafonner ici
 * seulement couperait le bas de la page au lieu de la reduire.
 *
 * L apercu est PREMIER dans le balisage plutot que remonte par `order` : un
 * lecteur d ecran rencontre donc « voici votre flyer » avant les champs, ce
 * qui est l ordre qu on veut aussi a la lecture. */
.fl-apercu {
    padding-bottom: 8px;
}

/* Sous la vignette collante, la note explicative n a plus sa place : elle
   doublerait la hauteur de ce qui colle pour dire que l apercu dit vrai. */
.fl-apercu /* L image FINIE d un montage professionnel : ce qu on publie, par opposition
   a l apercu qui montre la feuille A5. Cliquable pour l ouvrir en grand —
   c est ainsi qu on l enregistre sur un telephone. */
.fl-finie {
    display: block;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    overflow: hidden;
}

.fl-finie img {
    display: block;
    width: 100%;
    height: auto;
}

.fl-apercu__note {
    display: none;
}

@media (min-width: 1200px) {
    .fl-editeur__grille {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 220px);
        align-items: start;
        gap: 20px;
    }

    .fl-editeur__grille > * + * {
        margin-top: 0;
    }

    /* L apercu est PREMIER dans le balisage, parce que c est l ordre voulu sur
       telephone — et a la lecture. Ici il reprend sa place a DROITE des
       champs, d ou ces deux `order` : c est le seul endroit ou la colonne
       etroite a de la place pour lui. */
    .fl-champs {
        order: 1;
    }

    .fl-apercu {
        order: 2;
        padding-bottom: 0;
    }

    .fl-apercu .fl-apercu__note {
        display: block;
    }
}

/* 220px pour l apercu et non 320 : la coque connectee plafonne sa colonne
   centrale, donc chaque pixel donne a l apercu est pris au FORMULAIRE. Mesure
   au premier essai : une colonne de champs a 210px, ou l on ne compose pas
   une accroche. L apercu est une vignette, le formulaire est l outil.
   La bascule elle-meme est plus bas, avec le reste des regles a 1200px. */

/* L ASSISTANT DU MONTAGE PROFESSIONNEL (2026-10-07).
 *
 * Trois ecrans courts plutot qu un formulaire long : quatre utilisateurs sur
 * cinq sont sur telephone, et une TUILE est une cible facile au pouce la ou
 * une liste deroulante demande deux gestes et une bonne vue. */
.pfw {
    display: grid;
    gap: 16px;
}

.pfw-entete {
    display: grid;
    gap: 2px;
}

/* « 1 / 3 » : on sait toujours ou on en est, et surtout COMBIEN il reste.
   Un assistant dont on ignore la longueur se quitte au deuxieme ecran. */
.pfw-rang {
    margin: 0;
    font-size: var(--pj-fs-xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--pj-muted);
}

.pfw-titre {
    margin: 0;
    font-size: var(--pj-fs-lg);
}

/* `auto-fit` et `minmax` : deux tuiles par ligne sur un telephone, quatre sur
   un bureau, sans media query et sans nombre magique. */
.pfw-tuiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 10px;
}

.pfw-tuiles--liste {
    grid-template-columns: 1fr;
}

.pfw-tuile {
    display: grid;
    justify-items: center;
    gap: 6px;
    width: 100%;
    /* 88px : deux fois le plancher tactile. Une tuile est une CIBLE, et
       c est le geste principal de l ecran. */
    min-height: 88px;
    padding: 14px 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card);
    text-align: center;
    cursor: pointer;
}

.pfw-tuile:hover,
.pfw-tuile:focus-visible {
    border-color: var(--pj-orange);
}

.pfw-tuile--actif {
    border-color: var(--pj-orange);
    box-shadow: inset 0 0 0 1px var(--pj-orange);
}

.pfw-tuile--large {
    justify-items: start;
    min-height: 56px;
    text-align: left;
}

/* La FORME du format, dessinee a ses vraies proportions : « 1080 x 1920 » ne
   dit rien a un coiffeur, un rectangle haut si. */
.pfw-tuile__forme {
    display: block;
    width: 28px;
    border: 2px solid var(--pj-muted);
    border-radius: 2px;
}

.pfw-tuile__forme--carre {
    height: 28px;
}

.pfw-tuile__forme--portrait {
    height: 35px;
}

.pfw-tuile__forme--vertical {
    height: 50px;
}

.pfw-tuile__forme--a5 {
    height: 40px;
    border-style: dashed;
}

.pfw-tuile__nom {
    font-weight: 600;
    color: var(--pj-ink);
}

.pfw-tuile__aide {
    font-size: var(--pj-fs-xs);
    color: var(--pj-muted);
}

.pfw-recap {
    display: grid;
    gap: 8px;
    margin: 0;
    padding: 12px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-neutral-soft);
}

.pfw-recap div {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
}

.pfw-recap dt {
    min-width: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.pfw-recap dd {
    margin: 0;
    min-width: 0;
    font-weight: 600;
    overflow-wrap: anywhere;
}

/* Le brief est REPLIE : c est une sortie de secours, pas une etape. Ouvert
   d office, il ferait relire un paragraphe technique a quelqu un qui voulait
   une affiche. */
.pfw-brief > summary {
    min-height: 44px;
    padding: 11px 0;
    cursor: pointer;
    font-size: var(--pj-fs-sm);
    color: var(--pj-muted);
}

/* La case du logo : une CIBLE, pas une coche de formulaire. 44px de haut,
   le plancher tactile — c est le seul reglage de cet ecran. */
.pfw-case {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    cursor: pointer;
}

.pfw-case input {
    width: 20px;
    height: 20px;
    flex: 0 0 auto;
}

.pfw-cout {
    margin: 0;
    font-weight: 600;
}

/* Le lien de recharge, dans le message de credits epuises. Souligne et
   colore : c est une issue, et elle doit se voir comme telle au milieu
   d une phrase grise. */
.pfw-recharger {
    color: var(--pj-primary);
    font-weight: 600;
    text-decoration: underline;
}

.pfw-etat {
    margin: 0;
    min-height: 1.2em;
    font-size: var(--pj-fs-sm);
    color: var(--pj-muted);
}

/* Le bouton d avance a DROITE, le retour a gauche : l ordre de lecture, et
   celui du pouce qui avance. La reserve basse est celle de la bulle d aide. */
.pfw-pied {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 76px;
}

.pfw-pied .btn {
    width: auto;
}

@media (min-width: 1200px) {
    .pfw-pied {
        margin-bottom: 0;
    }
}

/* LA FICHE D UNE AFFICHE FINIE, et non un editeur ampute.
 *
 * Une colonne simple, centree sur l image : il n y a ni champ ni bouton
 * d enregistrement, donc rien qui laisse croire qu on retouche une
 * composition dont le texte est dans les pixels. */
.fl-fiche {
    display: grid;
    gap: 12px;
    max-width: 640px;
}

/* DÉCLINER : un bloc à part, séparé par un filet.
 *
 * Il ne se range pas avec « télécharger » et « supprimer » : ceux-là agissent
 * sur l'affiche qu'on regarde, celui-ci en fabrique une autre. Les mêler
 * ferait cliquer « décliner » en croyant exporter. */
.fl-decliner {
    display: grid;
    gap: 8px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
}

.fl-decliner__titre {
    margin: 0;
    font-weight: 600;
    font-size: var(--pj-fs-body);
}

.fl-decliner__ligne {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

/* Le sélecteur prend la place qui reste, le bouton garde la sienne — sur
   téléphone la ligne se replie et chacun passe pleine largeur. */
.fl-decliner__ligne .form-control {
    flex: 1 1 180px;
    min-width: 0;
}

.fl-decliner__recadre {
    margin: 0;
    color: var(--pj-warning-ink);
}

/* UN CHAMP FACULTATIF, qui ne doit pas avoir l air d une corvee.
 *
 * Le libelle au-dessus, l aide en dessous, et rien qui crie : qui n a rien a
 * dire passe devant sans s arreter, et c est le but. Les trois clics sont
 * intacts pour lui. */
.pfw-champ {
    display: block;
    margin-bottom: 16px;
}

.pfw-champ__nom {
    display: block;
    margin-bottom: 6px;
    font-weight: 600;
}

/* LE TELECHARGEMENT EST L ACTION, pas une option parmi trois.
 *
 * « La derniere etape devait etre juste le telechargement du flyer » (PO,
 * 2026-10-07). Pleine largeur et colle sous l image : c est ce que le pouce
 * rencontre juste apres avoir vu le resultat. Les trois autres issues — en
 * refaire une, essayer le manuel, fermer — sont des sorties et non des
 * suites, et elles vivent en dessous a poids egal. */
.pfw-telecharger {
    width: 100%;
    margin-top: 12px;
}

/* `space-between` ecarterait trois boutons aux deux bords en laissant un trou
   au milieu, ce qui donne a celui du centre l air d un intrus. Aucune des
   trois sorties ne prime, donc elles se suivent. */
.pfw-pied--fini {
    justify-content: flex-start;
}

/* LES DEUX BOUTONS DE DEPART, avant la liste.
 *
 * Ils vivaient en bas de la carte, apres le titre, les flyers et le quota :
 * la premiere action possible tombait a y=877 pour un ecran de 883. Ici, ils
 * sont ce que le pouce rencontre en premier. */
.fl-demarrer {
    display: grid;
    gap: 8px;
    margin-bottom: 20px;
}

/* LES COORDONNEES, repliees derriere ce qu elles valent deja.
 *
 * Telephone, e-mail et adresse arrivent pre-remplis depuis la fiche
 * entreprise et seront justes la quasi-totalite du temps. Mesure sur
 * telephone : pres de 600px de defilement pour une confirmation. Le resume
 * montre le numero et la ville — de quoi verifier sans ouvrir, ce qui est la
 * seule raison pour laquelle on irait regarder. */
.fl-coord {
    margin-top: 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-neutral-soft);
}

.fl-coord__resume {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    /* 44px : le plancher tactile du projet. Un `summary` est la cible, et
       une cible de 20px de haut se rate une fois sur trois au pouce. */
    min-height: 44px;
    padding: 11px 12px;
    cursor: pointer;
}

.fl-coord__titre {
    font-weight: 600;
}

.fl-coord__valeurs {
    min-width: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    overflow-wrap: anywhere;
}

/* Le padding est sur les champs et non sur le `details` : ferme, le bloc ne
   doit etre rien de plus que sa ligne de resume. */
.fl-coord__champs {
    padding: 0 12px 12px;
}

/* `margin-top` du premier label annule : il colle deja au resume. */
.fl-coord__champs .form-label:first-child {
    margin-top: 0;
}

.fl-champs .form-label {
    margin-top: 12px;
}

.fl-couleur {
    /* Un selecteur de couleur natif s etire a 100 % comme tout `.form-control`,
       ce qui donne une bande de couleur large comme la page. */
    width: 64px;
    padding: 4px;
}

/* `width: auto` : la regle `button, .btn` de cette feuille met tout bouton a
   100 % dans la coque connectee, et trois boutons empiles au lieu d une
   rangee. */
.fl-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 20px;
    /* La bulle « Aide » est `position: fixed` a 16px du bas et fait 48px de
       haut : sans cette reserve elle recouvre le bouton d enregistrement, qui
       est le dernier element de la colonne. Mesure : elle occupait y=819 a
       y=867 sur un ecran de 883. */
    margin-bottom: 76px;
}

@media (min-width: 1200px) {
    .fl-actions {
        margin-bottom: 20px;
    }
}

.fl-actions .btn {
    width: auto;
}

.fl-apercu__titre {
    margin: 0 0 8px;
    font-size: var(--pj-fs-sm);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--pj-muted);
}

/* `overflow: hidden` n est pas decoratif : un element transforme occupe
   toujours sa place d origine dans le flux, donc sans cette coupe l apercu
   pousserait 794px de vide sous lui. La hauteur vient du JS, qui la calcule
   sur l echelle courante. */
.fl-apercu__cadre {
    position: relative;
    overflow: hidden;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
}

/* `top left` et non le centre par defaut : on veut que le document reduise
   VERS le coin du cadre, sinon il se centre sur son milieu et deborde des
   quatre cotes. */
.fl-apercu__doc {
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: top left;
    border: 0;
    /* Le document est deja inerte (sandbox vide) ; ceci evite en plus qu un
       clic aille a l iframe. */
    pointer-events: none;
}

/* Une note d information, pas une alerte : elle explique que l apercu dit la
   verite, elle n annonce aucune panne. */
.fl-apercu__note {
    margin-top: 8px;
    font-size: var(--pj-fs-xs);
    color: var(--pj-muted);
}

/* Le selecteur de visuel d un flyer (2026-09-26). */

.fl-visuel {
    margin-top: 6px;
}

/* Un `<details>` : la generation IA est un CHEMIN, pas le defaut. Ouvert
   d office il occuperait la moitie du formulaire pour une option que la
   plupart des entreprises n utiliseront pas a chaque flyer. */
.fl-visuel__ia {
    margin-top: 12px;
    padding: 10px 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
}

.fl-visuel__ia > summary {
    cursor: pointer;
    font-weight: 600;
    /* 44px : le plancher tactile du projet. Un `summary` ne l a pas seul. */
    min-height: 44px;
    display: flex;
    align-items: center;
}

/* `width: auto` : la regle `button, .btn` de cette feuille met tout bouton a
   100 % dans la coque connectee. */
/* La case « sans fond » du panneau de generation (2026-09-28).

   Une case et son libelle sur une ligne, cible tactile comprise : elle vit a
   cote d un bouton payant, et une case qu on coche par erreur coute une
   generation. */
/* Le cout de la generation, juste au-dessus du bouton qui la declenche.

   Il porte la couleur de l encre et non celle du texte doux : ce n est pas une
   precision, c est un prix, et il est lu avant une depense. */
.fl-visuel__cout {
  margin: 12px 0 0;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-ink);
}

.fl-visuel__option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  margin-top: 12px;
  cursor: pointer;
}

.fl-visuel__option input {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin: 0;
}

.fl-visuel__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

.fl-visuel__actions .btn {
    width: auto;
}

.fl-compteur {
    text-align: right;
}

/* L ecran de statistiques d un mini-site (2026-09-26). */

/* Les raccourcis de periode. `width: auto` parce que la regle `button, .btn`
   de cette feuille met tout bouton a 100 % dans la coque connectee : sans
   cela les trois s empileraient au lieu de se ranger. */
.wst-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

.wst-presets .wst-preset {
    width: auto;
    min-height: 44px;
}

/* Le raccourci actif.

   On redefinit les VARIABLES que `prosyjob-app.css` lit — `color:
   var(--bs-btn-color)`, `background: var(--bs-btn-bg)` — plutot que de peindre
   par-dessus. Cette feuille chargeant avant l autre, une declaration directe
   perdait a specificite egale : mesure avant correction, les trois raccourcis
   calculaient le meme `rgb(254, 237, 229)` et l actif etait indiscernable. Une
   propriete personnalisee, elle, se resout sur l ELEMENT : aucune bataille de
   cascade, et c est exactement la forme que cette feuille-la emploie pour ses
   propres variantes de boutons.

   Un REMPLISSAGE et non une teinte : une difference de quelques pourcents de
   saturation ne se voit pas, et pas du tout pour qui distingue mal les
   couleurs. `aria-pressed` porte l information pour qui ne voit rien. */
.wst-presets .wst-preset--on {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--pj-orange-fill);
    --bs-btn-border-color: var(--pj-orange-fill);
}

/* Les deux dates et leur bouton sur une rangee qui PASSE A LA LIGNE : a
   360px trois elements cote a cote deborderaient, et `flex-wrap` est ce qui
   evite le debordement horizontal de la page entiere. */
.wst-range {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 12px;
    margin-top: 16px;
}

.wst-range .field {
    margin: 0;
    flex: 1 1 140px;
}

.wst-range__go {
    width: auto;
    min-height: 44px;
}

/* Les quatre chiffres. `auto-fit` plutot qu un nombre de colonnes fixe :
   quatre sur un ecran large, deux sur une tablette, un sur un telephone,
   sans point de rupture a maintenir. */
.wst-figures {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 16px;
    margin-top: 8px;
}

.wst-figure__value {
    font-size: var(--pj-fs-title);
    font-weight: 600;
    line-height: 1.2;
    color: var(--pj-ink);
}

/* La pastille de progression, collee au chiffre qu elle qualifie. La fleche
   double la couleur : une hausse ne doit pas se lire uniquement au vert. */
.wst-delta {
    font-size: var(--pj-fs-sm);
    font-weight: 600;
    white-space: nowrap;
    vertical-align: middle;
}

.wst-delta--up {
    color: var(--pj-success);
}

.wst-delta--down {
    color: var(--pj-danger);
}

.wst-delta--flat {
    color: var(--pj-muted);
}

.wst-compare {
    margin: 12px 0 0;
    font-size: var(--pj-fs-body);
}

/* La phrase de positionnement. Un fond doux plutot qu un simple paragraphe :
   elle ne parle pas du meme objet que ce qui l entoure — les chiffres decrivent
   la periode choisie, celle-ci une position sur trente jours — et rien ne le
   signalerait si elle avait la meme allure. */
.wst-percentile {
    margin: 12px 0 0;
    padding: 10px 12px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-accent-soft);
    color: var(--pj-accent-ink);
    font-size: var(--pj-fs-body);
}

/* Le graphique et son axe. `position: relative` porte les etiquettes, qui
   sont positionnees en POURCENTAGE de la largeur : le SVG s etire en
   `preserveAspectRatio="none"`, donc un decalage en pixels se decalerait
   avec lui alors qu un pourcentage suit. */
.wst-chart {
    position: relative;
    overflow-x: auto;
}

.wst-chart svg {
    display: block;
    width: 100%;
    height: 160px;
}

.wst-bar {
    fill: var(--pj-orange-fill);
}

/* Un jour a zero garde un trait, en gris : une barre absente se confond avec
   « pas de donnee », alors que zero visiteur est une information. */
.wst-bar--zero {
    fill: var(--pj-line);
}

.wst-axis {
    position: relative;
    height: 20px;
    margin-top: 4px;
}

/* `translateX(-50%)` centre l etiquette sous sa barre. */
.wst-tick {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    font-size: var(--pj-fs-xs);
    white-space: nowrap;
    color: var(--pj-muted);
}

/* Sauf aux deux bords, ou il n y a pas de place de ce cote. Mesure : la
   derniere depassait le cadre de 13 px et le faisait defiler (860 px de
   contenu pour 846 visibles), la premiere etait rognee — « 29 juin » se
   lisait « juin ». */
.wst-tick--first {
    transform: none;
}

.wst-tick--last {
    transform: translateX(-100%);
}

/* Le resume garde sur la carte de configuration du site. */
.wbs-stats-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 24px;
}

.wbs-stats-more {
    width: auto;
    min-height: 44px;
    margin-top: 16px;
    display: inline-flex;
    align-items: center;
}

/* Les deux surfaces d'actions du tableau de bord (2026-09-25) : « reprenez ou
   vous en etiez » et « votre prochaine etape ». Jusqu'a trois lignes chacune,
   la ou il y avait une action unique.

   Une `<ul>` sans puces ni retrait : les lignes sont bien une liste pour qui
   l'ecoute, et le marqueur n'apporte rien a qui la voit. */
.dash-actions {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 16px;
}

/* Un filet entre deux rappels, et aucun avant le premier : trois blocs de
   texte colles seraient illisibles, et une bordure en tete redoublerait le
   trait de la carte. */
.dash-actions__item + .dash-actions__item {
    padding-top: 16px;
    border-top: 1px solid var(--pj-line);
}

/* Le bouton et « ignorer » sur une rangee, qui PASSE A LA LIGNE : a 360px un
   libelle traduit en allemand ou en anglais deborde, et `flex-wrap` est ce qui
   evite le debordement horizontal de la page entiere (CLAUDE.md §9). */
.dash-actions__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 16px;
    margin-top: 16px;
}

/* Le bouton de la ligne annule la marge de `.dash-next__cta`, qui la portait
   pour une carte a action unique. Ici c'est la rangee qui espace. */
.dash-actions__row .dash-next__cta {
    margin-top: 0;
}

/* « Ignorer » : volontairement discret — c'est une sortie, pas une invitation —
   mais a la meme zone tactile que le bouton principal. Le seuil de 44px est
   celui que le projet s'est donne (E10), et il vaut AUSSI pour un bouton
   secondaire : une cible qu'on rate est une cible qu'on finit par frapper au
   hasard, ce qui sur un « ignorer » masque ce qu'on voulait garder.

   `width: auto` parce que la regle `button, .btn` de cette feuille met tout
   bouton a 100 % dans la coque connectee — sans cela il chasserait le bouton
   principal hors de sa rangee. */
/* Selecteurs a DEUX classes, et c'est la raison d'etre du parent ici :
   `.btn-link` du theme vendeur est a (0,1,0) comme `.dash-actions__dismiss`,
   et cette feuille charge AVANT le theme — donc a egalite le vendeur gagne
   (CLAUDE.md §9, et c'est voulu). Mesure avant correction : la couleur
   calculee etait `rgb(192, 64, 23)`, l'orange du bouton principal. Un
   « ignorer » aussi voyant que « continuer » se clique par erreur, et il
   masque alors ce qu'on voulait garder. */
.dash-actions__row .dash-actions__dismiss,
.dash-actions__hidden .dash-actions__restore {
    /* Ces deux-la ne portent PAS `.btn` : cette classe traine
       `.btn.btn-link { color: var(--bs-btn-color) }` depuis `prosyjob-app.css`,
       qui charge en dernier et peignait « ignorer » de l'orange du bouton
       principal. Un bouton de sortie aussi voyant que l'action se clique par
       erreur, et masque alors ce qu'on voulait garder.

       La contrepartie est qu'il faut neutraliser le chrome par defaut du
       navigateur — fond gris et bordure, criants sur le theme sombre. */
    background: none;
    border: 0;
    cursor: pointer;
    width: auto;
    min-height: 44px;
    padding: 0 8px;
    display: inline-flex;
    align-items: center;
    font-size: var(--pj-fs-body);
    color: var(--pj-muted);
    text-decoration: underline;
}

.dash-actions__row .dash-actions__dismiss:hover,
.dash-actions__hidden .dash-actions__restore:hover {
    color: var(--pj-ink);
}

/* La porte de sortie du masquage. Hors des deux cartes, donc elle porte son
   propre alignement : ce qui a ete masque peut etre la seule chose que le
   compte avait, auquel cas les deux cartes sont fermees et cette ligne est
   tout ce qui reste. */
.dash-actions__hidden {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    font-size: var(--pj-fs-body);
    color: var(--pj-muted);
}

/* Les trois parcours du tableau de bord (E43) : leurs regles vivent dans
   prosyjob-app.css, a cote des tuiles de profil, avec lesquelles ils partagent
   la container query `dash-lanes` (maquette du 2026-09-27). */

/* L'espace de revenus (E43), servi à `/gagner` — mise en page de la maquette
   du 2026-09-23.

   Deux colonnes quand la page dispose de 880px, une sinon. C'est la largeur
   de la PAGE qui compte, pas celle de l'écran : à 1366px, entre la barre
   latérale et le rail, il reste ~690px, et deux colonnes y coupaient le titre
   mot par mot. D'où une container query plutôt qu'une media query.

   Sur une colonne, les deux `.pj-stack` s'effacent (`display: contents`) et
   leurs cartes se rangent par `order` : le formulaire remonte sous l'aperçu,
   les explications passent dessous. Les replier est une autre question, qui
   ne concerne que le téléphone (`FOLDED` dans CommercialActivatePage.js). */
.co-activate {
    container: co-activate / inline-size;
}

.commercial-activate-grid {
    display: grid;
    gap: 16px;
}

.commercial-activate-grid > .pj-stack {
    display: contents;
}

.co-hero { order: 1; }
.co-preview { order: 2; }
.co-form-card { order: 3; }
.co-benefits { order: 4; }
.co-how { order: 5; }
.co-rewards { order: 6; }

@container co-activate (min-width: 880px) {
    .commercial-activate-grid {
        grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
        align-items: start;
    }

    .commercial-activate-grid > .pj-stack {
        display: grid;
    }
}

/* Le bandeau : le texte à gauche, l'illustration à droite sur toute la
   hauteur, la puce « Commissions » sous le texte. Quand le bandeau est
   étroit, le titre et la puce prennent toute la largeur et l'illustration se
   range à côté de l'introduction : à 360px, partagée avec l'image, la ligne
   ne laissait que ~130px au titre, qui se coupait mot par mot.

   Tout ici se règle sur la largeur du BANDEAU (`cqi` de `.co-hero`), pas sur
   celle de la page : le même bandeau fait 297px sur un téléphone, 705px seul
   sur une tablette et ~500px en demi-colonne à 1920px, où la page n'a que
   900px entre la barre latérale et le rail. */
.co-hero {
    container: co-hero / inline-size;
    overflow: hidden;
}

.co-hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
        "title title"
        "intro art"
        "fact fact";
    gap: 12px 14px;
    align-items: center;
}

.co-hero__text { display: contents; }
.co-hero__title { grid-area: title; }
.co-hero__intro { grid-area: intro; }

@container co-hero (min-width: 600px) {
    .co-hero__inner {
        grid-template-areas:
            "text art"
            "fact art";
        gap: 18px 20px;
    }

    .co-hero__text { display: block; grid-area: text; min-width: 0; }
}

.co-hero__title {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-display);
    font-weight: 800;
    line-height: 1.1;
    letter-spacing: -0.02em;
}

.co-hero__accent {
    display: block;
    color: var(--pj-orange);
}

.co-hero__intro {
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-body);
    line-height: 1.55;
}

@container co-hero (min-width: 600px) {
    .co-hero__intro { margin-top: 10px; }
}

.co-hero__art {
    grid-area: art;
    align-self: end;
    /* La nouvelle illustration (2026-09-23) est presque carrée : plus large
       que l'ancienne, qui était en hauteur, pour garder la même présence. */
    width: clamp(110px, 40cqi, 300px);
    height: auto;
}

.co-hero__fact {
    grid-area: fact;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-orange-soft);
}

.co-hero__fact strong {
    display: block;
    color: var(--pj-orange-text);
    font-weight: 700;
}

/* `> div > span` et non `span` : la pastille de la pièce est un span elle
   aussi, et la règle large lui prenait sa couleur. */
.co-hero__fact > div > span {
    color: var(--pj-ink);
    font-size: var(--pj-fs-body);
    line-height: 1.45;
}

/* La pièce et le cadeau : même pastille dans le bandeau et les récompenses. */
.co-coin,
.co-reward__gift {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    font-size: 1.3rem;
}

.co-coin {
    background: var(--pj-warning-soft);
    color: var(--pj-warning-ink);
}

.co-reward__gift {
    background: color-mix(in srgb, var(--pj-blue) 14%, var(--pj-card));
    color: var(--pj-blue);
}

/* Les sections repliables. Le chevron n'existe que sur téléphone : au-delà,
   tout est ouvert et le script empêche de replier. */
.co-fold__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 44px;
    list-style: none;
    cursor: pointer;
}

.co-fold__summary::-webkit-details-marker { display: none; }

.co-fold__summary h2,
.co-preview h2,
.co-form-card h2 {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-card);
    font-weight: 700;
}

.co-fold__summary::after {
    content: "";
    flex: none;
    width: 10px;
    height: 10px;
    border-right: 2px solid var(--pj-ink);
    border-bottom: 2px solid var(--pj-ink);
    transform: translateY(-3px) rotate(45deg);
    transition: transform .15s ease;
}

.co-fold[open] > .co-fold__summary::after {
    transform: translateY(3px) rotate(-135deg);
}

@media (min-width: 768px) {
    .co-fold__summary { cursor: default; min-height: 0; }
    .co-fold__summary::after { display: none; }
}

/* Comment ça fonctionne : numéro vert, icône sur fond pêche, texte. */
.co-how__steps {
    list-style: none;
    margin: 14px 0 0;
    padding: 0;
    display: grid;
}

.co-how__steps li {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr);
    align-items: center;
    gap: 14px;
    padding: 12px 0;
    border-bottom: 1px solid var(--pj-line);
}

.co-how__steps li:last-child { border-bottom: 0; padding-bottom: 0; }

.co-how__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--pj-success-fill);
    color: var(--pj-card);
    font-size: var(--pj-fs-sm);
    font-weight: 700;
}

.co-how__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-orange-soft);
    color: var(--pj-orange);
    font-size: 1.25rem;
}

.co-how__steps strong {
    display: block;
    color: var(--pj-ink);
}

.co-how__steps div span {
    color: var(--pj-muted);
    font-size: var(--pj-fs-body);
}

/* Les deux récompenses : pêche pour l'argent, bleu pour les Miles. */
.co-rewards__grid {
    display: grid;
    gap: 14px;
    margin-top: 14px;
}

@media (min-width: 768px) {
    .co-rewards__grid { grid-template-columns: 1fr 1fr; }
}

.co-reward {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px;
    border-radius: var(--pj-radius-sm);
}

.co-reward--cash { background: var(--pj-orange-soft); }
.co-reward--miles { background: color-mix(in srgb, var(--pj-blue) 8%, var(--pj-card)); }

.co-reward h3 {
    margin: 0 0 6px;
    font-size: var(--pj-fs-md);
}

.co-reward--cash h3 { color: var(--pj-orange-text); }
.co-reward--miles h3 { color: var(--pj-blue); }

.co-reward p {
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-body);
    line-height: 1.55;
}

/* Information due, pas mention légale : contraste du texte courant. */
.co-rewards__warning {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 14px 0 0;
    padding: 8px 14px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
    color: var(--pj-ink);
    font-weight: 600;
    font-size: var(--pj-fs-body);
}

.co-rewards__warning i { color: var(--pj-warning-ink); }

/* Ce que vous obtenez : cases cochées vertes. */
.co-benefits ul {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    display: grid;
    gap: 10px;
    color: var(--pj-ink);
}

.co-benefits li {
    display: flex;
    align-items: center;
    gap: 12px;
}

.co-benefits li i {
    color: var(--pj-success);
    font-size: 1.15rem;
}

/* L'aperçu : la future carte, pré-remplie avec le compte. */
.co-preview__card {
    margin-top: 12px;
    padding: 16px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-orange-soft);
}

.co-preview__who {
    display: flex;
    align-items: center;
    gap: 16px;
}

.co-preview__avatar {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--pj-card-2);
    color: var(--pj-ink);
    font-weight: 700;
    font-size: 1.1rem;
}

.co-preview__id {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.co-preview__id strong {
    color: var(--pj-ink);
    font-size: var(--pj-fs-lg);
    overflow-wrap: anywhere;
}

.co-preview__role,
.co-preview__line {
    color: var(--pj-muted);
    font-size: var(--pj-fs-body);
    overflow-wrap: anywhere;
}

.co-preview__unset { color: var(--pj-orange-text); }

.co-preview__counters {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: 16px;
    text-align: center;
    font-size: var(--pj-fs-sm);
    color: var(--pj-muted);
}

.co-preview__counters span + span { border-left: 1px solid var(--pj-line); }

.co-preview__counters b {
    display: block;
    color: var(--pj-ink);
    font-size: var(--pj-fs-lg);
}

.co-preview__after {
    margin: 12px 0 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

/* Le formulaire : deux boutons pleine largeur, l'un sous l'autre. */
.co-form-card__intro {
    margin: 6px 0 14px;
    color: var(--pj-muted);
}

.co-form-card__actions {
    display: grid;
    gap: 10px;
    margin-top: 8px;
}

.co-form-card__actions .btn {
    width: 100%;
    min-height: 44px;
}

@media (min-width: 768px) {
    .onb-choices {
        grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    }
}

/* Le choix des bases importées, sur l'étape budget. */
.ads-lists {
    display: grid;
    gap: 8px;
    margin-bottom: 16px;
}

.ads-list-pick {
    align-items: center;
    display: flex;
    gap: 10px;
    margin: 0;
}

.ads-list-pick small {
    color: var(--pj-muted);
    display: block;
    font-size: var(--pj-fs-xs);
}

/* Le calendrier d'envoi (E24-05). Juste au-dessus du compteur, parce que
   « a combien de personnes » et « livre quand » se lisent ensemble. */
.ads-schedule {
    margin-bottom: 16px;
}

.ads-schedule:empty {
    display: none;
}

/* Le compteur en cours de recalcul. Sous le plancher, chaque réponse est la
   même phrase — sans ce signal, resserrer puis élargir un filtre donne un
   écran identique et se lit comme un compteur en panne. */
.ads-reach.is-loading {
    opacity: .45;
    transition: opacity 120ms ease-out;
}


/* ------------------------------------------------------------------ *
 * M22/E23-10 — l'emailing : ce qu'on ecrit, et a qui on l'envoie
 *
 * Deux blocs qui repondent a la meme question — « est-ce que ce que je
 * vois est ce qui partira ? ». L'apercu montre le message, le choix des
 * sources montre l'audience, et les deux sont mobile-first : la colonne
 * unique est la mise en page normale, pas un repli.
 * ------------------------------------------------------------------ */

/* L'apercu du HTML. Fond blanc en dur — c'est une boite mail, pas notre
   page : la peindre avec --pj-card montrerait a l'annonceur un message
   qui n'existe nulle part, et en theme sombre un texte noir sur noir.
   C'est la seule exception assumee a la regle « jamais de hex brut ». */
.ads-preview {
    margin-bottom: 16px;
}

.ads-preview__frame {
    background: #fff;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: block;
    /* Le cadre ne peut pas se mesurer lui-même : il ne fait tourner aucun
       script (c'est tout l'interet du sandbox), donc rien ne peut lui
       rendre sa hauteur de contenu. Il defile. */
    height: 420px;
    width: 100%;
}

.ads-email-tools {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
}

/* Ce que le nettoyage a retire du HTML colle. Informatif, pas une erreur :
   l'annonceur n'a rien fait de mal en collant un document entier. */
.ads-html-notice {
    background: var(--pj-card-2);
    border-left: 3px solid var(--pj-orange-fill);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    margin-bottom: 16px;
    padding: 10px 12px;
}

.ads-html-notice p {
    margin: 0;
}

.ads-html-notice p + p {
    margin-top: 6px;
}

.ads-email-tools .btn {
    width: auto;
}

/* Les images du message. La liste est le seul endroit ou l'annonceur peut
   voir ce que le destinataire ne verra pas. */
.ads-images {
    margin-bottom: 16px;
}

.ads-images__list {
    display: grid;
    gap: 8px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.ads-image {
    align-items: center;
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-sm);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 12px;
}

.ads-image code {
    color: var(--pj-ink);
    flex: 1 1 200px;
    font-size: var(--pj-fs-xs);
    /* Une URL n'a pas d'espaces : sans ceci elle deborde la carte. */
    overflow-wrap: anywhere;
}

.ads-image small {
    color: var(--pj-muted);
}

.ads-image .btn {
    width: auto;
}

.ads-image__state {
    color: var(--pj-orange-text);
    font-size: var(--pj-fs-xs);
}

.ads-image.is-ok {
    background: var(--pj-orange-soft);
}

/* Le choix des sources. Trois cartes cliquables plutot que trois boutons
   radio : chacune porte une phrase qui dit ce qu'elle englobe, et c'est
   cette phrase qui fait le choix — « ma base » et « les deux » ne se
   distinguent pas par leur titre. */
.ads-source {
    display: grid;
    gap: 8px;
    grid-template-columns: 1fr;
    margin-bottom: 16px;
}

.ads-source__choice {
    background: var(--pj-card);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-ink);
    cursor: pointer;
    display: grid;
    gap: 4px;
    justify-items: start;
    /* Cible tactile mesuree, pas devinee. */
    min-height: 44px;
    padding: 12px 14px;
    text-align: left;
    width: 100%;
}

.ads-source__choice small {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}

.ads-source__choice.is-picked {
    background: var(--pj-orange-soft);
    border-color: var(--pj-orange-fill);
    color: var(--pj-orange-text);
}

.ads-source__choice.is-picked small {
    color: var(--pj-orange-text);
}

/* L'import sur place. Replie par defaut : la plupart des annonceurs ont
   deja leur base, et le formulaire complet pousserait le compteur — la
   raison d'etre de l'ecran — sous la ligne de flottaison. */
.ads-list-actions {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin: 8px 0 0;
}

.ads-list-actions .btn {
    width: auto;
}

.ads-import {
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-sm);
    display: grid;
    gap: 12px;
    margin-top: 12px;
    padding: 14px 16px;
}

.ads-import .btn {
    justify-self: start;
    width: auto;
}

/* The row is a `.pj-consent` (prosyjob-app.css §2bis); only its size is local. */
.ads-consent {
    font-size: var(--pj-fs-sm);
}

@media (min-width: 768px) {
    .ads-source {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* ============================================================================
   E32 — le barème des Miles (.ma-)
   ----------------------------------------------------------------------------
   One admin screen, and the whole design problem is that it must show three
   different kinds of nothing: an activity nobody priced, one inheriting the
   platform amount, and one deliberately switched off. Colour alone cannot say
   that — the state is written in words on every card, and the accent bar is
   only a second signal.

   Cards rather than a table because this console is read on a phone as often
   as on a desktop, and five columns there is a horizontal scrollbar. The grid
   collapses to one column below 768px without anything else changing.

   No raw hex: every colour is a --pj-* token, which is what keeps dark mode an
   override block rather than a second pass over this file.
   ========================================================================== */

.ma-intro {
    margin-bottom: 16px;
}

.ma-filters {
    margin-bottom: 16px;
}

.ma-notice {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    margin: 0;
}

.ma-notice--rule {
    background: var(--pj-orange-soft);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-orange-text);
    margin-bottom: 16px;
    padding: 8px 12px;
}

.ma-notice--muted {
    font-style: italic;
}

/* The list. `gap` is the only spacing mechanism here — no margins on the
   cards — so a row never accumulates two rhythms. */
.ma-list {
    display: grid;
    gap: 16px;
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .ma-list {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1200px) {
    .ma-list {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.ma-card {
    background: var(--pj-card);
    border: 1px solid var(--pj-line);
    border-left: 3px solid var(--pj-line);
    border-radius: var(--pj-radius);
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 16px;
}

/* Priced here, and paying. */
.ma-card--active {
    border-left-color: var(--pj-blue);
}

/* Paying, but the number belongs to the platform line. */
.ma-card--inherited {
    border-left-color: var(--pj-muted);
}

/* Nobody has priced this. The loudest of the four on purpose: it is the hole
   the whole barème exists to make visible. */
.ma-card--unpriced {
    border-left-color: var(--pj-orange);
}

/* Priced, and deliberately switched off. Quiet rather than loud — nothing is
   paid here either, but somebody decided that, and drawing it like a hole
   would keep asking them to fix it. */
.ma-card--off {
    border-left-color: var(--pj-line);
    opacity: 0.75;
}

.ma-card__head {
    align-items: flex-start;
    display: flex;
    gap: 8px;
    justify-content: space-between;
}

.ma-card__title {
    font-size: var(--pj-fs-md);
    font-weight: 600;
    margin: 0;
}

.ma-card__state {
    border-radius: var(--pj-radius-pill);
    flex: 0 0 auto;
    font-size: var(--pj-fs-2xs);
    padding: 2px 8px;
    white-space: nowrap;
}

.ma-card__state--active {
    background: var(--pj-orange-soft);
    color: var(--pj-orange-text);
}

.ma-card__state--inherited,
.ma-card__state--unpriced,
.ma-card__state--off {
    background: var(--pj-card-2);
    color: var(--pj-muted);
}

.ma-card__code {
    color: var(--pj-muted);
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: var(--pj-fs-xs);
    margin: 0;
}

.ma-card__facts {
    display: grid;
    gap: 8px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin: 0;
}

.ma-card__facts dt {
    color: var(--pj-muted);
    font-size: var(--pj-fs-2xs);
    font-weight: 400;
    margin: 0;
}

.ma-card__facts dd {
    font-size: var(--pj-fs-sm);
    margin: 0;
    overflow-wrap: anywhere;
}

.ma-card__miles {
    font-size: var(--pj-fs-lg);
    font-weight: 700;
}

.ma-card__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
}

.ma-card__tag {
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-pill);
    color: var(--pj-muted);
    font-size: var(--pj-fs-2xs);
    padding: 2px 8px;
}

.ma-card__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: auto;
}

/* Every bare button in this app is width:100% (prosyjob-components.css, near
   the top), and .layout-admin only neutralises the block — a row of buttons
   still has to claim its own width. Tap target ≥ 44px, measured rather than
   assumed. */
.ma-btn {
    min-height: 44px;
    width: auto;
}

.ma-empty {
    color: var(--pj-muted);
    margin: 0;
    padding: 16px 0;
    text-align: center;
}

.ma-modal-sub {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    margin: 0 0 8px;
}

.ma-check {
    margin-top: 8px;
}

/* The RG025 trail. Historising is only worth something if somebody can read
   it, so the versions are a list and not a paragraph. */
.ma-history {
    display: grid;
    gap: 8px;
}

.ma-version {
    align-items: baseline;
    border-bottom: 1px solid var(--pj-line);
    display: grid;
    gap: 4px 8px;
    grid-template-columns: auto 1fr;
    padding-bottom: 8px;
}

@media (min-width: 576px) {
    .ma-version {
        grid-template-columns: auto 1fr auto auto;
    }
}

.ma-version--off {
    color: var(--pj-muted);
}

.ma-version__miles {
    font-weight: 700;
}

.ma-version__date,
.ma-version__state {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
}
/* =====================================================================
   E34 — Responsabilité géographique (.gr-)
   =====================================================================

   Un seul geste appuyé sur tout le module : la ligne de non-retour du
   parcours de candidature. Le cahier répète trois fois que les frais
   d'examen ne sont jamais remboursés — « y compris en cas de refus,
   d'abandon de la procédure ou d'annulation après paiement » — et c'est
   la seule chose qu'un candidat doit comprendre avant de cliquer. Tout
   le reste du module est délibérément silencieux pour que cette ligne
   se voie.

   Aucun hex : la palette est celle des jetons --pj-*. Mobile d'abord,
   les grilles ne s'élargissent qu'à 768 px. */

.gr-card__title {
    font-size: var(--pj-fs-lg);
    font-weight: 700;
    color: var(--pj-navy);
    margin: 0 0 12px;
}

/* ---- La jauge de miles cumulés ---- */

/* L'en-tête de « Devenir responsable » (2026-09-23, maquette
   « devenir_commercial.png »). Téléphone d'abord : titre, retour,
   explication, illustration, jauge. Quand l'en-tête a la place (700px, sa
   propre largeur et non celle de l'écran), l'illustration passe à droite sur
   toute la hauteur. */
.gr-hero {
    container: gr-hero / inline-size;
}

.gr-hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
        "title"
        "back"
        "intro"
        "art"
        "meter";
    gap: 14px;
}

.gr-hero__title {
    grid-area: title;
    margin: 0;
    color: var(--pj-navy-dark);
    font-size: var(--pj-fs-display);
    font-weight: 800;
    line-height: 1.08;
    letter-spacing: -0.02em;
}

.gr-hero__accent {
    display: block;
    color: var(--pj-orange);
}

a.gr-back {
    grid-area: back;
    justify-self: start;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 0 18px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
    color: var(--pj-ink);
    font-weight: 600;
    text-decoration: none;
}

.gr-hero__intro {
    grid-area: intro;
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-body);
    line-height: 1.6;
}

.gr-hero__art {
    grid-area: art;
    justify-self: center;
    width: min(100%, 340px);
    height: auto;
}

.gr-hero .gr-meter {
    grid-area: meter;
    margin-top: 0;
}

@container gr-hero (min-width: 700px) {
    .gr-hero__inner {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        grid-template-areas:
            "title art"
            "back  art"
            "intro art"
            "meter art";
        grid-template-rows: auto auto auto 1fr;
        column-gap: 32px;
        align-items: start;
    }

    .gr-hero__title {
        font-size: var(--pj-fs-display);
    }

    .gr-hero__art {
        align-self: center;
        width: min(100%, 460px);
    }

    .gr-hero .gr-meter {
        align-self: end;
    }
}

/* Le titre de la maquette est bleu nuit ; en sombre ce bleu serait illisible
   sur la carte, il reprend la couleur du texte. */
:root[data-theme="dark"] .gr-hero__title {
    color: var(--pj-ink);
}

.gr-meter { margin-top: 16px; }

.gr-meter__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.gr-meter__label { font-size: var(--pj-fs-body); color: var(--pj-muted); }

.gr-meter__value {
    font-size: var(--pj-fs-title);
    font-weight: 800;
    color: var(--pj-navy);
    font-variant-numeric: tabular-nums;
}

.gr-meter__track {
    height: 8px;
    margin-top: 8px;
    border-radius: var(--pj-radius-pill);
    background: var(--pj-line);
    overflow: hidden;
}

.gr-meter__fill {
    height: 100%;
    border-radius: var(--pj-radius-pill);
    background: var(--pj-orange-fill);
    transition: width .5s ease;
}

.gr-meter__hint { margin: 8px 0 0; font-size: var(--pj-fs-body); color: var(--pj-muted); }

/* ---- Le choix du barreau ---- */

.gr-levels__grid { display: grid; gap: 12px; }

.gr-level {
    width: 100%;
    display: grid;
    gap: 2px;
    text-align: left;
    padding: 14px 16px;
    min-height: 44px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card);
    cursor: pointer;
}

.gr-level.is-open:hover { border-color: var(--pj-orange); }
.gr-level.is-locked { cursor: not-allowed; opacity: .55; }
.gr-level__name { font-weight: 700; color: var(--pj-ink); }
.gr-level__threshold { font-size: var(--pj-fs-body); color: var(--pj-muted); }
.gr-level__gap { font-size: var(--pj-fs-body); color: var(--pj-orange-text); font-weight: 600; }
.gr-level.is-locked .gr-level__gap { color: var(--pj-muted); }

/* ---- Le parcours, et sa ligne de non-retour ---- */

.gr-steps { list-style: none; margin: 0; padding: 0; }

.gr-step {
    display: grid;
    grid-template-columns: 32px 1fr;
    gap: 12px;
    padding: 14px 0;
    border-top: 1px solid var(--pj-line);
}

.gr-step:first-child { border-top: 0; }

.gr-step__rank {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 1px solid var(--pj-line);
    font-size: var(--pj-fs-sm);
    font-weight: 700;
    color: var(--pj-muted);
    font-variant-numeric: tabular-nums;
}

.gr-step.is-done .gr-step__rank {
    background: var(--pj-navy);
    border-color: var(--pj-navy);
    color: var(--pj-card);
}

.gr-step.is-current .gr-step__rank {
    background: var(--pj-orange-fill);
    border-color: var(--pj-orange-fill);
    color: var(--pj-card);
}

.gr-step__title { margin: 0; font-size: var(--pj-fs-md); font-weight: 700; color: var(--pj-ink); }
.gr-step.is-todo .gr-step__title { color: var(--pj-muted); }
.gr-step__note { margin: 2px 0 0; font-size: var(--pj-fs-body); color: var(--pj-muted); }
.gr-step__btn { width: auto; margin-top: 10px; }

/* La ligne. Le seul endroit du module qui hausse la voix : au-dessus tout
   s'annule sans frais, en dessous plus rien ne revient. Une règle tirée et
   une étiquette en petites capitales — pas une couleur d'alerte, qui
   crierait à chaque affichage sans rien dire de plus. */
.gr-step--commits { border-top: 0; margin-top: 8px; padding-top: 22px; position: relative; }

.gr-step--commits::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    border-top: 2px dashed var(--pj-orange);
}

.gr-step--commits::after {
    content: attr(data-line);
    position: absolute;
    top: -9px;
    left: 0;
    padding-right: 10px;
    background: var(--pj-card);
    font-size: .68rem;
    letter-spacing: .09em;
    text-transform: uppercase;
    font-weight: 700;
    color: var(--pj-orange-text);
}

/* ---- Refus ---- */

.gr-refusal { border-left: 3px solid var(--pj-danger); }
.gr-refusal__reason { margin: 0; color: var(--pj-ink); }
.gr-refusal__todo { margin: 8px 0 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }

/* ---- Ma zone (2026-09-23, maquette « ma_zone.png ») ----
   L'en-tête : le titre, puis le menu de la zone à gauche et la carte du lieu
   tenu à droite quand il a la place (740px, sa propre largeur). Sur
   téléphone : titre, menu, puis le lieu, l'illustration en bandeau au-dessus
   de sa carte. */

/* Le conteneur est la carte, la grille est à l'intérieur : un élément ne
   s'interroge pas lui-même par une container query. */
.gr-zone-hero {
    container: gr-zone-hero / inline-size;
}

.gr-zone-hero__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
        "head"
        "menu"
        "place";
    gap: 18px;
}

.gr-zone-hero__head { grid-area: head; }

.gr-zone-hero__title {
    margin: 0;
    color: var(--pj-navy-dark);
    font-size: var(--pj-fs-display);
    font-weight: 800;
    line-height: 1.1;
}

:root[data-theme="dark"] .gr-zone-hero__title { color: var(--pj-ink); }

.gr-zone-hero__intro {
    margin: 6px 0 0;
    color: var(--pj-navy);
    font-size: var(--pj-fs-body);
}

/* Le menu : une liste de lignes, l'onglet ouvert sur fond pêche. Des
   boutons pleine largeur voulus ici — ce sont des lignes, pas des boutons de
   la gamme `.btn`. */
.gr-zone-menu {
    grid-area: menu;
    display: grid;
    gap: 6px;
    align-content: start;
}

/* Classe doublée : `.pj-app a { color: inherit }` (0,1,1) battait
   `a.gr-zone-menu__item` à égalité de poids, prosyjob.css chargeant après. */
.gr-zone-menu__item.gr-zone-menu__item {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 14px;
    min-height: 52px;
    padding: 6px 14px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card);
    color: var(--pj-ink);
    font: inherit;
    font-weight: 500;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.gr-zone-menu__item.is-active {
    border-color: transparent;
    background: var(--pj-orange-soft);
    color: var(--pj-orange-text);
}

.gr-zone-menu__icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
    color: var(--pj-navy);
}

.gr-zone-menu__item.is-active .gr-zone-menu__icon {
    background: var(--pj-orange-fill);
    color: white;
}

/* Le lieu : l'illustration et la carte qui le nomme. */
.gr-place {
    grid-area: place;
    display: grid;
    border-radius: var(--pj-radius);
    overflow: hidden;
    border: 1px solid var(--pj-line);
}

/* L'illustration est transparente et en paysage (2026-09-23) : elle
   s'affiche entière, jamais recadrée, et se pose sur le fond de la carte. */
.gr-place__art {
    display: block;
    width: 100%;
    height: auto;
    padding: 8px 8px 0;
}

.gr-place__card {
    padding: 14px 16px 16px;
    background: var(--pj-card);
}

.gr-place__label {
    margin: 0;
    color: var(--pj-muted);
    font-size: var(--pj-fs-body);
}

.gr-place__name {
    margin: 2px 0 12px;
    color: var(--pj-navy-dark);
    font-size: var(--pj-fs-display);
    font-weight: 800;
    line-height: 1.15;
}

:root[data-theme="dark"] .gr-place__name { color: var(--pj-ink); }

/* Chaque barreau garde au moins 96px : en dessous, ils passent à la ligne
   plutôt que de couper « Cameroun » en « Came / roun ». */
.gr-place__rungs {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
    row-gap: 8px;
}

.gr-place__rung {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 8px;
    align-items: center;
    padding: 4px 10px;
}

.gr-place__rung + .gr-place__rung { border-left: 1px solid var(--pj-line); }

.gr-place__rung-icon {
    grid-row: span 2;
    font-size: 1.3rem;
}

.gr-place__rung-icon--country { color: var(--pj-orange); }
.gr-place__rung-icon--city { color: var(--pj-danger); }
.gr-place__rung-icon--district { color: var(--pj-orange-dark); }

.gr-place__rung-label { color: var(--pj-ink); font-weight: 700; font-size: var(--pj-fs-body); }
.gr-place__rung-name { color: var(--pj-muted); font-size: var(--pj-fs-body); }

@container gr-zone-hero (min-width: 740px) {
    .gr-zone-hero__inner {
        grid-template-columns: minmax(240px, 0.8fr) minmax(0, 1.2fr);
        grid-template-areas:
            "head  head"
            "menu  place";
        column-gap: 28px;
    }

    /* Sur poste la carte chevauche le bas de l'illustration, décalée à
       droite. Pas par le côté : la colonne ne fait que ~490px à 1920, et une
       carte posée sur la moitié droite cachait la carte du quartier tout en
       n'ayant plus la place d'aligner ses trois barreaux. */
    .gr-place {
        border: 0;
        align-self: center;
        overflow: visible;
    }

    .gr-place__art {
        padding: 0;
    }

    .gr-place__card {
        position: relative;
        justify-self: end;
        width: 88%;
        margin-top: -34px;
        border: 1px solid var(--pj-line);
        border-radius: var(--pj-radius);
        box-shadow: var(--pj-shadow);
    }
}

/* ---- Échéance ---- */

.gr-term {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}

.gr-term__icon,
.gr-rights__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: var(--pj-radius-sm);
    font-size: 1.4rem;
}

.gr-term__icon { background: var(--pj-orange-soft); color: var(--pj-orange); }

.gr-term__title {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-lg);
    font-weight: 700;
}

.gr-term__date {
    margin: 4px 0 0;
    font-size: var(--pj-fs-display);
    font-weight: 800;
    color: var(--pj-navy-dark);
    font-variant-numeric: tabular-nums;
}

:root[data-theme="dark"] .gr-term__date { color: var(--pj-ink); }

.gr-term__note { margin: 4px 0 0; font-size: var(--pj-fs-body); color: var(--pj-muted); }
.gr-term.is-soon { border-left: 3px solid var(--pj-orange); }
.gr-term.is-urgent { border-left: 3px solid var(--pj-danger); }
.gr-term.is-urgent .gr-term__note { color: var(--pj-danger); font-weight: 600; }

a.gr-term__renew {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    width: auto;
    min-height: 44px;
    margin-top: 14px;
    padding-left: 18px;
    padding-right: 18px;
}

/* L'illustration du calendrier : fond blanc d'origine, fondu dans la carte
   par `multiply` en clair ; sur téléphone elle disparaît (maquette). */
.gr-term__art {
    display: none;
    width: 240px;
    height: auto;
    mix-blend-mode: multiply;
}

:root[data-theme="dark"] .gr-term__art {
    mix-blend-mode: normal;
    border-radius: var(--pj-radius-sm);
    opacity: .85;
}

@media (min-width: 768px) {
    .gr-term {
        grid-template-columns: auto minmax(0, 1fr) auto;
        align-items: center;
    }

    .gr-term__art { display: block; }
}

/* ---- Vos droits ---- */

.gr-rights__summary {
    display: flex;
    align-items: center;
    gap: 16px;
    list-style: none;
    cursor: pointer;
}

.gr-rights__summary::-webkit-details-marker { display: none; }

.gr-rights__icon.is-ok { background: var(--pj-success-soft); color: var(--pj-success); }
.gr-rights__icon.is-pending { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }

.gr-rights__heading {
    flex: 1 1 auto;
    display: grid;
    gap: 6px;
    justify-items: start;
}

.gr-rights__title {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-lg);
    font-weight: 700;
}

.gr-rights__state {
    margin: 0;
    padding: 2px 10px;
    border-radius: var(--pj-radius-sm);
    font-size: var(--pj-fs-body);
    font-weight: 700;
}

.gr-rights__state.is-ok { background: var(--pj-success-soft); color: var(--pj-success); }
.gr-rights__state.is-pending { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }

/* Le chevron n'existe que sur téléphone, où le bloc se replie. */
.gr-rights__summary::after {
    content: "";
    flex: none;
    width: 10px;
    height: 10px;
    border-right: 2px solid var(--pj-ink);
    border-bottom: 2px solid var(--pj-ink);
    transform: translateY(-3px) rotate(45deg);
}

.gr-rights[open] .gr-rights__summary::after { transform: translateY(3px) rotate(-135deg); }

@media (min-width: 768px) {
    .gr-rights__summary { cursor: default; }
    .gr-rights__summary::after { display: none; }
}

.gr-rights__note { margin: 12px 0 0; font-size: var(--pj-fs-body); color: var(--pj-muted); }

.gr-rights__list {
    margin: 16px 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 8px 24px;
    font-size: var(--pj-fs-body);
    color: var(--pj-ink);
}

@media (min-width: 768px) {
    .gr-rights__list {
        grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
        padding-left: 68px;
    }
}

.gr-rights__list li {
    display: flex;
    align-items: center;
    gap: 10px;
}

.gr-rights__list i { color: var(--pj-success); }

/* ---- L'en-tête d'un onglet, et la progression ---- */

.gr-tab-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 20px;
}

.gr-tab-head__title {
    margin: 0;
    color: var(--pj-ink);
    font-size: var(--pj-fs-card);
    font-weight: 700;
}

.gr-tab-head__intro { margin: 6px 0 0; color: var(--pj-muted); font-size: var(--pj-fs-body); }

.gr-tab-head__btn {
    width: auto;
    min-height: 44px;
}

.gr-progress__levels {
    list-style: none;
    margin: 14px 0 0;
    padding: 0;
    display: grid;
    gap: 10px;
}

.gr-progress__level {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
        "icon name threshold"
        "icon detail threshold";
    column-gap: 12px;
    align-items: center;
    padding: 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
}

.gr-progress__icon { grid-area: icon; color: var(--pj-muted); font-size: 1.2rem; }
.gr-progress__level.is-reached .gr-progress__icon { color: var(--pj-success); }
.gr-progress__name { grid-area: name; color: var(--pj-ink); font-weight: 700; }
.gr-progress__detail { grid-area: detail; color: var(--pj-muted); font-size: var(--pj-fs-body); }
.gr-progress__threshold { grid-area: threshold; color: var(--pj-muted); font-size: var(--pj-fs-body); white-space: nowrap; }

/* ---- Délégations ---- */

.gr-deleg__rule {
    margin: 0 0 12px;
    padding: 10px 12px;
    border-radius: var(--pj-radius-sm);
    background: var(--pj-card-2);
    font-size: var(--pj-fs-body);
    color: var(--pj-muted);
}

.gr-deleg__empty { margin: 0; color: var(--pj-muted); }
.gr-deleg__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }

.gr-deleg__item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
}

.gr-deleg__who { display: grid; gap: 2px; }
.gr-deleg__who span { font-size: var(--pj-fs-sm); color: var(--pj-muted); }
.gr-deleg__btn { width: auto; min-height: 44px; }
/* Le sélecteur de rôle de la ligne en cours de modification. `flex` plutôt
   qu'une largeur fixe : il occupe la place laissée par le nom et les deux
   boutons sur grand écran, et passe à la ligne sous 400px au lieu de les
   comprimer. 44px comme les boutons — c'est une cible tactile. */
.gr-deleg__select { width: auto; min-width: 180px; min-height: 44px; flex: 1 1 180px; }

.gr-invite { display: grid; gap: 12px; }
.gr-invite__hint { margin: 4px 0 0; font-size: var(--pj-fs-sm); color: var(--pj-muted); }
.gr-invite__actions { display: flex; flex-wrap: wrap; gap: 10px; }
.gr-invite__actions .btn { width: auto; min-height: 44px; }

/* ---- File d'audit ---- */

.gr-admin__empty { margin: 0; color: var(--pj-muted); }

.gr-admin__row { display: grid; gap: 10px; }
.gr-admin__who { display: grid; gap: 2px; }
.gr-admin__mail { font-size: var(--pj-fs-sm); color: var(--pj-muted); }
.gr-admin__what { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.gr-admin__level { font-weight: 700; color: var(--pj-navy); }
.gr-admin__place { color: var(--pj-ink); }
.gr-admin__country { font-size: var(--pj-fs-sm); color: var(--pj-muted); }
.gr-admin__miles { display: flex; gap: 8px; align-items: baseline; font-size: var(--pj-fs-body); color: var(--pj-muted); }
.gr-admin__miles strong { color: var(--pj-ink); font-variant-numeric: tabular-nums; }
.gr-admin__reason { margin: 6px 0 0; font-size: var(--pj-fs-body); color: var(--pj-muted); }
.gr-admin__actions { display: flex; flex-wrap: wrap; gap: 8px; }
.gr-admin__btn { width: auto; min-height: 44px; }

.gr-badge {
    display: inline-block;
    padding: 3px 10px;
    border-radius: var(--pj-radius-pill);
    font-size: var(--pj-fs-xs);
    font-weight: 700;
    background: var(--pj-card-2);
    color: var(--pj-muted);
}

.gr-badge--under_audit { background: var(--pj-orange-soft); color: var(--pj-orange-text); }
.gr-badge--approved,
.gr-badge--activated { background: var(--pj-orange-soft); color: var(--pj-blue); }
.gr-badge--refused { background: var(--pj-card-2); color: var(--pj-danger); }

@media (min-width: 768px) {
    .gr-levels__grid { grid-template-columns: repeat(3, 1fr); }
    .gr-admin__row { grid-template-columns: 1.4fr 1.4fr .8fr .9fr auto; align-items: center; }
}

@media (prefers-reduced-motion: reduce) {
    .gr-meter__fill { transition: none; }
}

/* Le choix du périmètre, sous la grille des barreaux. */
.gr-where { margin-top: 16px; display: grid; gap: 12px; }
.gr-where__title { margin: 0; font-size: var(--pj-fs-md); font-weight: 700; color: var(--pj-navy); }
.gr-where__btn { width: auto; min-height: 44px; justify-self: start; }

/* Le prerequis de la candidature : meme traitement que le bouton ci-dessus.
   `.btn` vaut `width: 100%` dans la couche connectee, et la cible tactile se
   mesure (>= 44px) plutot qu-elle ne se suppose. */
/* Le prérequis : le texte et son bouton, l'illustration à droite quand la
   carte a la place — jamais sur téléphone (maquette). */
.gr-prereq {
    display: grid;
    gap: 20px;
    align-items: center;
}

.gr-prereq__text {
    display: grid;
    gap: 12px;
    justify-items: start;
}

.gr-prereq__text p { margin: 0; }

.gr-prereq__btn {
    width: auto;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    gap: 12px;
    padding-left: 22px;
    padding-right: 22px;
}

.gr-prereq__art {
    display: none;
    width: 190px;
    height: auto;
}

@media (min-width: 768px) {
    .gr-prereq {
        grid-template-columns: minmax(0, 1fr) auto;
    }

    .gr-prereq__art {
        display: block;
    }
}
.gr-level.is-picked { border-color: var(--pj-orange); box-shadow: var(--pj-shadow-sm); }
/* ── « Suivi du terrain » (Ma zone, maquette « suivi_terrain.png », 2026-09-24)
   Un en-tête avec deux compteurs, puis un tableau par volet. Téléphone
   d'abord : les compteurs côte à côte, les volets repliables, les entreprises
   en cartes (numéro, nom, lieu, contact, badge) et cinq lignes avant « Voir
   les N entreprises ». Dès 768px : de vrais tableaux, les volets figés
   ouverts. */

.gr-ops-head__title {
  margin: 0;
  color: var(--pj-navy-dark);
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.1;
}

:root[data-theme="dark"] .gr-ops-head__title { color: var(--pj-ink); }

.gr-ops-head__intro {
  margin: 6px 0 0;
  color: var(--pj-navy);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.gr-ops-tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 16px;
}

.gr-ops-tile {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  min-width: 0;
  padding: 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.gr-ops-tile__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--pj-radius-sm);
  font-size: 1.2rem;
}

.gr-ops-tile__icon--info { background: var(--pj-info-soft); color: var(--pj-blue); }
.gr-ops-tile__icon--success { background: var(--pj-success-soft); color: var(--pj-success); }

.gr-ops-tile__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.gr-ops-tile__label { color: var(--pj-ink); font-size: var(--pj-fs-sm); font-weight: 700; }
.gr-ops-tile__value { color: var(--pj-navy-dark); font-size: var(--pj-fs-card); font-weight: 800; line-height: 1.1; }
:root[data-theme="dark"] .gr-ops-tile__value { color: var(--pj-ink); }
.gr-ops-tile__note { color: var(--pj-muted); font-size: var(--pj-fs-xs); line-height: 1.35; }

/* Un volet : un `<details>` ouvert, dont le titre ne replie rien sur poste
   (OperationsPanel l'empêche, et le chevron n'y est pas dessiné). */
.gr-ops-sec__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  list-style: none;
  cursor: pointer;
}

.gr-ops-sec__summary::-webkit-details-marker { display: none; }

.gr-ops-sec__title {
  margin: 0;
  color: var(--pj-navy-dark);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

:root[data-theme="dark"] .gr-ops-sec__title { color: var(--pj-ink); }

.gr-ops-sec__count { font-weight: 800; }

.gr-ops-sec__chevron {
  color: var(--pj-navy);
  transition: transform .2s ease;
}

.gr-ops-sec:not([open]) .gr-ops-sec__chevron { transform: rotate(180deg); }

.gr-ops-table-wrap {
  margin-top: 12px;
  overflow-x: auto;
}

.gr-ops-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--pj-fs-body);
}

.gr-ops-table thead th {
  padding: 8px 10px;
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  text-align: left;
  white-space: nowrap;
}

.gr-ops-table td,
.gr-ops-table tbody th {
  padding: 9px 10px;
  border-bottom: 1px solid var(--pj-line);
  color: var(--pj-ink);
  font-weight: 400;
  text-align: left;
  vertical-align: middle;
}

.gr-ops-table__num { width: 2.5rem; color: var(--pj-muted); }

.gr-ops-contact {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: var(--pj-ink);
  text-decoration: none;
  line-height: 1.5;
}

.gr-ops-contact i { flex: none; width: 14px; color: var(--pj-navy); }
.gr-ops-contact span { overflow-wrap: anywhere; }

.gr-ops-badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 10px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.gr-ops-badge__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

.gr-ops-badge--ko { background: var(--pj-danger-soft); color: var(--pj-danger); }
.gr-ops-badge--wait { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.gr-ops-badge--ok { background: var(--pj-success-soft); color: var(--pj-success); }

/* « Voir les N entreprises » : une ligne, pas un bouton de la gamme `.btn`. */
.gr-ops-more {
  width: 100%;
  display: none;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  margin-top: 10px;
  padding: 8px 14px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.gr-ops-pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
}

.gr-ops-pager__btn {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

/* Blanc sur `--pj-orange-fill`, comme la gamme de boutons (§5). */
.gr-ops-pager__btn.is-active {
  border-color: transparent;
  background: var(--pj-orange-fill);
  color: white;
}

.gr-ops-pager__btn:disabled { opacity: .45; cursor: default; }
.gr-ops-pager__gap { color: var(--pj-muted); }

@media (max-width: 767px) {
  /* Cinq lignes, puis « Voir les N … » pour le reste de la page. */
  .gr-ops-sec:not(.is-expanded) tr.is-extra { display: none; }
  .gr-ops-sec:not(.is-expanded) .gr-ops-more { display: flex; }

  .gr-ops-table { font-size: var(--pj-fs-sm); }
  .gr-ops-table td,
  .gr-ops-table tbody th { padding: 8px 6px; }

  /* Les entreprises en cartes : n° | nom + lieu + contact | badge. */
  /* Deux tuiles sur 360px : pastille et marges au plus juste, pour que la
     phrase « aucune offre » tienne en trois lignes plutôt que cinq. */
  .gr-ops-tile { gap: 8px; padding: 10px 8px; }
  .gr-ops-tile__icon { width: 32px; height: 32px; font-size: 1rem; }

  .gr-ops-table--entreprises thead { display: none; }

  .gr-ops-table--entreprises tr {
    display: grid;
    grid-template-columns: 2rem minmax(0, 1fr) auto;
    grid-template-areas:
      "num name    badge"
      "num lieu    lieu"
      "num contact contact";
    column-gap: 8px;
    row-gap: 2px;
    padding: 10px 0;
    border-bottom: 1px solid var(--pj-line);
  }

  .gr-ops-table--entreprises td,
  .gr-ops-table--entreprises tbody th { padding: 0; border: 0; }

  .gr-ops-table--entreprises .gr-ops-table__num { grid-area: num; align-self: center; width: auto; }
  .gr-ops-table--entreprises .gr-ops-table__name { grid-area: name; font-weight: 700; }
  .gr-ops-table--entreprises .gr-ops-table__lieu { grid-area: lieu; color: var(--pj-muted); }
  .gr-ops-table--entreprises .gr-ops-table__contact { grid-area: contact; }
  .gr-ops-table--entreprises .gr-ops-table__badge { grid-area: badge; }

  .gr-ops-pager { justify-content: center; }
}

@media (min-width: 768px) {
  .gr-ops-tile { padding: 14px 16px; }
  .gr-ops-tile__icon { width: 56px; height: 56px; font-size: 1.6rem; }
  .gr-ops-tile__label { font-size: var(--pj-fs-md); }
  .gr-ops-tile__value { font-size: var(--pj-fs-title); }
  .gr-ops-tile__note { font-size: var(--pj-fs-body); }
  .gr-ops-sec__chevron { display: none; }
  .gr-ops-sec__summary { cursor: default; }

  /* Le contact tient sur ses deux lignes, sans couper une adresse au milieu :
     c'est le nom, colonne souple, qui passe à la ligne. Trop long pour la
     colonne, le tableau défile dans son cadre plutôt que d'élargir la page. */
  .gr-ops-contact span { overflow-wrap: normal; white-space: nowrap; }
  .gr-ops-table__lieu,
  .gr-ops-table__code_parrainage,
  .gr-ops-table__miles_cumules,
  .gr-ops-table__candidatures { white-space: nowrap; }
}

/* ── « Rentabilité de la zone », une page à onglets (2026-09-23) ─────────
   Maquette « la_rentabilite_de_ma_zone.png », et depuis le 2026-09-24 la
   disposition de « Ma zone » (PO) : l'en-tête porte le titre, la phrase et
   les boutons de l'onglet, puis le menu à gauche et l'illustration à droite ;
   le contenu de l'onglet vient dessous, sur toute la largeur. Téléphone
   d'abord : titre, boutons, menu — l'illustration n'y paraît pas, comme sur
   la maquette. */

/* Le conteneur est la carte, la grille est à l'intérieur : un élément ne
   s'interroge pas lui-même par une container query. */
.zf-hero {
  container: zf-hero / inline-size;
}

.zf-hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "head"
    "menu";
  gap: 18px;
}

.zf-hero__head { grid-area: head; }

.zf-hero__title {
  margin: 0;
  color: var(--pj-navy-dark);
  font-size: var(--pj-fs-display);
  font-weight: 800;
  line-height: 1.1;
}

:root[data-theme="dark"] .zf-hero__title { color: var(--pj-ink); }

.zf-hero__intro {
  margin: 6px 0 0;
  color: var(--pj-navy);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.zf-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}

.zf-hero__btn {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.zf-hero__art {
  display: none;
  grid-area: art;
  width: 100%;
  height: auto;
  align-self: center;
}

/* 740px, la largeur de la carte et non celle de l'écran — le même seuil que
   l'en-tête de « Ma zone », pour que les deux pages basculent ensemble. */
@container zf-hero (min-width: 740px) {
  .zf-hero__inner {
    grid-template-columns: minmax(240px, 0.8fr) minmax(0, 1.2fr);
    grid-template-areas:
      "head  head"
      "menu  art";
    column-gap: 28px;
  }

  .zf-hero__art { display: block; }
}

/* Le menu : une liste de lignes, l'onglet ouvert sur fond pêche — la forme
   de `.gr-zone-menu`. Des boutons pleine largeur voulus ici : ce sont des
   lignes, pas des boutons de la gamme `.btn`. */
.zf-menu {
  grid-area: menu;
  display: grid;
  gap: 6px;
  align-content: start;
}

/* Classe doublée : `.pj-app a { color: inherit }` (0,1,1) battait
   `a.zf-menu__item` à égalité de poids, prosyjob.css chargeant après. */
.zf-menu__item.zf-menu__item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  padding: 6px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font: inherit;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.zf-menu__item.is-active {
  border-color: transparent;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.zf-menu__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-navy);
}

.zf-menu__item.is-active .zf-menu__icon {
  background: var(--pj-orange-fill);
  color: white;
}

/* Les quatre compteurs de la rentabilité sur une ligne, comme la maquette,
   dès que l'onglet en a la place ; deux par ligne sur téléphone. */
.zf-hub .dashboard-stats-grid {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 125px), 1fr));
}

@media (max-width: 559px) {
  .zf-hub .dashboard-stats-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Les sections repliables d'un onglet : ouvertes et figées sur poste,
   repliées sur téléphone (ZoneFinancePage.bindFolds). */
.zf-fold__summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  list-style: none;
  cursor: pointer;
}

.zf-fold__summary::-webkit-details-marker { display: none; }

.zf-fold__summary h2 {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

.zf-fold__summary::after {
  content: "";
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--pj-ink);
  border-bottom: 2px solid var(--pj-ink);
  transform: translateY(-3px) rotate(45deg);
}

.zf-fold[open] > .zf-fold__summary::after { transform: translateY(3px) rotate(-135deg); }
.zf-fold[open] > .zf-fold__summary { margin-bottom: 10px; }

@media (min-width: 768px) {
  .zf-fold__summary { cursor: default; min-height: 0; }
  .zf-fold__summary::after { display: none; }
}

/* ── E35 — la console financière de zone (`.zf-`) ────────────────────────
   Mobile d'abord : une colonne à 360, deux à 768, la grille des formulaires
   à 1200. Aucun hex brut — la palette n'a ni vert ni rouge, ce qui a une
   conséquence assumée plus bas sur les pastilles d'alerte. */

.zf-page {
  display: grid;
  gap: 16px;
}

/* Les filtres : un bandeau de champs qui s'empile au téléphone. */
.zf-filters__row {
  display: grid;
  gap: 12px;
}

.zf-filters__field {
  display: grid;
  gap: 4px;
}

.zf-filters__field label {
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.zf-filters__field--check label {
  align-items: center;
  display: flex;
  font-weight: 500;
  gap: 8px;
  min-height: 44px;
}

.zf-filters__field--check input {
  min-height: 20px;
  min-width: 20px;
}

.zf-filters__note,
.zf-form__hint {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  margin: 8px 0 0;
}

.zf-scope__label {
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.zf-scope__single {
  font-weight: 700;
  margin: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
}

.zf-scope__empty {
  color: var(--pj-muted);
  margin: 0;
}

/* Le formulaire unique d'EF-006. Une seule colonne au téléphone : un champ
   par ligne est ce qui rend une saisie de dix champs supportable au pouce. */
.zf-form__grid {
  display: grid;
  gap: 12px;
}

.zf-form__inline {
  display: grid;
  gap: 8px;
}

.zf-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 16px;
}

/* Tout <button> nu de la coquille connectée est width:100% (CLAUDE.md §9) :
   une rangée de deux doit reprendre sa largeur et de quoi se partager la
   place, sinon elle s'empile à toutes les tailles. */
.zf-form__actions .btn,
.zf-line__actions .btn {
  flex: 0 1 auto;
  min-height: 44px;
  width: auto;
}

/* Un tableau large déborde de sa propre boîte plutôt que d'étirer la mise en
   page (CLAUDE.md §9) : c'est ce conteneur qui défile, jamais le corps. */
.zf-table-scroll {
  overflow-x: auto;
}

.zf-table {
  border-collapse: collapse;
  min-width: 100%;
  width: 100%;
}

.zf-table th,
.zf-table td {
  border-bottom: 1px solid var(--pj-line);
  padding: 10px 8px;
  text-align: left;
}

.zf-table th[scope="row"] {
  font-weight: 600;
}

.zf-table__num {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.zf-table__row--total th,
.zf-table__row--total td {
  border-bottom: 2px solid var(--pj-line);
  font-weight: 700;
}

.zf-num--up {
  color: var(--pj-navy);
}

.zf-num--down {
  color: var(--pj-orange-text);
}

/* Une ligne de charge : le texte à gauche, le montant et les gestes à droite.
   Au téléphone les deux blocs s'empilent, ce qui garde le montant lisible
   plutôt que serré contre le libellé. */
.zf-line {
  display: grid;
  gap: 12px;
}

.zf-line--past {
  opacity: 0.7;
}

.zf-line__body {
  display: grid;
  gap: 4px;
}

.zf-line__title {
  font-size: var(--pj-fs-md);
}

.zf-line__meta,
.zf-line__note {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

/* Le contrôle automatique d'EF-017 (E35-16). Il ne s'affiche que lorsqu'il a
   trouvé quelque chose : un bandeau vert sur chaque ligne apprendrait à ne plus
   regarder l'endroit où l'avertissement apparaîtra. D'où une teinte d'alerte
   plutôt qu'une neutre — et une bordure plutôt qu'un fond plein, la ligne
   restant une charge et non une erreur. */
.zf-check {
  border-left: 3px solid var(--pj-orange-fill);
  color: var(--pj-orange-text);
  margin-top: 4px;
  padding-left: 10px;
}

.zf-check__list {
  list-style: disc;
  margin: 2px 0 0;
  padding-left: 18px;
}

/* Le taux hérité et le champ d'ajustement (EF-006, E33-17). L'inline-flex garde
   le champ et son bouton sur une ligne, et `width: auto` est obligatoire : la
   règle `button, .btn` du haut de cette feuille met tout bouton nu à 100 %. */
.zf-inherited {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.zf-rate-edit {
  align-items: center;
  display: inline-flex;
  gap: 8px;
}

.zf-rate-edit input {
  max-width: 96px;
}

.zf-rate-edit .btn {
  width: auto;
}

.zf-line__side {
  align-items: flex-start;
  display: grid;
  gap: 8px;
}

.zf-line__amount {
  font-size: var(--pj-fs-md);
  font-variant-numeric: tabular-nums;
}

.zf-line__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.zf-badge {
  border-radius: var(--pj-radius-pill);
  display: inline-block;
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  padding: 4px 12px;
  white-space: nowrap;
}

.zf-badge--draft,
.zf-badge--correction {
  background: var(--pj-bg);
  color: var(--pj-muted);
}

.zf-badge--submitted {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.zf-badge--validated {
  background: var(--pj-bg);
  color: var(--pj-navy);
}

.zf-badge--rejected {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-fill);
}

/* Les trois pastilles d'EF-016. La palette n'a ni vert ni rouge, et en
   inventer deux obligerait à les mirer dans prosyjob.css (CLAUDE.md §9) pour
   une nuance que le mot porte déjà : la pastille écrit « Rouge », « Orange »
   ou « Verte ». Ce que la couleur ajoute ici est l'urgence, donc c'est le
   poids qui la porte — plein pour le rouge, teinté pour l'orange, discret
   pour le vert. */
.zf-alert {
  border-radius: var(--pj-radius-pill);
  display: inline-block;
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  margin: 8px 0 0;
  padding: 4px 12px;
}

.zf-alert--rouge {
  background: var(--pj-orange-fill);
  color: var(--pj-card);
}

.zf-alert--orange {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.zf-alert--verte {
  background: var(--pj-bg);
  border: 1px solid var(--pj-line);
  color: var(--pj-navy);
}

/* Les trois etats d'une charge, ramenes sur les six roles (2026-09-08).
   Ils etaient deja sur des tokens, mais sur les mauvais : « valide » etait
   peint en navy et « rejete » avec l'orange de marque, c'est-a-dire la
   couleur de l'action principale. Un rejet ne se signale pas avec la
   couleur du bouton « Publier ». Depuis que --pj-success et --pj-danger
   existent, il y a un vocabulaire pour le dire. */
.zf-btn--validated {
  background: var(--pj-success-fill);
  color: var(--pj-card);
}

.zf-btn--correction {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.zf-btn--rejected {
  background: var(--pj-danger-fill);
  color: var(--pj-card);
}

.zf-goal--missed th,
.zf-goal--missed td {
  color: var(--pj-orange-text);
}

.zf-goal--unknown th,
.zf-goal--unknown td {
  color: var(--pj-muted);
}

.zf-scenario {
  display: grid;
  gap: 12px;
}

/* EF-013 — les trois scenarios nommes. Une colonne a 360px, trois des que la
   place existe : trois cartes cote a cote sur un telephone donneraient trois
   colonnes de chiffres illisibles, et ce sont des montants. */
.zf-presets {
  display: grid;
  gap: 16px;
}

.zf-presets__grid {
  display: grid;
  gap: 12px;
}

.zf-presets__card {
  background: var(--pj-card-2);
  border: 1px solid var(--pj-line);
  border-radius: 12px;
  display: grid;
  gap: 8px;
  padding: 16px;
}

.zf-presets__card h3 {
  font-size: var(--pj-fs-md);
  margin: 0;
}

.zf-presets__card .btn {
  justify-self: start;
  min-height: 44px;
  width: auto;
}

.zf-presets__lever {
  display: grid;
  gap: 4px;
  font-size: var(--pj-fs-body);
}

.zf-presets__figure {
  color: var(--pj-ink);
  font-size: var(--pj-fs-card);
  font-weight: 600;
  margin: 0;
}

.zf-presets__result {
  display: grid;
  gap: 2px;
  margin: 0;
}

.zf-presets__result dt {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-weight: 400;
}

.zf-presets__result dd {
  margin: 0;
}

/* EF-014 — le choix de l'axe. Des boutons et non un select : il y en a trois,
   et lequel est actif doit se voir sans ouvrir quoi que ce soit. Ils s'enroulent
   plutot que de deborder, la barre etant dans la carte des filtres. */
.zf-axes {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.zf-axes .btn {
  min-height: 44px;
  width: auto;
}

.zf-empty {
  color: var(--pj-muted);
  margin: 0;
}

.zf-pager {
  align-items: center;
  display: flex;
  gap: 12px;
  justify-content: center;
}

.zf-pager .btn {
  min-height: 44px;
  width: auto;
}

@media (min-width: 768px) {
  .zf-filters__row {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .zf-presets__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .zf-form__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .zf-form__wide {
    grid-column: 1 / -1;
  }

  .zf-form__inline {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) minmax(0, 1fr);
  }

  .zf-line {
    align-items: start;
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .zf-line__side {
    justify-items: end;
    text-align: right;
  }
}

@media (min-width: 1200px) {
  .zf-form__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* ── SecurityConfirmation : validation en deux temps (Task 12) ──────────── */

/* `/validation` — la carte de confirmation. `.co-empty` (Company) est reprise
   telle quelle pour les états terminaux (lien mort, confirmé, refusé) : c'est
   déjà la carte "état vide" partagée par quatre modules. */

.sc-validation {
  display: grid;
  gap: 16px;
}

.sc-card {
  display: grid;
  gap: 14px;
}

.sc-card__lead {
  margin: 0;
  color: var(--pj-muted);
}

.sc-card__facts {
  margin: 0;
  display: grid;
  gap: 8px;
}

.sc-card__facts div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--pj-line);
}

.sc-card__facts dt {
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.sc-card__facts dd {
  margin: 0;
  font-weight: 600;
  text-align: right;
  overflow-wrap: anywhere;
}

.sc-card__error {
  margin: 0;
  color: var(--color-error);
  font-size: var(--pj-fs-body);
}

.sc-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Every tap target clears 44px — most of this is used on a phone. */
.sc-card__actions .btn {
  min-height: 44px;
}

.sc-card__hint {
  margin: 4px 0 0;
  font-size: var(--pj-fs-body);
}

@media (min-width: 640px) {
  /* Full width on a phone (one decision at a time), side by side once there
     is room — same breakpoint as `.co-invitation__actions`. */
  .sc-card__actions .btn {
    width: auto;
  }
}

/* `/validation/en-attente` — the list of live requests. */

.sc-pending__empty {
  margin: 0;
  color: var(--pj-muted);
}

.sc-pending__list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 10px;
}

.sc-pending__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.sc-pending__who {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.sc-pending__meta {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.sc-pending__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Row actions in a list, not a single page-level call to action: hug their
   label at every width, same choice as `.gr-deleg__btn`. */
.sc-pending__btn {
  width: auto;
  min-height: 44px;
}

/* ============================================================================
   E42 — « Bêta test privé » : the home page when BETA_TEST=Y.

   Ported from the product mock-up (prosyjob-reconstruction/styles.css). Every
   colour goes through a --pj-* token: that rule is what keeps dark mode an
   override block instead of a second pass over the page. The `beta__` prefix is
   mandatory — .content, .btn, .badge, .footer, .brand, .feature and .icon
   already exist further up this sheet and in the vendor theme.

   The page is `chrome = false`, so `.is-chromeless .pj-shell` strips the
   shell's padding and max-width: the frame below is the page's own.
   ========================================================================= */

body.beta-page {
  background: var(--pj-bg);
}

.beta {
  width: min(1180px, 100%);
  margin: 26px auto;
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
  box-shadow: var(--pj-shadow);
  color: var(--pj-ink);
}

.beta__hero {
  position: relative;
  min-height: 620px;
  display: grid;
  grid-template-columns: 56% 44%;
}

.beta__content {
  position: relative;
  z-index: 2;
  padding: 34px 0 24px 48px;
  display: flex;
  flex-direction: column;
}

.beta__topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding-right: 34px;
}

.beta__brand {
  display: inline-flex;
  align-items: center;
  width: fit-content;
}

.beta__brand img {
  display: block;
  width: clamp(180px, 20vw, 280px);
  height: auto;
  object-fit: contain;
}

.beta__tools {
  display: flex;
  align-items: center;
  gap: 10px;
}

.beta__message {
  margin-top: 44px;
}

.beta__badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 20px;
  padding: 7px 15px 7px 12px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-2xs);
  font-weight: 800;
  line-height: 1;
  letter-spacing: 1.1px;
  text-transform: uppercase;
}

.beta__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--pj-orange);
  flex: none;
}

.beta__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  line-height: 1.04;
  letter-spacing: -2.4px;
  font-weight: 800;
}

.beta__title span {
  color: var(--pj-orange);
}

.beta__rule {
  width: 42px;
  height: 3px;
  background: var(--pj-orange);
  margin: 22px 0 20px;
}

.beta__lead {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  line-height: 1.7;
}

.beta__points {
  list-style: none;
  margin: 22px 0 36px;
  padding: 0;
  display: grid;
  gap: 11px;
  max-width: 530px;
}

.beta__points li {
  font-size: var(--pj-fs-body);
  line-height: 1.5;
  color: var(--pj-ink);
}

.beta__features {
  margin-top: auto;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding-right: 18px;
}

.beta__feature {
  padding: 0 24px 0 0;
  min-height: 150px;
}

.beta__feature + .beta__feature {
  border-left: 1px solid var(--pj-line);
  padding-left: 24px;
}

.beta__feature h2 {
  font-size: var(--pj-fs-md);
  margin: 0 0 8px;
  font-weight: 700;
}

.beta__feature p {
  font-size: var(--pj-fs-xs);
  line-height: 1.55;
  color: var(--pj-muted);
  margin: 0;
}

.beta__icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  margin-bottom: 13px;
}

.beta__icon svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* `width: auto` spelled out: the `button, .btn` rule near the top of this sheet
   makes every button 100%, and a link-button inside a grid track would stretch
   with it. `min-height: 44px` because ~90% of the audience is on a thumb, and a
   tap target is something you measure. */
.beta__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  align-self: start;
  justify-self: start;
  width: auto;
  min-height: 44px;
  margin-top: 15px;
  padding: 12px 18px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-fill);
  /* The one literal in this block, and it is deliberate: a label sitting on a
     brand fill does not follow the theme, the fill staying orange in both.
     Same call as `.btn-primary` in prosyjob-app.css. */
  color: #fff;
  text-decoration: none;
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  transition: background .18s ease, transform .18s ease;
}

.beta__btn svg {
  width: 15px;
  height: 15px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.beta__btn:hover {
  background: var(--pj-orange-fill-hover);
  color: #fff;
}

.beta__btn:active {
  transform: translateY(1px);
}

.beta__visual {
  position: relative;
  overflow: hidden;
}

.beta__visual img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* The mock-up faded the photo out over four stops of hard white. Two stops on
   `--pj-card` melt it into the panel just as well and follow the theme, which
   four opaque stops could not do. */
.beta__fade {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--pj-card) 0%, transparent 48%);
}

.beta__footer {
  min-height: 84px;
  border-top: 1px solid var(--pj-line);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 44px;
  gap: 24px;
}

.beta__contact {
  display: flex;
  align-items: center;
  gap: 18px;
  font-size: var(--pj-fs-sm);
}

.beta__contact span {
  font-weight: 700;
}

.beta__contact svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: var(--pj-ink);
  stroke-width: 1.7;
}

.beta__contact a {
  color: var(--pj-ink);
  text-decoration: none;
}

.beta__contact a:hover {
  text-decoration: underline;
}

@media (min-width: 901px) {
  /* Two of the card titles wrap onto two lines: line the paragraphs up. */
  .beta__feature h2 { min-height: 36px; }
}

@media (max-width: 900px) {
  .beta { margin: 14px auto; }
  .beta__hero { grid-template-columns: 1fr; min-height: auto; }
  .beta__content { padding: 28px 28px 24px; }
  .beta__topbar { padding-right: 0; }
  .beta__message { margin-top: 34px; }
  .beta__title { font-size: var(--pj-fs-display); }
  .beta__points { max-width: none; margin-bottom: 0; }
  .beta__features { margin-top: 44px; padding-right: 0; }
  .beta__visual { height: 330px; order: 2; }
  .beta__fade { background: linear-gradient(180deg, var(--pj-card) 0%, transparent 45%); }
}

@media (max-width: 640px) {
  .beta { margin: 0; width: 100%; border: 0; border-radius: 0; box-shadow: none; }
  .beta__content { padding: 24px 20px 20px; }
  .beta__topbar { gap: 12px; }
  .beta__brand img { width: clamp(150px, 40vw, 215px); }
  .beta__message { margin-top: 28px; }
  .beta__badge { font-size: var(--pj-fs-2xs); letter-spacing: .9px; }
  .beta__title { font-size: var(--pj-fs-display); letter-spacing: -1.6px; }
  .beta__lead { font-size: var(--pj-fs-body); }
  .beta__lead br { display: none; }
  .beta__points { margin-top: 18px; gap: 10px; }
  .beta__points li { font-size: var(--pj-fs-sm); }
  .beta__features { grid-template-columns: 1fr; gap: 22px; }
  .beta__feature,
  .beta__feature + .beta__feature {
    padding: 0;
    border-left: 0;
    min-height: auto;
    display: grid;
    grid-template-columns: 48px 1fr;
    column-gap: 14px;
  }
  .beta__feature h2 { align-self: end; min-height: 0; }
  .beta__feature p { grid-column: 2; }
  .beta__icon { grid-row: 1 / 3; margin: 0; }
  .beta__btn { grid-column: 2; margin-top: 12px; }
  .beta__visual { height: 260px; }
  .beta__footer { padding: 22px 20px; align-items: flex-start; flex-direction: column; }
  .beta__contact { flex-wrap: wrap; gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .beta__btn { transition: none; }
}

/* The locked referral code (E42): it came from the invitation link and it
   resolved, so it reads as a fact rather than as a field to fill in. */
#register-form input[readonly] {
  background: var(--pj-card-2);
  cursor: default;
}

/* E42: what taking part in the private beta means, said immediately above the
   box that confirms it — its last sentence is what ticking that box accepts.
   A note and not an alert: nothing has gone wrong, these are simply the terms
   of this particular signup, so it reads as body text with a mark rather than
   as a warning. */
.beta-notice {
  margin: 0 0 16px;
  padding: 14px 16px;
  border-left: 3px solid var(--pj-orange);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  line-height: 1.6;
  text-align: left;
}

/* =====================================================================
   E44 — « Gérer mes miles » : une page, quatre gestes
   =====================================================================
   Le solde, un descriptif, quatre onglets, et le panneau choisi en
   dessous. Tout est en jetons `--pj-*` : c'est ce qui fait du thème
   sombre un bloc de surcharge et non une seconde passe sur ce fichier.

   Mobile d'abord — ~90% de cette audience arrive sur un téléphone : à
   360 px les quatre onglets se rangent en 2×2 et le tableau des
   transactions devient une pile de cartes.
   ===================================================================== */

.gm-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.gm-head__main {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  min-width: 0;
  flex: 1 1 320px;
}

.gm-head__text h1 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.gm-head__text p {
  margin: 0;
  color: var(--pj-muted);
  line-height: 1.5;
}

/* La pastille ronde qui ouvre chaque bloc de la maquette. */
.gm-icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: 1.1rem;
}

.gm-icon--lg {
  width: 56px;
  height: 56px;
  font-size: 1.4rem;
}

.gm-icon--soft {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.gm-icon--muted {
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.gm-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  flex: 1 1 260px;
  padding: 12px 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.gm-note i {
  color: var(--pj-navy);
  margin-top: 2px;
}

.gm-note p {
  margin: 0;
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

/* Le solde et les onglets dans une seule carte : la maquette les lit comme
   une barre. `minmax(0, …)` partout, sinon un solde à sept chiffres élargit
   la colonne au lieu de rester dans sa piste. */
.gm-switch {
  display: grid;
  gap: 14px;
}

.gm-balance {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  min-width: 0;
}

.gm-balance__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  font-size: 1.6rem;
  color: var(--pj-orange-text);
}

.gm-balance__text {
  min-width: 0;
}

.gm-balance__label {
  display: block;
  font-weight: 700;
  color: var(--pj-ink);
}

.gm-balance__value {
  display: block;
  font-size: var(--pj-fs-display);
  line-height: 1.15;
  font-weight: 800;
  color: var(--pj-orange-text);
  overflow-wrap: anywhere;
}

.gm-balance__value small {
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

/* Le nombre d'onglets n'est pas fixe : un pays peut fermer le transfert et
   l'encaissement (E47), et il en reste alors deux, ou trois quand un blocage
   vivant garde le sien ouvert. Une grille en `repeat(2|4, 1fr)` gardait ses
   quatre pistes quoi qu'il arrive — les deux onglets survivants occupaient la
   moitié gauche d'une rangée vide à droite. `auto-fit` effondre les pistes
   sans contenu, donc les colonnes suivent ce qui est réellement affiché, et le
   `minmax` fait le travail des deux points de rupture d'un coup : deux de front
   à 360 px comme avant, quatre dès que la rangée est assez large.
   112 px est mesuré et non deviné — c'est la plus grande valeur qui tient
   encore deux onglets dans les 243 px de la rangée à 360 px. */
.gm-tabs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 10px;
}

/* Échappe au `button, .btn { width: 100% }` du haut de cette feuille — ici
   c'est la grille qui donne la largeur — et tient les 44 px de cible
   tactile du projet, mesurés et non devinés. */
.gm-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: 88px;
  padding: 12px 8px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-weight: 700;
  font-size: var(--pj-fs-body);
  line-height: 1.25;
  text-align: center;
}

.gm-tab i {
  font-size: 1.35rem;
  color: var(--pj-navy);
}

.gm-tab:hover {
  border-color: var(--pj-orange);
}

.gm-tab.is-active {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  box-shadow: inset 0 -3px 0 var(--pj-orange);
}

.gm-tab.is-active i {
  color: var(--pj-orange-text);
}

@media (min-width: 1200px) {
  .gm-switch {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 2fr);
    align-items: stretch;
  }
}

/* ── Mes transactions en miles ─────────────────────────────────────── */

.mh-panel {
  display: grid;
  gap: 16px;
}

.mh-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 14px 16px;
}

.mh-head .gm-icon {
  width: 52px;
  height: 52px;
}

.mh-head__text {
  flex: 1 1 0;
  min-width: 0;
}

.mh-head__text h2 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-navy);
}

.mh-head__text p {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.mh-head__tools {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

.mh-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

.mh-toggle.is-open .mh-toggle__caret {
  transform: rotate(180deg);
}

/* La période : l'icône à gauche, le chevron à droite, le <select> natif
   entre les deux et sans sa propre flèche — sinon deux chevrons. */
.mh-period {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin: 0;
  padding: 0 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
}

.mh-period select {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 42px;
  padding: 0 22px 0 0;
  border: 0;
  background: transparent none;
  box-shadow: none;
  appearance: none;
  color: var(--pj-ink);
  font-weight: 600;
  cursor: pointer;
}

.mh-period__caret {
  position: absolute;
  right: 12px;
  pointer-events: none;
  color: var(--pj-ink);
}

/* Sur téléphone les deux contrôles prennent la largeur, l'un sous l'autre
   (maquette mobile). */
@media (max-width: 767.98px) {
  .mh-head__tools {
    flex: 1 1 100%;
    flex-direction: column;
    align-items: stretch;
  }

  .mh-toggle {
    width: 100%;
    justify-content: center;
    padding-inline: 12px;
    white-space: nowrap;
  }

  .mh-head .gm-icon {
    width: 44px;
    height: 44px;
  }
}

.mh-advanced {
  display: grid;
  gap: 14px;
  padding: 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.mh-field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.mh-field label {
  font-weight: 700;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.mh-input {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
}

.mh-input input {
  border: 0;
  background: transparent;
  box-shadow: none;
}

.mh-range {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  color: var(--pj-muted);
}

.mh-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.mh-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

@media (min-width: 768px) {
  .mh-advanced {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: end;
  }

  .mh-field--wide {
    grid-column: span 2;
  }

  .mh-actions {
    grid-column: span 2;
  }
}

@media (min-width: 1200px) {
  .mh-advanced {
    grid-template-columns: minmax(0, 2fr) repeat(3, minmax(0, 1fr)) auto;
  }

  .mh-field--wide,
  .mh-actions {
    grid-column: auto;
  }
}

/* Les lignes, en deux rendus (maquette `mon_portefeuille_ok.png`).

   Le choix se fait sur la largeur du BLOC, pas de l'écran : à 1366 px avec
   le rail, la colonne centrale mesure 676 px, et sept colonnes n'y tiennent
   qu'en défilant de côté — mesuré, le tableau demandait 880 px. Une requête
   de conteneur choisit, en trois paliers : le tableau complet à partir de
   820 px (à 1920 px d'écran le bloc offre 846 px, sa largeur maximale) ; un
   tableau resserré de 600 à 820 px — sans « Solde après », l'heure sous la
   date, la facture en icône — qui est ce que voit un écran de 1366 px ; et
   les cartes en dessous,
   sur téléphone comme dans une colonne étroite. Le panneau écrit les deux à
   chaque chargement ; seul l'affichage bascule. */
.mh-rows {
  container: mh-rows / inline-size;
  min-width: 0;
  overflow-x: auto; /* filet : une référence très longue ne casse pas la page */
}

.mh-table {
  display: none;
  width: 100%;
  border-collapse: collapse;
  font-size: var(--pj-fs-body);
}

.mh-list {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

@container mh-rows (min-width: 600px) {
  .mh-table {
    display: table;
  }

  .mh-list {
    display: none;
  }
}

/* L'en-tête du tableau : une bande pâle, comme la maquette. */
.mh-table th {
  padding: 12px 8px;
  text-align: left;
  font-weight: 700;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  background: var(--pj-card-2);
  white-space: nowrap;
}

.mh-table th:first-child {
  border-radius: var(--pj-radius-sm) 0 0 var(--pj-radius-sm);
}

.mh-table th:last-child {
  border-radius: 0 var(--pj-radius-sm) var(--pj-radius-sm) 0;
}

.mh-table td {
  padding: 14px 8px;
  border-bottom: 1px solid var(--pj-line);
  color: var(--pj-ink);
  vertical-align: middle;
}

.mh-table tbody tr:last-child td {
  border-bottom: 0;
}

/* La date sur une ligne : « 10 sept. 2026, 00:45 » reparti sur quatre lignes
   fait des rangees deux fois trop hautes, et la colonne ne gagne rien. */
.mh-table td:first-child {
  white-space: nowrap;
}

.mh-table td.mh-desc {
  min-width: 130px;
  max-width: 220px;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.mh-num {
  text-align: right;
  white-space: nowrap;
}

.mh-table .mh-center {
  text-align: center;
}

/* Ces trois-la portent sur la CELLULE, et `.mh-table td` fixe deja une
   couleur : (0,1,1) contre (0,1,0), la cellule gagne quel que soit l ordre
   des feuilles. Mesure en machine — le credit sortait en `--pj-ink` dans les
   deux themes, ce qui ote a la colonne son unique raison d etre. */
.mh-table td.mh-ref {
  font-variant-numeric: tabular-nums;
  color: var(--pj-muted);
  white-space: nowrap;
}

.mh-table td.mh-amount {
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.mh-table td.mh-amount--credit,
.mh-item__amount.mh-amount--credit {
  color: var(--pj-success);
}

.mh-table td.mh-amount--debit,
.mh-item__amount.mh-amount--debit {
  color: var(--pj-danger);
}

/* Le tableau resserré. Le solde reste lisible dans le registre complet et
   n'est pas une information d'action ; c'est la colonne qui cède. Placé
   après les règles de base, qu'il surcharge à spécificité égale. */
.mh-date__time {
  white-space: nowrap;
}

@container mh-rows (max-width: 819.98px) {
  .mh-table .mh-col-balance {
    display: none;
  }

  .mh-table .mh-date__sep {
    display: none;
  }

  .mh-table .mh-date__time {
    display: block;
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
  }

  .mh-table .mh-invoice {
    width: 44px;
    padding: 0;
    justify-content: center;
  }

  .mh-table .mh-invoice__label {
    display: none;
  }

  .mh-table th {
    white-space: normal;
  }

  .mh-table td.mh-desc {
    min-width: 100px;
  }
}

/* Les badges, par famille (décision produit du 2026-10-02) : vert ce qui
   rentre, orange ce qui sort, bleu les corrections ; l'achat en orange plein. */
.mh-badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
}

.mh-badge--reception,
.mh-badge--recompense,
.mh-badge--commission,
.mh-badge--remboursement {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.mh-badge--depense,
.mh-badge--transfert,
.mh-badge--blocage,
.mh-badge--expiration {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.mh-badge--contrepassation,
.mh-badge--ajustement {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.mh-badge--achat {
  background: var(--pj-orange-fill);
  /* Le libellé des boutons orange du §5 : même orange et même blanc dans
     les deux thèmes. */
  color: #fff;
}

.mh-none {
  color: var(--pj-muted);
}

.mh-invoice {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  white-space: nowrap;
}

/* La carte : un bouton entier. Le haut porte la date et le type, puis la
   description, puis la référence ; le montant et le chevron à droite. */
.mh-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 4px 10px;
  width: 100%;
  min-height: 44px;
  padding: 12px 12px 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.mh-item:hover,
.mh-item:focus-visible {
  border-color: var(--pj-orange);
}

.mh-item__main {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.mh-item__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

.mh-item__date {
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  color: var(--pj-ink);
  white-space: nowrap;
}

.mh-item__desc {
  font-size: var(--pj-fs-sm);
  line-height: 1.4;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.mh-item__ref {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.mh-item__amount {
  font-size: var(--pj-fs-sm);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.mh-item__chev {
  color: var(--pj-ink);
}

.mh-empty {
  margin: 0;
  padding: 28px 12px;
  text-align: center;
  color: var(--pj-muted);
}

/* Le pied : « Afficher [10] lignes par page », le décompte, la pagination —
   trois zones sur une ligne quand le bloc est large, centrées et empilées
   sinon. Même bascule que les lignes, sur la même largeur. */
.mh-panel {
  container: mh-panel / inline-size;
}

.mh-foot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding-top: 4px;
  text-align: center;
}

@container mh-panel (min-width: 600px) {
  .mh-foot {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 16px;
    text-align: left;
  }

  .mh-foot .mh-perpage {
    justify-self: start;
  }

  .mh-foot .paginations {
    justify-self: end;
  }
}

.mh-perpage {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.mh-perpage select {
  width: auto;
  min-width: 76px;
  min-height: 44px;
}

.mh-count {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.mh-foot .paginations {
  margin: 0;
}

/* La fenêtre de détail d'une opération (`MilesTransactionSheet`) vit sur
   `document.body`, hors de `.pj-app` : ses règles sont dans prosyjob-app.css,
   à côté de la chrome qu'elle partage avec les autres modales. */

/* ── Acheter des Miles, en onglet (la maquette en deux étapes) ───────── */

.bm-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.bm-head__text {
  flex: 1 1 220px;
  min-width: 0;
}

.bm-head__text h2 {
  margin: 0 0 2px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.bm-head__text p {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

/* Remplace la ligne « solde » d'E16-07 : ici c'est la pastille de droite de
   la maquette, pas une ligne de formulaire. */
.bm-card .bm-balance {
  display: inline-flex;
  align-items: baseline;
  justify-content: flex-end;
  gap: 6px;
  margin: 0;
  padding: 12px 18px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-title);
  font-weight: 800;
  overflow-wrap: anywhere;
}

.bm-step {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.bm-step__n {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-fill);
  color: #fff;
  font-weight: 800;
}

.bm-step__body {
  display: grid;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
}

.bm-step__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.bm-step__hint {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.bm-amount {
  display: grid;
  gap: 12px;
}

.bm-amount__field {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
}

.bm-amount__field input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 52px;
  border: 0;
  background: transparent;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.bm-amount__unit {
  font-weight: 700;
  color: var(--pj-muted);
}

.bm-card .bm-presets {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

.bm-card .bm-preset {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: 100%;
  min-height: 62px;
  padding: 8px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-weight: 700;
}

.bm-card .bm-preset:hover {
  border-color: var(--pj-orange);
}

.bm-card .bm-preset strong {
  font-size: var(--pj-fs-lg);
}

.bm-card .bm-preset small {
  color: var(--pj-muted);
}

.bm-card .bm-preset.is-active {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.bm-card .bm-preset.is-active small {
  color: var(--pj-orange-text);
}

.bm-card .bm-quote {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  padding: 18px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.bm-quote__icon {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.bm-quote__miles {
  display: grid;
  flex: 1 1 auto;
  min-width: 0;
}

.bm-quote__miles strong {
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-orange-text);
  overflow-wrap: anywhere;
}

.bm-quote__miles small {
  color: var(--pj-muted);
}

.bm-card .bm-quote__price {
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-orange-text);
  overflow-wrap: anywhere;
}

.bm-card .bm-form__submit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 56px;
  font-size: var(--pj-fs-md);
}

.bm-card .bm-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  color: var(--pj-muted);
}

/* ── Scanner, en onglet ─────────────────────────────────────────────── */

.sc-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.sc-head h2,
.sc-head h3 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.sc-head--sub h3 {
  font-size: var(--pj-fs-lg);
}

/* Le séparateur « ou » de la maquette : deux filets et un mot. */
.sc-or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.sc-or::before,
.sc-or::after {
  content: "";
  flex: 1 1 auto;
  height: 1px;
  background: var(--pj-line);
}

.sc-manual {
  display: grid;
  gap: 8px;
}

.sc-manual__field {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
}

.sc-manual__field input {
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
  min-height: 50px;
  border: 0;
  background: transparent;
}

.sc-panel .sc-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
}

#sc-result {
  display: grid;
  gap: 8px;
  padding: 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

/* ── E44-06 — Transférer des Miles, au dessin de la maquette ──────────
   Les trois cartes du modèle : le formulaire, la confirmation en deux
   colonnes avec son QR, et les codes en attente. Rien du flux n'a bougé —
   seulement sa mise en forme, qui était restée celle du portefeuille. */

.tr-card {
  display: grid;
  gap: 16px;
}

.tr-head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.tr-head__text {
  flex: 1 1 auto;
  min-width: 0;
}

.tr-head__text h2 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.tr-head__text p {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.tr-form {
  display: grid;
  gap: 16px;
}

.tr-field {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.tr-field label {
  font-weight: 700;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

/* Le champ de la maquette : une icône dedans, à gauche, et le contrôle qui
   remplit le reste. La bordure est portée par l'enveloppe, sans quoi elle
   apparaîtrait deux fois. */
.tr-input {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-left: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
  overflow: hidden;
}

.tr-input input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 50px;
  padding-left: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  color: var(--pj-ink);
}

.tr-input input:focus {
  box-shadow: none;
}

.tr-input:focus-within {
  border-color: var(--pj-orange);
}

/* « miles » collé à droite du montant, sur son propre fond, comme au modèle. */
.tr-input__unit {
  align-self: stretch;
  display: flex;
  align-items: center;
  padding: 0 18px;
  border-left: 1px solid var(--pj-line);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-weight: 700;
}

.tr-hint {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 2px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.45;
}

.tr-hint i {
  margin-top: 2px;
  color: var(--pj-navy);
}

.tr-count {
  margin: 0;
  color: var(--pj-muted);
  font-size: 0.8rem;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.tr-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Échappe au `button, .btn { width: 100% }` du haut de cette feuille, et
   tient les 44 px de cible tactile du projet. */
.tr-actions .tr-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: auto;
  min-height: 48px;
  padding-inline: 22px;
}

/* ── La confirmation, en deux colonnes ───────────────────────────────── */

.tr-confirm {
  display: grid;
  gap: 16px;
  align-items: start;
}

.tr-confirm__main {
  display: grid;
  gap: 14px;
  min-width: 0;
}

.tr-confirm__recap {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.tr-confirm__line {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

/* Le code se lit chiffre par chiffre : on l'espace, comme au modèle. */
.tr-input input.tr-code {
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  letter-spacing: 0.35em;
}

.tr-qr {
  display: grid;
  gap: 10px;
  padding: 18px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  min-width: 0;
}

.tr-qr__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 800;
  color: var(--pj-ink);
}

.tr-qr__hint {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.45;
}

/* Le QR est carré et borné : plein cadre sur une carte de bureau, il est plus
   difficile à viser, pas plus facile.

   La borne est portée par un cadre et non par l image : `prosyjob.css` declare
   `.pj-app .pj-main img { max-width: 100% }` en (0,2,1), qui bat une classe
   seule et gagne l ordre des feuilles par-dessus le marche (celle-ci se charge
   avant le theme). Contraindre le parent evite la surenchere de specificite et
   dit la meme chose. */
.tr-qr__frame {
  display: block;
  width: 100%;
  max-width: 220px;
  margin-inline: auto;
  padding: 10px;
  border-radius: var(--pj-radius-sm);
  background: #fff;
}

.tr-qr__image {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
}

.tr-qr__label {
  font-weight: 700;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.tr-qr .tr-input {
  background: var(--pj-card);
  padding-left: 12px;
}

.tr-qr .tr-input input {
  min-height: 44px;
  font-size: 0.85rem;
}

/* Le bouton copier collé dans le champ, comme au modèle. Pas un `.btn` : il
   n'a pas de libellé et vit à l'intérieur d'un contrôle. */
.tr-qr__copy {
  align-self: stretch;
  width: auto;
  padding: 0 14px;
  border: 0;
  border-left: 1px solid var(--pj-line);
  background: transparent;
  color: var(--pj-muted);
}

.tr-qr__copy:hover {
  color: var(--pj-orange-text);
}

/* Le doublon assumé : le bouton dans le champ pour la souris, celui du bas
   pour le doigt — 44 px de cible, ce que le premier ne peut pas offrir sans
   déformer le champ. Sous 1200 px, seul le second reste. */
@media (max-width: 1199.98px) {
  .tr-qr__copy {
    display: none;
  }
}

@media (min-width: 1200px) {
  .tr-confirm {
    grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
    gap: 20px;
  }
}

/* Une fois le blocage frappe, la colonne de gauche a dit tout ce qu elle
   avait a dire : la carte revient a une colonne et le QR se centre. Deux
   colonnes dont une vide seraient pires que la maquette, pas plus fideles —
   celle-ci dessine l etape de la confirmation, pas celle-ci. */
.tr-confirm--hold {
  grid-template-columns: minmax(0, 1fr) !important;
  justify-items: center;
  text-align: center;
}

.tr-confirm--hold .tr-confirm__main {
  justify-items: center;
}

.tr-confirm--hold .tr-head {
  align-items: center;
}

.tr-confirm--hold .tr-qr {
  width: 100%;
  max-width: 420px;
  text-align: left;
}

.tr-qr .tr-actions {
  justify-content: center;
}

.tr-qr .tr-actions .tr-btn {
  padding-inline: 16px;
}

/* ── Mes codes en attente ────────────────────────────────────────────── */

.hl-rows {
  display: grid;
  gap: 10px;
}

.hl-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.hl-row__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: 1.1rem;
}

.hl-row__body {
  flex: 1 1 auto;
  min-width: 0;
}

.hl-row__amount {
  display: block;
  font-size: var(--pj-fs-md);
  font-weight: 800;
  color: var(--pj-ink);
}

.hl-row__meta {
  display: block;
  color: var(--pj-muted);
  font-size: 0.85rem;
}

/* L'annulation rend des Miles bloqués : c'est l'action de la ligne, pas une
   note de bas de page. Bordé rouge, avec les 44 px de cible tactile. */
.hl-row__cancel {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  width: auto;
  min-height: 44px;
  padding-inline: 16px;
  border: 1px solid var(--pj-danger);
  border-radius: var(--pj-radius-sm);
  background: transparent;
  color: var(--pj-danger);
  font-weight: 700;
}

.hl-row__cancel:hover {
  background: var(--pj-danger);
  color: #fff;
}

@media (max-width: 575.98px) {
  .hl-row {
    flex-wrap: wrap;
  }

  .hl-row__cancel {
    width: 100%;
    justify-content: center;
  }
}

/* ── E44-07 — Revoir le QR d'un code en attente ─────────────────────── */

/* Trois boutons par ligne : deux rappels discrets et l'annulation, qui garde
   son rouge. `flex-wrap` parce qu'a 360 px ils passent a la ligne, et chacun
   tient les 44 px de cible tactile du projet. */
.hl-row__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

/* Volontairement pas un `.btn-*` de la gamme : ce sont des rappels a cote
   d'une action, et §5 peint `.btn-outline-secondary` en orange pale, ce qui
   les mettrait au meme niveau que le bouton rouge d'a cote. */
.hl-row__ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding-inline: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-weight: 600;
  font-size: var(--pj-fs-body);
  white-space: nowrap;
}

.hl-row__ghost:hover {
  border-color: var(--pj-orange);
  color: var(--pj-orange-text);
}

@media (max-width: 575.98px) {
  .hl-row__actions {
    width: 100%;
  }

  .hl-row__ghost {
    flex: 1 1 auto;
    justify-content: center;
  }
}

/* ── E56 — Bons d'achat de Miles ─────────────────────────────────────── */

/* Une ligne de bon reprend `.hl-row` ; elle passe a la ligne pour que la liste
   des demandes d'un bon anonyme prenne toute la largeur sous lui. */
.vc-row {
  flex-wrap: wrap;
}

.vc-status {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
}

.vc-status--en_attente,
.vc-status--pending {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.vc-status--utilise,
.vc-status--accepted {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.vc-status--annule,
.vc-status--rejected {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.vc-requests,
.vc-requests__empty {
  flex: 1 1 100%;
  margin: 0;
}

.vc-requests {
  padding-top: 10px;
  border-top: 1px solid var(--pj-line);
}

.vc-requests__title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  color: var(--pj-ink);
}

.vc-requests__list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.vc-req {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
}

.vc-req__who {
  display: grid;
  min-width: 0;
}

.vc-req__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Les boutons nus font 100 % par defaut (CLAUDE.md §9) : ceux-ci se tiennent
   cote a cote, avec les 44 px de cible tactile. */
.vc-req__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: auto;
  min-height: 44px;
  padding-inline: 14px;
}

@media (max-width: 575.98px) {
  .vc-req__actions {
    width: 100%;
  }

  .vc-req__btn {
    flex: 1 1 auto;
  }
}

/* La part reservee du solde, sous le nombre des miles utilisables. */
.gm-balance__reserved {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.sc-result__kind {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  text-transform: uppercase;
}

.sc-result__status {
  margin: 8px 0 0;
  padding: 10px 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

/* =====================================================================
   E48 — « Trouver un emploi » : une page, quatre gestes du candidat
   =====================================================================
   La coquille (`.tj-`), puis les quatre panneaux : offres (`.jox-`),
   CV (`.cvp-`), candidatures (`.apx-`). Le profil candidat garde ses
   `.cand-` d'origine, son écran étant déjà à sa maquette.

   Tout est en jetons `--pj-*` : c'est ce qui fait du thème sombre un
   bloc de surcharge et non une seconde passe sur ce fichier.

   Mobile d'abord — ~90 % de cette audience arrive sur un téléphone.
   Chaque bloc est écrit à 360 px puis enrichi ; les points de rupture
   sont 768 (deux colonnes de contenu) et 1200 (la colonne de filtres,
   qui est aussi là où le rail réapparaît et où la colonne centrale
   cesse de pouvoir tout porter).

   Un `<button>` nu vaut `width: 100%` dans la coque connectée (règle
   `button, .btn` en tête de cette feuille). Chaque rangée de boutons
   ci-dessous reprend donc `width: auto` — ou laisse la grille décider,
   ce qui revient au même et se lit mieux.
   ===================================================================== */

/* `minmax(0, 1fr)` et non la piste `auto` implicite : sans cela le minimum
   `auto` d'un enfant elargit la colonne au lieu de le faire deborder de
   lui-meme, et c'est toute la page qui se decale. Meme raison que `.pj-stack`
   dans prosyjob-app.css §2 — mesure a 357 px : `#jox-list` sortait a 329 dans
   un conteneur de 289. */
.tj-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

/* ── Le bandeau ─────────────────────────────────────────────────────── */

.tj-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.tj-head__text {
  flex: 1 1 260px;
  min-width: 0;
}

.tj-head__text h1 {
  margin: 0 0 6px;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
  line-height: 1.2;
}

.tj-head__text p {
  margin: 0;
  max-width: 62ch;
  color: var(--pj-muted);
  line-height: 1.55;
}

.tj-head__art {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}

/* La phrase manuscrite de la maquette. Une vraie police cursive serait un
   fichier de plus à charger pour six mots ; l'italique penché du système
   dit la même chose et suit le thème. */
.tj-head__tag {
  max-width: 9rem;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
  font-style: italic;
  font-weight: 700;
  line-height: 1.3;
  text-align: right;
}

.tj-art {
  width: 96px;
  height: 72px;
  flex: 0 0 auto;
}

.tj-art__blob {
  fill: var(--pj-info-soft);
}

.tj-art__blob--soft {
  fill: var(--pj-orange-soft);
}

.tj-art__case {
  fill: var(--pj-navy);
}

.tj-art__handle,
.tj-art__stem {
  fill: none;
  stroke: var(--pj-navy);
  stroke-width: 3;
  stroke-linecap: round;
}

.tj-art__clasp {
  fill: var(--pj-orange);
}

.tj-art__lens {
  fill: none;
  stroke: var(--pj-orange);
  stroke-width: 3;
}

@media (max-width: 400px) {
  /* À 360 px, le titre et le descriptif valent mieux que l'illustration :
     elle passe sous les deux lignes de texte au lieu de les comprimer. */
  .tj-head__tag {
    display: none;
  }

  .tj-art {
    width: 72px;
    height: 54px;
  }
}

/* ── Les quatre portes ──────────────────────────────────────────────── */

.tj-tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.tj-tab {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 64px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  text-align: left;
}

.tj-tab__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-navy);
  font-size: 1rem;
}

.tj-tab__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.tj-tab__label {
  font-weight: 700;
  font-size: var(--pj-fs-body);
  line-height: 1.2;
}

.tj-tab__hint {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  line-height: 1.25;
}

.tj-tab:hover {
  border-color: var(--pj-orange);
}

.tj-tab.is-active {
  border-color: var(--pj-orange-fill);
  background: var(--pj-orange-fill);
  color: #fff;
}

.tj-tab.is-active .tj-tab__icon {
  background: rgba(255, 255, 255, .2);
  color: #fff;
}

.tj-tab.is-active .tj-tab__hint {
  color: rgba(255, 255, 255, .85);
}

/* A 360 px, l'icone passe au-dessus du texte.
   Mesure : en 2 colonnes, chaque bouton dispose de 140 px et le seul mot
   « candidatures » en demande 84 — plus 36 d'icone, les ecarts et le
   rembourrage, on depasse. Le texte ne peut pas se replier davantage : un mot
   ne se coupe pas. Empiler, c'est ce que `.gm-tab` fait deja pour les quatre
   onglets des miles, et pour la meme raison. */
@media (max-width: 575px) {
  .tj-tab {
    flex-direction: column;
    justify-content: center;
    gap: 8px;
    min-height: 92px;
    text-align: center;
  }

  .tj-tab__text {
    justify-items: center;
  }
}

@media (min-width: 992px) {
  .tj-tabs {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* =====================================================================
   Panneau « Offres d'emploi »
   ===================================================================== */

.jox {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  align-items: start;
}

.jox-results {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  min-width: 0;
}

/* ── Colonne de filtres ─────────────────────────────────────────────── */

.jox-filters {
  display: grid;
  gap: 12px;
  align-content: start;
}

.jox-filters__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.jox-filters__title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.jox-filters__title i {
  color: var(--pj-orange);
}

/* Un lien d'action, pas un bouton du barème : il n'a ni fond ni bordure et
   n'a donc rien à reprendre à `.btn`. `width: auto` parce que c'est un
   `<button>` nu, que la règle du haut de cette feuille étirerait. */
.jox-reset {
  width: auto;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.jox-reset:hover {
  text-decoration: underline;
}

.jox-reset--block {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
}

.jox-filters__body {
  display: grid;
  gap: 12px;
}

.jox-field label {
  display: block;
  margin-bottom: 4px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-ink);
}

.jox-field {
  margin-bottom: 0;
}

.jox-search {
  position: relative;
}

.jox-search__icon {
  position: absolute;
  top: 50%;
  left: 12px;
  transform: translateY(-50%);
  color: var(--pj-muted);
  font-size: 0.85rem;
  pointer-events: none;
}

.jox-search .form-control {
  padding-left: 34px;
}

.jox-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
}

/* Le dépliant du téléphone. */
.jox-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-weight: 600;
}

.jox-toggle__chevron {
  transition: transform .15s ease;
}

.jox-filters.is-open .jox-toggle__chevron {
  transform: rotate(90deg);
}

/* ── Barre de résultats ─────────────────────────────────────────────── */

.jox-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.jox-count {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.jox-count strong {
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-lg);
}

.jox-bar__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

.jox-sort,
.cvp-sort,
.apx-sort {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.jox-sort .form-control,
.cvp-sort .form-control,
.apx-sort .form-control {
  width: auto;
  min-width: 11rem;
  min-height: 44px;
}

.jox-save {
  width: auto;
  min-height: 44px;
  white-space: nowrap;
}

/* La bascule grille/liste. Deux `<button>` nus dans un groupe : la largeur
   vient du contenu, pas de la règle globale. */
.jox-views {
  display: inline-flex;
  overflow: hidden;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.jox-view {
  display: grid;
  place-items: center;
  width: 44px;
  min-height: 44px;
  border: 0;
  background: var(--pj-card);
  color: var(--pj-muted);
}

.jox-view + .jox-view {
  border-left: 1px solid var(--pj-line);
}

.jox-view.is-active {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

/* ── Puces de facette ───────────────────────────────────────────────── */

.jox-chips,
.cvp-chips,
.apx-chips {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}

/* Au-dela du telephone, les puces se replient au lieu de defiler.
   Mesure a 1821px de fenetre : la rangee demande 699px et la colonne
   centrale ne lui en laisse que 527, donc « Classique » et « Retiree »
   etaient coupees en plein mot — un defilement horizontal qu'aucune
   barre ne signale, sur un ecran assez large pour tout montrer. */
@media (min-width: 768px) {
  .jox-chips,
  .cvp-chips,
  .apx-chips {
    flex-wrap: wrap;
    overflow-x: visible;
  }
}

.jox-chips::-webkit-scrollbar,
.cvp-chips::-webkit-scrollbar,
.apx-chips::-webkit-scrollbar {
  display: none;
}

/* Délibérément hors du barème des boutons : une puce montre un **choix**,
   pas une action, et §5 peint `.btn-outline-secondary` d'un orange pâle qui
   rendrait la puce active et les autres identiques — la leçon d'E44 sur les
   trois montants préréglés d'achat de miles. Elles portent donc leurs propres
   jetons et ne touchent jamais à `.btn`. */
.jox-chip,
.cvp-chip,
.apx-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  white-space: nowrap;
}

.jox-chip__count,
.cvp-chip__count,
.apx-chip__count {
  display: inline-grid;
  place-items: center;
  min-width: 1.4rem;
  height: 1.4rem;
  padding: 0 5px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
}

.jox-chip:hover,
.cvp-chip:hover,
.apx-chip:hover {
  border-color: var(--pj-orange);
}

.jox-chip.is-active,
.cvp-chip.is-active,
.apx-chip.is-active {
  border-color: var(--pj-navy);
  background: var(--pj-navy);
  color: #fff;
}

.jox-chip.is-active .jox-chip__count,
.cvp-chip.is-active .cvp-chip__count,
.apx-chip.is-active .apx-chip__count {
  background: rgba(255, 255, 255, .22);
  color: #fff;
}

/* ── Cartes d'offre ─────────────────────────────────────────────────── */

.jox-list {
  display: grid;
  gap: 16px;
}

/* `min(260px, 100%)` et non `260px` : entre 1201 et ~1390 px la colonne des
   resultats tombe a 227 px (barre laterale 264 + rail 300 + colonne de filtres
   288 + ecarts, tous presents a la fois), et `minmax(260px, 1fr)` y produisait
   une piste de 260 dans un conteneur de 227 — mesure : la carte d'offre sortait
   de 33 px de sa colonne. Un minimum plus grand que le conteneur ne se replie
   pas tout seul ; c'est la meme famille de faute que la piste `auto` non bornee
   du §9. Corrige ici, donc pour les deux panneaux qui partagent cette classe. */
.jox-list--grid {
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}

.jox-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease;
}

/* Deux cartes cote a cote ont la meme hauteur (la grille les etire) mais pas
   le meme contenu : sans cela leurs boutons « Voir l'offre » se retrouvent a
   des hauteurs differentes, ce qui se voit immediatement et ne se lit nulle
   part dans le code. */
.jox-card__foot {
  margin-top: auto;
}

.jox-card:hover,
.jox-card:focus-visible {
  border-color: var(--pj-orange);
  box-shadow: var(--pj-shadow);
}

.jox-card__head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.jox-logo,
.apx-logo {
  display: grid;
  place-items: center;
  overflow: hidden;
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.jox-logo img,
.apx-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.jox-card__ident {
  flex: 1 1 auto;
  min-width: 0;
}

.jox-card__title {
  margin: 0 0 2px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  line-height: 1.25;
  color: var(--pj-ink);
}

.jox-card__company {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.jox-verified {
  color: var(--pj-success);
  font-size: var(--pj-fs-sm);
}

.jox-flag {
  flex: 0 0 auto;
  padding: 3px 9px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-2xs);
  font-weight: 700;
}

.jox-flag--new {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.jox-flag--tender {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.jox-card__facts {
  display: grid;
  gap: 5px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.jox-card__facts li {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.jox-card__facts i {
  width: 14px;
  color: var(--pj-navy);
  text-align: center;
}

.jox-card__skills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.jox-skill {
  padding: 3px 9px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.jox-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--pj-line);
}

.jox-card__age {
  font-size: var(--pj-fs-xs);
}

/* Un `<span>` peint en bouton : la carte entière est le lien, et un vrai
   bouton imbriqué dans un `role="link"` serait une cible dans une cible. */
.jox-card__cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: auto;
  pointer-events: none;
}

.jox-empty,
.cvp-empty,
.apx-empty {
  display: grid;
  gap: 10px;
  justify-items: center;
  padding: 40px 22px;
  text-align: center;
}

.jox-empty h3,
.cvp-empty h3,
.apx-empty h3 {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.cvp-empty__cta,
.apx-empty__cta {
  width: auto;
  min-height: 44px;
}

.jox-loading,
.cvp-loading,
.apx-loading {
  padding: 24px 0;
  text-align: center;
}

/* ── Pied de liste, partagé par les trois panneaux ──────────────────── */

.jox-foot,
.cvp-foot,
.apx-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.jox-foot__count,
.cvp-foot__count,
.apx-foot__count {
  margin: 0;
  font-size: var(--pj-fs-body);
}

.jox-foot__pager,
.cvp-foot__pager,
.apx-foot__pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-left: auto;
}

.jox-perpage,
.cvp-perpage,
.apx-perpage {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.jox-perpage .form-control,
.cvp-perpage .form-control,
.apx-perpage .form-control {
  width: auto;
  min-height: 44px;
}

@media (min-width: 768px) {
  /* La vue liste reprend une grille : la carte est un flex en colonne au
     defaut (c'est ce qui colle son pied en bas), et `grid-template-columns`
     sur un conteneur flex ne fait rien du tout — silencieusement. */
  .jox-list--rows .jox-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }

  .jox-list--rows .jox-card__foot {
    margin-top: 0;
  }

  .jox-list--rows .jox-card__head,
  .jox-list--rows .jox-card__facts,
  .jox-list--rows .jox-card__skills {
    grid-column: 1;
  }

  .jox-list--rows .jox-card__foot {
    flex-direction: column;
    align-items: flex-end;
    grid-column: 2;
    grid-row: 1 / -1;
    padding-top: 0;
    border-top: 0;
    border-left: 1px solid var(--pj-line);
    padding-left: 16px;
  }
}

@media (min-width: 1200px) {
  .jox {
    grid-template-columns: 288px minmax(0, 1fr);
  }

  /* Au large, la colonne de filtres est toujours ouverte et son dépliant
     n'a plus de sens. `!important` est le seul moyen de reprendre
     `[hidden] { display: none !important }`, que prosyjob-app.css pose
     délibérément en dernière feuille — c'est l'exception, pas l'usage. */
  .jox-filters__body[hidden] {
    display: grid !important;
  }

  .jox-toggle {
    display: none;
  }
}

/* Le tri sur telephone. Mesure a 357 px : `.jox-bar` debordait de 13 px
   (300 de contenu pour 287 de boite), parce que le `min-width: 11rem` du
   selecteur, son libelle et la bascule grille/liste ne tiennent pas cote a
   cote. En dessous de 576 px l'outil prend donc la ligne entiere et le
   selecteur s'etire au lieu d'imposer sa largeur. */
@media (max-width: 575px) {
  .jox-bar__tools {
    width: 100%;
  }

  .jox-sort,
  .cvp-sort,
  .apx-sort {
    flex: 1 1 auto;
    min-width: 0;
  }

  .jox-sort .form-control,
  .cvp-sort .form-control,
  .apx-sort .form-control {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
  }

  .jox-sort__label,
  .cvp-sort__label,
  .apx-sort__label {
    display: none;
  }
}

/* =====================================================================
   Panneau « Mes CV »
   ===================================================================== */

.cvp-head,
.apx-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.cvp-head__icon,
.apx-head__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: 1.25rem;
}

.cvp-head__text,
.apx-head__text {
  flex: 1 1 240px;
  min-width: 0;
}

.cvp-head__text h2,
.apx-head__text h2 {
  margin: 0 0 3px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.cvp-head__text p,
.apx-head__text p {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.cvp-head__new {
  width: 100%;
  min-height: 44px;
}

.apx-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  flex: 1 1 260px;
  padding: 12px 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  line-height: 1.5;
}

.apx-note p {
  margin: 0;
}

.apx-note i {
  color: var(--pj-info-ink);
}

.cvp-bar,
.apx-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.cvp-chips,
.apx-chips {
  flex: 1 1 240px;
  min-width: 0;
}

.cvp-sort,
.apx-sort {
  flex: 0 0 auto;
  margin-left: auto;
}

.cvp-sort i,
.apx-sort i {
  color: var(--pj-muted);
}

@media (min-width: 768px) {
  .cvp-head__new {
    width: auto;
    margin-left: auto;
  }
}

/* ── Carte de CV ────────────────────────────────────────────────────── */

.cvp-card {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}

.cvp-card--archived {
  opacity: .72;
}

/* Le profil tenant lieu de CV tant qu'aucun n'a ete compose : un contour en
   pointille dit « pas encore un document » en meme temps que le badge, et
   evite qu'on le prenne pour une ligne qu'on pourrait supprimer. */
.cvp-card--virtual {
  border-style: dashed;
}

.cvp-card__main {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.cvp-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.cvp-card__name {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.cvp-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cvp-card__desc {
  margin: 0;
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.cvp-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cvp-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin: 0;
  font-size: var(--pj-fs-sm);
}

.cvp-card__meta i {
  margin-right: 5px;
  color: var(--pj-navy);
}

.cvp-card__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  grid-column: 1 / -1;
}

.cvp-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 100%;
  min-height: 44px;
}

/* ── L'illustration de mise en page ─────────────────────────────────────
   Ce n'est **pas** un aperçu du document : aucun rendu de CV en image
   n'existe (hors lot, 2026-09-12). Ce que cette case montre est la
   famille de mise en page, et la photo du CV quand il en porte une.
   Elle ne prétend rien d'autre. */

.cvp-thumb {
  overflow: hidden;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  aspect-ratio: 3 / 4;
}

.cvp-thumb__sheet {
  display: grid;
  grid-template-columns: 40% minmax(0, 1fr);
  gap: 4px;
  width: 100%;
  height: 100%;
  padding: 6px;
  background: var(--pj-card);
}

.cvp-thumb__side {
  display: grid;
  align-content: start;
  gap: 3px;
  padding: 4px 3px;
  border-radius: 3px;
  background: var(--pj-navy);
}

.cvp-thumb__photo {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 2px;
  object-fit: cover;
  background: var(--pj-card-2);
}

.cvp-thumb__photo--none {
  display: block;
  background: rgba(255, 255, 255, .35);
}

.cvp-thumb__bar {
  height: 2px;
  border-radius: 1px;
  background: rgba(255, 255, 255, .5);
}

.cvp-thumb__bar--short {
  width: 60%;
}

.cvp-thumb__body {
  display: grid;
  align-content: start;
  gap: 3px;
  padding: 3px 2px;
}

.cvp-thumb__line {
  height: 2px;
  border-radius: 1px;
  background: var(--pj-line);
}

.cvp-thumb__line--title {
  height: 3px;
  width: 55%;
  background: var(--pj-orange);
}

.cvp-thumb__line--short {
  width: 70%;
}

/* Depuis E57 la vignette se dessine depuis les réglages de la mise en page :
   sa structure fait la classe, sa couleur d'accent arrive en `--cvp-accent`
   (une couleur du catalogue, vérifiée #RRGGBB des deux côtés). Sans elle, les
   jetons de la marque. `colonne_laterale` est le dessin de base ci-dessus. */
.cvp-thumb__side {
  background: color-mix(in srgb, var(--cvp-accent, var(--pj-navy)) 24%, var(--pj-card));
}

.cvp-thumb__bar {
  background: color-mix(in srgb, var(--cvp-accent, var(--pj-navy)) 55%, var(--pj-card));
}

.cvp-thumb__line--title {
  background: var(--cvp-accent, var(--pj-orange));
}

.cvp-thumb--une_colonne .cvp-thumb__sheet,
.cvp-thumb--bandeau .cvp-thumb__sheet {
  grid-template-columns: minmax(0, 1fr);
  align-content: start;
}

/* One column or banner: a miniature header, the photo on the left and the
   name lines beside it — a grid rather than a flex row, so the photo can be
   40% wide (it was 16px, too small to see) with the lines stacked next to it. */
.cvp-thumb--une_colonne .cvp-thumb__side,
.cvp-thumb--bandeau .cvp-thumb__side {
  grid-template-columns: 40% minmax(0, 1fr);
  align-items: center;
  align-content: center;
  gap: 3px 5px;
  padding: 4px;
}

.cvp-thumb--une_colonne .cvp-thumb__side {
  background: transparent;
}

.cvp-thumb--bandeau .cvp-thumb__side {
  background: var(--cvp-accent, var(--pj-navy));
}

.cvp-thumb--bandeau .cvp-thumb__bar {
  background: color-mix(in srgb, var(--pj-card) 70%, transparent);
}

.cvp-thumb--une_colonne .cvp-thumb__photo,
.cvp-thumb--bandeau .cvp-thumb__photo {
  grid-row: 1 / span 3;
}

.cvp-thumb--une_colonne .cvp-thumb__bar,
.cvp-thumb--bandeau .cvp-thumb__bar {
  grid-column: 2;
}

/* The layout's own photo shape (`photo` in its settings). */
.cvp-thumb--photo-ronde .cvp-thumb__photo {
  border-radius: 50%;
}

@media (min-width: 576px) {
  .cvp-card__actions {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 992px) {
  .cvp-card {
    grid-template-columns: 112px minmax(0, 1fr) 190px;
  }

  .cvp-card__actions {
    grid-template-columns: minmax(0, 1fr);
    grid-column: 3;
    grid-row: 1;
  }
}

/* =====================================================================
   Panneau « Mes candidatures »
   ===================================================================== */

.apx-row {
  display: grid;
  gap: 14px;
  align-items: start;
}

.apx-row__ident {
  display: flex;
  gap: 12px;
  min-width: 0;
}

.apx-row__titles {
  min-width: 0;
}

.apx-row__title {
  margin: 0 0 2px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  line-height: 1.25;
  color: var(--pj-ink);
}

.apx-row__company {
  margin: 0 0 6px;
  font-size: var(--pj-fs-body);
}

.apx-row__facts {
  display: grid;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.apx-row__facts li {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.apx-row__facts i {
  width: 14px;
  color: var(--pj-navy);
  text-align: center;
}

.apx-row__state {
  display: grid;
  gap: 8px;
  align-content: start;
}

/* La frise de la maquette : une pastille, un trait, et ce que l'état veut
   dire en une phrase. « Consultée » ne rassure que si l'on sait que
   quelqu'un a ouvert le dossier. */
.apx-timeline {
  position: relative;
  padding-left: 16px;
}

.apx-timeline::before {
  content: "";
  position: absolute;
  top: 6px;
  left: 3px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--pj-navy);
}

.apx-timeline::after {
  content: "";
  position: absolute;
  top: 15px;
  bottom: 4px;
  left: 6px;
  width: 1px;
  background: var(--pj-line);
}

.apx-timeline__what {
  margin: 0 0 2px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  line-height: 1.4;
}

.apx-timeline__when {
  margin: 0;
  font-size: var(--pj-fs-xs);
}

.apx-row__score {
  display: flex;
  align-items: center;
  gap: 12px;
}

.apx-row__scoretext {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.apx-row__scorelabel {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.apx-row__scorelevel {
  font-size: var(--pj-fs-body);
  font-weight: 700;
  color: var(--pj-ink);
}

.apx-row__scorelevel--very_compatible {
  color: var(--pj-success);
}

.apx-row__scorelevel--compatible {
  color: var(--pj-info-ink);
}

.apx-row__scorelevel--partially_compatible {
  color: var(--pj-warning-ink);
}

.apx-row__scorelevel--low {
  color: var(--pj-danger);
}

.apx-row__scorelevel--none {
  color: var(--pj-muted);
}

.apx-row__gap {
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.apx-row__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.apx-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 100%;
  min-height: 44px;
}

@media (min-width: 992px) {
  .apx-row {
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1.1fr) minmax(0, 1fr);
  }

  .apx-row__score {
    justify-content: flex-end;
  }

  .apx-row__actions {
    grid-column: 3;
    grid-template-columns: minmax(0, 1fr);
  }
}

/* =====================================================================
   L'anneau de compatibilité (ScoreBadge.donut)
   =====================================================================
   Une variante du composant de Matching plutôt qu'un second rendu du
   score : le vocabulaire des niveaux, les quatre teintes et surtout
   « null n'est pas zéro » n'y sont écrits qu'une fois.
   ===================================================================== */

.mt-donut {
  position: relative;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
}

.mt-donut__svg {
  width: 100%;
  height: 100%;
  /* L'arc part de midi. En CSS et pas dans un `stroke-dashoffset` calculé :
     ici la rotation se lit, là-bas c'était un nombre magique. */
  transform: rotate(-90deg);
}

.mt-donut__track {
  stroke: var(--pj-line);
}

.mt-donut__fill {
  stroke: var(--pj-muted);
}

.mt-donut__value {
  position: absolute;
  font-size: var(--pj-fs-sm);
  font-weight: 800;
  color: var(--pj-ink);
}

.mt-donut--very_compatible .mt-donut__fill {
  stroke: var(--pj-success);
}

.mt-donut--compatible .mt-donut__fill {
  stroke: var(--pj-info-ink);
}

.mt-donut--partially_compatible .mt-donut__fill {
  stroke: var(--pj-warning-ink);
}

.mt-donut--low .mt-donut__fill {
  stroke: var(--pj-danger);
}

/* Rien n'a été comparé : l'anneau reste vide et gris. Ce n'est pas un
   mauvais score, et il ne doit pas en avoir la couleur. */
.mt-donut--none .mt-donut__fill {
  stroke: transparent;
}

.mt-donut--none .mt-donut__value {
  color: var(--pj-muted);
}

/* =====================================================================
   E49 — « Trouver une formation » : la même page, pour se former
   =====================================================================
   La coquille est celle d'E48 (`.tj-*`, plus haut) : un bandeau, quatre
   portes, un panneau. Deux jeux de règles jumeaux dériveraient à la
   première correction portée à un seul, donc rien n'est recopié ici —
   seule l'illustration change, `.tf-art__*`.

   Le panneau des offres réutilise de même la structure de `.jox-*` :
   colonne de filtres, barre, puces, liste, pied. Ce qui appartient en
   propre à une formation — le prix, les faits de session, la colonne
   d'actions — porte `.tfx-*`.

   Tout est en jetons `--pj-*` : c'est ce qui fait du thème sombre un
   bloc de surcharge et non une seconde passe sur ce fichier.

   Mobile d'abord. Points de rupture 768 (la carte se met en deux
   colonnes) et 1200 (la colonne de filtres, là où le rail réapparaît).
   ===================================================================== */

/* ── L'illustration du bandeau ──────────────────────────────────────── */

.tf-art__blob {
  fill: var(--pj-info-soft);
}

.tf-art__blob--soft {
  fill: var(--pj-orange-soft);
}

.tf-art__book {
  fill: var(--pj-navy);
}

.tf-art__spine {
  stroke: var(--pj-card);
  stroke-width: 2;
}

.tf-art__board {
  fill: var(--pj-orange);
}

.tf-art__stem {
  fill: none;
  stroke: var(--pj-orange);
  stroke-width: 3;
  stroke-linecap: round;
}

.tf-art__tassel {
  fill: var(--pj-orange);
}

/* ── Cartes de formation ────────────────────────────────────────────── */

/* Une carte de formation n'est **pas** un lien comme une carte d'offre :
   la maquette y met deux vrais boutons (« Voir les détails », « Postuler »),
   et une cible dans une cible n'est ni utilisable au clavier ni
   annonçable. D'où une classe à elle, qui ne reprend ni le `cursor`
   ni le `:hover` de `.jox-card`. */
.tfx-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}

.tfx-card__main {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.tfx-card__head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.tfx-card__ident {
  flex: 1 1 auto;
  min-width: 0;
}

.tfx-card__title {
  margin: 0 0 2px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  line-height: 1.25;
  color: var(--pj-ink);
}

.tfx-card__org {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.tfx-card__excerpt {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.tfx-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.tfx-badge {
  padding: 3px 9px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.tfx-badge--certified {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.tfx-facts {
  display: grid;
  gap: 5px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tfx-facts li {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.tfx-facts i {
  width: 14px;
  color: var(--pj-navy);
  text-align: center;
}

.tfx-card__side {
  display: grid;
  gap: 8px;
  align-content: start;
}

.tfx-price {
  margin: 0;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  line-height: 1.2;
}

.tfx-price--free {
  color: var(--pj-success);
}

.tfx-actions {
  display: grid;
  gap: 8px;
}

/* Un `<button>` nu vaut `width: 100%` dans la coque connectée (règle
   `button, .btn` en tête de cette feuille) ; ici c'est la grille qui
   décide, et une hauteur de 44 px est le minimum tactile de §9. */
.tfx-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: 44px;
}

/* « Voir les détails » est un bouton **neutre**, et il a fallu sortir de
   l'échelle pour l'obtenir.

   `.btn-outline-secondary` est peint par le §5 de prosyjob-app.css en fond
   orange pâle sous un libellé orange (`rgb(254,237,229)` / `rgb(192,64,23)`,
   mesuré) : à côté d'un prix orange et d'un « Postuler » orange plein, cela
   faisait trois orangés empilés dans une colonne de 186 px, et plus aucune
   hiérarchie entre « regarder » et « s'inscrire ». C'est exactement ce
   qu'ont rencontré les puces d'achat de Miles (§9 de CLAUDE.md) : reprendre
   la couleur à la feuille des composants est injouable — elle charge avant
   le thème — donc le bouton quitte les classes de couleur de l'échelle et
   porte les siennes.

   Écrit `.btn.tfx-btn--ghost` — deux classes — pour passer devant
   `.pj-app .btn-outline-secondary` ; et c'est un vrai `<button>`, donc le
   piège de l'ancre (`.pj-app a { color: inherit }` à (0,1,1)) ne s'applique
   pas ici. Contraste mesuré : 14,57:1 en clair, contre 4,63 avant. */
.btn.tfx-btn--ghost {
  border-color: var(--pj-line);
  background: var(--pj-card);
  color: var(--pj-ink);
}

.btn.tfx-btn--ghost:hover,
.btn.tfx-btn--ghost:focus-visible {
  border-color: var(--pj-navy);
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

@media (min-width: 576px) {
  /* Deux boutons côte à côte dès qu'il y a la place, plutôt qu'empilés
     pleine largeur sous chaque carte. */
  .tfx-actions {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ── La vue liste : deux colonnes, et pas trois ─────────────────────────
   La maquette dessine la carte en trois colonnes — identité, faits,
   prix/actions — parce qu'elle est dessinée **pleine page** (~1536 px).
   Ici la colonne des résultats mesure 596 px : mesuré, le titre n'y
   recevait plus que 108 px et « Administration des ventes et relation
   client » tombait sur trois lignes hautes de 80 px. C'est le même mur
   qu'E48 (arbitrage 3 : la coque garde ses trois colonnes, rail compris,
   donc la colonne centrale vaut 900 px et non 1536).

   Deux colonnes, donc : le texte à gauche, le prix et les actions à
   droite, et les faits passent en ligne sous le résumé — la seule chose
   qui se lise à 596 px. `minmax(0, 1fr)` et non `1fr` : sans borne, le
   minimum `auto` d'un titre insécable élargit la piste au lieu de le
   faire se replier, et c'est toute la colonne qui se décale (§9). */
/* Les deux bandes ou la colonne des resultats est assez large, et le trou
   entre elles. Mesure de la colonne des resultats selon la largeur de fenetre :

     < 860      tiroir lateral, pas de rail, pas de colonne de filtres  ~ V - 32
     860-1200   barre laterale, pas de rail, pas de colonne de filtres  ~ V - 328
     >= 1201    barre + rail + colonne de filtres, tous ensemble        ~ min(V,1560) - 970

   La troisieme bande demarre donc a **227 px** a 1201 px de fenetre. Mesures :
   227 a 1210, 297 a 1280, 384 a 1366, 457 a 1440, 596 a 1700.

   Le titre recoit `resultats - 314` (rembourrage de la carte, colonne de cote,
   ecarts, vignette). A 1440 la scission lui laisse **143 px** quand la carte
   empilee lui en donne 365 : la scission n'est un gain qu'a partir de ~540 px
   de colonne, soit une fenetre de 1510. Entre 1201 et 1509 la carte reste donc
   empilee, ce qui est aussi la forme que montre la maquette sur telephone — pas
   une disposition inventee pour l'occasion. Un titre de formation est une
   phrase (« Administration des ventes et relation client »), pas un intitule de
   poste d'un mot ou deux ; c'est lui qui fixe le seuil.

   Une requete de conteneur dirait cela en une ligne et sans arithmetique ; le
   projet n'en utilise aucune, et en introduire une ici en ferait la seule de la
   feuille. La bande est ecrite en clair a la place. */
@media (min-width: 576px) and (max-width: 1200px), (min-width: 1510px) {
  .jox-list--rows .tfx-card {
    grid-template-columns: minmax(0, 1fr) 186px;
    /* `auto 1fr` et non deux lignes implicites : la colonne de droite couvre
       les deux lignes, et la hauteur d'un element qui en couvre plusieurs est
       **repartie** entre les pistes qu'il traverse quand elles sont `auto`.
       Mesure sur une carte recommandee, dont l'anneau rend la colonne de
       droite plus haute que le texte : 94 px de vide entre le resume et les
       faits, qui se retrouvaient colles en bas de la carte. `align-content`
       n'y peut rien — il range des lignes, il ne les empeche pas de grandir.
       Avec `1fr` sur la seconde, tout le surplus y tombe d'un coup, et
       `align-items: start` y garde les faits en haut. */
    grid-template-rows: auto 1fr;
    gap: 18px;
  }

  .jox-list--rows .tfx-card__main,
  .jox-list--rows .tfx-facts {
    grid-column: 1;
  }

  .jox-list--rows .tfx-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
  }

  .jox-list--rows .tfx-card__side {
    grid-column: 2;
    grid-row: 1 / -1;
    padding-left: 18px;
    border-left: 1px solid var(--pj-line);
  }

  .jox-list--rows .tfx-actions {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── Les trois autres onglets (E49-03 à E49-05) ─────────────────────────
   Ils partagent la charpente du panneau des offres (`.jox-*`) et la carte
   (`.tfx-card`) : un seul dessin pour quatre onglets, ce qui est tout
   l'intérêt de les avoir regroupés. Ce qui suit n'ajoute que ce qui leur
   appartient en propre. */

.trx,
.enx,
.cex {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

/* La phrase qui reste quand le titre est parti : elle dit d'où viennent les
   conseils, ce que le bouton de l'onglet ne dit pas. */
.trx-lead,
.enx-lead,
.cex-lead {
  margin: 0;
  max-width: 72ch;
  line-height: 1.55;
}

/* ── « Compétences à renforcer » ────────────────────────────────────── */

.trx-gaps {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
  align-items: start;
}

.trx-gaps__head {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.trx-gaps__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.trx-gaps__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.trx-gaps__sub {
  margin: 0;
  font-size: var(--pj-fs-sm);
}

.trx-gaps__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.trx-gaps__aside {
  display: grid;
  gap: 8px;
  justify-items: start;
}

.trx-gaps__count {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

/* Un bouton qui se lit comme un lien : c'est une navigation, pas une action,
   et la maquette le dessine ainsi. `width: auto` parce qu'un `<button>` nu
   vaut 100 % dans la coque connectée. */
.trx-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: auto;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
  font-weight: 700;
}

.trx-link:hover {
  text-decoration: underline;
}

.trx-chip {
  padding: 5px 12px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.trx-chip--more {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.trx-chip--sm {
  padding: 3px 9px;
  font-size: var(--pj-fs-xs);
}

.trx-covers {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: var(--pj-fs-sm);
}

/* L'anneau de correspondance, au-dessus des deux boutons. `ScoreBadge.donut`
   apporte le dessin et les quatre teintes ; il ne reste que la place. */
.trx-score {
  display: grid;
  justify-items: center;
  gap: 4px;
}

.trx-score__label {
  font-size: var(--pj-fs-xs);
  text-align: center;
}

@media (min-width: 768px) {
  .trx-gaps {
    grid-template-columns: minmax(0, 1fr) minmax(0, 15rem);
    grid-template-rows: auto 1fr;   /* meme raison que .tfx-card ci-dessus */
  }

  .trx-gaps__head,
  .trx-gaps__chips {
    grid-column: 1;
  }

  .trx-gaps__aside {
    grid-column: 2;
    grid-row: 1 / -1;
    padding-left: 18px;
    border-left: 1px solid var(--pj-line);
  }
}

/* ── Inscriptions et certificats ────────────────────────────────────── */

/* La pastille d'état. Elle est au-dessus des actions, comme sur la maquette,
   et non dans la rangée des badges : c'est l'information qui décide si on
   clique, pas une caractéristique de la formation. */
.enx-status,
.cex-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-align: center;
}

/* Les paires « encre sur teinte » de prosyjob-app.css §2, et pas les
   couleurs de signal nues : `--pj-warning-ink` n'est pas `--pj-warning` avec
   un suffixe, les deux repondent a des questions differentes (l'une sur une
   carte, l'autre sur une teinte, six unites de luminance d'ecart). Peindre
   `--pj-orange-text` sur `--pj-warning-soft` aurait redescendu sous AA une
   pastille qui est justement la seule information de la ligne. */
.enx-status--enrolled,
.enx-status--paid,
.enx-status--attended,
.enx-status--preregistered,
.enx-status--awaiting_payment,
.enx-status--info_request,
.enx-status--waitlisted {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.enx-status--completed,
.enx-status--certified,
.cex-status--on {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.enx-status--cancelled,
.enx-status--refunded {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

/* « Annuler » et « Masquer » sont des retraits, pas des destructions : un
   secondaire teinté, jamais le rouge plein d'une suppression. Deux classes
   pour passer devant `.pj-app .btn-*` du §5 (CLAUDE.md §9). */
.btn.enx-btn--danger {
  border-color: var(--pj-danger);
  background: var(--pj-card);
  color: var(--pj-danger);
}

.btn.cex-btn--mute {
  border-color: var(--pj-line);
  background: var(--pj-card);
  color: var(--pj-muted);
}

.btn.enx-btn--danger:hover,
.btn.cex-btn--mute:hover {
  background: var(--pj-card-2);
}

/* La vignette du certificat : l'icône est dessous, l'image par-dessus. Si
   l'image ne charge pas, le panneau la retire et l'icône réapparaît — une
   vignette cassée est pire que pas de vignette. */
.cex-thumb {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  flex: 0 0 auto;
  width: 64px;
  height: 46px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.cex-thumb img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.enx-side,
.cex-side,
.trx-side {
  justify-items: stretch;
}

/* Un bouton d'appel dans une carte vide : `auto` contre le `width: 100%`
   des `<button>` nus de la coque connectée. */
.trx-cta,
.enx-cta,
.cex-cta {
  width: auto;
  min-height: 44px;
}

/* =====================================================================
   VF — la vérification du compte dans le tunnel d'inscription (E50)
   ---------------------------------------------------------------------
   Deux états sur un seul arbre : rien ici ne se réécrit, tout se montre
   ou se cache. La carte WhatsApp est le même nœud avant et après la
   preuve de l'e-mail, donc son code à demi saisi survit à la bascule.

   Cette feuille charge AVANT le thème vendeur : une règle vendeur de
   spécificité égale gagne. D'où `.vf-otp .vf-otp__box` (0,2,0) et non
   `.vf-otp__box`, qui perdrait contre `.form-control`.

   Aucun hex : le thème sombre suit les tokens sans une seconde passe.
   ===================================================================== */

.vf-cards {
  display: grid;
  gap: 16px;
}

@media (min-width: 768px) {
  .vf-cards {
    /* auto-fit : deux cartes à l'état 1, trois à l'état 2, sans que la
       page ait à compter. Le plancher à 260px fait retomber à deux
       colonnes sur tablette plutôt que d'en serrer trois. */
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  }
}

.vf-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 10px;
  padding: 20px 16px;
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
}

@media (min-width: 768px) {
  .vf-card { padding: 24px 20px; }
}

.vf-card--done {
  background: var(--pj-success-soft);
  border-color: var(--pj-success-soft);
}

/* L'icône dans sa pastille. La couleur dit le canal, pas l'état — sauf
   `--ok`, qui dit justement l'état. */
.vf-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  font-size: 22px;
}

.vf-card__icon--mail     { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.vf-card__icon--whatsapp { background: var(--pj-success-soft); color: var(--pj-success); }
.vf-card__icon--ok       { background: var(--pj-success-soft); color: var(--pj-success); }
.vf-card__icon--account  { background: var(--pj-info-soft);    color: var(--pj-info-ink); }

.vf-card--done .vf-card__icon {
  background: var(--pj-card);
}

/* La coche verte et la puce « à vérifier » occupent le même coin : une
   carte ne porte jamais les deux, l'une disant que c'est fait et l'autre
   que ça reste à faire. */
.vf-card__check,
.vf-card__chip {
  position: absolute;
  top: 14px;
  right: 14px;
}

.vf-card__check {
  color: var(--pj-success);
  font-size: var(--pj-fs-card);
  line-height: 1;
}

.vf-card__chip {
  padding: 4px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.vf-card__title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

.vf-card__hint {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  line-height: 1.5;
}

.vf-card__label {
  align-self: flex-start;
  margin: 6px 0 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

/* L'adresse confirmée, en lecture seule : une boîte, pas un champ — il
   n'y a plus rien à y saisir. */
.vf-card__value {
  width: 100%;
  margin: 0;
  padding: 10px 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  word-break: break-all;
}

.vf-card__submit {
  width: 100%;
  min-height: 44px;
}

/* « Renvoyer le code » : un bouton qui se lit comme un lien. `.btn` nu,
   donc sans fond, et la couleur vient du token de texte orange — celui
   qui tient le contraste, pas `--pj-orange`. */
.vf-card__resend {
  width: 100%;
  min-height: 44px;
  background: transparent;
  border: 0;
  color: var(--pj-orange-text);
  font-weight: 600;
  font-size: var(--pj-fs-body);
}

.vf-card__resend:hover {
  color: var(--pj-orange-dark);
  text-decoration: underline;
}

/* ── Les six cases ──────────────────────────────────────────────────
   `flex: 1 1 0` plutôt qu'une largeur fixe : à 360px six cases fixes
   débordent la carte, et un débordement horizontal ne se voit pas en
   revue. Elles se partagent la place, la hauteur garantit la cible
   tactile, et `max-width` les empêche de s'étirer sur grand écran. */
.vf-otp {
  display: flex;
  gap: 6px;
  width: 100%;
}

.vf-otp .vf-otp__box {
  flex: 1 1 0;
  min-width: 0;
  max-width: 56px;
  height: 52px;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  text-align: center;
  font-size: var(--pj-fs-card);
  font-weight: 600;
}

.vf-otp .vf-otp__box:focus {
  border-color: var(--pj-orange);
  box-shadow: 0 0 0 3px var(--pj-orange-soft);
  outline: none;
}

@media (min-width: 768px) {
  .vf-otp { gap: 8px; }
}

/* À 360px, six cases de 44px ne tiennent pas : ce qui reste dans la
   carte donne des cases de 33,5px — mesurées, pas estimées. On reprend
   la place sur les paddings, là où il y a de toute façon une seule
   colonne. Le troisième padding, celui de `.account-content`, ne peut
   PAS se corriger ici : le vendeur le pose à (0,2,0) et cette feuille
   charge avant lui. Il est dans prosyjob-app.css, §2. */
@media (max-width: 575px) {
  .vf-card { padding: 20px 8px; }
  .vf-otp { gap: 4px; }
}

/* ── Le pied ────────────────────────────────────────────────────────── */

.vf-foot {
  display: grid;
  gap: 12px;
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--pj-line);
}

/* État 1 : inerte et gris. La maquette le peint orange, ce qui se lit
   comme disponible ; un bouton vivant d'apparence et mort au clic est
   pire que gris (décision du 2026-09-14). En état 2 la page lui ajoute
   `btn-primary`, et §5 de prosyjob-app.css le peint. */
.vf-continue {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-weight: 700;
}

.vf-continue:disabled {
  background: transparent;
  border: 0;
  color: var(--pj-muted);
  cursor: not-allowed;
}

.vf-privacy {
  margin: 0;
  color: var(--pj-muted);
  text-align: center;
  font-size: var(--pj-fs-sm);
}

.vf-privacy i { color: var(--pj-success); }

/* L'écran de reprise ne porte qu'un champ, dans une carte dimensionnée pour
   trois cartes de front : sans cette borne, un champ e-mail s'étire sur près
   d'un mètre d'écran. La carte garde sa largeur — c'est le même gabarit que
   les deux autres états — et c'est le formulaire qui se recentre. */
#vf-resume {
  max-width: 420px;
  margin: 0 auto;
}

/* « Vouliez-vous dire … ? » sous un champ e-mail (E50-15). Une ligne
   discrète : elle suggère, elle ne refuse rien, et rien ici ne doit
   ressembler à un message d'erreur — le champ est valide. */
.pj-email-suggest {
  margin: 6px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* Un `<button>` nu est en pleine largeur dans cette coquille : ici il vit
   dans une phrase, donc `auto` et aucune apparence de bouton. */
.pj-email-suggest .pj-email-suggest__pick {
  width: auto;
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-orange-text);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}

.pj-email-suggest .pj-email-suggest__pick:hover {
  color: var(--pj-orange-dark);
}

/* =====================================================================
   PJ-SOCIAL — « créer un compte avec » (E51)
   ---------------------------------------------------------------------
   Trois boutons de marque, et une phrase qui dit ce qu'ils font
   vraiment : préremplir, pas connecter. Quelqu'un qui clique « Google »
   s'attend à être connecté, alors l'écran doit le détromper avant.

   Les logos sont dessinés en CSS plutôt que chargés : trois fichiers de
   plus, c'est trois requêtes sur la première page que voit un visiteur,
   sur un public à 90 % mobile. Le rond coloré porte l'initiale de la
   marque, ce qui reste reconnaissable et ne dépend d'aucun réseau.
   ===================================================================== */

.pj-social {
  display: grid;
  gap: 10px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.pj-social__title {
  margin: 0;
  color: var(--pj-ink);
  text-align: center;
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.pj-social__buttons {
  display: grid;
  gap: 8px;
}

@media (min-width: 576px) {
  .pj-social__buttons { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
}

/* `width: auto` contre la règle des `<button>` nus, et une hauteur au
   plancher tactile — mesurée, pas supposée. */
.pj-social .pj-social__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 48px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-weight: 600;
  font-size: var(--pj-fs-body);
}

.pj-social .pj-social__btn:hover {
  border-color: var(--pj-orange);
}

.pj-social__icon {
  display: inline-block;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  flex: 0 0 auto;
  position: relative;
}

.pj-social__icon::after {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  line-height: 1;
}

/* Les seules couleurs en dur de la feuille, et elles le sont à dessein :
   ce sont des marques déposées, pas des tokens de notre palette. Un
   thème sombre ne repeint pas le rouge de Google. */
.pj-social__icon--google   { background: #4285F4; }
.pj-social__icon--google::after   { content: "G"; }
.pj-social__icon--yahoo    { background: #6001D2; }
.pj-social__icon--yahoo::after    { content: "Y"; }
.pj-social__icon--linkedin { background: #0A66C2; }
.pj-social__icon--linkedin::after { content: "in"; font-size: 10px; }

.pj-social__note {
  margin: 0;
  color: var(--pj-muted);
  text-align: center;
  font-size: var(--pj-fs-xs);
  line-height: 1.5;
}

/* « ou créer un compte avec votre email », barré de part et d'autre. */
.pj-social__or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 16px 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.pj-social__or::before,
.pj-social__or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--pj-line);
}

/* =====================================================================
   PJ-INPUT / PJ-SUBMIT / PJ-RULE — la page de connexion (E55)
   ---------------------------------------------------------------------
   Maquette `se_connecter.png`. Trois ajouts seulement : une icône dans
   le champ, une flèche sur le bouton, un filet derrière le lien.

   Réutilisables ailleurs, et nommés pour ça : les cinq autres écrans
   d'authentification partagent cette structure, et la maquette d'une
   seule ne doit pas produire une famille qui ne sert qu'à elle.

   **Pas `.pj-field` : le nom est déjà pris.** Le thème vendeur
   (`user-template/css/prosyjob.css`) l'emploie pour un affichage
   clé/valeur en lecture seule, avec son cadre, son fond et son padding
   — et il charge APRÈS cette feuille, donc il gagne. Écrit d'abord sous
   ce nom, le champ est apparu dans une boîte grise, un cadre à
   l'intérieur d'un autre. Une famille `pj-` n'est pas forcément la
   nôtre : le préfixe est partagé avec le thème. Vérifier qu'un nom est
   libre dans les trois feuilles vendeur avant de le prendre.
   ===================================================================== */

.pj-input {
  position: relative;
}

/* `pointer-events: none` : l'icône couvre le bord gauche du champ, et
   sans ça un clic dessus ne donne pas le focus — le champ paraît mort
   là où l'œil va naturellement. */
.pj-input__icon {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--pj-muted);
  font-size: 15px;
  pointer-events: none;
  z-index: 2;
}

/* (0,2,0) contre le `.form-control` du thème à (0,1,0) : la spécificité
   gagne quel que soit l'ordre des feuilles, ce qui est justement ce
   qu'on veut ici puisque cette feuille charge avant le thème. */
.pj-input .form-control {
  padding-left: 42px;
}

.pj-input:focus-within .pj-input__icon {
  color: var(--pj-orange);
}

/* La flèche de la maquette. Le libellé reste centré : c'est un
   `inline-flex` centré, pas un texte poussé par une icône flottante. */
.pj-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

/* Le filet qui traverse, le lien posé dessus. Même mécanique que
   `.pj-social__or` — deux traits qui prennent la place restante. */
.pj-rule {
  display: flex;
  align-items: center;
  gap: 12px;
}

.pj-rule::before,
.pj-rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--pj-line);
}

/* Les liens d'action isolés de ces écrans — « Mot de passe oublié ? »,
   « Je n'ai pas reçu mon code » — sont des cibles à part entière, pas
   des mots dans une phrase. Mesurés à 23px de haut à 360px, la même
   faute qu'E52 sur les cases à cocher : ce qu'on touche, c'est le
   texte, pas le paragraphe qui l'entoure.

   `inline-flex` et non `block` : le lien reste centré par le
   `text-center` de son paragraphe, et ne prend que sa propre largeur.

   « Créer un compte » n'est pas visé : il vit dans une phrase
   (« Pas encore de compte ? … »), et l'agrandir désaligne la phrase. */
.account-page .forgot-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* ═══════════════════════════════════════════════════════════════════════
   « Des fiches portent déjà ce nom » (.src-) et la revendication (.crd-)
   ═══════════════════════════════════════════════════════════════════════

   L'avis vit DANS le formulaire de création, pas au-dessus : il informe et
   ne barre pas. Les homonymes sont permis — aucun index unique sur le nom —
   donc « continuer la création » doit peser autant que « c'est la mienne »,
   et c'est la mise en page qui le dit avant les mots. D'où un fond
   d'accent doux plutôt qu'un fond d'alerte : ce n'est pas un avertissement.

   Pas un seul hex ici : tout descend des tokens --pj-*, faute de quoi le
   thème sombre serait une seconde passe sur ce bloc (§9). */
.src-notice {
  padding: 16px;
  background: var(--pj-accent-soft);
  border: 1px solid var(--pj-line);
}

.src-notice__title {
  margin: 0 0 4px;
  font-weight: 600;
  color: var(--pj-ink);
}

.src-notice__intro {
  margin: 0 0 12px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.src-notice__list {
  list-style: none;
  margin: 0 0 12px;
  padding: 0;
  display: grid;
  gap: 8px;
}

/* Une carte par fiche : à 360px le nom, le lieu et l'action s'empilent,
   au-delà ils tiennent sur une ligne. `wrap` et non une media query —
   ce qui décide ici, c'est la longueur du nom, pas celle de l'écran. */
.src-notice__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.src-notice__name {
  font-weight: 600;
  color: var(--pj-ink);
  /* Un nom d'annuaire n'a pas toujours d'espace où se couper, et la carte
     déborderait plutôt que de rétrécir — la faute mesurée sur .alv-table. */
  overflow-wrap: anywhere;
}

.src-notice__place {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

/* Pousse l'action à droite quand la ligne tient, sous le nom sinon. */
.src-notice__item .btn,
.src-notice__taken {
  margin-left: auto;
}

/* Une fiche déjà tenue se montre — c'est ce qui évite le doublon — mais
   n'offre rien à cliquer : proposer de la revendiquer serait inviter à
   prendre l'entreprise de quelqu'un d'autre. */
.src-notice__taken {
  padding: 4px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

/* `btn, .btn` vaut width:100% dans ce shell : une action en ligne doit
   reprendre sa largeur elle-même (§9). */
.src-notice__item .btn,
.src-notice__continue {
  width: auto;
  min-height: 44px;
}

/* ── La modale de revendication ──────────────────────────────────────── */

.crd-backdrop {
  position: fixed;
  inset: 0;
  /* Au-dessus d'une modale Bootstrap (1055), sous ConfirmPasswordDialog
     (1080) : cette boîte-ci ne demande jamais de mot de passe. */
  z-index: 1060;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(0, 0, 0, 0.45);
}

/* Sa propre surface, et non `.pj-card` : cette classe vit dans
   `prosyjob.css`, que `AssetStacks` COUPE sur la console admin — or la file
   d'arbitrage y ouvre la meme boite. Une modale qui n'a de fond que sur deux
   shells sur trois est le genre de defaut qui ne se voit qu'a l'ecran. */
.crd-dialog {
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  color: var(--pj-ink);
  width: 100%;
  max-width: 520px;
  max-height: 90vh;
  overflow-y: auto;
  padding: 20px;
}

.crd-title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.crd-label {
  display: block;
  margin: 14px 0 6px;
  font-weight: 600;
  color: var(--pj-ink);
}

.crd-hint {
  margin: 6px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.crd-error {
  margin: 12px 0 0;
  padding: 8px 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.crd-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 18px;
}

.crd-actions .btn {
  width: auto;
  min-height: 44px;
}

/* --- Quiz (C4) : la banque, le constructeur, le passage -----------------

   Une seule famille `.qz-` pour les DEUX piles. Les panneaux (banque,
   constructeur) sont montés à la fois dans l'espace organisme (`.pj-app`) et
   dans la console d'administration (`.layout-admin`), or ces deux thèmes sont
   mutuellement exclusifs et `.pj-*` n'existe pas sur le second (CLAUDE.md §9).
   Les panneaux partages portent donc `.qz-panel` et non `.pj-card` — la
   premiere version utilisait la seconde, et sur la console les cartes
   s'affichaient sans fond ni marge interieure. Les jetons `var(--pj-*)`,
   eux, resolvent partout : `prosyjob-app.css` les miroite sur `:root`.

   Mobile d'abord : tout est en colonne sous 720px, et chaque cible tactile
   tient ses 44px. Les mesures sont vérifiées, pas supposées. */

/* Le panneau, et pourquoi ce n'est PAS `.pj-card`.

   `.pj-card` vit dans `prosyjob.css`, que `AssetStacks` ne charge que pour la
   pile utilisateur : sur la console d'administration la classe n'existe pas, et
   les deux panneaux s'y affichaient sans fond ni marge intérieure. Or ils sont
   montés des deux côtés — c'est tout leur intérêt. Ils portent donc leur propre
   classe, définie dans cette feuille, qui elle est chargée partout.

   Les jetons `--pj-*`, eux, résolvent sur les deux piles : `prosyjob-app.css`
   les miroite sur `:root` précisément pour cette raison. */
.qz-panel {
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  box-shadow: var(--pj-shadow-sm);
  padding: 18px;
}

/* La cible de rendu déclare son propre rythme : une pile de panneaux sans
   `gap` les laisse bord à bord, et `.qz-panel` ne porte aucune marge — même
   règle que `.pj-card`, pour la même raison. */
.qz-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ---- les trois onglets : maquettes du 2026-10-04 ----
   `examen_quiz.png`, `examen_banque.png`, `copie_a_corriger.png`. Les deux
   colonnes de la banque se décident sur la largeur de la PILE (`qz` est un
   conteneur), pas de l'écran : au centre de l'espace organisme, un écran de
   1366px ne laisse que 700px. */

.qz-stack {
  container: qz / inline-size;
}

.qz-tabs .nav-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
}

.qz-space__head {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-start;
  justify-content: space-between;
}

.qz-space__switcher {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 220px;
}

/* Un en-tête de panneau : le titre, et son bouton à droite. */
.qz-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 12px;
  margin-bottom: 14px;
}

.qz-head__title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

/* `width: auto` : dans la pile connectée tout `<button>` nu est à 100 %
   (la règle `button, .btn` en tête de cette feuille). */
.qz-head__cta,
.qz-form__actions .btn,
.qz-quiz__publish,
.qzr-open {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

/* Les pastilles d'icône, teintées. */
.qz-ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-lg);
}

.qz-ico--orange  { background: var(--pj-orange-soft);  color: var(--pj-orange); }
.qz-ico--success { background: var(--pj-success-soft); color: var(--pj-success); }
.qz-ico--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

/* Un bouton-icône carré, teinté : modifier en orange, supprimer en rouge,
   retirer en neutre (retirer n'est pas détruire). 44px, comme partout. */
.qz-icon-btn {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.qz-icon-btn--danger  { background: var(--pj-danger-soft);  color: var(--pj-danger); }
.qz-icon-btn--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.qz-icon-btn:disabled {
  opacity: 0.45;
}

/* « + Ajouter … » : une bande pleine largeur, comme la maquette. */
.qz-add-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 600;
}

.qz-hint {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.qz-req {
  color: var(--pj-danger);
}

.qz-empty-line {
  padding: 8px 0;
  color: var(--pj-muted);
  list-style: none;
}

/* ---- les formulaires en ligne (jamais de modale : cf. SectionListEditor) ---- */

.qz-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0 0 14px;
}

/* Le formulaire posé sur un fond : celui d'un quiz, celui d'une catégorie. */
.qz-form--soft {
  padding: 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.qz-form__title {
  margin: 0;
  color: var(--pj-ink);
  font-weight: 700;
}

.qz-form__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin-bottom: 12px;
}

.qz-form .qz-form__row {
  margin-bottom: 0;
}

.qz-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.qz-field .form-control {
  min-height: 44px;
  font-weight: 400;
}

.qz-field legend {
  float: none;
  width: auto;
  margin-bottom: 4px;
  padding: 0;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

/* Un suffixe dans le champ : « % », l'horloge. */
.qz-affix {
  position: relative;
  display: block;
}

.qz-affix .form-control {
  padding-right: 44px;
}

.qz-affix__end {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  display: grid;
  place-items: center;
  width: 44px;
  border-left: 1px solid var(--pj-line);
  color: var(--pj-muted);
  font-weight: 400;
  pointer-events: none;
}

.qz-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.qz-error {
  margin: 0;
  color: var(--pj-danger);
  font-size: var(--pj-fs-sm);
}

.qz-errors {
  margin: 12px 0;
}

/* ---- l'éditeur de réponses ---- */

.qz-checks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* La case ET son libellé forment la cible : c'est la faute d'E52, où l'on
   touchait le texte et non le paragraphe. 44px, mesurés. */
.qz-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin: 0;
  padding: 0 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  font-weight: 400;
  cursor: pointer;
}

.qz-check:has(input:checked) {
  border-color: var(--pj-info-ink);
  background: var(--pj-info-soft);
}

.qz-check .form-check-input,
.qz-answer__flag .form-check-input {
  margin: 0;
  float: none;
}

.qz-answers {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 10px;
}

.qz-answer {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

.qz-answer > .form-control {
  flex: 1 1 auto;
  min-width: 0;
}

.qz-answer__flag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  min-height: 44px;
  margin: 0;
  cursor: pointer;
}

.qz-answer__rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-body);
}

.qz-answer__label {
  flex: 1;
}

.qz-answer__actions {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}

/* ---- Mes quiz ---- */

.qz-plan-edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qz-plan-edit:empty {
  display: none;
}

.qz-plan-row {
  display: flex;
  gap: 8px;
  align-items: center;
}

.qz-plan-row .form-control {
  min-height: 44px;
}

.qz-plan-row select.form-control {
  flex: 1 1 auto;
  min-width: 0;
}

.qz-plan-row__n {
  width: 84px;
  flex-shrink: 0;
}

.qz-quizzes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qz-quiz {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.qz-quiz__body {
  min-width: 0;
}

.qz-quiz__title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.qz-quiz__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 14px;
  margin: 4px 0 6px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.qz-quiz__meta i {
  margin-right: 4px;
}

.qz-quiz__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
}

.qz-state {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.qz-state--draft     { background: var(--pj-warning-ink);  color: var(--pj-card); }
.qz-state--published { background: var(--pj-success-soft); color: var(--pj-success); }
.qz-state--archived  { background: var(--pj-neutral-soft); color: var(--pj-muted); }

.qz-plan {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.qz-plan__line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.qz-plan__count {
  white-space: nowrap;
}

/* Le demandé dépasse le disponible : la publication refusera en nommant cette
   catégorie. Le dire ici évite que le refus soit une surprise. */
.qz-plan__line.is-short .qz-plan__count,
.qz-shortfall {
  color: var(--pj-danger);
}

.qz-shortfall {
  margin: 0;
  font-size: var(--pj-fs-sm);
}

/* ---- La banque ---- */

.qz-bank {
  display: grid;
  gap: 16px;
}

.qz-cats,
.qz-questions {
  display: flex;
  flex-direction: column;
  margin: 0 0 14px;
  padding: 0;
  list-style: none;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.qz-questions {
  margin: 0;
}

.qz-cat,
.qz-question {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--pj-card);
}

.qz-cat + .qz-cat,
.qz-question + .qz-question {
  border-top: 1px solid var(--pj-line);
}

.qz-cat.is-dragging {
  position: relative;
  z-index: 1;
  box-shadow: var(--pj-shadow);
  outline: 2px solid var(--pj-orange);
}

/* La poignée : à glisser au doigt comme à la souris (`touch-action` le
   permet), ou à déplacer aux flèches une fois focalisée. */
.qz-cat__handle {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 32px;
  height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--pj-muted);
  cursor: grab;
  touch-action: none;
}

.qz-cat.is-dragging .qz-cat__handle {
  cursor: grabbing;
}

.qz-cat__text {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.qz-cat__text span {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.qz-cat__actions,
.qz-question__actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

/* Le type, en pastille teintée. */
.qz-type {
  flex: 0 0 auto;
  min-width: 112px;
  padding: 6px 10px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  text-align: center;
}

.qz-type--info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.qz-type--orange  { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.qz-type--success { background: var(--pj-success-soft); color: var(--pj-success); }
.qz-type--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.qz-type--accent  { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.qz-type--neutral { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.qz-question__body {
  flex: 1 1 auto;
  min-width: 0;
}

.qz-question__text {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  overflow-wrap: anywhere;
}

.qz-question__meta {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

/* Une question retirée reste lisible : elle est référencée par les tentatives
   passées, et l'écran doit dire « elle n'est plus tirée », pas la cacher. */
.qz-question.is-retired {
  opacity: 0.65;
}

/* La liste des questions court sous les deux colonnes. */
.qz-bank__list {
  padding: 10px;
}

/* Téléphone : le type passe au-dessus de l'énoncé. */
@container qz (max-width: 559px) {
  .qz-question {
    flex-wrap: wrap;
  }

  .qz-type {
    min-width: 0;
  }

  .qz-question__body {
    flex-basis: 100%;
    order: 1;
  }

  .qz-question__actions {
    margin-left: auto;
  }
}

@container qz (min-width: 820px) {
  .qz-bank {
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    align-items: start;
  }

  .qz-bank__list {
    grid-column: 1 / -1;
  }
}

/* ---- Copies à corriger ---- */

.qzr-head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 14px;
}

.qzr-head .qz-hint {
  margin-top: 4px;
}

.qzr-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.qzr-table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-size: var(--pj-fs-sm);
}

.qzr-table th {
  padding: 10px 12px;
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-weight: 700;
  text-align: left;
  white-space: nowrap;
}

.qzr-table td {
  padding: 8px 12px;
  border-top: 1px solid var(--pj-line);
  color: var(--pj-ink);
  vertical-align: middle;
}

.qzr-table th + th,
.qzr-table td + td {
  border-left: 1px solid var(--pj-line);
}

.qzr-table tr.is-open td {
  background: var(--pj-orange-soft);
}

.qzr-narrow {
  display: none;
}

.qzr-paper {
  display: grid;
  gap: 14px;
}

.qzr-who {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.qzr-who i {
  color: var(--pj-orange);
}

.qzr-questions {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.qzr-q + .qzr-q {
  border-top: 1px solid var(--pj-line);
}

/* Toute la ligne déplie, pas seulement le chevron. */
.qzr-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 10px 12px;
  border: 0;
  background: transparent;
  text-align: left;
}

.qzr-n {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--pj-accent-soft);
  color: var(--pj-accent-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.qzr-text {
  display: grid;
  gap: 2px;
  flex: 1 1 auto;
  min-width: 0;
}

.qzr-enonce {
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.qzr-sub {
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
}

.qzr-chev {
  flex: 0 0 auto;
  color: var(--pj-muted);
}

.qzr-detail {
  display: grid;
  gap: 10px;
  padding: 0 12px 14px 52px;
}

.qzr-written {
  margin: 0;
  padding: 10px 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.qzr-verdict {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* Juste / Faux : contour au repos, plein une fois choisi. */
.qzr-verdict__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding: 0 16px;
  border: 1.5px solid currentColor;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  font-weight: 600;
}

.qzr-verdict__btn--right { color: var(--pj-success); }
.qzr-verdict__btn--wrong { color: var(--pj-danger); }

.qzr-verdict__btn--right.is-on { background: var(--pj-success-soft); }
.qzr-verdict__btn--wrong.is-on { background: var(--pj-danger-soft); }

.qzr-ticks {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.qzr-tick {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.qzr-tick.is-on {
  background: var(--pj-info-soft);
  color: var(--pj-ink);
  font-weight: 600;
}

.qzr-tick__mark {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  border: 1px solid var(--pj-line);
  border-radius: 4px;
  background: var(--pj-card);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
}

.qzr-missing {
  margin-top: -4px;
}

@container qz (max-width: 559px) {
  .qzr-wide {
    display: none;
  }

  .qzr-narrow {
    display: inline;
  }

  .qzr-table th,
  .qzr-table td {
    padding: 8px 6px;
    font-size: var(--pj-fs-xs);
  }

  /* Deux classes : la règle vendue de `.btn` gagnait sur une seule, et le
     bouton gardait 118px — le tableau débordait de 44px à 375. */
  .qzr .qzr-open {
    padding: 4px 10px;
    font-size: var(--pj-fs-xs);
  }

  .qzr .qzr-open i {
    display: none;
  }

  .qzr-detail {
    padding-left: 12px;
  }
}

/* ---- L'accueil d'un examen : maquette `composer.png` (2026-10-04) ----
   Famille `qzh-`. La page vit sous `/examens` ET sous `/academy/examen`, deux
   coquilles : la carte porte donc son propre fond plutôt que `.pj-card`. Les
   tuiles se décident sur la largeur de la SECTION (un conteneur). */

/* La section espace ses blocs elle-même : le retour, l'en-tête de la copie,
   le corps — `.pj-card` ne porte aucune marge (CLAUDE.md §9). */
.qz-sitting {
  display: grid;
  gap: 16px;
  container: qzh / inline-size;
}

.qzh-back {
  display: inline-flex;
  align-items: center;
  justify-self: start;
  gap: 10px;
  width: auto;
  min-height: 44px;
}

.qzh-card {
  display: grid;
  gap: 16px;
  padding: 18px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
}

.qzh-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 14px;
}

.qzh-ico {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-card);
}

.qzh-title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.qzh-meta {
  margin: 6px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* Le cercle du seuil : un dégradé conique, l'anneau creusé par un masque. */
.qzh-ring {
  position: relative;
  display: grid;
  place-content: center;
  grid-column: 1 / -1;
  justify-self: center;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  background: conic-gradient(var(--pj-success) calc(var(--qzh-p, 0) * 1%), var(--pj-neutral-soft) 0);
  text-align: center;
}

.qzh-ring::before {
  content: "";
  position: absolute;
  inset: 12px;
  border-radius: 50%;
  background: var(--pj-card);
}

.qzh-ring__value,
.qzh-ring__label {
  position: relative;
}

.qzh-ring__value {
  color: var(--pj-success);
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.1;
}

.qzh-ring__label {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.qzh-info {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0;
  padding: 14px 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.qzh-info i {
  margin-top: 2px;
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-lg);
}

.qzh-tiles {
  display: grid;
  gap: 10px;
}

.qzh-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 12px 14px;
  border-radius: var(--pj-radius-sm);
}

.qzh-tile__ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  font-size: var(--pj-fs-lg);
}

.qzh-tile--info    { background: var(--pj-info-soft); }
.qzh-tile--success { background: var(--pj-success-soft); }
.qzh-tile--orange  { background: var(--pj-orange-soft); }
.qzh-tile--accent  { background: var(--pj-accent-soft); }

.qzh-tile--info    .qzh-tile__ico { color: var(--pj-info-ink); }
.qzh-tile--success .qzh-tile__ico { color: var(--pj-success); }
.qzh-tile--orange  .qzh-tile__ico { color: var(--pj-orange); }
.qzh-tile--accent  .qzh-tile__ico { color: var(--pj-accent-ink); }

.qzh-tile__text {
  display: grid;
  min-width: 0;
}

.qzh-tile__label {
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
}

.qzh-tile__value {
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
}

.qzh-foot {
  padding-top: 14px;
  border-top: 1px solid var(--pj-line);
}

.qzh-go {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
}

.qzh-hint {
  margin: 0;
  color: var(--pj-muted);
}

.qzh-subtitle {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.qzh-history__list {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.qzh-history__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  padding: 10px 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.qzh-history__row + .qzh-history__row {
  border-top: 1px solid var(--pj-line);
}

.qzh-history__when {
  flex: 1 1 140px;
  color: var(--pj-muted);
}

.qzh-history__score {
  font-weight: 700;
}

.qzh-pill {
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.qzh-pill--ok { background: var(--pj-success-soft); color: var(--pj-success); }
.qzh-pill--ko { background: var(--pj-danger-soft);  color: var(--pj-danger); }

.qzh-history__btn {
  width: auto;
  min-height: 44px;
}

@container qzh (min-width: 640px) {
  .qzh-card {
    padding: 22px 24px;
  }

  .qzh-head {
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 20px;
  }

  .qzh-ico {
    width: 72px;
    height: 72px;
    font-size: var(--pj-fs-title);
  }

  .qzh-title {
    font-size: var(--pj-fs-title);
  }

  .qzh-ring {
    grid-column: auto;
    width: 140px;
    height: 140px;
  }

  .qzh-ring__value {
    font-size: var(--pj-fs-title);
  }

  .qzh-tiles {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .qzh-go {
    width: auto;
    padding-left: 28px;
    padding-right: 28px;
  }
}

/* Entre les deux : deux tuiles par ligne. */
@container qzh (min-width: 460px) and (max-width: 639px) {
  .qzh-tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---- le passage : maquette `compser_examen.png` (2026-10-04) ----
   L'en-tête (titre, consigne, encart questions / temps restant), une carte
   par question, les réponses en deux colonnes quand la place le permet. Les
   cartes portent leur fond : la page vit sous deux coquilles. */

.qzc-head {
  display: grid;
  gap: 12px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
}

.qzc-title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-card);
  font-weight: 800;
  line-height: 1.2;
  overflow-wrap: anywhere;
}

.qzc-meta {
  margin: 4px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.qzc-stats {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  align-items: center;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.qzc-stats:not(:has(.qzc-stat:not([hidden]))) {
  display: none;
}

.qzc-stat {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 10px 16px;
  color: var(--pj-ink);
}

.qzc-stat + .qzc-stat:not([hidden]) {
  border-left: 1px solid var(--pj-line);
}

.qzc-stat i {
  font-size: var(--pj-fs-card);
}

.qzc-stat span {
  display: grid;
  line-height: 1.15;
}

.qzc-stat strong {
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.qzc-stat small {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.qzc-stat--clock {
  color: var(--pj-orange);
}

.qzc-stat--clock.is-urgent {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.qz-passed {
  color: var(--pj-success);
}

.qz-paper {
  display: grid;
  gap: 12px;
}

.qz-paper__q {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

/* Une question : une carte, son numéro dans une pastille.

   `display: block` et une légende FLOTTANTE : un <legend> se dessine
   nativement SUR la bordure de son <fieldset>, au-dessus de la marge
   intérieure — l'énoncé et sa pastille chevauchaient le bord de la carte
   (mesuré : la légende commençait au pixel même du bord). Flottée sur toute
   la largeur, elle redevient un bloc du contenu ; ce qui suit la dégage. */
.qzc-q {
  display: block;
  padding: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

/* Restée sans réponse au moment de rendre : signalée, pas bloquée. */
.qzc-q.is-missing {
  border-color: var(--pj-orange);
  box-shadow: 0 0 0 2px var(--pj-orange-soft);
}

.qz-paper__q legend {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  float: left;
  width: 100%;
  margin: 0 0 10px;
  padding: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 700;
}

.qz-paper__n {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--pj-accent-soft);
  color: var(--pj-accent-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 800;
}

.qz-paper__text {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 4px;
  overflow-wrap: anywhere;
}

.qzc-q__hint {
  display: block;
  margin-top: 2px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 400;
}

.qz-paper__verdict {
  flex: 0 0 auto;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
}

.qz-paper__verdict.is-right {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.qz-paper__verdict.is-wrong {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.qz-paper__answers {
  display: grid;
  clear: both;
  gap: 8px;
}

/* Toute la ligne est cliquable, pas seulement le rond. 44px, mesurés. */
.qz-answer--pick {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  margin: 0;
  padding: 8px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  cursor: pointer;
}

.qz-answer--pick .form-check-input {
  flex: 0 0 auto;
  margin: 0;
  float: none;
}

.qz-answer--pick:has(input:checked) {
  border-color: var(--pj-info-ink);
  background: var(--pj-info-soft);
}

.qz-answer--pick.is-expected {
  border-color: var(--pj-success);
  background: var(--pj-success-soft);
}

.qz-answer--pick.is-mistake {
  border-color: var(--pj-danger);
  background: var(--pj-danger-soft);
}

.qz-answer--order {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 6px 10px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-sm);
}

.qzc-move {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
  color: var(--pj-ink);
}

.qzc-move:disabled {
  opacity: 0.4;
}

.qz-answer--written textarea {
  min-height: 110px;
}

.qz-answer__expected {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* Deux colonnes d'office sur la largeur ; sur téléphone, seulement quand la
   question n'a que des réponses courtes, en nombre pair. */
.qzc-answers--short {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@container qzh (min-width: 640px) {
  .qzc-head {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    padding: 18px 22px;
  }

  .qzc-title {
    font-size: var(--pj-fs-title);
  }

  .qzc-q {
    padding: 14px 18px;
  }

  .qzc-answers {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Toutes les réponses — cases, classement, zone de texte — s'alignent
     sous l'énoncé, pas sous la pastille du numéro. */
  .qzc-q .qz-paper__answers {
    padding-left: 42px;
  }
}

.qzc-confirm {
  display: grid;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.qzc-confirm p {
  margin: 0;
}

.qzc-confirm i {
  margin-right: 6px;
  color: var(--pj-orange);
}

.qzc-confirm__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 10px;
}

.qzc-confirm__actions .btn {
  width: auto;
  min-height: 44px;
}

.qz-paper__actions {
  display: flex;
  justify-content: flex-end;
}

.qzc-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
}

@container qzh (min-width: 640px) {
  .qzc-submit {
    width: auto;
    padding-left: 28px;
    padding-right: 28px;
  }
}

/* Le résultat, en tête de la copie rendue. */
.qzc-verdict {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  border: 1px solid var(--pj-danger-soft);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.qzc-verdict.is-passed {
  border-color: var(--pj-success-soft);
}

.qzc-verdict__score {
  flex: 0 0 auto;
  color: var(--pj-danger);
  font-size: var(--pj-fs-display);
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.qzc-verdict.is-passed .qzc-verdict__score {
  color: var(--pj-success);
}

.qzc-verdict__ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-lg);
}

.qzc-verdict--waiting {
  border-color: var(--pj-warning-soft);
}

.qzc-verdict__label {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 800;
}

.qzc-verdict__hint {
  margin: 2px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* À 360px, une ligne d'actions et un en-tête à deux colonnes n'ont pas la
   place : ils passent en colonne plutôt que de déborder. `overflow-x: auto`
   ne bornerait que ce qui est MONTRÉ, pas ce qui déborde. */
@media (max-width: 719.98px) {
  .qz-question,
  .qz-quiz,
  .qz-cat {
    flex-direction: column;
    align-items: stretch;
  }

  .qz-question__actions,
  .qz-quiz__actions,
  .qz-cat__actions {
    justify-content: flex-end;
  }

  .qz-plan-row {
    flex-wrap: wrap;
  }

  .qz-plan-row select {
    flex: 1 1 100%;
  }
}

/* ---------------------------------------------------------------------
   Académie — l'accueil, le catalogue et l'axe du parcours (2026-09-23)
   --------------------------------------------------------------------- */

.ac-hero h1 {
  margin-bottom: 6px;
}

.ac-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--pj-muted);
  text-decoration: none;
  font-size: var(--pj-fs-body);
}

.ac-back:hover {
  color: var(--pj-ink);
}

/* Le catalogue. Une carte par parcours, en grille auto : à 360px il y en a
   une par ligne, et la grille se remplit d'elle-même au-delà. */
.ac-catalogue {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--pj-gap);
}

.ac-course {
  display: flex;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  text-decoration: none;
  color: inherit;
  /* Toute la carte est la cible : à 360px, un lien de trois mots dans un
     pavé de 260px est une cible qu'on rate. */
  min-height: 92px;
}

.ac-course:hover {
  border-color: var(--pj-orange);
  box-shadow: var(--pj-shadow-sm);
}

.ac-course--done {
  border-color: var(--pj-success);
}

.ac-course__seal {
  color: var(--pj-orange);
  font-size: var(--pj-fs-card);
  line-height: 1;
  flex: 0 0 auto;
}

.ac-course--done .ac-course__seal {
  color: var(--pj-success);
}

/* Un auto-test ne certifie rien : son sceau n'est pas celui d'un diplome.
   La couleur d'information plutot que l'orange de la marque, et la paire
   est celle deja mesuree pour les pastilles d'info — 6,35:1 en clair,
   7,76:1 en sombre. Un parcours obtenu passe au vert quoi qu'il arrive :
   la regle ci-dessus vient apres, et c'est bien ce qu'on veut. */
.ac-course--test .ac-course__seal,
.ac-reward--test .ac-reward__node {
  color: var(--pj-info-ink);
}

.ac-course__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.ac-course__name {
  font-weight: 600;
  color: var(--pj-ink);
}

/*
 * « Ce cours est en anglais », a cote du titre.
 *
 * Posee seulement quand la langue du parcours differe de celle qu'on lit
 * (voir `AcademyHomePage._langue`), donc rare par construction : sur un
 * catalogue francais elle marque les neuf parcours anglais et laisse les
 * douze autres nus.
 *
 * `inline-block` et `nowrap` : elle suit le titre et passe a la ligne avec
 * lui, mais ne se coupe jamais au milieu d'un nom de langue. Ton neutre et
 * non couleur d'alerte -- lire un cours dans une autre langue n'est pas une
 * erreur, c'est une information.
 */
.ac-course__lang {
  display: inline-block;
  white-space: nowrap;
  vertical-align: middle;
  padding: 1px 6px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 500;
}

/*
 * « Aussi en English », sur la carte du cours.
 *
 * Dans la ligne de meta, avec le nombre d'etapes : c'est une propriete du
 * cours au meme titre, et non une alerte. Absente quand le cours n'a pas de
 * traduction -- et cette absence DIT quelque chose, elle aussi.
 */
.ac-course__also {
  color: var(--pj-muted);
  font-style: italic;
}

/*
 * LE BANDEAU DU FILTRE DE LANGUE.
 *
 * Au-dessus du catalogue et non dans une carte : il parle de ce qu'on va
 * lire en dessous, pas d'un contenu a lui. Discret -- un fond neutre, pas
 * une couleur d'alerte -- parce qu'il annonce un choix d'affichage normal et
 * non un probleme.
 */
.ac-avis {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
}

.ac-avis__text {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/*
 * Un vrai bouton et non un lien : il ne mene nulle part, il repeint la page
 * d'ou on est. Les styles de lien sont reserves a ce qui navigue.
 */
.ac-avis__btn {
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-primary);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}

.ac-avis__btn:hover,
.ac-avis__btn:focus-visible {
  color: var(--pj-primary-ink);
}

.ac-course__desc {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.ac-course__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  margin-top: auto;
}

.ac-course__done {
  color: var(--pj-success);
  font-weight: 600;
}

/* « Où j'en suis » : une ligne par parcours engagé. */
.ac-mine {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ac-mine__sub {
  margin-top: 18px;
  font-size: var(--pj-fs-body);
}

.ac-mine__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.ac-mine__name {
  font-weight: 600;
  color: var(--pj-ink);
  text-decoration: none;
  flex: 1 1 200px;
}

.ac-mine__name:hover {
  color: var(--pj-orange);
}

.ac-mine__bar {
  flex: 0 0 120px;
  height: 6px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  overflow: hidden;
}

.ac-mine__bar > span {
  display: block;
  height: 100%;
  background: var(--pj-orange);
}

.ac-mine__pct {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-variant-numeric: tabular-nums;
}

/* ---- L'axe du parcours ----------------------------------------------
   « Les étapes sont placées de part et d'autre d'un axe central, au bout
   duquel apparaît la récompense. »

   De part et d'autre seulement quand il y a la place. À 360px, deux colonnes
   de texte font six mots par ligne : sous 768px l'axe se range à gauche et
   tout se lit du même côté. La description vaut pour un écran large ; elle ne
   vaut pas contre la lisibilité sur le téléphone de 90% des visiteurs.
   --------------------------------------------------------------------- */
.ac-axis {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 18px;
}

.ac-axis::before {
  content: "";
  position: absolute;
  top: 12px;
  bottom: 12px;
  left: 15px;
  width: 2px;
  background: var(--pj-line);
}

.ac-step {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  align-items: start;
  gap: 12px;
}

/* La pastille est opaque : sans fond, le trait de l'axe la traverse. */
.ac-step__node {
  grid-column: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--pj-card);
  border: 2px solid var(--pj-line);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  z-index: 1;
}

.ac-step__card {
  grid-column: 2;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.ac-step__order {
  color: var(--pj-muted);
  font-size: var(--pj-fs-2xs);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.ac-step__name {
  font-weight: 600;
  color: var(--pj-ink);
}

.ac-step__measure {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-variant-numeric: tabular-nums;
}

.ac-step__note {
  color: var(--pj-warning-ink);
  background: var(--pj-warning-soft);
  border-radius: var(--pj-radius-sm);
  padding: 6px 8px;
  font-size: var(--pj-fs-xs);
}

/* 44px de haut : c'est la règle de ce projet, et elle se mesure. */
.ac-step__go {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-fill);
  color: var(--pj-orange-text);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  width: auto;
}

.ac-step__go:hover {
  background: var(--pj-orange-fill-hover);
}

/* Les trois états, et le quatrième qui n'en est pas un : « courante » dit par
   où commencer, sans rien affirmer sur ce que le moteur autorise. */
.ac-step--satisfaite .ac-step__node {
  background: var(--pj-success);
  border-color: var(--pj-success);
  color: var(--pj-card);
}

.ac-step--satisfaite .ac-step__card {
  background: var(--pj-success-soft);
  border-color: var(--pj-success);
}

.ac-step--illisible .ac-step__node {
  border-color: var(--pj-warning);
  color: var(--pj-warning-ink);
}

/* Verrouillée : en retrait, jamais barrée. Elle n'est pas hors du parcours,
   elle est DEVANT — et son nom reste lisible, parce que c'est lui qui donne
   envie d'avancer. */
.ac-step--verrouillee .ac-step__node {
  border-style: dashed;
  border-color: var(--pj-line);
  color: var(--pj-muted);
  background: var(--pj-card-2);
}

.ac-step--verrouillee .ac-step__card {
  border-style: dashed;
}

.ac-step--verrouillee .ac-step__name {
  color: var(--pj-muted);
}

/* Il a tout fait et n'a rien reçu : la phrase qui dit pourquoi. En encadré et
   non en note grise — c'est la réponse à la question qu'il se pose en arrivant
   sur l'écran. */
.ac-path__waiting {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: var(--pj-radius);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-body);
}

/* ---- Les participants (E36-05) -----------------------------------------
   Monté dans DEUX coquilles : la console d'administration et l'espace d'un
   organisme. Ses règles ne s'appuient donc sur aucune des deux — des classes à
   lui, et des tokens. */

.ap-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

.ap-item {
  display: grid;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
}

.ap-item--awaiting_validation {
  border-color: var(--pj-warning-ink);
}

.ap-item__who {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.ap-item__name {
  font-weight: 600;
}

.ap-item__when {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* La note d'un refus se lit : c'est ce que la personne doit reprendre. */
.ap-item__note {
  margin: 0;
  padding: 8px 10px;
  border-radius: var(--pj-radius);
  background: var(--pj-card-2);
  font-size: var(--pj-fs-body);
}

.ap-badge {
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-transform: uppercase;
  white-space: nowrap;
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.ap-badge--awaiting_validation {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.ap-badge--validated {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.ap-badge--refused {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.ap-item__decide {
  display: grid;
  gap: 8px;
  margin-top: 4px;
}

.ap-field {
  display: grid;
  gap: 4px;
}

.ap-field > span {
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

/* Les deux gestes se suivent et passent à la ligne quand la colonne est
   étroite : à 360px deux boutons de 44px côte à côte ne rentrent pas toujours. */
.ap-item__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ap-item__actions .btn {
  width: auto;
  min-height: 44px;
}

.ap-warn {
  color: var(--pj-warning-ink);
}

/* ---- Le contrat partenaire (E36-06) ------------------------------------- */

.ac-contract {
  display: grid;
  gap: 16px;
}

.ac-contract__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.ac-contract__head h1 {
  margin: 0;
  font-size: var(--pj-fs-card);
}

/* Une colonne de LECTURE. Un contrat se lit en entier, et une ligne de 120
   caractères se relit trois fois — 70ch est la mesure que le reste du produit
   emploie déjà pour ses paragraphes. */
.ac-contract__body {
  max-width: 70ch;
  line-height: 1.65;
}

.ac-contract__body h2,
.ac-contract__body h3 {
  margin: 20px 0 8px;
  font-size: var(--pj-fs-lg);
}

.ac-contract__body p,
.ac-contract__body li {
  margin: 0 0 10px;
}

.ac-contract__warn {
  color: var(--pj-warning-ink);
}

/* QUEL PAYS ENGAGE LE SIGNATAIRE (2026-10-09).
   Discrete quand le contrat est bien celui du pays du compte : elle ne fait
   que confirmer. L'encre d'avertissement quand il vient du siege, parce que
   la phrase previent alors d'un engagement que le lecteur ne suppose pas. */
.ac-contract__origin {
  margin: 4px 0 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.ac-contract__origin--default {
  color: var(--pj-warning-ink);
}

.ac-contract__foot {
  display: grid;
  gap: 10px;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
  max-width: 70ch;
}

/* Le seul geste de la page : il se voit, et il fait 44px. */
.ac-contract__sign {
  justify-self: start;
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.ac-contract__legal {
  font-size: var(--pj-fs-body);
}

/* ---- Le numero et le PDF sur la liste des certificats (E36-07) ---------- */

.ac-cert__num {
  font-size: var(--pj-fs-sm);
  letter-spacing: .04em;
  color: var(--pj-muted);
}

/* Un bouton, pas un lien : la route est authentifiee, donc le fichier passe
   par le client API. 44px, comme toute cible tactile ici. */
.ac-cert__pdf {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: auto;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.ac-cert__pdf:hover {
  border-color: var(--pj-orange);
  color: var(--pj-orange);
}

/* ---- La verification publique (E36-07) --------------------------------- */

.cv-verify {
  display: grid;
  gap: 16px;
  max-width: 720px;
  margin: 0 auto;
}

.cv-verify__head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin-bottom: 18px;
}

.cv-verify__head h1 {
  margin: 0;
  font-size: var(--pj-fs-card);
}

.cv-verify__seal {
  font-size: var(--pj-fs-title);
  color: var(--pj-orange);
  line-height: 1;
}

/* Le champ et le bouton se suivent, et passent a la ligne quand la colonne est
   etroite : a 360px un champ de numero et un bouton cote a cote ne rentrent
   pas. */
.cv-verify__form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 10px;
}

.cv-verify__field {
  display: grid;
  gap: 4px;
  flex: 1 1 240px;
  min-width: 0;
}

.cv-verify__field > span {
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.cv-verify__field input {
  /* Un numero se relit caractere par caractere : l'espacement aide a le
     comparer avec le papier qu'on a sous les yeux. */
  letter-spacing: .08em;
  text-transform: uppercase;
}

.cv-verify__submit {
  width: auto;
  min-height: 44px;
}

.cv-verify__answer {
  margin-top: 20px;
  padding: 16px;
  border-radius: var(--pj-radius);
  border: 1px solid var(--pj-line);
}

.cv-verify__answer--ok {
  border-color: var(--pj-success);
  background: var(--pj-success-soft);
}

.cv-verify__answer--ko {
  border-color: var(--pj-danger);
  background: var(--pj-danger-soft);
}

/* Le verdict d'abord, et en grand : c'est la seule chose qu'on est venu lire,
   et le detail ne sert qu'a la confirmer. */
.cv-verify__verdict {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

.cv-verify__answer--ok .cv-verify__verdict {
  color: var(--pj-success);
}

.cv-verify__answer--ko .cv-verify__verdict {
  color: var(--pj-danger);
}

.cv-verify__facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 4px 14px;
  margin: 0;
}

.cv-verify__facts dt {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.cv-verify__facts dd {
  margin: 0;
  font-weight: 600;
}

.cv-verify__num {
  margin: 12px 0 0;
  font-size: var(--pj-fs-sm);
  letter-spacing: .06em;
  color: var(--pj-muted);
}

.cv-verify__unknown {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 20px;
  padding: 16px;
  border-radius: var(--pj-radius);
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.ac-step--current .ac-step__node {
  border-color: var(--pj-orange);
  color: var(--pj-orange);
}

.ac-step--current .ac-step__card {
  border-color: var(--pj-orange);
  box-shadow: var(--pj-shadow-sm);
}

/* Le bout de l'axe. */
.ac-reward {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  margin-top: 4px;
}

.ac-reward__node {
  grid-column: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--pj-card);
  border: 2px solid var(--pj-orange);
  color: var(--pj-orange);
  z-index: 1;
}

.ac-reward__card {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  padding: 12px;
  border: 1px dashed var(--pj-orange);
  border-radius: var(--pj-radius);
}

.ac-reward--won .ac-reward__node {
  background: var(--pj-success);
  border-color: var(--pj-success);
  color: var(--pj-card);
}

.ac-reward--won .ac-reward__card {
  border-style: solid;
  border-color: var(--pj-success);
  background: var(--pj-success-soft);
}

.ac-reward__label {
  color: var(--pj-muted);
  font-size: var(--pj-fs-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  width: 100%;
}

/* La vignette du certificat, sur sa propre ligne. Meme moyen que le libelle
   juste au-dessus : la carte est un `flex-wrap`, et sans cela la vignette se
   posait a cote du pourcentage. Son espacement vient de sa propre marge. */
.ac-reward__cert {
  width: 100%;
}

.ac-reward__name {
  font-weight: 700;
  color: var(--pj-ink);
}

.ac-reward__state {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-variant-numeric: tabular-nums;
}

.ac-path__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.ac-path__count {
  font-weight: 700;
  color: var(--pj-muted);
  font-variant-numeric: tabular-nums;
}

.ac-path__hint {
  margin: 18px 0 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* À partir de 768px seulement : l'axe se centre et les étapes se répartissent
   de part et d'autre, comme le demande la spécification. */
@media (min-width: 768px) {
  .ac-axis::before {
    left: 50%;
    transform: translateX(-50%);
  }

  .ac-step,
  .ac-reward {
    grid-template-columns: minmax(0, 1fr) 32px minmax(0, 1fr);
  }

  /* Sans cela, la carte de gauche (colonne 1) ne peut plus entrer dans
     la rangée que la pastille (colonne 2) a déjà ouverte : le placement
     automatique ne revient pas en arrière, et il en crée une seconde.
     Mesuré à 44px d'écart sur une ligne sur deux. */
  .ac-step > *,
  .ac-reward > * {
    grid-row: 1;
  }

  .ac-step__node,
  .ac-reward__node {
    grid-column: 2;
  }

  .ac-step--left .ac-step__card {
    grid-column: 1;
    align-items: flex-end;
    text-align: right;
  }

  .ac-step--left .ac-step__go {
    align-self: flex-end;
    flex-direction: row-reverse;
  }

  .ac-step--right .ac-step__card {
    grid-column: 3;
  }

  /* Colonne 3, comme une étape de droite. `2 / span 2` la faisait
     commencer dans la colonne de la PASTILLE, dont le `z-index: 1` la
     dessinait par-dessus le texte : 19px du nom cachés, mesurés. La
     récompense est le bout de l'axe, pas un bloc qui l'enjambe. */
  .ac-reward__card {
    grid-column: 3;
  }
}

/* Les certificats obtenus, repris de l'ancien écran : une ligne par
   certificat, et le passé grisé sans disparaître — il a été mérité. */
.ac-certs {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.ac-cert {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.ac-cert > .fa-certificate {
  color: var(--pj-orange);
}

.ac-cert--past {
  opacity: 0.7;
}

.ac-cert--past > .fa-certificate {
  color: var(--pj-muted);
}

.ac-cert__name {
  font-weight: 600;
}

/* Les étapes déclarées portent deux gestes : ouvrir la ressource, et dire
   qu'on l'a terminée. Ils se suivent, et passent à la ligne quand la colonne
   est étroite — à 360px deux boutons de 44px côte à côte ne rentrent pas. */
.ac-step__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Sortie du site : un chevron distinct du « suivant » interne, pour que le
   geste ne se confonde pas avec une navigation dans l'Académie. */
.ac-step__go--out {
  background: var(--pj-card-2);
  color: var(--pj-ink);
  border: 1px solid var(--pj-line);
}

.ac-step__go--out:hover {
  border-color: var(--pj-orange);
}

/* Le genre d'une étape, dans le composeur de la console. Quatre teintes de la
   palette plutôt que quatre nuances d'une seule : la liste se lit en diagonale,
   et c'est la couleur qu'on reconnaît avant le mot.

   Pas de hauteur de cible tactile ici — ce n'est pas un bouton, on ne clique
   pas dessus. */
.ac-type {
  display: inline-block;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}

.ac-type--condition {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.ac-type--quiz {
  background: var(--pj-accent-soft);
  color: var(--pj-accent-ink);
}

.ac-type--video {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.ac-type--document {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

/* Les flèches de réordonnancement. `min-width` et non `width` : le bouton
   porte un `width:auto` en ligne, qui gagnerait sur une classe. Mesuré à
   25x44 avant cette règle — une hauteur conforme ne rachète pas une largeur
   qui ne l'est pas. */
.ac-move {
  min-width: 44px;
}

/* ---- Les parcours d'un organisme (E36-02) ------------------------------- */

/* Le `gap` de la section : `.pj-card` ne porte aucune marge, donc l'espacement
   d'une page est entierement celui de son conteneur. */
.pc-space {
  display: grid;
  gap: 16px;
}

.pc-space__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
}

.pc-space__head h1 {
  margin: 0;
  font-size: var(--pj-fs-card);
}

.pc-space__switcher {
  display: grid;
  gap: 4px;
  min-width: 220px;
}

/* Une colonne d'abord. Deux seulement quand il y a la place : a 360px, « a
   cote » n'existe pas, et la liste doit rester au-dessus de l'editeur. */
.pc-grid {
  display: grid;
  gap: 16px;
}

@media (min-width: 992px) {
  .pc-grid {
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    align-items: start;
  }
}

/* Une ligne de la liste. `width: 100%` est explicite : dans la coquille
   connectee tout `<button>` nu l'est deja, mais celui-ci est une grille et le
   dire evite de dependre d'une regle lointaine. */
/* « Ouvert a tous » : une mention discrete, pas un second badge de statut.
   Le statut occupe deja le coin haut-droit, et deux pastilles cote a cote se
   liraient comme deux etats du meme fait. */
.pc-warn {
  color: var(--pj-warning-ink);
}

.pc-fields {
  display: grid;
  gap: 12px;
}

@media (min-width: 768px) {
  .pc-fields {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .pc-field--wide {
    grid-column: 1 / -1;
  }
}

.pc-field {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.pc-field > span {
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

/* Ce qu une formation porte en plus : un examen, un parcours (2026-09-27).

   Des puces DISCRETES et non des badges de statut : le statut dit ou en est
   la formation, celles-ci disent ce qu elle contient. Les mettre au meme
   niveau visuel ferait lire deux etats du meme fait.

   Elles REUTILISENT `.jo-chip`, qui existe plus haut dans cette feuille et
   que deux pages publiques emploient pour les competences : redefinir la
   classe de base ici la gagnerait a specificite egale, et changerait la
   taille et le fond de ces puces-la sans que personne l ait demande. Une
   forme de chip dans le produit, et la NATURE par-dessus. */
/* La puce d un METIER est un lien vers sa fiche (2026-09-27).

   Elle emprunte la forme a `.jo-chip` et n ajoute que ce qui dit « ceci se
   clique ». Aucun fond : un aplat plein sur un lien le fait lire comme un
   bouton, et la regle qui garde cette feuille refuse d ailleurs le cas. */
/* `.pj-app` devant : `prosyjob.css` porte `.pj-app a { color: inherit }`, qui
   charge apres cette feuille ET pese (0,1,1) contre (0,1,0) -- il gagnait deux
   fois, et la puce prenait l encre du texte (mesure : rgb(28,42,58)) pendant
   que sa bordure portait bien le bleu. Un lien de la couleur du texte courant
   ne se voit pas.

   44 px : celle-ci se CLIQUE, contrairement aux puces de competences qui
   restent a 26. */
.pj-app .jo-chip--metier {
  min-height: 44px;
  padding: 0 14px;
  color: var(--color-primary);
  border-color: var(--color-primary);
  text-decoration: none;
  gap: 6px;
}

.pj-app .jo-chip--metier:hover,
.pj-app .jo-chip--metier:focus-visible {
  text-decoration: underline;
}

.jo-chip--quiz,
.jo-chip--cursus {
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  white-space: nowrap;
  background: var(--pj-bg);
}

/* Une couleur par nature, pour que l oeil les separe sans lire : l examen
   evalue, le parcours certifie. */
/* Un seul token des deux cotes, comme la puce parcours : `--pj-info-soft` est
   un FOND, et sur `--pj-bg` il donnait un contraste de 1,06 (mesure) — la
   bordure n existait pas. */
.jo-chip--quiz {
  border-color: var(--pj-info-ink);
  color: var(--pj-info-ink);
}

.jo-chip--cursus {
  border-color: var(--pj-orange);
  color: var(--pj-orange);
}

/* Les onglets d un parcours d organisme (2026-09-27).

   La barre reutilise `.jo-tabs` / `.jo-tab`, qui ne sont scopes a aucun ecran
   — une seconde barre aurait diverge de la premiere au premier ajustement, et
   les deux editeurs de ce projet doivent se ressembler. */
/* Un panneau ne porte aucune bordure ni fond : la carte qui l entoure en a
   deja un, et le doubler donnerait une boite dans une boite. */
.pc-panel > h3:first-child {
  margin-top: 0;
}

/* L acces a un cursus d organisme : inviter, attribuer (2026-09-27). */

.pc-acces__titre {
  margin: 18px 0 4px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

/* La meme grille que le formulaire du parcours, et non une seconde : ce
   sont les memes champs au meme endroit, et deux grilles divergent au
   premier ajustement. */
.pc-acces__form {
  display: grid;
  gap: 12px;
  margin-top: 8px;
}

@media (min-width: 768px) {
  .pc-acces__form {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* `width: auto` : la regle `button, .btn` de cette feuille met tout bouton
   nu a 100 % dans la coque connectee. */
.pc-acces__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.pc-acces__actions .btn {
  width: auto;
}

/* Le lien d invitation ne se reaffiche JAMAIS : seule son empreinte est
   gardee. Il est donc montre une fois, et il doit se selectionner d un
   geste — d ou `user-select: all` et la coupe sur les mots longs. */
.pc-acces__lien {
  margin-top: 10px;
  padding: 8px 10px;
  border: 1px dashed var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-bg);
  font-size: var(--pj-fs-sm);
  word-break: break-all;
  user-select: all;
}

.pc-invit {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.pc-invit__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-bg);
  font-size: var(--pj-fs-sm);
}

.pc-invit__qui {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pc-invit__statut {
  flex: 0 0 auto;
  color: var(--pj-muted);
}

/* ---- Parcours : maquettes `parcours*.png` (2026-10-04) ----
   Famille `pcv-`. Les deux colonnes se décident sur la largeur du PANNEAU
   (`.pc-space` est un conteneur) et non de l'écran : dans l'espace organisme,
   un écran de 1366px ne laisse que 700px au centre. Les cartes portent leur
   propre fond (`pcv-card`) plutôt que `.pj-card`, comme les panneaux quiz. */

.pc-space {
  container: pcv / inline-size;
}

.pcv-card {
  padding: 18px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
}

.pcv-intro {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin: 0;
  padding: 14px 16px;
  border-radius: var(--pj-radius);
  background: var(--pj-info-soft);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
}

.pcv-intro__ico {
  flex: 0 0 auto;
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-card);
  line-height: 1;
}

.pc-space .pcv-grid {
  grid-template-columns: minmax(0, 1fr);
}

@container pcv (min-width: 760px) {
  .pc-space .pcv-grid {
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    align-items: start;
  }
}

.pcv-title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.pcv-subtitle {
  margin: 0 0 4px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 800;
}

.pcv-help {
  margin: 0 0 14px;
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-sm);
}

.pcv-req {
  color: var(--pj-danger);
}

/* ---- la liste ---- */

.pcv-new {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  margin: 12px 0;
}

.pcv-items {
  display: grid;
  gap: 10px;
}

.pcv-item {
  position: relative;
  display: grid;
  gap: 2px;
  width: 100%;
  padding: 12px 36px 12px 14px;
  border: 1px solid var(--pj-line);
  border-left: 3px solid transparent;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  text-align: left;
}

.pcv-item:hover {
  border-color: var(--pj-orange-soft);
  border-left-color: var(--pj-orange-soft);
}

.pcv-item.is-current {
  border-left-color: var(--pj-orange);
  background: var(--pj-card-2);
}

.pcv-item__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.pcv-item__name {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 700;
}

.pcv-item__code {
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
  overflow-wrap: anywhere;
}

.pcv-item__facts .pc-warn {
  color: var(--pj-warning-ink);
}

.pcv-item__public {
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-transform: uppercase;
}

.pcv-item__chev {
  position: absolute;
  top: 50%;
  right: 14px;
  transform: translateY(-50%);
  color: var(--pj-ink);
}

.pcv-badge {
  flex: 0 0 auto;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-2xs);
  font-weight: 700;
  text-transform: uppercase;
}

.pcv-badge--draft   { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.pcv-badge--active  { background: var(--pj-success-soft); color: var(--pj-success); }
.pcv-badge--retired { background: var(--pj-neutral-soft); color: var(--pj-muted); }

/* ---- l'éditeur ---- */

.pcv-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-bottom: 14px;
}

/* Trois boutons segmentés : l'onglet actif en bleu nuit plein. */
.pcv-tabs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 18px;
}

.pcv-tab {
  width: 100%;
  min-height: 44px;
  padding: 6px 10px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.pcv-tab.is-active {
  border-color: var(--pj-navy);
  background: var(--pj-navy);
  color: var(--pj-card);
}

.pcv-fields .pc-field > span {
  font-size: var(--pj-fs-sm);
}

.pcv-fields .form-control {
  min-height: 44px;
}

.pcv-fields small {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.pcv-affix {
  position: relative;
  display: block;
}

.pcv-affix .form-control {
  padding-right: 44px;
}

.pcv-affix__end {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  display: grid;
  place-items: center;
  width: 44px;
  color: var(--pj-ink);
  pointer-events: none;
}

.pcv-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

.pcv-actions .btn,
.pcv-save-steps,
.pcv-add__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

/* Deux classes : `.btn` du thème vendu gagnerait sur une seule. */
.btn.pcv-btn-green {
  border-color: var(--pj-success);
  background: var(--pj-success);
  color: var(--pj-card);
}

.btn.pcv-btn-navy {
  border-color: var(--pj-navy);
  background: var(--pj-navy);
  color: var(--pj-card);
}

/* ---- les étapes ---- */

.pcv-steps {
  display: grid;
  gap: 12px;
}

.pcv-step {
  display: grid;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.pcv-step__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
}

.pcv-step__n {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border: 1px solid var(--pj-line);
  border-radius: 50%;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.pcv-type {
  padding: 2px 10px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  text-transform: uppercase;
}

.pcv-type--quiz     { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.pcv-type--video    { background: var(--pj-danger-soft);  color: var(--pj-danger); }
.pcv-type--document { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.pcv-type--lecon    { background: var(--pj-success-soft); color: var(--pj-success); }

.pcv-step__name {
  flex: 1 1 140px;
  min-width: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.pcv-step__moves {
  display: flex;
  gap: 6px;
  margin-left: auto;
}

.pcv-move {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-navy);
  color: var(--pj-card);
}

.pcv-move:disabled {
  opacity: 0.4;
}

.pcv-drop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  border: 1.5px solid var(--pj-danger);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-danger);
  font-weight: 600;
}

.pcv-step__link {
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-xs);
  overflow-wrap: anywhere;
}

.pcv-save-steps {
  justify-self: start;
}

.pcv-add {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
  margin-top: 16px;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

.pcv-add .form-control {
  min-height: 44px;
}

@container pcv (min-width: 560px) {
  .pcv-add {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) auto;
    align-items: end;
  }
}

/* ---- les apprenants : l'état vide ---- */

.apt-empty,
.alib-empty {
  display: grid;
  justify-items: center;
  gap: 6px;
  padding: 24px 12px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  text-align: center;
}

.apt-empty p,
.alib-empty p {
  margin: 0;
}

.apt-empty__ico,
.alib-empty__ico {
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  margin-bottom: 4px;
  border-radius: 50%;
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-display);
}

.alib-empty__ico {
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
}

.apt-empty__title,
.alib-empty__title {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 700;
}

/* ---- la bibliothèque de leçons ---- */

.alib-wrap {
  container: alib / inline-size;
}

.alib {
  display: grid;
  gap: 16px;
}

@container alib (min-width: 760px) {
  .alib {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    align-items: start;
  }
}

.alib-card {
  padding: 18px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
}

.alib-head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.alib-ico {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-card);
}

.alib-head__text {
  min-width: 0;
}

.alib-title {
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.alib-intro {
  margin: 4px 0 12px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.alib-new,
.alib-actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

.alib-editor {
  margin-top: 18px;
}

.alib-grid {
  display: grid;
  gap: 14px;
}

@container alib (min-width: 560px) {
  .alib-grid {
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  }

  .alib-field--wide {
    grid-column: 1 / -1;
  }
}

.alib-field {
  display: grid;
  gap: 6px;
  min-width: 0;
  margin: 0;
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.alib-field .form-control {
  min-height: 44px;
  font-weight: 400;
}

.alib-field small {
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  font-weight: 400;
}

.alib-req {
  color: var(--pj-danger);
}

.alib-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}

.alib-subtitle {
  margin: 0 0 10px;
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 800;
}

.alib-search {
  position: relative;
  display: block;
  margin: 0 0 10px;
}

.alib-search i {
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  color: var(--pj-muted);
}

.alib-search .form-control {
  min-height: 44px;
  padding-left: 40px;
}

.alib-rows {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.alib-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  padding: 10px 0;
}

.alib-row + .alib-row {
  border-top: 1px solid var(--pj-line);
}

.alib-doc {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-lg);
}

.alib-doc--published { background: var(--pj-success-soft); color: var(--pj-success); }
.alib-doc--draft     { background: var(--pj-orange-soft);  color: var(--pj-orange); }
.alib-doc--archived  { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.alib-row__text {
  display: grid;
  flex: 1 1 120px;
  min-width: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
}

.alib-row__text strong {
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  overflow-wrap: anywhere;
}

.alib-pill {
  padding: 2px 8px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-2xs);
  font-weight: 700;
  text-transform: uppercase;
}

.alib-pill--published { background: var(--pj-success-soft); color: var(--pj-success); }
.alib-pill--draft     { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.alib-pill--archived  { background: var(--pj-neutral-soft); color: var(--pj-muted); }

.alib-row__actions {
  display: flex;
  gap: 6px;
  margin-left: auto;
}

.alib-icon {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.alib-icon--neutral {
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
}

.alib-none {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* Le même gabarit que `.ac-step__go` — 44px, la règle de ce projet — mais en
   bouton : il n'ouvre rien, il déclare. */
.ac-step__done {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  width: auto;
  border: 1px solid var(--pj-success);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-success-soft);
  color: var(--pj-success);
  font-weight: 600;
  font-size: var(--pj-fs-body);
}

.ac-step__done:disabled {
  opacity: 0.6;
}

/* La phrase qui dit pourquoi ce bouton existe. Discrète : c'est une mise au
   point, pas un avertissement — l'étape n'a rien d'anormal. */
.ac-step__note--soft {
  background: transparent;
  color: var(--pj-muted);
  padding: 0;
  font-size: var(--pj-fs-xs);
}

/* Du côté gauche de l'axe, tout s'aligne à droite, boutons compris. */
@media (min-width: 768px) {
  .ac-step--left .ac-step__actions {
    justify-content: flex-end;
  }
}

/* ---- La console : les trois portes de l'Académie --------------------- */

.aa-door {
  text-decoration: none;
  color: inherit;
}

.aa-door:hover {
  box-shadow: var(--pj-shadow);
}

.aa-door__icon {
  width: 28px;
  height: 28px;
  color: var(--pj-orange);
  margin-bottom: 8px;
}

.aa-door__counts {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.aa-door__n b {
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
}

/* ==========================================================================
   Le registre des certificats emis (E36-09)
   ========================================================================== */

/* Le panneau de decision s'ouvre SOUS la ligne qu'il concerne : on vient de
   lire un nom et un numero, et une modale les recouvrirait au moment precis
   ou l'on ecrit pourquoi on retire son certificat a cette personne-la. Le
   fond le detache de la ligne sans le sortir du tableau. */
.ic-decision__box {
  background: var(--pj-card-2);
  border-radius: 10px;
  padding: 12px;
}

.ic-decision__box .btn { width: auto; }

/* 44px de haut, mesures : §9 le demande pour toute cible tactile, et
   `.btn--sm` est reste a 38 pendant cinq jalons parce que personne ne
   mesurait. Ici la colonne d'actions en porte deux par ligne. */
.ic-table__actions .btn {
  min-height: 44px;
  width: auto;
}

.ic-pager__state { color: var(--color-muted); }

.ic-filters-actions__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Le motif d'un retrait est une PHRASE, et le theme pose `white-space:
   nowrap` sur les cellules du tableau. Mesure : des la premiere suspension
   la colonne « Etat » s'elargissait jusqu'a faire defiler tout le tableau,
   et il fallait aller chercher les boutons hors champ. `tbody td` d'un cran
   plus precis que la regle du theme, comme pour les autres tableaux de la
   console — cette feuille se charge AVANT lui (CLAUDE.md SS9). */
/* Meme cause pour la phrase qui explique POURQUOI un certificat perime
   n offre aucun geste : mesuree a 53px de largeur de table en plus, et le
   tableau se mettait a defiler. Elle se replie, comme le motif. */
.ic-table tbody td.ic-table__actions .ic-noaction {
  display: inline-block;
  max-width: 30ch;
  white-space: normal;
}

.ic-table tbody td .ic-reason {
  max-width: 34ch;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* ==========================================================================
   Les questions redactionnelles et la file de correction (E36-10)
   ========================================================================== */

/* Un champ de redaction prend toute la largeur : c'est un paragraphe, pas une
   case a cocher. `.qz-answer--pick` aligne son intitule a cote de sa case ;
   ici l'intitule est au-dessus. */
.qz-answer--written {
  display: block;
}

.qz-answer--written .qz-answer__label {
  display: block;
  margin-bottom: 6px;
  font-weight: 600;
}

/* Une copie relue se lit TELLE QU'ELLE A ETE ECRITE : `pre-wrap` garde les
   retours a la ligne. Sans lui, trois paragraphes reviennent sur une seule
   ligne — ce n'est plus la copie qu'on a rendue, et c'est celle-la qu'on
   corrige. `anywhere` parce qu'un candidat peut coller une URL de 200
   caracteres, qui elargirait la carte sur un telephone. */
.qz-answer__written {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0;
  padding: 10px 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

/* Le commentaire du correcteur, sous la question. Il ne ressemble pas a une
   reponse : c'est quelqu'un qui parle au candidat. */
.qz-answer__comment {
  margin: 8px 0 0;
  padding-left: 10px;
  border-left: 3px solid var(--pj-orange);
  color: var(--pj-muted);
}

/* Une copie en attente n'a pas de note a montrer : le pave de resultat perd
   son chiffre et garde sa phrase. */
.qz-verdict--waiting .qz-verdict__label {
  color: var(--pj-warning-ink);
}

/* ------------------------------------------------------------------ *
 * Frais de réseau de paiement (/admin/paiements/frais-reseau)
 *
 * Écran de configuration lu en comparant les pays : la grille des taux
 * est donc une liste de lignes alignées, et non un formulaire par pays.
 * ------------------------------------------------------------------ */

.pf-compare {
  display: grid;
  gap: var(--pj-gap, 16px);
  grid-template-columns: 1fr;
  margin-top: 16px;
}

@media (min-width: 720px) {
  .pf-compare {
    grid-template-columns: 1fr 1fr;
  }
}

.pf-compare__col {
  background: var(--pj-card-2);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  padding: 14px 16px;
}

/* Le nôtre est celui que cet écran règle ; l'autre est là pour ne pas être
   confondu avec lui, ce que la couleur dit plus vite qu'une phrase. */
.pf-compare__col--ours {
  background: var(--pj-orange-soft);
  border-color: var(--pj-orange);
}

.pf-compare__head {
  font-size: var(--pj-fs-md);
  margin: 0 0 6px;
}

.pf-compare__col p {
  margin: 0;
  color: var(--pj-muted);
}

.pf-rates {
  display: grid;
  gap: 10px;
  margin-top: 12px;
}

/* 360px d'abord : chaque ligne s'empile, le champ prend la largeur et le
   bouton reste au-dessus de 44px de haut. */
.pf-rate {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  align-items: center;
  background: var(--pj-card-2);
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  padding: 12px;
}

.pf-rate--platform {
  border-color: var(--pj-navy);
}

.pf-rate__name {
  font-weight: 600;
  color: var(--pj-ink);
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.pf-rate__field {
  display: flex;
  align-items: center;
  gap: 6px;
}

.pf-rate__field .form-control {
  max-width: 140px;
}

.pf-rate__unit {
  color: var(--pj-muted);
}

/* La règle `button, .btn` de ce fichier met tout bouton nu à 100 % ; une
   ligne de configuration veut un bouton de la largeur de son texte. */
.pf-rate__save.pf-rate__save {
  width: auto;
  justify-self: start;
}

.pf-rate__msg {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 0.875rem;
  color: var(--pj-muted);
}

.pf-rate__msg--error {
  color: var(--pj-danger);
}

@media (min-width: 720px) {
  .pf-rate {
    grid-template-columns: minmax(0, 1fr) auto auto;
  }

  .pf-rate__msg {
    grid-column: 1 / -1;
  }
}

.pf-note {
  border-left: 3px solid var(--pj-navy);
}


/* ── « Mes offres », maquette du 2026-09-27 ────────────────────────────────

   Tout est sous `.jo-offers` : `.jo-mine`, `.jo-tab`, `.jo-mine-card` sont
   partagées avec les éditeurs d'offre et de formation, qui ne changent pas.

   `display: grid` + `gap` sur chaque boîte qui tient des cartes : une
   `.pj-card` ne porte aucune marge (CLAUDE.md §9, check-card-gaps.mjs). */
.jo-offers__list {
  display: grid;
  gap: 14px;
}

.jo-offers .jo-mine__head {
  display: grid;
  gap: 14px;
}

.jo-offers .jo-mine__intro h1 {
  margin: 0;
  font-weight: 800;
}

/* Deux moitiés égales. À 360px la carte n'offre que ~243px utiles :
   « Assistant de publication » y passe sur deux lignes, et c'est voulu —
   `nowrap` le faisait déborder de son propre bouton (mesuré). */
.jo-offers .jo-mine__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

/* Sous 400px, « Sélectionner » et l'assistant perdent leur icône : dans une
   demi-rangée de ~118px, elle poussait le libellé sur trois lignes (74px de
   haut, mesuré). Le libellé dit déjà ce que fait le bouton. */
@media (max-width: 399.98px) {
  .jo-offers #jo-mine-select > i,
  .jo-offers #jo-mine-describe > i {
    display: none;
  }
}

/* Sur téléphone « Publier une offre » prend toute la rangée, sous les deux
   autres, comme sur la maquette. */
.jo-offers .jo-offers__new {
  grid-column: 1 / -1;
}

.jo-offers .jo-offers__btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding-inline: 10px;
  font-size: var(--pj-fs-body);
  line-height: 1.2;
  text-align: center;
}

.jo-offers .jo-offers__btn[hidden],
.jo-offers #jo-mine-back[hidden] {
  display: none;
}

/* La recherche avancée. */
.jo-search {
  padding: 0;
  overflow: hidden;
}

.jo-offers .jo-search__toggle {
  width: 100%;
  min-height: 52px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border: 0;
  background: none;
  color: var(--pj-ink);
  cursor: pointer;
  text-align: left;
}

.jo-search__title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
}

.jo-search__title i {
  color: var(--pj-navy);
}

.jo-search__toggle-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.jo-search__toggle-label i {
  transition: transform .15s ease;
}

.jo-search.is-open .jo-search__toggle-label i {
  transform: rotate(180deg);
}

.jo-search__fields {
  display: grid;
  gap: 12px;
  padding: 0 16px 16px;
}

.jo-search__fields[hidden] {
  display: none;
}

.jo-search__field {
  display: grid;
  gap: 6px;
  margin: 0;
  min-width: 0;
  padding: 0;
  border: 0;
}

.jo-search__field > span:first-child,
.jo-search__field legend {
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-ink);
  margin: 0;
  padding: 0;
}

.jo-search__field .form-control {
  min-height: 44px;
}

.jo-search__input {
  position: relative;
  display: block;
}

.jo-search__input > i {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--pj-muted);
  pointer-events: none;
}

.jo-search__input .form-control {
  padding-left: 36px;
}

.jo-search__dates {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}

.jo-search__buttons {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  align-self: end;
}

.jo-search__buttons .btn {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* La rangée des statuts : des pastilles qui défilent sur téléphone, avec le
   bouton filtre au bout et le choix du nombre par page en dessous. */
.jo-offers__bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
}

.jo-offers__tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 2px 0;
}

.jo-offers__tabs::-webkit-scrollbar {
  display: none;
}

.jo-offers .jo-offers__tab {
  flex: 0 0 auto;
  width: auto;
  min-height: 40px;
  padding: 8px 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.jo-offers .jo-offers__tab.is-active {
  background: var(--pj-navy);
  border-color: var(--pj-navy);
  color: var(--pj-card);
}

.jo-offers .jo-offers__filter {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--pj-line);
  border-radius: 50%;
  background: var(--pj-card);
  color: var(--pj-navy);
  cursor: pointer;
}

.jo-offers__per-page {
  grid-column: 1 / -1;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.jo-offers__per-page .form-control {
  width: auto;
  min-height: 40px;
}

/* Une offre. */
.jo-offers .jo-offer {
  display: grid;
  gap: 10px;
  padding: 14px;
}

.jo-offer__head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.jo-offer__ident {
  flex: 1;
  min-width: 0;
}

.jo-offer__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.jo-offer__meta {
  margin: 2px 0 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.jo-offer__chips {
  flex: none;
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.jo-offer__stats {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  gap: 0;
  margin: 0;
}

.jo-offer__stats > div {
  padding: 0 14px;
  border-left: 1px solid var(--pj-line);
}

.jo-offer__stats > div:first-child {
  padding-left: 0;
  border-left: 0;
}

.jo-offer__stats dt {
  font-size: var(--pj-fs-xs);
  font-weight: 400;
  color: var(--pj-muted);
}

.jo-offer__stats dd {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.jo-offer__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.jo-offers .jo-offer__act {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-inline: 12px;
}

/* Sur téléphone, les actions « wide » vivent dans le menu ⋮. Trois classes :
   la règle `.jo-offer__act` ci-dessus et le `.btn` du thème posent un
   `display` de même poids, et la mesure a montré que l'un d'eux gagnait. */
.jo-offers .jo-offer__actions .jo-offer__act--wide {
  display: none;
}

.jo-offer__more {
  margin-left: auto;
}

.jo-offers .jo-offer__kebab {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--pj-muted);
  cursor: pointer;
}

.jo-offers .jo-offer__kebab:hover,
.jo-offers .jo-offer__kebab[aria-expanded="true"] {
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

.jo-offer__more .dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.jo-offer__more .dropdown-item i {
  width: 16px;
  text-align: center;
}

.jo-offers .jo-offer__menu-danger {
  color: var(--pj-danger);
}

.jo-offers__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 16px;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.jo-offers__footer[hidden] {
  display: none;
}

.jo-offers__footer .paginations {
  margin: 0;
}

@media (min-width: 768px) {
  .jo-offers .jo-mine__head {
    grid-template-columns: minmax(0, 1fr);
    padding: 22px;
  }

  .jo-offers .jo-mine__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
  }

  .jo-offers .jo-offers__btn {
    width: auto;
  }

  .jo-search__fields {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .jo-search__field--q {
    grid-column: span 1;
  }

  .jo-search__range {
    grid-column: span 1;
  }

  .jo-offers__bar {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .jo-offers__tabs {
    flex-wrap: wrap;
    overflow: visible;
  }

  .jo-offers .jo-offers__filter {
    display: none;
  }

  .jo-offers__per-page {
    grid-column: auto;
  }

  .jo-offers .jo-offer {
    padding: 16px 20px;
  }

  /* Sur ordinateur, les actions « wide » sortent du menu… */
  .jo-offers .jo-offer__actions .jo-offer__act--wide {
    display: inline-flex;
  }

  /* …et le menu ne garde que les siennes — ou disparaît s'il n'avait qu'elles. */
  .jo-offer__menu-item--narrow,
  .jo-offer__more--narrow {
    display: none;
  }
}

/* ── L'étape « Matching » de l'éditeur d'offre (2026-09-27) ───────────────
   Le formulaire de pondérations est celui de M7 (WeightEditor), réutilisé tel
   quel ; seuls l'en-tête de l'étape et l'interrupteur sont propres ici. */
.jo-matching {
  display: grid;
  gap: 12px;
}

.jo-matching h2 {
  margin: 0;
}

.jo-matching__lead,
.jo-matching__source {
  margin: 0;
  color: var(--pj-muted);
}

.jo-matching__source {
  font-weight: 600;
  color: var(--pj-ink);
}

.jo-matching__switch {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 44px;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  cursor: pointer;
}

.jo-matching__switch[hidden] {
  display: none;
}

.jo-matching__switch input {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  accent-color: var(--pj-orange-fill);
}

/* ── Matching : pondérations, seuils et historique (maquette du 2026-09-27) ──

   `WeightEditor` dessine ces cartes pour les quatre écrans employeur :
   l'étape Matching de l'offre, la page de l'entreprise, le volet « Profils
   recommandés » et la console d'administration. Cette feuille est chargée des
   deux côtés, et les jetons `--pj-*` sont recopiés à `:root` dans
   prosyjob-app.css pour la console (CLAUDE.md §9). */
.mt-editor-host {
  display: grid;
  gap: 16px;
}

.mtx {
  display: grid;
  gap: 16px;
}

.mtx-card {
  display: grid;
  gap: 14px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.mtx-card__head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: start;
  gap: 4px 12px;
}

.mtx-card__icon {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--pj-info-ink);
  font-size: 1.25rem;
}

.mtx-card__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.mtx-card__hint {
  margin: 2px 0 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

/* Le bouton qui replie : utile sur téléphone, inutile au large. `width` posée :
   le `button` nu de cette feuille est à 100 %. */
.mtx-card .mtx-card__fold {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: -8px -8px 0 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--pj-ink);
  cursor: pointer;
}

.mtx-card__fold i {
  transition: transform .15s ease;
}

.mtx-card.is-folded .mtx-card__fold i {
  transform: rotate(180deg);
}

.mtx-card.is-folded .mtx-card__body {
  display: none;
}

.mtx-card__body {
  display: grid;
  gap: 14px;
}

.mtx-total {
  margin: 0;
  align-self: center;
  font-size: var(--pj-fs-md);
  color: var(--pj-ink);
  white-space: nowrap;
}

.mtx-total strong {
  font-size: var(--pj-fs-lg);
}

/* Les critères : une liste de lignes sur téléphone, une grille de cartes au large. */
.mtx-grid {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mtx-crit {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.mtx-crit.is-off {
  background: var(--pj-card-2);
}

.mtx-crit__icon {
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  font-size: 1.05rem;
}

.mtx-tint--blue   { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.mtx-tint--green  { background: var(--pj-success-soft); color: var(--pj-success); }
.mtx-tint--violet { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.mtx-tint--orange { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.mtx-tint--red    { background: var(--pj-danger-soft);  color: var(--pj-danger); }

.mtx-crit__main {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.mtx-crit__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.mtx-crit__name {
  margin: 0;
  font-weight: 700;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.mtx-crit__off {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.mtx-crit__controls {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
}

.mtx-range {
  width: 100%;
  min-height: 32px;
  accent-color: var(--pj-info-ink);
  cursor: pointer;
}

.mtx-crit__value,
.mtx-level__value {
  display: inline-flex;
  align-items: flex-end;
  gap: 2px;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.mtx .mtx-number {
  width: 64px;
  min-height: 40px;
  padding: 4px 6px;
  text-align: center;
  font-weight: 700;
  color: var(--pj-ink);
}

.mtx-crit__scale {
  display: flex;
  justify-content: space-between;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* Les seuils de compatibilité, à la place des « poids des pondérations ». */
.mtx-levels__list {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mtx-level {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px 12px;
}

.mtx-level__pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  justify-self: start;
  margin: 0;
  padding: 8px 14px;
  border-radius: var(--pj-radius-sm);
  font-weight: 700;
  font-size: var(--pj-fs-body);
}

.mtx-level__pill--very_compatible      { background: var(--pj-success-soft); color: var(--pj-success); }
.mtx-level__pill--compatible           { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.mtx-level__pill--partially_compatible { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }

.mtx-level__from {
  display: none;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

/* Le pied de la carte des seuils : la note et les boutons de l'écran hôte. */
.mtx-actions {
  display: grid;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--pj-line);
}

.mtx-actions[hidden] {
  display: none;
}

.mtx-actions .mt-actions,
.mtx-actions .mt-drawer__actions {
  margin: 0;
}

.mtx-actions .btn {
  min-height: 44px;
}

/* L'historique. */
.mtx-history__aside {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  grid-column: 1 / -1;
  flex-wrap: wrap;
}

.mtx-history__chip {
  padding: 4px 12px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.mtx-card .mtx-history__all {
  width: auto;
  min-height: 44px;
  padding: 0 10px;
  border: 0;
  background: none;
  color: var(--pj-info-ink);
  font-weight: 700;
  cursor: pointer;
}

.mtx-history__scroll {
  overflow-x: auto;
}

.mtx-history__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  color: var(--pj-ink);
}

.mtx-history__table th {
  padding: 8px 10px;
  border-bottom: 1px solid var(--pj-line);
  font-weight: 600;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  text-align: left;
  white-space: nowrap;
}

.mtx-history__table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--pj-line);
  vertical-align: top;
}

.mtx-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--pj-orange);
}

.mtx-dot--active {
  background: var(--pj-success);
}

/* Téléphone : le tableau devient des fiches empilées (CLAUDE.md §9). */
@media (max-width: 767.98px) {
  .mtx-history__table thead {
    display: none;
  }

  .mtx-history__table tr {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 2px 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--pj-line);
  }

  .mtx-history__table tr[hidden] {
    display: none;
  }

  .mtx-history__table td {
    padding: 0;
    border: 0;
  }

  .mtx-history__table td:first-child {
    grid-row: span 6;
    padding-top: 4px;
  }

  .mtx-history__table td[data-label]::before {
    content: attr(data-label) " : ";
    color: var(--pj-muted);
  }
}

@media (min-width: 768px) {
  .mtx-card {
    padding: 20px 22px;
  }

  .mtx-card .mtx-card__fold {
    display: none;
  }

  .mtx-card.is-folded .mtx-card__body {
    display: grid;
  }

  .mtx-history__aside {
    grid-column: auto;
    justify-content: flex-end;
  }

  .mtx-grid {
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 12px;
  }

  .mtx-crit {
    padding: 14px;
  }

  .mtx-level {
    grid-template-columns: minmax(180px, auto) auto auto;
    justify-content: start;
  }

  .mtx-level__from {
    display: inline;
  }
}

/* ── CVthèque, maquette du 2026-09-27 ──────────────────────────────────────

   Tout est sous `.cvx` : `.cvtheque-card`, `.cvt-chip`, `.cvt-lang-chip`
   restent ceux des écrans Favoris et Déverrouillages, qui ne changent pas.
   Mobile d'abord : une colonne, chaque groupe de filtres replié ; au large,
   deux colonnes et tout ouvert. */
/* Deux classes : `.pj-card` (prosyjob.css) charge après cette feuille. Sur
   téléphone, cadre et carte cumulaient 40px de marges de chaque côté et la
   carte candidat tombait à 232px (mesuré) ; on les resserre. */
.cvx .cvx-search,
.cvx .cvx-results {
  display: grid;
  gap: 16px;
  padding: 14px;
}

.cvx-search__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
}

.cvx-search__head h2,
.cvx-results__head h2 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.cvx-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
}

/* `a.` : `.pj-app a { color: inherit }` pèse (0,1,1) (CLAUDE.md §9). */
.cvx a.cvx-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  text-decoration: none;
}

.cvx a.cvx-link:hover {
  text-decoration: underline;
}

.cvx-company {
  flex-basis: 100%;
}

.cvx-form {
  display: grid;
  gap: 16px;
}

/* La barre de recherche : champ, Rechercher, puis Réinitialiser en dessous
   sur téléphone ; les trois sur une ligne au large. */
.cvx-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
}

.cvx-bar__input {
  position: relative;
  display: block;
  min-width: 0;
}

.cvx-bar__input > i {
  position: absolute;
  left: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--pj-muted);
  pointer-events: none;
}

.cvx-bar__input .form-control {
  min-height: 48px;
  padding-left: 40px;
}

.cvx .cvx-bar .btn {
  width: auto;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.cvx .cvx-bar .cvx-bar__reset {
  grid-column: 1 / -1;
  width: 100%;
}

/* Les filtres. */
.cvx-filters {
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
}

.cvx .cvx-filters__head,
.cvx .cvx-group__head {
  width: 100%;
  min-height: 52px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border: 0;
  background: none;
  color: var(--pj-ink);
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

.cvx-filters__head > i:first-child,
.cvx-group__head > i:first-child {
  width: 20px;
  text-align: center;
  color: var(--pj-navy);
}

.cvx-filters__head > span,
.cvx-group__head > span {
  flex: 1;
}

.cvx-chevron {
  color: var(--pj-muted);
  transition: transform .15s ease;
}

.cvx-filters.is-open > .cvx-filters__head .cvx-chevron,
.cvx-group.is-open > .cvx-group__head .cvx-chevron {
  transform: rotate(180deg);
}

.cvx-filters__cols {
  display: none;
}

.cvx-filters.is-open .cvx-filters__cols {
  display: grid;
}

.cvx-col {
  display: grid;
  align-content: start;
}

.cvx-group {
  margin: 0;
  padding: 0;
  min-width: 0;
  border: 0;
  border-top: 1px solid var(--pj-line);
}

.cvx-group__body {
  display: none;
  gap: 12px;
  padding: 4px 14px 16px;
}

.cvx-group.is-open .cvx-group__body {
  display: grid;
}

.cvx-group__body .form-group {
  margin: 0;
}

.cvx-group__body .form-control {
  min-height: 44px;
}

.cvx-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.cvx-grid__wide {
  grid-column: 1 / -1;
}

/* Les résultats. */
.cvx-results__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cvx-results__tools {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 16px;
}

.cvx-inline {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.cvx-inline .form-control {
  width: auto;
  min-height: 44px;
}

.cvx-list {
  display: grid;
  gap: 12px;
}

.cvx .cvx-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 10px 12px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.cvx-card__avatar .cvt-avatar {
  width: 44px;
  height: 44px;
  font-size: 1rem;
}

.cvx-card__body {
  min-width: 0;
  display: grid;
  gap: 6px;
}

.cvx-card__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

.cvx-card__name {
  font-size: var(--pj-fs-lg);
  color: var(--pj-ink);
}

.cvx-avail {
  padding: 3px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
}

.cvx-avail--immediate   { background: var(--pj-success-soft); color: var(--pj-success); }
.cvx-avail--notice      { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.cvx-avail--open        { background: var(--pj-info-soft);    color: var(--pj-info-ink); }

.cvx-lock {
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.cvx-lock.is-open {
  color: var(--pj-success);
}

.cvx-card__headline {
  margin: 0;
  color: var(--pj-ink);
}

.cvx-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 8px;
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.cvx-card__meta i {
  margin-right: 4px;
}

.cvx-card__resume {
  margin: 0;
  font-size: var(--pj-fs-body);
  line-height: 1.5;
  color: var(--pj-muted);
}

/* Téléphone : « Voir le profil » prend la rangée, l'étoile reste à côté. */
.cvx-card__actions {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
}

.cvx .cvx-card__view {
  order: 1;
  width: 100%;
  min-height: 44px;
}

.cvx .cvx-card__star {
  order: 2;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
  cursor: pointer;
}

.cvx .cvx-card__star.cvt-favorite-btn--on {
  color: var(--pj-orange);
}

.cvx-results__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.cvx-results__foot[hidden] {
  display: none;
}

.cvx-pager .paginations {
  margin: 0;
}

@media (min-width: 768px) {
  .cvx .cvx-search,
  .cvx .cvx-results {
    padding: 22px;
  }

  .cvx-search__head h2,
  .cvx-results__head h2 {
    font-size: var(--pj-fs-card);
  }

  .cvx-bar {
    grid-template-columns: minmax(0, 1fr) auto auto;
  }

  .cvx .cvx-bar .cvx-bar__reset {
    grid-column: auto;
    width: auto;
  }

  /* Au large : « Filtres avancés » reste un bouton — replié à l'arrivée,
     l'utilisateur l'ouvre s'il le veut (décision PO du 2026-10-01). Ouvert,
     tout est déplié sur deux colonnes, sans pliage par groupe. */
  .cvx-filters,
  .cvx-filters.is-open {
    border: 0;
  }

  .cvx .cvx-filters__head {
    padding: 0 0 8px;
    min-height: 44px;
  }

  .cvx-group__head .cvx-chevron {
    display: none;
  }

  .cvx-filters.is-open .cvx-filters__cols {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 20px;
    padding: 12px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
  }

  .cvx .cvx-group__head {
    cursor: default;
    pointer-events: none;
    padding: 12px 2px 8px;
    min-height: 0;
  }

  .cvx-group:first-child {
    border-top: 0;
  }

  .cvx-group .cvx-group__body {
    display: grid;
    padding: 0 2px 14px;
  }

  .cvx .cvx-card {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: start;
    padding: 18px 20px;
  }

  .cvx-card__avatar .cvt-avatar {
    width: 60px;
    height: 60px;
  }

  .cvx-card__actions {
    grid-column: auto;
    display: flex;
    align-items: center;
    gap: 10px;
  }

  .cvx .cvx-card__star {
    order: 1;
  }

  .cvx .cvx-card__view {
    order: 2;
    width: auto;
  }
}

/* ── Forfaits de publication, maquette du 2026-09-27 ───────────────────────

   Sous `.sbx` : `.sub-page`, `.sub-plan`, `.sub-state` restent ceux de
   `/organismes/abonnement` quand il n'est pas redessiné par cette maquette —
   c'est le même panneau, donc il prend aussi ce style, et c'est voulu.
   Mobile d'abord : chaque forfait est une ligne (icône, nom, prix, Souscrire),
   le chevron déplie ses avantages ; au large, une grille de cartes. */
.sbx-tile {
  width: 48px;
  height: 48px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 12px;
  font-size: var(--pj-fs-card);
}

.sbx-tint--orange { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.sbx-tint--blue   { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.sbx-tint--green  { background: var(--pj-success-soft); color: var(--pj-success); }
.sbx-tint--violet { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.sbx-tint--cyan   { background: var(--pj-card-2);       color: var(--pj-navy); }
.sbx-tint--grey   { background: var(--pj-neutral-soft); color: var(--pj-neutral-ink); }

.sbx-pill {
  display: inline-block;
  justify-self: start;
  padding: 2px 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-2xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.sbx-pill--active { background: var(--pj-success-soft); color: var(--pj-success); text-transform: none; font-size: var(--pj-fs-sm); }
.sbx-pill--orange { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.sbx-pill--blue   { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.sbx-pill--green  { background: var(--pj-success-soft); color: var(--pj-success); }
.sbx-pill--violet { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.sbx-pill--cyan   { background: var(--pj-card-2);       color: var(--pj-navy); }

/* L'état : le forfait en cours, ou son absence. */
.sbx .sbx-state {
  display: grid;
  gap: 14px;
  padding: 16px;
}

.sbx-state__main {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.sbx-state__text {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.sbx .sub-state__plan {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.sbx .sub-state__until {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 6px;
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.sbx-state__days {
  color: var(--pj-orange-text);
  font-weight: 700;
}

.sbx .sbx-state__manage {
  width: 100%;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.sbx .sub-plans__title {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.sbx-plans {
  display: grid;
  gap: 12px;
}

.sbx-grid {
  display: grid;
  gap: 10px;
}

/* Un forfait, en ligne sur téléphone. */
.sbx .sbx-plan {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 8px 10px;
  padding: 12px;
}

.sbx-plan__ident {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.sbx .sub-plan__name {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.sbx .sbx-plan__price {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-info-ink);
}

.sbx-plan__days {
  display: none;
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.sbx .sbx-plan__more {
  width: 32px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--pj-muted);
  cursor: pointer;
}

.sbx-plan__more i {
  transition: transform .15s ease;
}

.sbx-plan.is-open .sbx-plan__more i {
  transform: rotate(90deg);
}

.sbx-plan__features {
  grid-column: 1 / -1;
  grid-row: 2;
  display: none;
  gap: 6px;
  margin: 0;
  padding: 4px 0 0;
  list-style: none;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.sbx-plan.is-open .sbx-plan__features {
  display: grid;
}

.sbx-plan__features i {
  width: 16px;
  margin-right: 6px;
  color: var(--pj-orange-text);
}

.sbx-plan__action .btn {
  width: auto;
  min-height: 44px;
  white-space: nowrap;
}

.sbx .sub-plan__noperm {
  margin: 0;
  font-size: var(--pj-fs-sm);
}

/* Facturation : une ligne entière qui mène aux paiements sur téléphone. */
.sbx .sbx-billing {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  cursor: pointer;
}

.sbx-billing__text {
  min-width: 0;
}

.sbx .sub-billing__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.sbx-billing__text p {
  margin: 2px 0 0;
}

/* Trois classes : le `.btn` du thème (prosyjob-app.css, chargé après) pose un
   `display` de même poids et le réaffichait (mesuré). */
.sbx .sbx-billing .sbx-billing__btn {
  display: none;
}

.sbx-billing__chevron {
  color: var(--pj-muted);
}

@media (min-width: 768px) {
  .sbx .sbx-state {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    padding: 22px;
  }

  .sbx .sbx-state__manage {
    width: auto;
  }

  .sbx-tile {
    width: 60px;
    height: 60px;
    font-size: var(--pj-fs-title);
  }

  .sbx-grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 16px;
  }

  /* Au large : une carte, avantages toujours visibles, pas de chevron. */
  .sbx .sbx-plan {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto 1fr auto;
    align-items: start;
    gap: 12px 14px;
    padding: 20px;
  }

  .sbx .sbx-plan__more {
    display: none;
  }

  .sbx-plan__features,
  .sbx-plan.is-open .sbx-plan__features {
    display: grid;
    grid-row: 2;
    align-content: start;
  }

  .sbx-plan__action {
    grid-column: 1 / -1;
  }

  .sbx .sub-plan__name {
    font-size: var(--pj-fs-lg);
  }

  .sbx .sbx-plan__price {
    font-size: var(--pj-fs-card);
  }

  .sbx-plan__days {
    display: block;
  }

  .sbx .sbx-billing {
    padding: 20px 24px;
    cursor: default;
  }

  .sbx .sbx-billing .sbx-billing__btn {
    display: inline-flex;
    width: auto;
    min-height: 44px;
    align-items: center;
    gap: 8px;
  }

  .sbx-billing__chevron {
    display: none;
  }
}

/* La console : les avantages de chaque forfait. */
.sa-features {
  display: grid;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.sa-features__item {
  display: grid;
  gap: 6px;
}

.sa-features__label {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin: 0;
}

.sa-features__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.sa-features__foot .btn {
  width: auto;
  min-height: 44px;
}

/* ── L'assistant de publication dans « Mes offres » (2026-09-28) ──────────
   Monté à la place de la liste, dans l'hôte de l'éditeur. */
.jo-assist {
  display: grid;
  gap: 14px;
}

.jo-offers .jo-assist__back {
  justify-self: start;
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.jo-assist__card {
  display: grid;
  gap: 14px;
}

.jo-assist__title {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

/* ── Présence web : la barre d'onglets à plat (maquette du 2026-09-27) ─────
   Une seule rangée, « Site & domaine » en premier (CompanyWebPresenceNav),
   sur les 8 pages de la présence web. Sur téléphone, les icônes seules : le
   nom reste dans `aria-label` et `title`. */
.wpnav.wpnav--flat {
  flex-direction: row;
  flex-wrap: wrap;
  gap: 8px;
}

.wpnav--flat .wpnav__item.wpnav__item {
  min-width: 44px;
  justify-content: center;
  border-radius: var(--pj-radius-sm);
  padding: 8px 12px;
}

.wpnav--flat .wpnav__label {
  display: none;
}

/* L'onglet actif garde son nom même sur téléphone : c'est lui qui dit où l'on est. */
.wpnav--flat .wpnav__item.is-active .wpnav__label {
  display: inline;
}

@media (min-width: 768px) {
  .wpnav--flat .wpnav__label {
    display: inline;
  }

  .wpnav--flat .wpnav__item.wpnav__item {
    padding: 8px 16px;
  }
}

/* ── « Mon site web », maquette du 2026-09-27 ──────────────────────────────
   Tout est sous `.wbx`. Les états qui ne figurent pas sur la maquette (choix
   du modèle, achat du domaine en cours, boîtes e-mail) prennent seulement les
   règles générales ci-dessous : cartes, en-têtes à icône, boutons à icône. */
.wbx-tile {
  width: 52px;
  height: 52px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 14px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-card);
}

.wbx .wbx-hero {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px 14px;
  align-items: start;
  padding: 16px;
}

.wbx-hero__text h1 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.wbx-hero__text p {
  margin: 4px 0 0;
  color: var(--pj-muted);
}

.wbx-hero__actions {
  grid-column: 1 / -1;
  justify-self: end;
}

.wbx-hero__actions:empty {
  display: none;
}

/* Les en-têtes de section : l'icône en couleur, le titre en gras. */
.wbx .co-section__head h2 {
  display: flex;
  align-items: center;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.wbx .co-section__icon {
  font-size: 1.1em;
  margin-right: 10px;
}

/* Tous les boutons d'une rangée d'actions : largeur de leur libellé, icône à
   gauche, 44px (E10). */
.wbx .co-form__actions .btn,
.wbx .wbx-actions .btn,
.wbx .wbx-form-actions .btn,
.wbx .wbx-package__actions .btn {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.wbx-actions,
.wbx-form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* La carte « en ligne » : l'aperçu, puis les gestes — côte à côte au large. */
.wbx-live__grid {
  display: grid;
  gap: 14px;
}

.wbx .wbx-live .wbs-preview {
  margin: 0;
}

.wbx .wbx-live .wbs-preview__frame {
  max-width: none;
  background: var(--pj-ink);
}

.wbx-live__info {
  min-width: 0;
  display: grid;
  gap: 10px;
  align-content: start;
}

.wbx-live__model,
.wbx-live__hint {
  margin: 0;
  color: var(--pj-ink);
}

.wbx-live__hint {
  color: var(--pj-muted);
}

.wbx-details > summary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-weight: 600;
  color: var(--pj-ink);
  cursor: pointer;
}

/* Le forfait : une ligne, séparée de la carte par un filet. */
.wbx-package {
  display: grid;
  gap: 10px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
}

.wbx-package__main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
}

.wbx-package__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.wbx-package__exp {
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.wbx-package__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.wbx-package__notice {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

/* Options supplémentaires : un bloc à part, sous l'aperçu, sur toute la largeur. */
.wbx-options {
  display: grid;
  gap: 16px;
  margin-top: 16px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.wbx-options[hidden] {
  display: none;
}

.wbx-options__head,
.wbx-advanced__head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.wbx-options__head > i,
.wbx-advanced__head > i {
  font-size: 1.4rem;
  color: var(--pj-info-ink);
  margin-top: 2px;
}

.wbx-options__head h3,
.wbx-advanced__head h3 {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.wbx-options__head p,
.wbx-advanced__head p {
  margin: 2px 0 0;
  color: var(--pj-muted);
}

.wbx-options__grid {
  display: grid;
  gap: 16px;
}

.wbx-field {
  min-width: 0;
  display: grid;
  gap: 6px;
  align-content: start;
}

.wbx-field .form-label {
  margin: 0;
  font-weight: 700;
  color: var(--pj-ink);
}

.wbx-field .form-control {
  min-height: 44px;
}

/* La couleur : pastille, code, pipette. */
.wbx-color {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
  background: var(--pj-card);
}

.wbx .wbx-color__swatch {
  width: 52px;
  min-height: 44px;
  padding: 4px;
  border: 0;
  background: none;
  cursor: pointer;
}

.wbx .wbx-color .wbx-color__hex {
  flex: 1;
  min-width: 0;
  border: 0;
  border-radius: 0;
  font-family: monospace;
  text-transform: uppercase;
}

.wbx .wbx-color__pick {
  width: 48px;
  flex: none;
  border: 0;
  border-left: 1px solid var(--pj-line);
  background: none;
  color: var(--pj-ink);
  cursor: pointer;
}

.wbx .wbx-color__pick[hidden] {
  display: none;
}

/* Un envoi d'image et, à côté, ce que le serveur accepte. */
.wbx-upload {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 10px;
}

.wbx-upload__info {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  font-size: 0.82rem;
  color: var(--pj-muted);
}

.wbx-upload__info i {
  color: var(--pj-ink);
  margin-top: 2px;
}

.wbx-options__actions {
  padding-top: 14px;
  border-top: 1px solid var(--pj-line);
}

/* Le nom de domaine : le texte, et une illustration à droite au large. */
.wbx .wbx-domain {
  display: grid;
  gap: 12px;
}

.wbx-domain__art {
  display: none;
}

/* Les statistiques : deux tuiles, puis « Voir le détail ». */
.wbx-stats__row {
  display: grid;
  gap: 12px;
}

.wbx .wbx-stats__tiles {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.wbx-stat {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.wbx-stat__value {
  font-size: var(--pj-fs-title);
  font-weight: 800;
  line-height: 1.1;
  color: var(--pj-ink);
}

.wbx-stat > i {
  color: var(--pj-info-ink);
  font-size: 1.1rem;
}

.wbx .wbx-stats .wbs-stats-more {
  margin-top: 0;
  justify-self: start;
  gap: 8px;
}

.wbx-advanced {
  display: grid;
  gap: 8px;
  margin-top: 10px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
}

.wbx-input-icon {
  position: relative;
  display: block;
}

.wbx-input-icon .form-control {
  min-height: 44px;
  padding-right: 40px;
}

.wbx-input-icon > i {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--pj-muted);
}

@media (min-width: 768px) {
  .wbx .wbx-hero {
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    padding: 22px 24px;
  }

  .wbx-tile {
    width: 64px;
    height: 64px;
    font-size: var(--pj-fs-title);
  }

  .wbx-hero__text h1 {
    font-size: var(--pj-fs-display);
  }

  .wbx-hero__actions {
    grid-column: auto;
  }

  .wbx-live__grid {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    align-items: start;
    gap: 20px;
  }

  .wbx-package {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }

  .wbx-package__notice {
    grid-column: 1 / -1;
  }

  .wbx-options {
    padding: 22px 24px;
  }

  .wbx-options__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px 24px;
  }

  .wbx-upload {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    align-items: start;
  }

  .wbx .wbx-domain {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 24px;
  }

  .wbx-domain__art {
    position: relative;
    display: inline-flex;
    font-size: var(--pj-fs-display);
    color: var(--pj-orange-text);
  }

  .wbx-domain__art .fa-magnifying-glass {
    position: absolute;
    right: -10px;
    bottom: -6px;
    font-size: 1.8rem;
  }

  .wbx-stats__row {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }

  .wbx .wbx-stats .wbs-stats-more {
    justify-self: end;
  }
}

/* ── Carte de visite, maquettes du 2026-09-28 ──────────────────────────────
   Sous `.bcx`. Mobile d'abord : une colonne, boutons pleine largeur ; au
   large, le formulaire sur deux colonnes et les boutons à leur largeur. */
.bcx .bcx-hero {
  display: grid;
  gap: 6px;
  padding: 16px;
}

.bcx-hero h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.bcx-hero p {
  margin: 0;
  color: var(--pj-muted);
}

.bcx .bcx-panel {
  display: grid;
  gap: 16px;
  padding: 16px;
}

.bcx-panel__head {
  display: flex;
  align-items: center;
  gap: 10px;
}

.bcx-panel__head i {
  font-size: 1.3rem;
  color: var(--pj-orange-text);
}

.bcx-panel__head h2 {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.bcx-panel__meta {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

/* Le formulaire. */
.bcx-form {
  display: grid;
  gap: 14px;
}

.bcx-field {
  min-width: 0;
  display: grid;
  gap: 6px;
  margin: 0;
}

.bcx-field label {
  margin: 0;
  color: var(--pj-ink);
}

.bcx-field .form-control {
  min-height: 44px;
}

.bcx-field .form-control:disabled {
  background: var(--pj-card-2);
  color: var(--pj-ink);
}

.bcx-color {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
  background: var(--pj-card);
}

.bcx .bcx-color__swatch {
  width: 64px;
  min-height: 44px;
  padding: 6px;
  border: 0;
  background: none;
  cursor: pointer;
}

.bcx .bcx-color .bcx-color__hex {
  flex: 1;
  min-width: 0;
  border: 0;
  border-radius: 0;
  font-family: monospace;
  text-transform: uppercase;
}

.bcx .bcx-color__pick {
  width: 48px;
  flex: none;
  border: 0;
  border-left: 1px solid var(--pj-line);
  background: none;
  color: var(--pj-ink);
  cursor: pointer;
}

.bcx .bcx-color__pick[hidden] {
  display: none;
}

.bcx-actions {
  display: grid;
  gap: 10px;
  margin-top: 6px;
}

.bcx .bcx-actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* Les états vides : l'illustration, une phrase, un bouton. */
.bcx .bcx-empty {
  display: grid;
  justify-items: center;
  gap: 12px;
  padding: 20px 16px;
  text-align: center;
}

.bcx-empty__text {
  display: grid;
  justify-items: center;
  gap: 10px;
  max-width: 520px;
}

.bcx-empty__text h2 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.bcx-empty__text p {
  margin: 0;
  color: var(--pj-muted);
}

.bcx .bcx-empty .btn {
  width: auto;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.bcx-art {
  width: min(260px, 80%);
  height: auto;
}

.bcx-art__blob { fill: var(--pj-orange-soft); }
.bcx-art__back { fill: var(--pj-orange); opacity: 0.85; }
.bcx-art__mid  { fill: var(--pj-card-2); stroke: var(--pj-line); }
.bcx-art__card { fill: var(--pj-card); stroke: var(--pj-line); }
.bcx-art__line { fill: var(--pj-line); }
.bcx-art__line--strong { fill: var(--pj-muted); opacity: 0.5; }
.bcx-art__qr rect { fill: var(--pj-ink); }
.bcx-art__qr .bcx-art__qr-hole { fill: var(--pj-card); }

/* L'aperçu de la carte générée : sa couleur en liseré et sur le QR, sa forme. */
.bcx-preview {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  max-width: 420px;
  padding: 18px 18px 18px 22px;
  border: 1px solid var(--pj-line);
  border-left: 6px solid var(--bcx-accent);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow);
}

.bcx-preview.is-rounded {
  border-radius: 14px;
}

.bcx-preview__main {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.bcx-preview__name {
  font-size: var(--pj-fs-lg);
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.bcx-preview__tagline {
  margin-bottom: 4px;
  font-style: italic;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.bcx-preview__line {
  font-size: var(--pj-fs-sm);
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.bcx-preview__line i {
  width: 16px;
  color: var(--bcx-accent);
}

.bcx-preview__qr {
  font-size: var(--pj-fs-display);
  color: var(--bcx-accent);
}

@media (min-width: 768px) {
  .bcx .bcx-hero,
  .bcx .bcx-panel {
    padding: 22px 24px;
  }

  .bcx-hero h1 {
    font-size: var(--pj-fs-display);
  }

  .bcx-form {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 24px;
  }

  .bcx-field--wide {
    grid-column: 1 / -1;
  }

  .bcx-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
  }

  .bcx .bcx-actions .btn {
    width: auto;
    padding-inline: 22px;
  }

  .bcx .bcx-actions #bc-confirm {
    min-width: 240px;
  }

  .bcx .bcx-empty {
    grid-template-columns: auto minmax(0, 1fr);
    justify-items: start;
    align-items: center;
    gap: 24px;
    padding: 24px;
    text-align: left;
  }

  .bcx-empty__text {
    justify-items: start;
  }

  .bcx-art {
    width: 260px;
  }
}

/* ── Statistiques de visite, maquette du 2026-09-28 ────────────────────────
   Sous `.wstx`. Les règles `.wst-*` ci-dessus (raccourcis, dates, graphique)
   restent la base ; celles-ci les mettent en forme comme la maquette. */
.wstx .wstx-hero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
  padding: 18px 16px;
  overflow: hidden;
}

.wstx-hero__text h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  line-height: 1.15;
  color: var(--pj-ink);
}

.wstx-hero__text p {
  margin: 8px 0 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.wstx-art {
  width: 120px;
  height: auto;
  margin: -12px -16px -18px 0;
}

.wstx-art__blob   { fill: var(--pj-orange-soft); }
.wstx-art__panel  { fill: var(--pj-card); stroke: var(--pj-line); }
.wstx-art__accent { fill: var(--pj-orange); }
.wstx-art__dot    { fill: var(--pj-orange); opacity: 0.55; }
.wstx-art__dot--soft { opacity: 0.3; }
.wstx-art__line   { fill: var(--pj-line); }
.wstx-art__bar    { fill: var(--pj-orange); }
.wstx-art__bar--1 { opacity: 0.6; }
.wstx-art__bar--2 { opacity: 0.8; }
.wstx-art__trend  { fill: none; stroke: var(--pj-orange); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }

.wstx-card__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

/* La période. */
.wstx .wstx-period {
  display: grid;
  gap: 12px;
}

.wstx .wst-presets {
  margin-top: 0;
}

.wstx .wstx-range {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 0;
}

.wstx .wstx-range .field {
  display: grid;
  gap: 6px;
}

.wstx .wstx-range label {
  margin: 0;
  font-weight: 600;
  color: var(--pj-ink);
}

.wstx .wstx-range .form-control {
  min-height: 44px;
}

.wstx .wstx-range .wst-range__go {
  grid-column: 1 / -1;
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

/* Les quatre chiffres : 2 × 2 sur téléphone, en ligne au large, chacun avec
   sa pastille colorée. */
.wstx .wst-figures {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  margin-top: 0;
}

.wstx-figure {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 10px;
}

.wstx-figure:nth-child(odd) {
  border-right: 1px solid var(--pj-line);
}

.wstx-figure:nth-child(-n+2) {
  border-bottom: 1px solid var(--pj-line);
}

.wstx-figure__icon {
  width: 44px;
  height: 44px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  font-size: 1.1rem;
}

.wstx-tint--orange { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.wstx-tint--blue   { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.wstx-tint--green  { background: var(--pj-success-soft); color: var(--pj-success); }
.wstx-tint--violet { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }

.wstx-figure__text {
  min-width: 0;
}

.wstx .wst-figure__value {
  font-size: var(--pj-fs-title);
  font-weight: 800;
}

.wstx .wstx-figures-card,
.wstx .wstx-chart-card {
  display: grid;
  gap: 12px;
}

/* Le graphique : l'échelle à gauche, la grille pointillée. */
.wstx .wstx-chart {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px;
}

.wstx-yaxis {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 160px;
  padding: 8px 0 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  text-align: right;
}

.wstx-plot {
  position: relative;
  min-width: 0;
}

.wstx-grid {
  stroke: var(--pj-line);
  stroke-width: 1;
  stroke-dasharray: 4 4;
  vector-effect: non-scaling-stroke;
}

.wstx-grid--base {
  stroke-dasharray: none;
  stroke: var(--pj-muted);
  opacity: 0.5;
}

@media (min-width: 768px) {
  .wstx .wstx-hero {
    padding: 24px 28px;
  }

  .wstx-hero__text h1 {
    font-size: var(--pj-fs-display);
  }

  .wstx-hero__text p {
    font-size: var(--pj-fs-body);
  }

  .wstx-art {
    width: 240px;
    margin: -24px -28px -24px 0;
  }

  .wstx .wstx-range {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
    align-items: end;
    gap: 16px;
  }

  .wstx .wstx-range .wst-range__go {
    grid-column: auto;
    width: auto;
    padding-inline: 28px;
  }

  .wstx .wst-figures {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .wstx-figure,
  .wstx-figure:nth-child(-n+2) {
    border-bottom: 0;
  }

  .wstx-figure:nth-child(odd) {
    border-right: 0;
  }

  .wstx-figure:not(:last-child) {
    border-right: 1px solid var(--pj-line);
  }

  .wstx .wstx-chart svg,
  .wstx-yaxis {
    height: 200px;
  }
}

/* ── Pages personnalisées, maquette du 2026-09-28 ──────────────────────────
   Sous `.wpgx`. Téléphone : la pastille de visibilité en haut à droite, trois
   actions (Gérer, Modifier, Supprimer) dessous ; au large, la bascule
   Visible/Masquée et les quatre actions sur la ligne du titre. */
.wpgx .wpgx-hero {
  display: grid;
  gap: 8px;
  padding: 16px;
}

.wpgx-hero h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.wpgx-hero p {
  margin: 0;
  color: var(--pj-muted);
}

.wpgx .wpgx-form-card {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.wpgx-title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.wpgx-form {
  display: grid;
  gap: 12px;
}

.wpgx-form .form-group {
  margin: 0;
}

.wpgx-form .form-control {
  min-height: 44px;
}

.wpgx-checks {
  display: grid;
  gap: 4px;
}

.wpgx-checks .form-check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 36px;
  margin: 0;
  padding-left: 0;
}

.wpgx-checks .form-check-input {
  width: 20px;
  height: 20px;
  margin: 0;
  float: none;
  accent-color: var(--pj-info-ink);
}

.wpgx-checks .form-check-label {
  color: var(--pj-ink);
}

/* Le thème ajoute ses propres marges aux cases et à leur libellé : mesuré,
   56px entre deux lignes et la case plus basse que son texte. Deux classes
   de plus pour reprendre la main. */
.wpgx .wpgx-checks .form-check {
  min-height: 32px;
  margin: 0;
}

.wpgx .wpgx-checks .form-check .form-check-input {
  margin: 0;
  position: static;
}

.wpgx .wpgx-checks .form-check .form-check-label {
  margin: 0;
  padding: 0;
  line-height: 1.3;
}

.wpgx-placement {
  padding-top: 12px;
  border-top: 1px solid var(--pj-line);
}

.wpgx-placement__label {
  margin: 0 0 4px;
  color: var(--pj-ink);
}

.wpgx-actions {
  display: grid;
  gap: 10px;
}

.wpgx .wpgx-actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.wpgx .wpgx-actions .btn[hidden] {
  display: none;
}

/* Une page. */
.wpgx .wpgx-page {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px 12px;
  padding: 14px 16px;
}

.wpgx-page__main {
  min-width: 0;
  display: grid;
  gap: 2px;
}

.wpgx-page__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.wpgx-page__line {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.wpgx-page__line--muted {
  color: var(--pj-muted);
}

.wpgx-page__contents {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 4px 0 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.wpgx-page__contents i {
  margin-right: 3px;
}

/* La pastille : l'état, et un toucher la bascule. */
.wpgx .wpgx-pill {
  align-self: start;
  width: auto;
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
  cursor: pointer;
}

.wpgx-pill.is-visible { background: var(--pj-success-soft); color: var(--pj-success); }
.wpgx-pill.is-hidden  { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }

.wpgx-page__actions {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.wpgx .wpgx-page__actions .btn {
  width: 100%;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding-inline: 8px;
  font-size: var(--pj-fs-body);
}

.wpgx-switch {
  display: none;
}

.wpgx-long {
  display: none;
}

.wpgx .wpgx-delete {
  color: var(--pj-danger);
}

/* La bascule Visible / Masquée (ordinateur). L'état actuel est coloré et
   inactif ; l'autre, pâle, bascule. */
.wpgx .wpgx-switch .btn {
  border: 0;
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.wpgx .wpgx-switch .wpgx-switch__on.is-current {
  background: var(--pj-success-soft);
  color: var(--pj-success);
  opacity: 1;
}

.wpgx .wpgx-switch .wpgx-switch__off.is-current {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  opacity: 1;
}

@media (min-width: 768px) {
  .wpgx .wpgx-hero,
  .wpgx .wpgx-form-card {
    padding: 22px 24px;
  }

  .wpgx-hero h1 {
    font-size: var(--pj-fs-display);
  }

  .wpgx-actions {
    display: flex;
    gap: 12px;
  }

  .wpgx .wpgx-actions .btn {
    width: auto;
    padding-inline: 24px;
  }

  .wpgx .wpgx-page {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    padding: 16px 22px;
  }

  .wpgx .wpgx-pill {
    display: none;
  }

  .wpgx-page__actions {
    grid-column: auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
  }

  .wpgx .wpgx-page__actions .btn {
    width: auto;
    padding-inline: 14px;
  }

  .wpgx-switch {
    display: inline-flex;
    gap: 8px;
  }

  .wpgx-long {
    display: inline;
  }

  .wpgx-short {
    display: none;
  }
}

/* ── Organisation du site, maquette du 2026-09-28 ──────────────────────────
   Sous `.wpox`. Deux cartes ; les deux listes deviennent des tableaux à
   lignes fines, la poignée à gauche. Le glisser-déposer ne change pas. */
.wpox .wpox-hero {
  display: grid;
  gap: 6px;
  padding: 16px;
}

.wpox-hero h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.wpox-hero p {
  margin: 0;
  color: var(--pj-info-ink);
}

.wpox .wpox-card {
  display: grid;
  gap: 8px;
  padding: 16px;
}

.wpox-title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.wpox-hint {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.wpox-hint--wide {
  display: none;
}

.wpox .wpox-list {
  gap: 0;
  margin: 6px 0 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  overflow: hidden;
}

.wpox-table .wpox-list {
  margin: 0;
  border-top: 0;
  border-radius: 0 0 var(--pj-radius-sm) var(--pj-radius-sm);
}

.wpox .wpox-row {
  min-height: 44px;
  padding: 6px 12px;
  border: 0;
  border-bottom: 1px solid var(--pj-line);
  border-radius: 0;
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.wpox .wpox-list > .wpox-row:last-child {
  border-bottom: 0;
}

.wpox .wpox-grip {
  width: 16px;
  color: var(--pj-muted);
}

/* Le menu : grip | nom | mention | Accueil | En-tête | Pied de page. */
.wpox .wpox-menu-row {
  display: grid;
  /* Sur téléphone, DEUX LIGNES par rubrique : le nom sur toute la largeur,
     les trois cases dessous, chacune sous son en-tête (mention masquée,
     hors grille). Trois colonnes de cases sur une seule ligne laissaient au
     nom 18 à 76 px selon l'écran : « Événements » passait sous la case
     « Accueil », mesuré le 2026-10-08 à 360 px. Un mot seul ne se coupe
     pas, et minmax(0, 1fr) laisse alors le texte déborder sur la case. */
  grid-template-columns: 16px repeat(3, minmax(0, 1fr));
  grid-template-areas:
    "grip name name name"
    ".    home head foot";
  align-items: center;
  column-gap: 8px;
  row-gap: 0;
}

.wpox .wpox-menu-row > :nth-child(1) { grid-area: grip; }
.wpox .wpox-menu-row > :nth-child(2) { grid-area: name; min-width: 0; overflow-wrap: anywhere; }
.wpox .wpox-menu-row > :nth-child(4) { grid-area: home; }
.wpox .wpox-menu-row > :nth-child(5) { grid-area: head; }
.wpox .wpox-menu-row > :nth-child(6) { grid-area: foot; }

/* L'en-tête n'a pas de nom à porter : une seule ligne, les trois intitulés
   au-dessus de leurs colonnes, et « Page » masqué. */
.wpox .wpox-menu-head { grid-template-areas: "grip home head foot"; }
.wpox .wpox-menu-head > :nth-child(2) { display: none; }

.wpox-menu-head {
  margin-top: 6px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm) var(--pj-radius-sm) 0 0;
  background: var(--pj-card-2);
  font-weight: 700;
  font-size: var(--pj-fs-body);
  cursor: default;
}

.wpox .wpox-menu-head {
  border-bottom: 1px solid var(--pj-line);
  background: var(--pj-card-2);
}

.wpox-col {
  text-align: center;
  line-height: 1.2;
}

.wpox .wpox-check {
  justify-content: center;
  min-height: 44px;
  margin: 0;
}

.wpox-check input {
  width: 18px;
  height: 18px;
  accent-color: var(--pj-info-ink);
}

/* Une case « Accueil » grisée n'est pas en panne : la rubrique est retirée
   des deux menus, donc elle n'est plus nulle part sur le site et la question
   de l'accueil ne se pose plus. Voir `_syncMenuRow()`. */
.wpox-check input:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.wpox-unavailable {
  display: none;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  white-space: nowrap;
}

.wpox-info {
  margin-left: 6px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.wpox-actions {
  display: grid;
  margin-top: 10px;
}

.wpox .wpox-actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

@media (min-width: 768px) {
  .wpox .wpox-hero,
  .wpox .wpox-card {
    padding: 20px 24px;
  }

  .wpox-hero h1 {
    font-size: var(--pj-fs-display);
  }

  .wpox-hint--wide {
    display: block;
  }

  .wpox .wpox-menu-row {
    grid-template-columns: 16px minmax(0, 1fr) auto 110px 110px 110px;
    grid-template-areas: none;
    gap: 8px;
  }

  /* Une ligne par rubrique dès qu'il y a la place : les cellules reprennent
     leur ordre naturel, et « Page » reparaît dans l'en-tête.
     `:nth-child(n)` et non `*` : la remise à zéro doit peser autant que les
     `:nth-child(2)`… du téléphone, sinon les cellules gardent des zones
     nommées qui n'existent plus et la grille s'invente des colonnes. */
  .wpox .wpox-menu-row > :nth-child(n) { grid-area: auto; }
  .wpox .wpox-menu-head > :nth-child(2) { display: block; }

  .wpox-unavailable {
    display: inline;
  }

  .wpox-info--inline {
    display: none;
  }

  .wpox-actions {
    display: flex;
  }

  .wpox .wpox-actions .btn {
    width: auto;
    padding-inline: 24px;
  }
}

/* ── Mes actualités, maquette du 2026-09-28 ────────────────────────────────
   Sous `.wnx`. Le formulaire garde ses champs ; la boîte image devient une
   zone basse en pointillés, et « Enregistrer » occupe toute la largeur sur
   téléphone. « Contenu additionnel » (`/entreprises/sections`) porte le même
   formulaire et reprend `.wnx` ; ses écarts sont sous `.wcsx`, plus bas. */
.wnx .wnx-hero {
  display: grid;
  gap: 6px;
  padding: 16px;
}

.wnx-hero h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.wnx-hero p {
  margin: 0;
  color: var(--pj-muted);
}

.wnx .wnx-form-card {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.wnx-form-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
}

.wnx-title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.wnx-quota {
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.wnx-form {
  display: grid;
  gap: 14px;
}

.wnx-form .form-group {
  margin: 0;
}

.wnx-form .form-control {
  min-height: 44px;
}

.wnx-form .rte__editor {
  min-height: 96px;
}

.wnx .mu__preview {
  /* --pj-line est trop proche du fond gris clair : le pointillé disparaissait. */
  border: 2px dashed color-mix(in srgb, var(--pj-muted) 40%, transparent);
  background: var(--pj-card-2);
}

.wnx .mu--wide .mu__preview {
  aspect-ratio: auto;
  height: 120px;
}

.wnx .mu--wide .mu__preview:has(img) {
  aspect-ratio: 3 / 1;
  height: auto;
}

.wnx .mu__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.wnx .mu__actions .mu__pick,
.wnx .mu__actions .mu__gallery-toggle {
  width: 100%;
  min-height: 44px;
  justify-content: center;
  border: 0;
  gap: 6px;
  padding-inline: 6px;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  white-space: nowrap;
}

.wnx .mu__actions .mu__clear {
  grid-column: 1 / -1;
  justify-self: start;
}

.wnx-actions {
  display: grid;
  gap: 10px;
}

.wnx .wnx-actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-weight: 700;
}

.wnx .wnx-actions .btn[hidden] {
  display: none;
}

@media (min-width: 768px) {
  .wnx .wnx-hero,
  .wnx .wnx-form-card {
    padding: 22px 24px;
  }

  .wnx-hero h1 {
    font-size: var(--pj-fs-display);
  }

  .wnx .mu--wide .mu__preview {
    height: 160px;
  }

  .wnx .mu__actions {
    display: flex;
  }

  .wnx .mu__actions .mu__pick,
  .wnx .mu__actions .mu__gallery-toggle {
    width: auto;
    padding-inline: 16px;
    font-size: var(--pj-fs-body);
  }

  .wnx-actions {
    display: flex;
  }

  .wnx .wnx-actions .btn {
    width: auto;
    padding-inline: 32px;
  }
}

/* ── Ma galerie, maquette du 2026-09-28 ────────────────────────────────────
   Sous `.wgx`. Téléphone : une ligne par photo (vignette | légende, Masquée,
   Supprimer). Au large : des tuiles, photo et légende dans un cadre, les
   deux actions dessous. `.wgx-frame` est le cadre, posé derrière. */
.wgx .wgx-hero {
  display: grid;
  gap: 6px;
  padding: 16px;
}

.wgx-hero h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.wgx-hero p {
  margin: 0;
  color: var(--pj-muted);
}

.wgx .wgx-card {
  display: grid;
  gap: 14px;
  padding: 16px;
}

.wgx-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.wgx-hint {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.wgx-quota {
  flex: none;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.wgx .wp-gallery-grid {
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  margin: 0;
}

.wgx .wgx-item {
  position: relative;
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr);
  grid-template-rows: auto auto 1fr;
  gap: 4px 10px;
  padding: 0;
  border: 0;
  background: none;
}

.wgx-frame {
  grid-column: 1;
  grid-row: 1 / 4;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.wgx .wgx-photo {
  grid-column: 1;
  grid-row: 1 / 4;
  align-self: center;
  width: calc(100% - 16px);
  margin: 8px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: var(--pj-radius-sm);
}

.wgx .wgx-caption {
  grid-column: 2;
  grid-row: 1;
  min-height: 44px;
  margin-top: 8px;
  padding-inline: 8px;
  font-size: var(--pj-fs-body);
}

.wgx .wgx-link {
  width: auto;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  font-size: var(--pj-fs-body);
  cursor: pointer;
}

.wgx .wgx-visibility {
  grid-column: 2;
  grid-row: 2;
  color: var(--pj-muted);
}

.wgx .wgx-visibility.is-public {
  color: var(--pj-success);
}

.wgx .wgx-remove {
  grid-column: 2;
  grid-row: 3;
  align-self: start;
  color: var(--pj-danger);
}

/* L'emplacement d'ajout : pleine largeur sur téléphone. */
.wgx .wp-gallery-add {
  max-width: none;
}

.wgx .mu--square .mu__preview {
  aspect-ratio: auto;
  max-width: none;
  height: 140px;
  border: 2px dashed color-mix(in srgb, var(--pj-muted) 40%, transparent);
}

.wgx .mu__actions .mu__pick {
  width: 100%;
  min-height: 48px;
  justify-content: center;
  border: 0;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 600;
}

@media (min-width: 768px) {
  .wgx .wgx-hero,
  .wgx .wgx-card {
    padding: 22px 24px;
  }

  .wgx-hero h1 {
    font-size: var(--pj-fs-display);
  }

  .wgx .wp-gallery-grid {
    grid-template-columns: repeat(auto-fill, minmax(190px, 230px));
    gap: 20px;
  }

  .wgx .wgx-item {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto auto;
    gap: 0;
  }

  .wgx-frame {
    grid-row: 1 / 3;
  }

  .wgx .wgx-photo {
    grid-row: 1;
    width: calc(100% - 20px);
    margin: 10px 10px 0;
  }

  .wgx .wgx-caption {
    grid-column: 1;
    grid-row: 2;
    width: calc(100% - 20px);
    margin: 8px 10px 10px;
    font-size: var(--pj-fs-body);
  }

  .wgx .wgx-link {
    justify-self: center;
  }

  .wgx .wgx-visibility {
    grid-column: 1;
    grid-row: 3;
    margin-top: 4px;
  }

  .wgx .wgx-remove {
    grid-column: 1;
    grid-row: 4;
  }

  .wgx .wp-gallery-add {
    max-width: 230px;
  }

  .wgx .mu--square .mu__preview {
    height: 180px;
  }
}

/* ── Contenu additionnel : ce qui diffère de « Mes actualités » ──────────
   Sur téléphone, la maquette empile les deux boutons d'image, chacun sur
   toute la largeur. */
.wcsx .mu__actions {
  grid-template-columns: minmax(0, 1fr);
}

.wnx.wcsx .mu__actions .mu__pick,
.wnx.wcsx .mu__actions .mu__gallery-toggle {
  font-size: var(--pj-fs-body);
}

@media (min-width: 768px) {
  .wcsx .mu__actions {
    display: flex;
  }
}

/* ── Vendre sur Prosyjob (« Mes publications »), maquette du 2026-09-28 ────
   Sous `.mlx`. Trois cartes : le quota et les boutons de création, les
   filtres avec le bouton de sélection multiple, puis une carte par
   publication (vignette, titre, pastilles, actions dessous). */
.mlx .mlx-head {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.mlx-head #ml-head h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.mlx-head #ml-head p {
  margin: 4px 0 0;
  color: var(--pj-muted);
}

.mlx-quota {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.mlx-quota:empty {
  display: none;
}

.mlx-create {
  display: grid;
  gap: 8px;
}

.mlx .mlx-create .btn {
  width: 100%;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  padding-inline: 16px;
  font-weight: 600;
}

.mlx .mlx-create .btn[hidden] {
  display: none;
}

.mlx .mlx-filters {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.mlx-filters__grid {
  display: grid;
  gap: 12px;
}

.mlx-filters__grid .form-group {
  margin: 0;
}

.mlx-filters__grid label {
  font-weight: 700;
  color: var(--pj-ink);
}

.mlx-filters__grid .form-control {
  min-height: 44px;
}

/* Le bouton de sélection multiple sort de `#ml-create-actions` exprès :
   cette boîte-là voit ses boutons désactivés au quota atteint, qui est
   précisément le moment où l'on veut pouvoir supprimer en lot. */
.mlx-filters__actions {
  display: grid;
}

.mlx .mlx-filters__actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 700;
}

.mlx .mlx-filters__actions .btn[hidden] {
  display: none;
}

.mlx-filters__actions:has(.btn[hidden]) {
  display: none;
}

/* Une publication. */
.mlx .mlx-card {
  gap: 12px 14px;
  align-items: flex-start;
  padding: 14px;
}

.mlx .mlx-card .ml-card__cover {
  width: 84px;
  height: 72px;
  background: var(--pj-card-2);
}

/* En mode sélection, la règle générique `.pj-select__box + div` fait grandir
   l'élément qui suit la case — ici la vignette, qui mangeait la place du
   titre. La vignette garde sa taille, c'est le texte qui prend le reste. */
.mlx .mlx-card .pj-select__box + .ml-card__cover {
  flex: 0 0 auto;
}

.mlx .mlx-card .ml-card__body {
  flex: 1 1 0;
  min-width: 0;
}

.mlx .mlx-card .ml-card__placeholder {
  display: grid;
  justify-items: center;
  gap: 2px;
  font-size: 0.68rem;
  line-height: 1.2;
  color: var(--pj-muted);
}

.mlx-card .ml-card__placeholder i {
  font-size: 1.3rem;
}

.mlx .mlx-card .ml-card__title {
  margin: 0 0 6px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.mlx-pill {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.mlx-pill--type {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

/* ==========================================================================
   L'ANNONCE PAR AGREGATION (PO, 2026-10-03)
   --------------------------------------------------------------------------
   `pkw-` : l'assistant de composition. `mpd-pack__` : la fiche publique.
   Aucun hex en dur, et tout s'empile a 360px -- une ligne de package porte un
   titre, une entreprise, un tarif, une quantite et trois boutons, ce qui ne
   tient pas cote a cote sur un telephone.
   ========================================================================== */

/* ---- l'assistant : les lignes choisies ---------------------------------- */
.pkw-lines,
.pkw-picks {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.pkw-line,
.pkw-pick {
  display: grid;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

/* Une ligne dont le tarif a disparu : elle reste LA, et elle se voit. */
.pkw-line.is-missing {
  border-color: var(--pj-danger);
  background: var(--pj-danger-soft);
}

.pkw-line__main,
.pkw-pick__main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.pkw-line__title {
  overflow-wrap: anywhere;
}

.pkw-line__company,
.pkw-pick__meta {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.pkw-line__fields {
  display: grid;
  gap: 6px;
}

.pkw-line__label {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  margin: 0;
}

/* « Gratuit » se lit comme un prix. Vert comme la remise -- c'est la meme
   nature, ce que l'acheteur ne paie pas -- et jamais rouge, qui est la
   couleur de la panne juste en dessous. */
.pkw-line__free {
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-success);
}

.pkw-line__missing {
  font-size: var(--pj-fs-xs);
  color: var(--pj-danger);
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Les trois boutons d'une ligne : `width: auto` et 44px de cote.
   Le bloc `button, .btn` de ce fichier les mettrait sinon a 100 %, et le
   plancher tactile du projet est 44 -- mesure, pas devine. */
.pkw-line__actions {
  display: flex;
  gap: 6px;
}

.pkw-line__actions .btn {
  width: auto;
  min-width: 44px;
  min-height: 44px;
}

/* ---- l'assistant : le catalogue ---------------------------------------- */
.pkw-search {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.pkw-search .form-control {
  flex: 1 1 auto;
  min-width: 0;
}

.pkw-search .btn {
  width: auto;
  flex: 0 0 auto;
  min-height: 44px;
}

.pkw-group + .pkw-group {
  margin-top: 16px;
}

.pkw-group__name {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
}

.pkw-pick .btn {
  width: auto;
  justify-self: start;
  min-height: 44px;
}

/* Deja prise : la ligne reste lisible, le bouton seul est eteint. */
.pkw-pick.is-taken .pkw-pick__main {
  opacity: 0.7;
}

.pkw-empty {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px;
  border: 1px dashed var(--pj-line);
  border-radius: var(--pj-radius-sm);
  margin: 0;
}

/* ---- l'assistant : la remise et les totaux ------------------------------ */
.pkw-discount {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 220px;
}

.pkw-discount .form-control {
  min-width: 0;
}

.pkw-discount__unit {
  color: var(--pj-muted);
  font-weight: 600;
}

.pkw-totals {
  margin-top: 12px;
  padding: 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  display: grid;
  gap: 4px;
}

.pkw-totals__row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: var(--pj-fs-sm);
  font-variant-numeric: tabular-nums;
}

.pkw-totals__row--discount {
  color: var(--pj-success);
}

.pkw-totals__row--total {
  padding-top: 6px;
  border-top: 1px solid var(--pj-line);
  font-size: var(--pj-fs-md);
}

.pkw-totals__warn {
  margin: 6px 0 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-danger);
  display: flex;
  align-items: center;
  gap: 6px;
}

/* ---- la fiche publique ------------------------------------------------- */
.mpd-pack__lines {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

/* FLEX et non grille : la vignette est OPTIONNELLE, et un element absent ne
   laisse pas de trou en flex -- ce qu'une colonne de grille fait toujours.
   `flex-wrap` suffit a faire passer le montant dessous quand c'est etroit,
   sans point de rupture a tenir. */
.mpd-pack__line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--pj-line);
}

.mpd-pack__line:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

/* Il prend la place restante et se laisse rétrécir : `min-width: 0` est ce
   qui autorise un titre long a passer a la ligne plutot qu'a elargir la
   rangee. La base de 12rem est le seuil ou le montant passe dessous. */
.mpd-pack__what {
  flex: 1 1 12rem;
  display: grid;
  gap: 2px;
  min-width: 0;
}

.mpd-pack__who {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* A DROITE, toujours : `margin-left: auto` le pousse au bout de la rangee,
   qu'il y ait une vignette ou non. C'est ce que la grille conditionnelle
   n'arrivait pas a tenir. */
.mpd-pack__amount {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* L'illustration d'une prestation incluse (PO, 2026-10-03). Carree et
   `object-fit: cover` : les photos d'annonce ont tous les rapports, et une
   vignette qui se deforme se remarque plus qu'une vignette rognee.
   `flex: 0 0 auto` parce que la ligne est un flex : sans lui, la vignette se
   laisserait ecraser par un titre long, et 48px est une taille, pas une
   suggestion. */
.mpd-pack__thumb {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: var(--pj-radius-sm);
  object-fit: cover;
  background: var(--pj-card-2);
}

/* Le vrai logo prend la place des initiales, a la pastille pres : meme taille,
   meme chevauchement, meme bordure. Sans quoi la pile se desaligne des qu'une
   entreprise n'a pas de logo. */
/* Pas de photo : la tuile garde la colonne et le DIT. Meme icone que
   `.ml-card__placeholder`, qui tient ce role sur les cartes de « Mes
   publications » -- un idiome de plus serait un idiome de trop. */
.mpd-pack__thumb--vide {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--pj-muted);
  border: 1px dashed var(--pj-line);
}

.mpd-pack__logo--img {
  object-fit: contain;
  background: var(--pj-card);
  padding: 2px;
}
.mpd-pack__free {
  font-weight: 600;
  color: var(--pj-success);
}

.mpd-pack__missing {
  color: var(--pj-danger);
  font-size: var(--pj-fs-xs);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
}

/* Les logos EMPILES : ils se chevauchent d'un tiers, comme une pile de jetons.
   A defaut de media, les initiales -- mieux qu'une rangee de cadres vides. */
.mpd-pack__stack {
  display: flex;
  margin-bottom: 8px;
}

.mpd-pack__logo {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  color: var(--pj-accent-ink);
  background: var(--pj-accent-soft);
  border: 2px solid var(--pj-card);
}

.mpd-pack__logo + .mpd-pack__logo {
  margin-left: -12px;
}

.mpd-pack__names {
  font-size: var(--pj-fs-sm);
}

.mpd-pack__totals {
  display: grid;
  gap: 4px;
  font-variant-numeric: tabular-nums;
}

.mpd-pack__totals > div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.mpd-pack__discount {
  color: var(--pj-success);
}

.mpd-pack__total {
  padding-top: 6px;
  border-top: 1px solid var(--pj-line);
  font-weight: 700;
}

/* A partir de 600px la ligne retrouve sa rangee : titre a gauche, champs au
   milieu, boutons a droite. En dessous, tout est empile -- cinq choses cote a
   cote sur 360px ne se lisent pas. */
@media (min-width: 600px) {
  .pkw-line {
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: center;
  }

  .pkw-line__fields {
    grid-template-columns: auto minmax(0, 160px) auto minmax(0, 90px);
    align-items: center;
    gap: 8px;
  }

  .pkw-pick {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }

}
/* Le signe distinctif d'une prestation deja agregee (PO, 2026-10-03).
   Violet et non bleu : la pastille de type occupe deja le bleu, et deux
   teintes identiques dans la meme rangee ne se distinguent pas d'un coup
   d'oeil -- ce qui est tout ce qu'un signe distinctif doit faire. */
.mlx-pill--package {
  gap: 5px;
  background: var(--pj-accent-soft);
  color: var(--pj-accent-ink);
}
.mlx-pill.is-published {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.mlx-pill.is-suspended {
  background: var(--pj-orange-soft);
  color: var(--pj-danger);
}

.mlx .mlx-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin-top: 0;
}

.mlx .mlx-actions .btn {
  width: 100%;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding-inline: 6px;
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.mlx .mlx-actions .btn.mlx-delete {
  grid-column: 1 / -1;
  justify-self: start;
  width: auto;
  padding-inline: 12px;
  background: none;
  border: 0;
  color: var(--pj-danger);
}

.mlx-long {
  display: none;
}

@media (min-width: 768px) {
  .mlx .mlx-head,
  .mlx .mlx-filters {
    padding: 22px 24px;
  }

  .mlx-quota {
    font-size: var(--pj-fs-title);
  }

  .mlx-create {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
  }

  .mlx .mlx-create .btn {
    width: auto;
    min-height: 50px;
    padding-inline: 20px;
  }

  .mlx-filters__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
  }

  .mlx-filters__actions {
    justify-content: end;
  }

  .mlx .mlx-filters__actions .btn {
    width: auto;
    padding-inline: 24px;
  }

  .mlx .mlx-card {
    padding: 22px 28px;
  }

  .mlx .mlx-card .ml-card__cover {
    width: 126px;
    height: 110px;
  }

  .mlx .mlx-card .ml-card__title {
    margin-top: 16px;
    font-size: var(--pj-fs-card);
  }

  .mlx-pill {
    padding: 5px 14px;
    font-size: var(--pj-fs-body);
  }

  .mlx .mlx-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
  }

  .mlx .mlx-actions .btn {
    width: auto;
    min-height: 50px;
    padding-inline: 20px;
    font-size: var(--pj-fs-md);
  }

  .mlx .mlx-actions .btn.mlx-delete {
    grid-column: auto;
  }

  .mlx-long {
    display: inline;
  }

  .mlx-short {
    display: none;
  }
}

/* ── Les assistants « Publier un événement / un service / un article »,
   maquettes du 2026-09-28 ──────────────────────────────────────────────
   Sous `.mwz`, commun aux trois. L'en-tête porte le titre et les étapes ;
   chaque étape est une carte ; les choix sont des tuiles à icône ; l'aperçu
   est une pile de cartes à icône. Sur téléphone, les boutons du bas vont
   par deux, et le bouton principal d'une rangée impaire prend la largeur. */
.mwz .mwz-head {
  display: grid;
  gap: 14px;
  padding: 16px;
}

.mwz-head h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

/* Les étapes : une rangée de pastilles. */
.mwz .mwz-steps {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.mwz .mwz-steps li {
  flex: 0 1 auto;
  min-width: 0;
  gap: 6px;
  padding: 5px 8px 5px 5px;
  border-color: transparent;
  background: none;
  font-size: var(--pj-fs-sm);
}

.mwz .mwz-steps li span {
  flex: 0 0 24px;
  height: 24px;
  font-size: var(--pj-fs-xs);
}

.mwz .mwz-steps li strong {
  font-weight: 500;
  white-space: nowrap;
}

.mwz .mwz-steps li.is-current {
  border-color: var(--pj-orange-fill);
  background: var(--pj-orange-soft);
  color: var(--pj-ink);
}

.mwz .mwz-steps li.is-current strong {
  font-weight: 700;
}

/* `.mwz-long` / `.mwz-short` sont des <span> : la règle des pastilles
   ci-dessus (`li span`) les peindrait en ronds. On les rend au texte. */
.mwz .mwz-steps li strong span {
  display: inline;
  flex: none;
  height: auto;
  padding: 0;
  background: none;
  border-radius: 0;
  color: inherit;
  font-size: inherit;
  font-weight: inherit;
}

.mwz .mwz-steps li strong .mwz-long {
  display: none;
}

/* Sous 420px, la carte n'a que ~260px : quatre libellés n'y tiennent pas
   sur une ligne. Seule l'étape en cours garde le sien, les autres leur
   numéro — la barre reste une rangée, et l'on sait toujours où l'on est. */
@media (max-width: 419px) {
  .mwz .mwz-steps {
    flex-wrap: nowrap;
  }

  .mwz .mwz-steps li:not(.is-current) {
    padding-right: 5px;
  }

  .mwz .mwz-steps li:not(.is-current) strong {
    display: none;
  }
}

/* Une étape = une carte. */
.mwz .mwz-card {
  display: grid;
  gap: 14px;
  padding: 16px;
}

.mwz .mwz-card .form-group {
  margin: 0;
}

.mwz .mwz-card .form-group > label,
.mwz .mwz-card .co-section__title,
.mwz .mwz-card .mk-visibility__title {
  margin: 0 0 6px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.mwz .mwz-card .form-control {
  min-height: 44px;
}

.mwz .mwz-card .rte__editor {
  min-height: 96px;
}

/* Cases et boutons radio : le thème les fait flotter devant un retrait du
   libellé, et ils décrochaient de leur ligne. Une rangée flex les aligne. */
.mwz .mwz-card .form-check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 36px;
  margin: 0;
  padding-left: 0;
}

.mwz .mwz-card .form-check .form-check-input {
  flex: none;
  float: none;
  width: 18px;
  height: 18px;
  margin: 0;
}

.mwz .mwz-card .form-check .form-check-label {
  margin: 0;
  color: var(--pj-ink);
}

.mwz .mwz-card .mk-netcom__hint {
  margin: 4px 0 8px;
  font-size: var(--pj-fs-body);
}

/* Les rubriques de l'étape des tarifs, séparées d'un filet. */
.mwz .mwz-card .co-section__block {
  margin: 0;
}

.mwz .mwz-card .co-section__block + .co-section__block {
  padding-top: 14px;
  border-top: 1px solid var(--pj-line);
}

/* Les photos : la même zone en pointillés que les autres écrans du site,
   sur toute la largeur (le composant la borne à une vignette ailleurs). */
.mwz .pg__add {
  max-width: none;
  width: 100%;
}

.mwz .pg__add .mu__preview {
  aspect-ratio: auto;
  max-width: none;
  height: 110px;
  border: 2px dashed color-mix(in srgb, var(--pj-muted) 40%, transparent);
  background: var(--pj-card-2);
}

.mwz .pg__add .mu__actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
}

.mwz .pg__add .mu__actions .mu__pick,
.mwz .pg__add .mu__actions .mu__gallery-toggle {
  width: 100%;
  min-height: 44px;
  justify-content: center;
  border: 0;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 600;
}

/* Les choix (accès, format, type…) : des tuiles à icône. */
.mwz .mwz-choices {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 8px;
  width: 100%;
}

.mwz .mwz-choices > .btn {
  width: 100%;
  min-height: 52px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  margin: 0;
  padding: 10px 16px;
  text-align: left;
  white-space: normal;
  font-weight: 600;
}

/* Bootstrap équerre les boutons d'un groupe et les colle (marge -1px) avec
   des sélecteurs à quatre classes : des tuiles séparées doivent les battre. */
.mwz .mwz-card .mwz-choices.btn-group > .btn:nth-child(n) {
  margin: 0;
  border-radius: var(--pj-radius-sm);
}

.mwz .mwz-choices > .btn i {
  flex: none;
  width: 22px;
  font-size: 1.15rem;
  text-align: center;
}

/* L'adresse, repliée : l'épingle devant la phrase. */
.mwz .co-location--view .co-location__text {
  display: flex;
  align-items: center;
  gap: 12px;
}

.mwz .co-location--view .co-location__text::before {
  content: "\f3c5";
  font-family: "Font Awesome 7 Free", "Font Awesome 6 Free", "Font Awesome 5 Free";
  font-weight: 900;
  font-size: 1.2rem;
  color: var(--pj-navy);
}

.mwz .co-location--view .btn {
  width: 100%;
  min-height: 44px;
}

/* Les tarifs : libellé | montant, « Retirer » en rouge. */
.mwz .ev-price-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 12px;
  align-items: end;
}

.mwz .ev-price-row .form-group {
  margin: 0;
}

.mwz .ev-price-row .form-group > label {
  font-size: var(--pj-fs-body);
  font-weight: 500;
}

.mwz .mwz-card .ev-price-row [data-action="remove-price"] {
  grid-column: 1 / -1;
  justify-self: end;
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--pj-danger);
  text-decoration: none;
}

.mwz .mwz-card [data-action="add-price"] {
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  font-weight: 600;
}

/* Les boutons du bas. */
.mwz .mwz-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 4px 0 0;
}

.mwz .mwz-actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-weight: 600;
}

.mwz .mwz-actions .btn.btn-primary:last-child:nth-child(odd),
.mwz .mwz-actions [data-action="save-draft"],
.mwz .mwz-actions [data-action="publish"] {
  grid-column: 1 / -1;
}

/* L'aperçu. */
.mwz-review__head h2 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.mwz-review__head p {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-info-ink);
}

.mwz-review__name {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.mwz-review {
  display: grid;
  gap: 10px;
}

.mwz-review__row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.mwz-review__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: 1.25rem;
}

.mwz-review__text {
  min-width: 0;
}

.mwz-review__text h4 {
  margin: 4px 0 4px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.mwz-review__body {
  color: var(--pj-info-ink);
  overflow-wrap: anywhere;
}

.mwz-review__body .ap-detail__letter > :last-child {
  margin-bottom: 0;
}

@media (min-width: 768px) {
  .mwz .mwz-head,
  .mwz .mwz-card {
    padding: 22px 26px;
  }

  .mwz-head h1 {
    font-size: var(--pj-fs-display);
  }

  /* Au large, les étapes se partagent la ligne et un trait les relie. */
  .mwz .mwz-steps {
    flex-wrap: nowrap;
    gap: 8px;
  }

  .mwz .mwz-steps li {
    flex: 1 1 0;
    padding: 8px 12px 8px 8px;
    font-size: var(--pj-fs-body);
  }

  .mwz .mwz-steps li:not(:last-child)::after {
    content: "";
    flex: 1 1 auto;
    min-width: 12px;
    height: 1px;
    background: var(--pj-line);
  }

  .mwz .mwz-steps li span {
    flex-basis: 30px;
    height: 30px;
    font-size: var(--pj-fs-body);
  }

  .mwz .mwz-steps li strong .mwz-long {
    display: inline;
  }

  .mwz .mwz-steps li strong .mwz-short {
    display: none;
  }

  .mwz .pg__add .mu__preview {
    height: 130px;
  }

  .mwz .pg__add .mu__actions {
    display: flex;
  }

  .mwz .pg__add .mu__actions .mu__pick,
  .mwz .pg__add .mu__actions .mu__gallery-toggle {
    width: auto;
    padding-inline: 16px;
  }

  .mwz .mwz-choices {
    display: flex;
    flex-wrap: wrap;
  }

  .mwz .mwz-choices > .btn {
    width: auto;
    flex: 0 1 auto;
  }

  .mwz .co-location--view .btn {
    width: auto;
    padding-inline: 18px;
  }

  .mwz .ev-price-row {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  }

  .mwz .mwz-card .ev-price-row [data-action="remove-price"] {
    grid-column: auto;
  }

  .mwz .mwz-actions {
    display: flex;
    flex-wrap: wrap;
  }

  .mwz .mwz-actions .btn {
    width: auto;
    padding-inline: 24px;
  }

  .mwz .mwz-actions [data-action="publish"] {
    flex: 1 1 200px;
  }

  .mwz-review__row {
    padding: 18px 22px;
  }

  .mwz-review__icon {
    width: 56px;
    height: 56px;
  }
}

/* ── L'import par tableau, maquette du 2026-09-28 ─────────────────────────
   `CsvImportPanel` : les imports de services et d'articles (onglet
   « Vendre ») et l'onglet « Tableau » de l'assistant de publication des
   offres et des formations — un composant, un aspect (décision PO). */
.imp-panel {
  display: grid;
  gap: 14px;
}

.imp-panel .imp-howto {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin: 0;
  padding: 14px 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
}

.imp-howto__icon {
  flex: none;
  margin-top: 2px;
  font-size: 1.6rem;
  color: var(--pj-orange-text);
}

.imp-howto p {
  margin: 0;
  font-size: var(--pj-fs-body);
  line-height: 1.5;
  color: var(--pj-ink);
}

.imp-panel .btn.imp-template,
.imp-panel .btn.imp-drafts,
.imp-panel .btn.imp-submit {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 600;
}

.imp-panel .btn.imp-submit {
  font-weight: 700;
}

/* Sur téléphone, le libellé tient sur une ligne avec l'icône. */
.imp-panel .btn.imp-template {
  padding-inline: 10px;
  font-size: 0.9rem;
  white-space: nowrap;
}

/* « Votre fichier rempli », sous un filet. */
.imp-file {
  position: relative;
  display: grid;
  gap: 8px;
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
}

.imp-file__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

/* Le vrai champ : caché à l'œil, pas au clavier ni aux lecteurs d'écran. */
.imp-file__input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.imp-file__picker {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin: 0;
  padding: 6px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: pointer;
}

.imp-file__input:focus-visible + .imp-file__picker {
  outline: 2px solid var(--pj-orange);
  outline-offset: 2px;
}

.imp-file__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-weight: 600;
}

.imp-file__name {
  min-width: 0;
  padding: 0 8px;
  color: var(--pj-muted);
  overflow-wrap: anywhere;
}

.imp-file__name.is-chosen {
  color: var(--pj-ink);
}

.imp-panel .imp-limit {
  margin: 0;
}

/* Le résultat. */
.imp-result {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
  padding: 14px 16px;
  border-radius: var(--pj-radius-sm);
}

.imp-result p {
  margin: 0;
}

.imp-result i {
  flex: none;
  font-size: 1.4rem;
}

.imp-result--ok {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.imp-result--ko {
  background: var(--pj-orange-soft);
  color: var(--pj-danger);
}

/* Le titre de l'écran d'import dans l'onglet « Vendre ». */
.mlx .mlx-import {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.mlx-import__title {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.mlx-import__intro {
  margin: 0;
  color: var(--pj-muted);
}

@media (min-width: 768px) {
  .imp-panel .btn.imp-template,
  .imp-panel .btn.imp-drafts,
  .imp-panel .btn.imp-submit {
    justify-self: start;
    width: auto;
    padding-inline: 22px;
  }

  .imp-panel .btn.imp-template {
    font-size: var(--pj-fs-md);
  }

  .imp-panel .btn.imp-submit {
    min-height: 52px;
    padding-inline: 32px;
  }

  .mlx .mlx-import {
    padding: 24px 28px;
  }

  .mlx-import__title {
    font-size: var(--pj-fs-title);
  }
}

/* ── Fiche entreprise, maquettes du 2026-09-28 ────────────────────────────
   Sous `.fsx-card` : « Informations de l'entreprise » (sections repliables à
   icône de couleur), « Vendre sur Prosyjob », « Paramètres de vente » (sa
   propre carte, sous la précédente) et « Mon site web ». Les teintes sont
   celles de la charte, jamais une couleur écrite en dur. */
.fsx-tint--orange  { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.fsx-tint--info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.fsx-tint--success { background: var(--pj-success-soft); color: var(--pj-success); }
.fsx-tint--accent  { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.fsx-tint--danger  { background: var(--pj-danger-soft);  color: var(--pj-danger); }
.fsx-tint--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }

#co-space-body .fsx-card {
  display: grid;
  gap: 14px;
  padding: 16px;
}

/* Écrit sur le conteneur de l'espace et non sur `.pj-card.fsx-card` :
   `check-card-gaps` lit les règles par classe, et un `gap` porté par un
   sélecteur contenant `.pj-card` ferait de chaque carte une pile à ses yeux. */
#co-space-body .fsx-card[hidden] {
  display: none;
}

/* L'en-tête : l'icône ronde, le titre et sa phrase, une action à droite. */
.fsx-head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.fsx-head__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  font-size: 1.3rem;
}

.fsx-head__text {
  flex: 1 1 auto;
  min-width: 0;
}

.fsx-head__text h2 {
  margin: 4px 0 4px;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.fsx-head__text p {
  margin: 0;
  font-size: 0.85rem;
  color: var(--pj-muted);
}

.fsx-card .btn.fsx-head__action {
  flex: none;
  width: auto;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-inline: 12px;
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

/* Sur téléphone, la pastille « Prêt ! » et le bouton « Paramètres » se
   rangent dans le coin : seul le titre leur laisse la place, la phrase
   dessous reprend toute la largeur. */
@media (max-width: 767px) {
  .fsx-head {
    position: relative;
  }

  .fsx-head .fsx-ready,
  .fsx-card .fsx-head .btn.fsx-head__action {
    position: absolute;
    top: 0;
    right: 0;
  }

  .fsx-head {
    gap: 10px;
  }

  .fsx-head__icon {
    width: 40px;
    height: 40px;
    font-size: 1.1rem;
  }

  .fsx-head__text h2 {
    font-size: var(--pj-fs-lg);
  }

  .fsx-head:has(.fsx-ready) .fsx-head__text h2 {
    padding-right: 64px;
  }

  .fsx-head:has(.fsx-head__action) .fsx-head__text h2 {
    padding-right: 112px;
  }

  .fsx-card .fsx-head .btn.fsx-head__action {
    min-height: 36px;
    padding-inline: 10px;
    font-size: var(--pj-fs-xs);
  }
}

/* Les sections repliables : une barre grise, l'icône teintée, le chevron. */
.fsx-card .co-form {
  gap: 10px;
}

.fsx-card .co-accordion {
  border: 1px solid transparent;
}

.fsx-card .co-accordion[open] {
  border-color: var(--pj-line);
}

.fsx-card .co-accordion__summary {
  justify-content: flex-start;
  gap: 12px;
  min-height: 48px;
  padding: 8px 14px;
  font-weight: 700;
  color: var(--pj-ink);
}

.fsx-card .co-accordion__summary::after {
  margin-left: auto;
}

.fsx-card .co-accordion[open] > .co-accordion__summary {
  box-shadow: inset 0 0 0 1px var(--pj-navy);
  border-radius: var(--pj-radius-sm);
}

.fsx-acc__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  font-size: 0.95rem;
}

.fsx-acc__label {
  min-width: 0;
}

.fsx-card .co-form__actions .btn[data-act="save"] {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

/* Vendre sur Prosyjob. */
.fsx-sell__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.fsx-sell__grid .btn {
  width: 100%;
  min-height: 50px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 600;
}

.fsx-sell__grid .btn:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.fsx-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 24px;
  padding-top: 8px;
  border-top: 1px solid var(--pj-line);
}

.fsx-links a.fsx-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: var(--pj-orange-text);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.fsx-links a.fsx-link:hover {
  text-decoration: underline;
}

/* Paramètres de vente. */
.fsx-info {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 12px;
  padding: 14px 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
}

.fsx-info i {
  flex: none;
  margin-top: 2px;
  font-size: 1.4rem;
  color: var(--pj-orange);
}

.fsx-info p {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.fsx-pm-list {
  display: grid;
  gap: 10px;
}

.fsx-pm {
  display: grid;
  grid-template-columns: 52px auto minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  margin: 0;
  padding: 10px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: pointer;
}

.fsx-pm__icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  padding-right: 12px;
  border-right: 1px solid var(--pj-line);
  box-sizing: content-box;
}

.fsx-pm__icon i {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  font-size: 1.4rem;
}

.fsx-pm__icon img {
  width: 40px;
  height: 40px;
  object-fit: contain;
}

.fsx-pm .form-check-input {
  float: none;
  width: 22px;
  height: 22px;
  margin: 0;
}

.fsx-pm__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.fsx-pm__text strong {
  color: var(--pj-ink);
}

.fsx-pm__text span {
  font-size: var(--pj-fs-body);
  color: var(--pj-info-ink);
}

.fsx-settings__actions .btn {
  width: auto;
  min-height: 48px;
  padding-inline: 28px;
}

/* Mon site web. */
.fsx-ready {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-success-soft);
  color: var(--pj-success);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.fsx-ready::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pj-success);
}

.fsx-site__actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.fsx-site__actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-weight: 600;
}

/* Sur téléphone, les trois petits boutons mettent l'icône au-dessus du
   libellé : à 80px de large, un libellé à côté d'une icône ne tient pas. */
.fsx-site__actions .btn.fsx-site__small {
  flex-direction: column;
  gap: 4px;
  padding: 8px 4px;
  font-size: var(--pj-fs-xs);
  line-height: 1.2;
  text-align: center;
}

.fsx-site__actions .btn.fsx-site__wide {
  grid-column: 1 / -1;
}

@media (min-width: 768px) {
  #co-space-body .fsx-card {
    padding: 22px 24px;
  }

  .fsx-head__icon {
    width: 60px;
    height: 60px;
    font-size: 1.6rem;
  }

  .fsx-head__text h2 {
    font-size: var(--pj-fs-card);
  }

  .fsx-head__text p {
    font-size: var(--pj-fs-body);
  }

  .fsx-sell__grid .btn:last-child:nth-child(odd) {
    grid-column: auto;
  }

  .fsx-site__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }

  .fsx-site__actions .btn,
  .fsx-site__actions .btn.fsx-site__small {
    width: auto;
    flex-direction: row;
    gap: 8px;
    padding: 8px 16px;
    font-size: var(--pj-fs-body);
  }

  .fsx-site__actions .btn.fsx-site__wide {
    grid-column: auto;
  }
}

/* ── Collaborateurs et droits, maquettes du 2026-09-28 ─────────────────────
   Sous `.clx-card` : l'espace entreprise et l'espace organisme de formation
   (décision PO : un seul aspect), et l'éditeur de droits partagé
   (`PermissionMatrix`, classes `co-rights__*`). */
.clx-card {
  display: grid;
  gap: 14px;
}

.clx-card[hidden] {
  display: none;
}

.clx-head {
  display: flex;
  align-items: center;
  gap: 14px;
}

.clx-head__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: 1.15rem;
}

.clx-head__text {
  flex: 1 1 auto;
  min-width: 0;
}

.clx-head__text h2 {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.clx-head__text p {
  margin: 2px 0 0;
  color: var(--pj-muted);
}

.clx-count {
  flex: none;
  min-width: 32px;
  padding: 4px 10px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-weight: 700;
  text-align: center;
}

.clx-hint {
  margin: -4px 0 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

/* La liste des membres. */
.clx-members {
  display: grid;
  gap: 8px;
}

/* Téléphone : la carte n'a que ~230px de large dans l'espace — le nom, puis
   les pastilles, puis les deux actions, chacun sur sa ligne. */
.clx-card .co-member {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr);
  grid-template-areas:
    "av who"
    "av role"
    "act act";
  align-items: center;
  gap: 6px 12px;
  margin: 0;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.clx-card .co-member__ident {
  display: contents;
}

.clx-card .co-member__ident > .clx-avatar {
  grid-area: av;
  align-self: start;
}

.clx-card .co-member__ident > div {
  grid-area: who;
  min-width: 0;
}

.clx-card .co-member__name {
  display: block;
  color: var(--pj-ink);
}

.clx-card .co-member__contact {
  margin: 0;
  font-size: var(--pj-fs-body);
  overflow-wrap: anywhere;
}

.clx-card .co-member__role {
  grid-area: role;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  min-width: 0;
}

.clx-card .co-member__actions {
  grid-area: act;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}

.clx-card .co-member__actions:empty {
  display: none;
}

.clx-card .co-member__actions .btn {
  width: auto;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding-inline: 10px;
  font-size: var(--pj-fs-sm);
}

.clx-avatar {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  overflow: hidden;
  border-radius: 50%;
  background: var(--pj-card);
  color: var(--pj-ink);
  font-weight: 700;
  font-size: 0.95rem;
}

.clx-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.clx-avatar--info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.clx-avatar--accent  { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.clx-avatar--success { background: var(--pj-success-soft); color: var(--pj-success); }
.clx-avatar--danger  { background: var(--pj-danger-soft);  color: var(--pj-danger); }
.clx-avatar--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }

/* Les pastilles : le rôle en gris, propriétaire en bleu, personnalisé en jaune. */
.clx-card .co-badge,
.clx-card .co-member__custom {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  border: 1px solid var(--pj-line);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-style: normal;
  font-weight: 500;
}

.clx-card .co-badge--owner {
  border-color: transparent;
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.clx-card .co-member__custom {
  border-color: transparent;
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

/* Inviter : le champ précédé de son icône. */
.clx-form {
  gap: 12px;
}

.clx-form .form-group {
  margin: 0;
}

.clx-form .form-control {
  min-height: 44px;
}

.clx-field {
  position: relative;
}

.clx-field > i {
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  color: var(--pj-muted);
  pointer-events: none;
}

.clx-field > .form-control {
  padding-left: 42px;
}

.clx-form .co-form__actions .btn[data-act="invite"] {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 700;
}

.clx-sub {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
  font-weight: 700;
  color: var(--pj-ink);
}

.clx-sub i {
  color: var(--pj-orange);
}

.clx-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  color: var(--pj-muted);
}

.clx-empty i {
  font-size: 1.5rem;
}

.clx-empty p {
  margin: 0;
}

.clx-empty__more {
  font-size: var(--pj-fs-sm);
}

.clx-invite {
  padding: 10px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

/* L'éditeur de droits. */
.clx-head--rights {
  padding-bottom: 12px;
  border-bottom: 1px solid var(--pj-line);
}

.clx-card .co-rights__row {
  display: grid;
  gap: 10px;
}

.clx-card .co-rights__row .form-group {
  margin: 0;
}

.clx-card .co-rights__row label.focus-label {
  font-weight: 700;
  color: var(--pj-ink);
}

.clx-card .co-rights__role {
  min-height: 44px;
}

/* « Suspendre cet accès » : la case du thème est placée en absolu à 4px du
   haut d'un libellé de 44px — on centre les deux sur la même ligne. */
.clx-card .co-rights__status .custom_check {
  align-items: center;
  min-height: 44px;
  margin: 0;
}

.clx-card .co-rights__status .custom_check .checkmark {
  top: 50%;
  transform: translateY(-50%);
}

.clx-card .co-rights__role-desc,
.clx-card .co-rights__hint {
  margin: 6px 0 0;
  font-size: var(--pj-fs-body);
}

.clx-card .co-rights__groups {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  margin-top: 12px;
}

.clx-card .co-rights__group {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.co-rights__group-head {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  list-style: none;
  cursor: pointer;
  font-weight: 800;
  font-size: var(--pj-fs-body);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--pj-ink);
}

.co-rights__group-head::-webkit-details-marker {
  display: none;
}

/* Le chevron, dessiné (même raison que `.co-accordion__summary::after`). */
.co-rights__group-head::after {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  margin-left: auto;
  border-right: 2px solid var(--pj-muted);
  border-bottom: 2px solid var(--pj-muted);
  transform: rotate(45deg);
  transition: transform 0.2s ease;
}

.co-rights__group[open] > .co-rights__group-head::after {
  transform: rotate(-135deg);
}

.co-rights__group-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  font-size: 1.05rem;
}

.co-rights__tint--info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.co-rights__tint--accent  { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.co-rights__tint--success { background: var(--pj-success-soft); color: var(--pj-success); }
.co-rights__tint--danger  { background: var(--pj-danger-soft);  color: var(--pj-danger); }
.co-rights__tint--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.co-rights__tint--orange  { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.co-rights__tint--neutral { background: var(--pj-card-2);       color: var(--pj-ink); }

.clx-card .co-rights__perm-row {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin: 8px 0 0;
  color: var(--pj-ink);
}

.clx-card .co-rights__deviation {
  padding: 1px 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
  font-size: var(--pj-fs-xs);
  font-style: normal;
}

.clx-rights__actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.clx-rights__actions .btn {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-weight: 700;
}

@media (min-width: 768px) {
  .clx-head__icon {
    width: 52px;
    height: 52px;
    font-size: 1.35rem;
  }

  .clx-head__text h2 {
    font-size: var(--pj-fs-card);
  }

  .clx-card .co-member {
    grid-template-columns: 44px minmax(0, 1fr) auto auto;
    grid-template-areas: "av who role act";
    padding: 12px 16px;
  }

  .clx-card .co-member__ident > .clx-avatar {
    align-self: center;
  }

  .clx-card .co-member__role {
    justify-content: flex-end;
  }

  .clx-card .co-member__actions .btn {
    min-height: 44px;
    padding-inline: 14px;
    font-size: var(--pj-fs-body);
  }

  .clx-form__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .clx-form .co-form__actions .btn[data-act="invite"] {
    width: auto;
    padding-inline: 24px;
  }

  .clx-card .co-rights__row {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
  }

  .clx-card .co-rights__groups {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /* Au large, les groupes restent ouverts : pas de chevron, pas de repli. */
  .co-rights__group-head {
    cursor: default;
    pointer-events: none;
  }

  .co-rights__group-head::after {
    display: none;
  }

  .clx-rights__actions {
    display: flex;
  }

  .clx-rights__actions .btn {
    width: auto;
    padding-inline: 26px;
  }
}

/* ── Marketplace (le catalogue public), maquette du 2026-09-29 ─────────────
   Sous `.mkx`. En-tête à icône, recherche, barre « Trier par » + deux vues,
   puis les cartes. La vue est `#mc-results[data-view]` : liste (défaut) ou
   grille, et le CSS seul fait la différence. */
.mkx .mkx-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
}

.mkx-hero__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: 1.35rem;
}

.mkx-hero__text h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.mkx-hero__text p {
  margin: 4px 0 0;
  color: var(--pj-muted);
}

/* La recherche. */
.mkx .mkx-search {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.mkx-search__grid {
  display: grid;
  gap: 12px;
}

.mkx-search .form-group {
  margin: 0;
}

.mkx-search label {
  font-weight: 700;
  color: var(--pj-ink);
}

.mkx-search .form-control {
  min-height: 46px;
}

.mkx-field {
  position: relative;
}

.mkx-field > i {
  position: absolute;
  top: 50%;
  left: 14px;
  transform: translateY(-50%);
  color: var(--pj-muted);
  pointer-events: none;
}

.mkx-field > .form-control {
  padding-left: 42px;
}

.mkx .mkx-search .btn.mkx-search__submit {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 700;
}

/* « 3 résultat(s) », puis « Trier par » et les deux vues. */
.mkx-toolbar {
  display: grid;
  gap: 8px;
}

.mkx-count {
  margin: 0;
  color: var(--pj-muted);
}

.mkx-toolbar__tools {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mkx-sort-label {
  flex: none;
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.mkx .mkx-sort {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
}

.mkx-views {
  flex: none;
  display: flex;
  gap: 4px;
}

.mkx .mkx-view {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-lg);
  cursor: pointer;
}

.mkx .mkx-view.is-active {
  border-color: var(--pj-orange-fill);
  background: var(--pj-orange-fill);
  color: var(--pj-card);
}

/* Une carte, vue liste : vignette | contenu, le bouton sous le contenu. */
.mkx .mkx-card {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  grid-template-areas:
    "cover body"
    "cover cta";
  align-items: start;
  gap: 8px 14px;
  padding: 14px;
  text-align: left;
}

.mkx .mkx-card__cover {
  grid-area: cover;
  width: 84px;
  height: 84px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.mkx-card__placeholder {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  color: var(--pj-muted);
  font-size: 1.8rem;
}

.mkx-card__body {
  grid-area: body;
  display: grid;
  gap: 6px;
  min-width: 0;
}

.mkx-card__title {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.mkx-card__title i {
  margin-top: 3px;
  color: var(--pj-orange-text);
}

.mkx-card__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}

.mkx .mkx-pill {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 500;
  text-decoration: none;
}

.mkx .mkx-pill--event   { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.mkx .mkx-pill--service { background: var(--pj-success-soft); color: var(--pj-success); }
.mkx .mkx-pill--article { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }

.mkx a.mkx-pill--company {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.mkx-card__price {
  margin: 0;
  font-weight: 800;
  color: var(--pj-orange-text);
}

.mkx-card__price--free {
  color: var(--pj-success);
}

.mkx .mkx-card .mkx-card__cta {
  grid-area: cta;
  justify-self: end;
  width: auto;
  min-height: 40px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-inline: 14px;
  border: 1px solid var(--pj-orange);
  background: var(--pj-card);
  font-size: var(--pj-fs-body);
  pointer-events: none;
}

/* Vue grille : des cartes en colonne, la vignette en tête. */
.mkx-results[data-view="grid"] {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}

.mkx-results[data-view="grid"] .mkx-card {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "cover"
    "body"
    "cta";
  padding: 10px;
}

.mkx-results[data-view="grid"] .mkx-card__cover {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
}

.mkx-results[data-view="grid"] .mkx-card__title {
  font-size: var(--pj-fs-body);
}

/* Sur téléphone, deux colonnes de ~125px : la carte entière s'ouvre au
   toucher, le bouton n'y tiendrait pas — on le garde pour l'ordinateur. */
.mkx-results[data-view="grid"] .mkx-card__cta {
  display: none;
}

@media (min-width: 768px) {
  .mkx .mkx-hero,
  .mkx .mkx-search {
    padding: 22px 26px;
  }

  .mkx-hero__icon {
    width: 68px;
    height: 68px;
    font-size: 1.8rem;
  }

  .mkx-hero__text h1 {
    font-size: var(--pj-fs-display);
  }

  .mkx-search__grid {
    grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
    gap: 16px;
  }

  .mkx .mkx-search .btn.mkx-search__submit {
    justify-self: start;
    width: auto;
    padding-inline: 24px;
  }

  .mkx-toolbar {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
  }

  .mkx .mkx-sort {
    flex: 0 0 190px;
  }

  .mkx .mkx-card {
    grid-template-columns: 134px minmax(0, 1fr) auto;
    grid-template-areas: "cover body cta";
    align-items: center;
    padding: 16px 20px;
  }

  .mkx .mkx-card__cover {
    width: 134px;
    height: 112px;
  }

  .mkx-card__title {
    font-size: var(--pj-fs-lg);
  }

  .mkx .mkx-pill {
    padding: 4px 14px;
    font-size: var(--pj-fs-body);
  }

  .mkx-card__price {
    font-size: var(--pj-fs-lg);
  }

  .mkx .mkx-card .mkx-card__cta {
    align-self: end;
    min-height: 44px;
    padding-inline: 18px;
    font-size: var(--pj-fs-md);
  }

  .mkx-results[data-view="grid"] {
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 16px;
  }

  .mkx-results[data-view="grid"] .mkx-card {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "cover"
      "body"
      "cta";
    align-items: stretch;
    padding: 14px;
  }

  .mkx-results[data-view="grid"] .mkx-card__cover {
    width: 100%;
    height: auto;
  }

  .mkx-results[data-view="grid"] .mkx-card__cta {
    display: inline-flex;
    justify-self: stretch;
    justify-content: center;
  }
}

/* ── Détail d'une publication dans /marketplace, maquette du 2026-09-29 ─────
   Sous `.mpd` (le panneau MarketplaceListingDetailPanel). En-tête à icône,
   galerie et informations côte à côte, carte d'achat, publications liées. */
.mkx .btn.mkx-back {
  justify-self: start;
  width: auto;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-inline: 16px;
  font-weight: 600;
}

.mpd .mpd-head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px;
}

.mpd-head__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: 1.35rem;
}

.mpd-head__text {
  min-width: 0;
}

.mpd-head__text h1 {
  margin: 4px 0 2px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.mpd-head__text p {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-info-ink);
}

.mpd-pill {
  display: inline-flex;
  padding: 2px 10px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.mpd-pill:empty {
  display: none;
}

.mpd-pill--event   { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.mpd-pill--service { background: var(--pj-success-soft); color: var(--pj-success); }
.mpd-pill--article { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }

/* Le titre d'une carte : un trait orange devant. */
.mpd-card-title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
  color: var(--pj-ink);
}

.mpd-card-title::before {
  content: "";
  flex: none;
  width: 4px;
  height: 22px;
  border-radius: 2px;
  background: var(--pj-orange);
}

/* Galerie | informations. */
.mpd-top {
  display: grid;
  gap: 16px;
}

.mpd .mpd-gallery,
.mpd .mpd-info,
.mpd .mpd-buy,
.mpd .mpd-links {
  padding: 16px;
}

.mpd-gallery .mp-preview__main img {
  border-radius: var(--pj-radius-sm);
}

.mpd-rows {
  display: grid;
  gap: 14px;
}

.mpd-row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.mpd-row__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: 1rem;
}

.mpd-row__text {
  min-width: 0;
  color: var(--pj-info-ink);
  overflow-wrap: anywhere;
}

.mpd-row__text strong {
  display: block;
  color: var(--pj-ink);
}

.mpd-row__text .ap-detail__letter > :last-child {
  margin-bottom: 0;
}

/* L'achat : ce qu'on achète | comment on paie. */
.mpd-buy__form {
  display: grid;
  gap: 12px;
}

.mpd-buy__grid {
  display: grid;
  gap: 12px;
}

.mpd-buy__form .form-group {
  margin: 0;
}

.mpd-buy__form label {
  font-weight: 600;
  color: var(--pj-ink);
}

.mpd-buy__form .form-control {
  min-height: 44px;
}

.mpd-buy__form #mpl-buy-quantity {
  max-width: 160px;
}

.mpd .mpd-buy__form .form-check {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 36px;
  margin: 0;
  padding-left: 0;
}

.mpd .mpd-buy__form .form-check .form-check-input {
  flex: none;
  float: none;
  width: 18px;
  height: 18px;
  margin: 0;
}

.mpd .mpd-buy__form .form-check .form-check-label {
  min-height: 0;
  margin: 0;
  color: var(--pj-ink);
}

.mpd-total {
  margin: 6px 0 0;
  font-weight: 700;
  color: var(--pj-ink);
}

.mpd-total span {
  color: var(--pj-orange-text);
}

.mpd .btn.mpd-buy__submit {
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 700;
}

@media (min-width: 768px) {
  .mpd .mpd-head {
    padding: 20px 24px;
  }

  .mpd-head__icon {
    width: 68px;
    height: 68px;
    font-size: 1.8rem;
  }

  .mpd-head__text h1 {
    font-size: var(--pj-fs-display);
  }

  .mpd-head__text p {
    font-size: var(--pj-fs-body);
  }

  .mpd-top {
    grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
    align-items: start;
  }

  .mpd-top--solo {
    grid-template-columns: minmax(0, 1fr);
  }

  .mpd .mpd-buy,
  .mpd .mpd-info,
  .mpd .mpd-links {
    padding: 20px 24px;
  }

  .mpd-buy__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
    gap: 24px;
  }

  /* Les moyens de paiement en ligne, sur deux ou trois colonnes. */
  .mpd-methods {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 28px;
  }

  .mpd-methods > label {
    flex: 1 0 100%;
  }

  .mpd .btn.mpd-buy__submit {
    justify-self: start;
    width: auto;
    padding-inline: 28px;
  }
}

/* ── Mes commandes, maquette du 2026-09-29 ─────────────────────────────────
   Sous `.mox`. En-tête à icône, statut + recherche, « Trier par », une carte
   par commande qui se déplie (le bouton couvre toute la carte). */
.mox .mox-hero {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
}

.mox-hero__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: 1.35rem;
}

.mox-hero__text h1 {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.mox-hero__text p {
  margin: 4px 0 0;
  color: var(--pj-muted);
}

.mox .mox-search {
  display: grid;
  gap: 12px;
  padding: 16px;
}

.mox-search .form-group {
  margin: 0;
}

.mox-search label {
  font-weight: 700;
  color: var(--pj-ink);
}

.mox-search .form-control {
  min-height: 46px;
}

.mox .mox-search .btn.mox-search__submit {
  width: 100%;
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 700;
}

.mox-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.mox-count {
  margin: 0;
  color: var(--pj-muted);
  white-space: nowrap;
}

/* Sur téléphone, le menu suffit : « Trier par » prendrait la place du compte. */
@media (max-width: 767px) {
  .mox-sort .mkx-sort-label {
    display: none;
  }
}

.mox-sort {
  display: flex;
  align-items: center;
  gap: 8px;
}

.mox-sort .form-control {
  min-height: 44px;
  width: auto;
}

/* Une commande. */
.mox .mox-card {
  padding: 0;
  overflow: hidden;
}
/* La commande qu'une notification a nommée (`&commande=`, 2026-10-08). */
.mox .mox-card.mox-card--focus { box-shadow: 0 0 0 2px var(--pj-orange); }

.mox .mox-card__toggle {
  width: 100%;
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  grid-template-areas:
    "cover main chevron"
    "cover status chevron";
  align-items: start;
  gap: 6px 12px;
  padding: 12px;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.mox-card__cover {
  grid-area: cover;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  overflow: hidden;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-card);
}

.mox-card__cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mox-card__main {
  grid-area: main;
  display: grid;
  gap: 5px;
  min-width: 0;
}

.mox-card__title {
  font-weight: 700;
  color: var(--pj-ink);
}

.mox-card__pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.mox-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 500;
}

.mox-pill--event   { background: var(--pj-orange-soft);  color: var(--pj-orange-text); }
.mox-pill--service { background: var(--pj-success-soft); color: var(--pj-success); }
.mox-pill--article { background: var(--pj-accent-soft);  color: var(--pj-accent-ink); }
.mox-pill--mode    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }

.mox-card__amount {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
}

.mox-card__date {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.mox-status {
  grid-area: status;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  white-space: nowrap;
}

.mox-status.is-info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.mox-status.is-success { background: var(--pj-success-soft); color: var(--pj-success); }
.mox-status.is-warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.mox-status.is-muted   { background: var(--pj-card-2);       color: var(--pj-muted); }

.mox-card__chevron {
  grid-area: chevron;
  align-self: center;
  color: var(--pj-muted);
  transition: transform 0.2s ease;
}

.mox-card__toggle[aria-expanded="true"] .mox-card__chevron {
  transform: rotate(90deg);
}

.mox-card__detail {
  display: grid;
  gap: 8px;
  padding: 12px 16px 16px;
  border-top: 1px solid var(--pj-line);
  background: var(--pj-card-2);
}

.mox-card__detail[hidden] {
  display: none;
}

.mox-detail-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.mox-detail-row i {
  flex: none;
  width: 18px;
  margin-top: 3px;
  color: var(--pj-muted);
  text-align: center;
}

.mox-detail-row strong {
  margin-right: 4px;
}

@media (min-width: 768px) {
  .mox .mox-hero,
  .mox .mox-search {
    padding: 22px 26px;
  }

  .mox-hero__icon {
    width: 68px;
    height: 68px;
    font-size: 1.8rem;
  }

  .mox-hero__text h1 {
    font-size: var(--pj-fs-display);
  }

  .mox .mox-search {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr) auto;
    align-items: end;
    gap: 16px;
  }

  .mox .mox-search .btn.mox-search__submit {
    width: auto;
    padding-inline: 24px;
  }

  .mox .mox-card__toggle {
    grid-template-columns: 100px minmax(0, 1fr) auto auto;
    grid-template-areas: "cover main status chevron";
    padding: 16px 20px;
  }

  .mox-card__cover {
    width: 100px;
    height: 90px;
  }

  .mox-card__title {
    font-size: var(--pj-fs-lg);
  }

  .mox-pill {
    padding: 3px 12px;
    font-size: var(--pj-fs-body);
  }

  .mox-card__detail {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding: 14px 20px 18px 132px;
  }
}

/* La grande image du détail s'ouvre en plein écran : un bouton qui la
   recouvre, et une loupe dans le coin pour le dire. */
.mpd .mpd-zoom {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}

.mpd .mpd-zoom img {
  display: block;
  width: 100%;
}

.mpd-zoom__hint {
  position: absolute;
  right: 10px;
  bottom: 10px;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--pj-card);
  color: var(--pj-ink);
  box-shadow: var(--pj-shadow-sm);
}

.mpd .mpd-zoom:focus-visible {
  outline: 2px solid var(--pj-orange);
  outline-offset: 2px;
}

/* ── Le tunnel de paiement, maquette du 2026-09-29 ─────────────────────────
   Sous `.payx`. En-tête à icône, montant dans un bandeau orange clair, une
   carte par moyen (case, icône, nom, consigne, montant s'il diffère), puis
   « Annuler » et « Payer ». */
.payx .payx-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
}

.payx-head__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: 1.35rem;
}

.payx .pay-checkout__title {
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-ink);
}

.payx-head__sub {
  margin: 2px 0 0;
  color: var(--pj-info-ink);
}

/* Le montant : l'argent en grand et en orange, les miles à côté, un trait
   entre les deux. */
.payx .payx-summary {
  align-items: center;
  padding: 14px 16px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
}

.payx .payx-summary .pay-summary__label {
  color: var(--pj-ink);
  font-weight: 500;
}

.payx .payx-summary .pay-summary__price {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-left: auto;
}

.payx .payx-summary .pj-price__main {
  font-size: var(--pj-fs-title);
  font-weight: 800;
  color: var(--pj-orange-text);
}

.payx .payx-summary .pj-price__miles {
  margin: 0;
  padding-left: 14px;
  border-left: 1px solid color-mix(in srgb, var(--pj-orange) 35%, transparent);
  font-size: var(--pj-fs-md);
  color: var(--pj-ink);
}

.payx .pay-form {
  padding: 16px;
}

.payx .pay-form__legend {
  font-weight: 700;
  color: var(--pj-ink);
}

/* Un moyen : case | icône | nom et consigne | montant. */
.payx .pay-method {
  gap: 14px;
  padding: 12px 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.payx .pay-method:has(input:checked) {
  border-color: var(--pj-orange-fill);
  box-shadow: none;
  background: var(--pj-orange-soft);
}

.payx .pay-method .form-check-input {
  float: none;
  margin: 0;
}

.payx-icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--pj-radius-sm);
  font-size: 1.35rem;
}

.payx-icon img {
  width: 30px;
  height: 30px;
  object-fit: contain;
}

.payx-icon--brand   { background: var(--pj-orange-soft); }
.payx-icon--orange  { background: var(--pj-orange-soft);  color: var(--pj-orange); }
.payx-icon--info    { background: var(--pj-info-soft);    color: var(--pj-info-ink); }
.payx-icon--warning { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.payx-icon--success { background: var(--pj-success-soft); color: var(--pj-success); }

.payx .pay-method__title {
  color: var(--pj-ink);
}

/* La consigne d'un canal est écrite par l'administrateur, retours à la ligne
   compris : on les garde. */
.payx .pay-method__sub {
  white-space: pre-line;
  overflow-wrap: anywhere;
  color: var(--pj-info-ink);
}

.payx .pay-method__amount {
  align-self: flex-start;
  color: var(--pj-ink);
}

/* Sur téléphone, la carte n'a que ~240px : le montant se range sur la
   ligne du titre, et la consigne passe dessous sur toute la largeur qui reste
   — en colonne à part, elle tombait à quelques caractères de large. */
@media (max-width: 767px) {
  .payx .pay-method {
    display: grid;
    grid-template-columns: auto 40px minmax(0, 1fr) auto;
    grid-template-areas:
      "radio icon title amount"
      "radio icon sub sub";
    align-items: center;
    gap: 2px 10px;
    padding: 10px 12px;
  }

  .payx .pay-method .form-check-input { grid-area: radio; }
  .payx .pay-method .payx-icon { grid-area: icon; width: 40px; height: 40px; font-size: 1.15rem; }
  .payx .pay-method .pay-method__body { display: contents; }
  .payx .pay-method .pay-method__title { grid-area: title; align-self: end; }
  .payx .pay-method .pay-method__sub,
  .payx .pay-method .pay-method__warn { grid-area: sub; align-self: start; }
  .payx .pay-method .pay-method__amount { grid-area: amount; align-self: end; margin: 0; font-size: var(--pj-fs-body); }
}

/* Les bons d'achat sous les moyens de paiement (E58) : une liste de cases,
   un champ pour un code, et ce que les bons paient. Les cases ne sont pas des
   `.pay-method` : `:has(input:checked)` les peindrait comme un moyen choisi. */
.payx .pay-bons {
  display: grid;
  gap: 10px;
  margin-top: 14px;
  padding: 14px;
  border: 1px dashed var(--pj-orange-fill);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

.payx .pay-bons.is-busy { opacity: 0.7; }

.payx .pay-bons__title {
  margin: 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.payx .pay-bons__hint { margin: 0; font-size: var(--pj-fs-sm); }

.payx .pay-bons__list {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.payx .pay-bons__empty { font-size: var(--pj-fs-sm); }

.payx .pay-bon {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--connected-border);
  border-radius: var(--pj-radius-sm);
  cursor: pointer;
}

.payx .pay-bon .form-check-input {
  float: none;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin: 0;
}

.payx .pay-bon--on {
  border-color: var(--pj-orange-fill);
  background: var(--pj-orange-soft);
}

.payx .pay-bon--locked { opacity: 0.55; cursor: not-allowed; }

.payx .pay-bon__body { display: grid; gap: 2px; min-width: 0; }
.payx .pay-bon__amount { color: var(--pj-ink); }

.payx .pay-bons__add { display: grid; gap: 6px; }
.payx .pay-bons__label { font-size: var(--pj-fs-sm); font-weight: 600; color: var(--pj-ink); }

.payx .pay-bons__add-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px;
}

.payx .pay-bons__add-row .field__control { min-height: 44px; }

.payx .pay-bons__add-btn {
  width: auto;
  min-height: 44px;
  margin: 0;
  white-space: nowrap;
}

.payx .pay-bons__error,
.payx .pay-bons__short {
  margin: 0;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pay-failed);
}

.payx .pay-bons__summary {
  display: grid;
  gap: 4px;
  margin: 0;
  padding-top: 10px;
  border-top: 1px solid var(--connected-border);
}

.payx .pay-bons__summary div {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}

.payx .pay-bons__summary dt { font-weight: 400; color: var(--pj-muted); }
.payx .pay-bons__summary dd { margin: 0; font-weight: 700; color: var(--pj-ink); white-space: nowrap; }
.payx .pay-bons__covered { margin: 0; font-size: var(--pj-fs-sm); color: var(--pj-success); font-weight: 600; }

/* Annuler | Payer. */
.payx-actions {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
  gap: 12px;
  margin-top: 18px;
}

.payx .payx-actions .btn {
  width: 100%;
  min-height: 50px;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-weight: 700;
}

@media (min-width: 768px) {
  .payx .payx-head {
    padding: 22px 26px;
  }

  .payx-head__icon {
    width: 72px;
    height: 72px;
    font-size: 1.9rem;
  }

  .payx .pay-checkout__title {
    font-size: var(--pj-fs-display);
  }

  .payx .payx-summary {
    padding: 18px 22px;
  }

  .payx .payx-summary .pj-price__main {
    font-size: var(--pj-fs-display);
  }

  .payx .pay-form {
    padding: 20px 22px;
  }

  .payx .pay-method {
    padding: 14px 18px;
  }

  .payx-actions {
    grid-template-columns: minmax(160px, 1fr) minmax(0, 3fr);
  }
}

/* L'annuaire (2026-10-05, d'après `Model pages/Annuaire/annuaire.png`).
   Un en-tête à pictogramme, une « Recherche avancée » repliée par défaut,
   une barre de résultats (nombre, tri, affichage) et des cartes sobres — logo,
   nom, secteur, lieu. Pensé à 360px d'abord : une colonne, la barre sans ses
   libellés, et le chevron qui dit qu'une carte s'ouvre. */
.dir-head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.dir-head__ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-title);
}

.dir-head__text { min-width: 0; }

.dir-head__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  color: var(--pj-ink);
}

.dir-head__intro {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

/* La recherche avancée : une barre teintée qui se déplie. */
.dir-adv {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.dir-adv__bar {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 52px;
  padding: 10px 16px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  text-align: left;
  cursor: pointer;
}

/* ─────────────────────────────────────────────────────────────────────────
   L'ENTREPRISE À LA UNE — la grande forme.

   Elle traverse la grille entière (`1 / -1`) quel que soit le nombre de
   colonnes : c'est la demande, « prendre toute la surface si possible », et
   c'est aussi la seule façon de donner à une bannière la place d'exister.

   Le logo chevauche la bannière (marge négative) : c'est ce qui rattache
   l'image à l'identité au lieu d'empiler deux blocs qui s'ignorent.
   ───────────────────────────────────────────────────────────────────────── */
.dir-une {
  grid-column: 1 / -1;
  padding: 0;
  overflow: hidden;
}

/* La bannière garde un rapport fixe : les entreprises téléversent tout et
   n'importe quoi, et une hauteur qui suit l'image ferait sauter la page. */
.dir-une__banniere {
  position: relative;
  aspect-ratio: 4 / 1;
  min-height: 140px;
  background: var(--surface-sunken);
}

.dir-une__banniere img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Sur la bannière, donc sur une photo quelconque : le fond opaque est ce qui
   rend la pastille lisible quelle que soit l'image dessous. */
.dir-une__marque {
  position: absolute;
  top: 12px;
  left: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--pj-orange-fill);
  color: #fff;
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.dir-une__corps {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 16px;
  padding: 0 20px 20px;
}

.dir-une__logo {
  flex: 0 0 auto;
  width: 88px;
  height: 88px;
  margin-top: -44px;
  border-radius: 12px;
  object-fit: contain;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  padding: 6px;
}

.dir-une__texte {
  flex: 999 1 260px;
  min-width: 0;
}

.dir-une__nom {
  margin: 10px 0 2px;
  font-size: var(--pj-fs-title);
  line-height: 1.15;
}

.dir-une__nom a { color: inherit; text-decoration: none; }
.dir-une__nom a:hover { text-decoration: underline; }

.dir-une__secteur,
.dir-une__slogan {
  margin: 0 0 4px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.dir-adv__ico { font-size: var(--pj-fs-lg); }

.dir-adv__title {
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

.dir-adv__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-fill);
  color: var(--pj-card);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
}

.dir-adv__state {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

/* À 360px la barre ne dit que le chevron, comme la maquette mobile. */
.dir-adv__state-t { display: none; }

.dir-adv__chev { transition: transform 0.15s ease; }
.dir-adv.is-open .dir-adv__chev { transform: rotate(180deg); }

.dir-adv__body {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.dir-adv__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px 20px;
}

.dir-field label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-ink);
}

.dir-adv .form-control { min-height: 44px; }

.dir-adv__actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* Un lien d'action, pas un bouton de la gamme : il ne fait que vider. */
.dir-adv__reset {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  cursor: pointer;
}

.dir-adv__reset-long { display: none; }

.dir-adv__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: auto;
  min-height: 44px;
  padding: 0 24px;
}

/* La barre de résultats. */
.dir-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
}

.dir-bar__count {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.dir-une__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
}

/* Les portes passent sous le texte dès qu'on manque de largeur, et jamais en
   colonne étroite à côté de lui : trois boutons empilés sur 90px ne se
   touchent pas du doigt. */
.dir-une__portes {
  flex: 1 1 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

@media (max-width: 720px) {
  .dir-une__banniere { aspect-ratio: 16 / 9; }
  .dir-une__portes { width: 100%; }
  .dir-une__portes .btn { flex: 1 1 140px; justify-content: center; }
}

.dir-bar__tools {
  display: flex;
  align-items: center;
  gap: 12px;
}

.dir-bar__sort,
.dir-bar__views {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.dir-bar__label {
  display: none;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.dir-bar__sort .form-control {
  width: auto;
  min-width: 140px;
  min-height: 44px;
}

.dir-view {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-muted);
  cursor: pointer;
}

.dir-view.is-active {
  border-color: var(--pj-orange-fill);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

/* Les cartes compactes n'ont de sens que là où trois colonnes tiennent. */
.dir-view--wide-only { display: none; }

/* La grille et ses trois affichages. */
.dir-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 14px;
}

.dir-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 14px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.dir-card:hover,
.dir-card:focus-visible {
  border-color: var(--pj-orange-fill);
  box-shadow: var(--pj-shadow-sm);
}

/* Un carré fixe : les logos arrivent dans toutes les proportions, et une
   rangée de cartes dont chaque en-tête a sa hauteur ne se lit pas. */
.dir-card__logo {
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius-sm);
  object-fit: contain;
  background: var(--pj-card-2);
}

.dir-card__logo--vide {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--pj-blue);
  font-size: 24px; /* fs-ok: glyphe de remplacement du logo */
}

.dir-card__body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  min-width: 0;
}

.dir-card__name {
  font-size: var(--pj-fs-md);
  font-weight: 700;
  line-height: 1.3;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

/* À la une : le nom passe à l'orange, comme sur la maquette, et la pastille
   « À la une » dit pourquoi. */
.dir-card--une .dir-card__name { color: var(--pj-orange-text); }

.dir-card__cat {
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-success-soft);
  color: var(--pj-success);
  font-size: var(--pj-fs-sm);
  font-weight: 500;
}

.dir-card__cat--org {
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
}

.dir-card__place {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.dir-card__place i { color: var(--pj-orange-text); }

.dir-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.dir-card__chev {
  align-self: center;
  color: var(--pj-muted);
}

/* Liste : une ligne par fiche, le logo réduit. */
.dir-grid[data-view="liste"] .dir-card { align-items: center; }
.dir-grid[data-view="liste"] .dir-card__logo { width: 44px; height: 44px; }

.dir-loading,
.dir-empty { grid-column: 1 / -1; }

.dir-more {
  display: flex;
  justify-content: center;
}

.dir-more .btn { width: auto; }

.dir-back-row { display: flex; }

.dir-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

@media (min-width: 768px) {
  .dir-head { align-items: center; gap: 24px; }
  .dir-head__ico { width: 80px; height: 80px; font-size: var(--pj-fs-display); }

  .dir-adv__state-t { display: inline; }
  .dir-adv__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .dir-adv__reset-long { display: inline; }
  .dir-adv__reset-short { display: none; }

  .dir-bar__label { display: inline; }
  .dir-view--wide-only { display: inline-flex; }

  .dir-grid[data-view="grille"] { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
  .dir-grid[data-view="compacte"] { grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr)); }

  /* En grille, la carte entière est la cible : pas de chevron. */
  .dir-grid[data-view="grille"] .dir-card__chev,
  .dir-grid[data-view="compacte"] .dir-card__chev { display: none; }
  .dir-grid[data-view="grille"] .dir-card,
  .dir-grid[data-view="compacte"] .dir-card { grid-template-columns: auto minmax(0, 1fr); }

  .dir-grid[data-view="compacte"] .dir-card { gap: 10px; padding: 14px; }
  .dir-grid[data-view="compacte"] .dir-card__logo { width: 40px; height: 40px; }
  .dir-grid[data-view="compacte"] .dir-card__name { font-size: var(--pj-fs-body); }
}

/* La marque de confiance. La paire mesurée du bloc de succès : elle dit
   « constaté », pas « mis en avant ». */
.dir-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-success-soft);
  color: var(--pj-success);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

/* La mise à la une, PAYÉE, et qui doit se lire comme telle.
   Elle emprunte l'accent d'avertissement et non celui du succès : une marque
   verte dirait « Prosyjob a constaté », alors que celle-ci dit « cette
   entreprise a payé pour être devant ». Confondre les deux serait vendre de la
   confiance, ce que la fiche produit refuse explicitement — « ce n'est pas de
   la publicité » s'applique au score, justement parce que ceci en est. */
.dir-badge--une {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

/* « Certifiée » prend la couleur de son sceau : mesuré dans un banc d'essai,
   un sceau orange sur le fond vert de `.dir-badge` lisait comme une erreur de
   copier-coller. La pastille et sa marque disent la même chose, donc elles
   portent la même couleur — et c'est ce qui la détache de sa voisine verte au
   premier coup d'œil, ce qui est tout l'objet. */
.dir-badge--certifiee {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

/* « Utilise sur Prosyjob » : l'encart dont la fiche produit dit qu'il est le
   point le plus intéressant du produit — les autres entreprises qui consultent
   l'annuaire y découvrent les services de la plateforme. */
.dir-uses {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}

.dir-uses__chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 1px 8px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-xs);
  white-space: nowrap;
}

.dir-uses__chip i { color: var(--pj-success); }

/* Le même vocabulaire dans l'espace de l'entreprise, où un critère MANQUANT se
   montre aussi : c'est là qu'il vend quelque chose. Barré et pâle, jamais
   rouge — il ne s'agit pas d'une faute. */
.co-uses__chip--manquant {
  border-style: dashed;
  background: transparent;
  opacity: 0.75;
}

.co-uses__chip--manquant i { color: var(--pj-muted); }

/* La jauge de valorisation de l'espace entreprise : la même idée, en grand. */
/* L avertissement de jumeau : une meme enseigne peut avoir une entreprise ET
   un organisme, 236 couples sur 238 portant le meme nom. Ton informatif et non
   d erreur : inscrire les deux est parfois JUSTE, et l ecran ne tranche pas a
   la place de qui les gere. */
.co-directory__twin {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 0 0 4px;
  padding: 10px 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.co-directory__twin i { margin-top: 2px; color: var(--pj-orange); }

.co-score {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.co-score__value {
  font-size: var(--pj-fs-title);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.co-score__gauge {
  flex: 1 1 160px;
  min-width: 120px;
  height: 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  overflow: hidden;
}

.co-score__gauge > span { display: block; height: 100%; background: var(--pj-orange-fill); }

/* « Vous avez » / « Il vous manque » : la classe était posée par le JS et
   n'avait aucune règle, donc les deux libellés touchaient leurs pastilles.
   Une marge au-dessus les rattache à ce qu'ils annoncent, pas à ce qui
   précède. */
.co-score__label {
  margin: 12px 0 6px;
  font-size: var(--pj-fs-sm);
}

/* Les deux mises à la une, côte à côte puis empilées sous 640px — la cible est
   à ~90 % mobile, donc c'est l'empilement qui est le cas normal. */
.co-feature__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}

.co-feature__item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.co-feature__item h4 { margin: 0; font-size: var(--pj-fs-md); }
.co-feature__item p { margin: 0; font-size: var(--pj-fs-sm); }
.co-feature__item .btn { width: auto; margin-top: auto; justify-self: start; }

/* ------------------------------------------------------------------
   Console : le catalogue des mises en page de CV (E57, .cvl-)
   Trois zones à partir de 1200px — la liste, le formulaire, l'aperçu
   collant —, empilées en dessous, l'aperçu après le formulaire. L'aperçu
   est le seul élément appuyé : c'est le document que recevront les
   candidats, redessiné à chaque réglage.
   ------------------------------------------------------------------ */
.cvl-intro {
  max-width: 72ch;
}

.cvl-list__head,
.cvl-preview__head,
.cvl-form__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 12px;
}

.cvl-form__head {
  justify-content: flex-start;
  align-items: baseline;
}

.cvl-list__head .btn,
.cvl-preview__head .btn,
.cvl-actions .btn,
.cvl-structure,
.cvl-order__btn {
  width: auto;
}

.cvl-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.cvl-row__swatch {
  flex: 0 0 auto;
  width: 14px;
  height: 36px;
  border-radius: var(--pj-radius-sm);
  background: var(--cvl-swatch, var(--pj-line));
}

.cvl-row__text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.cvl-row__name {
  font-weight: 600;
}

.cvl-row__meta {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.cvl-row.active .cvl-row__meta {
  color: inherit;
}

.cvl-group {
  margin: 0 0 20px;
  padding: 0;
  border: 0;
}

.cvl-group legend {
  float: none;
  width: auto;
  margin-bottom: 10px;
  font-size: var(--pj-fs-md);
  font-weight: 600;
}

.cvl-check {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  margin: 0;
  cursor: pointer;
}

.cvl-check input {
  width: 18px;
  height: 18px;
}

/* Les trois structures, dessinées avec la vignette de « Mes CV ». */
.cvl-structures {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}

/* `.cvl` in front: the admin template sizes and displays every button, and a
   single class loses to it. */
.cvl .cvl-structure {
  display: grid;
  height: auto;
  align-content: start;
  gap: 6px;
  padding: 8px;
  border: 2px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  text-align: center;
  cursor: pointer;
}

.cvl .cvl-structure .cvp-thumb,
.cvl .cvl-structure .cvp-thumb__sheet,
.cvl .cvl-structure .cvp-thumb__side,
.cvl .cvl-structure .cvp-thumb__body {
  display: grid;
}

.cvl .cvl-structure .cvp-thumb__photo,
.cvl .cvl-structure .cvp-thumb__bar,
.cvl .cvl-structure .cvp-thumb__line {
  display: block;
}

.cvl .cvl-structure--flat .cvp-thumb__side {
  display: flex;
}

.cvl-structure.is-on {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
}

.cvl-structure:focus-visible {
  outline: 2px solid var(--pj-orange);
  outline-offset: 2px;
}

.cvl-color {
  display: flex;
  gap: 8px;
}

.cvl-color input[type="color"] {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  padding: 2px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
}

/* L'ordre des sections est une séquence : ici, les numéros disent quelque chose. */
.cvl-order {
  display: grid;
  gap: 6px;
  margin: 0;
  padding-left: 1.6em;
}

.cvl-order__item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.cvl-order__name {
  flex: 1 1 auto;
  min-width: 0;
}

.cvl-order__btn {
  min-width: 44px;
  min-height: 44px;
}

.cvl-advanced {
  margin-bottom: 20px;
}

.cvl-advanced summary {
  min-height: 44px;
  display: flex;
  align-items: center;
  font-weight: 600;
  cursor: pointer;
}

.cvl-css {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--pj-fs-xs);
}

.cvl-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.cvl-actions .btn {
  min-height: 44px;
}

.cvl-preview__frame {
  transition: opacity .15s ease;
}

.cvl-preview__frame.is-busy {
  opacity: .55;
}

@media (prefers-reduced-motion: reduce) {
  .cvl-preview__frame {
    transition: none;
  }
}

@media (min-width: 1200px) {
  /* Under the console's 60px top bar, not behind it. */
  .cvl-preview {
    position: sticky;
    top: 76px;
  }
}

/* Un CV mis à l'échelle d'une page entière (console, E57) : l'iframe garde
   sa largeur A4 et se réduit ; l'hôte prend la hauteur réduite. */
.cv-doc-page-host {
  overflow: hidden;
}

.cv-doc-frame--page {
  max-width: none;
  transform-origin: 0 0;
}

/* ── La leçon : un cours lu DANS l'application ─────────────────────────────
   Écrite à 360 px d'abord, et c'est tout l'enjeu : elle existe parce qu'un PDF
   ouvert dans le lecteur du système ne se lit pas sur un téléphone (PO,
   2026-09-30). Les seules règles qui comptent ici sont la largeur de ligne et
   l'interligne. */
.ac-lesson {
  padding: 20px 18px 26px;
}
.ac-lesson__back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
  text-decoration: none;
  /* 44 px de haut : c'est une cible tactile, pas un lien de bas de page. */
  min-height: 44px;
}
.ac-lesson__back:hover {
  color: var(--pj-orange);
}
.ac-lesson__title {
  margin: 6px 0 0;
  font-size: var(--pj-fs-card);
  line-height: 1.25;
  color: var(--pj-ink);
  text-wrap: balance;
}
.ac-lesson__meta {
  margin: 6px 0 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}
/* Le corps. `max-width` en `ch` : au-delà d'une soixantaine de signes, l'œil
   perd la ligne suivante en revenant à la marge — et sur un écran large sans
   cette borne, un cours devient une bande de texte illisible. */
.ac-lesson__body {
  margin-top: 18px;
  max-width: 66ch;
  font-size: var(--pj-fs-md);
  line-height: 1.65;
  color: var(--pj-ink);
}
.ac-lesson__body h2,
.ac-lesson__body h3,
.ac-lesson__body h4,
.ac-lesson__body h5 {
  margin: 26px 0 8px;
  line-height: 1.3;
  color: var(--pj-ink);
}
.ac-lesson__body h2 { font-size: var(--pj-fs-lg); }
.ac-lesson__body h3 { font-size: var(--pj-fs-lg); }
.ac-lesson__body h4,
.ac-lesson__body h5 { font-size: var(--pj-fs-md); }
.ac-lesson__body p {
  margin: 0 0 14px;
}
.ac-lesson__body ul,
.ac-lesson__body ol {
  margin: 0 0 14px;
  padding-left: 22px;
}
.ac-lesson__body li {
  margin-bottom: 6px;
}
.ac-lesson__body blockquote {
  margin: 0 0 14px;
  padding: 10px 14px;
  border-left: 3px solid var(--pj-orange);
  background: var(--pj-neutral-soft);
  color: var(--pj-muted);
}
/* Le filet separe les sections d'un tutoriel. Sans regle, c'est le
   `groove` 3D du navigateur — un relief qui n'existe nulle part
   ailleurs dans le produit. */
.ac-lesson__body hr {
  height: 1px;
  margin: 22px 0;
  border: 0;
  background: var(--pj-line);
}
.ac-lesson__body code {
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--pj-neutral-soft);
  font-size: var(--pj-fs-sm);
}
.ac-lesson__foot {
  margin-top: 28px;
  padding-top: 18px;
  border-top: 1px solid var(--pj-line);
}
.ac-lesson__done {
  /* `width: auto` : dans la coquille connectée, tout `<button>` nu est à
     100 % (CLAUDE.md §9), et un bouton pleine largeur ici ressemble à une
     barre de chargement. */
  width: auto;
  min-height: 44px;
  padding: 0 20px;
  border: 0;
  border-radius: 8px;
  background: var(--pj-orange);
  color: #fff;
  font-size: var(--pj-fs-body);
  font-weight: 600;
  cursor: pointer;
}
.ac-lesson__done:disabled {
  opacity: 0.6;
  cursor: default;
}
.ac-lesson__note {
  margin: 10px 0 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}
.ac-lesson__error {
  margin: 16px 0 0;
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
  font-size: var(--pj-fs-body);
}

/* La carte de lecture reprend de la largeur sur un telephone.
   `.pj-card.ac-lesson` et non `.ac-lesson` : a specificite egale c'est la
   derniere feuille chargee qui gagne, et `.pj-card` vit dans prosyjob-app.css
   qui charge APRES celle-ci (CLAUDE.md §9). Mes 18px etaient donc ecrases par
   ses 26px sans que rien ne le dise — mesure, pas devine.
   Ce qui est en jeu : avec 24px de coquille + 26px de carte, la colonne de
   texte tombait a 239px sur un ecran de 356, soit une trentaine de signes par
   ligne. Une page de COURS n'est pas une carte de formulaire ; elle veut de la
   largeur, et c'est exactement ce que ce type d'etape existe pour donner. */
@media (max-width: 520px) {
  .pj-card.ac-lesson {
    padding-left: 14px;
    padding-right: 14px;
  }
}

/* « Ou vous en etes » : les chiffres de la cohorte, sous l'axe du parcours. */
.ac-stats__title {
  margin: 0 0 12px;
  font-size: var(--pj-fs-lg);
  color: var(--pj-ink);
}
.ac-stats__row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: space-between;
  align-items: baseline;
  padding: 8px 0;
  border-bottom: 1px solid var(--pj-line);
}
.ac-stats__row:last-of-type {
  border-bottom: 0;
}
.ac-stats__k {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}
.ac-stats__v {
  /* Les chiffres s'alignent : c'est une colonne de valeurs, pas une phrase. */
  font-variant-numeric: tabular-nums;
  font-size: var(--pj-fs-md);
  font-weight: 600;
  color: var(--pj-ink);
}
.ac-stats__note {
  margin: 10px 0 0;
  font-size: var(--pj-fs-xs);
  line-height: 1.5;
  color: var(--pj-muted);
}

/* La bibliotheque de lecons (console). */
.ac-lib__new {
  width: auto;
  min-height: 44px;
}
.ac-lib__row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  justify-content: space-between;
}
.ac-lib__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: baseline;
  min-width: 0;
}
.ac-lib__badge {
  padding: 2px 8px;
  border-radius: 10px;
  font-size: var(--pj-fs-2xs);
  text-transform: uppercase;
  letter-spacing: 1px;
}
/* La paire -soft / couleur, et NON -fill : `--pj-success-fill` vaut la MEME
   couleur que `--pj-success` en clair, donc le texte etait vert sur vert —
   contraste 1, mesure. `-fill` est un aplat plein pour un bouton ; un fond
   doux se prend sur `-soft`. Le garde des couleurs ne voit que les
   litteraux, pas un nom de token mal choisi. */
.ac-lib__badge--published {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}
.ac-lib__badge--draft {
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
}
.ac-lib__badge--archived {
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
}
/* Le corps s'ecrit en texte simple : une chasse fixe aide a voir les ## et
   les - qui structurent, ce qu'une proportionnelle noie. */
/* PLUS DE MONOSPACE (2026-10-03). Cette regle habillait un <textarea> ou
   l on tapait du Markdown a la main, et une chasse fixe y etait juste : on
   y lisait du balisage. Le corps est desormais une boite WYSIWYG, ou
   l auteur doit voir le document TEL QU IL SE LIRA -- une lecon en
   monospace ne ressemble a rien de ce que l apprenant verra. */
.ac-lib__body {
  line-height: 1.6;
}
.ac-lib__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.ac-lib__actions .btn {
  width: auto;
  min-height: 44px;
}
.ac-lib__error {
  margin: 14px 0 0;
  padding: 12px 14px;
  border-radius: 8px;
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
  font-size: var(--pj-fs-body);
}

/* ===========================================================================
   LA BARRE D'INTERACTIONS D'UN CONTENU (PO, 2026-10-02)
   ---------------------------------------------------------------------------
   Quatre icônes significatives : l'œil (les vues, comptées depuis toujours et
   affichées nulle part avant ce lot), le cœur (le favori et son compte), le
   drapeau (le signalement), le partage.

   Pensée au doigt d'abord : ~90 % de l'audience arrive au téléphone. Chaque
   cible fait 44px de haut — le minimum que §9 impose et que `.btn--sm` a raté
   pendant cinq jalons faute de l'avoir mesuré.
   =========================================================================== */

.ci-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* 44px de haut, et pas 38 : c'est une cible tactile, pas une puce. */
.ci-item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  min-width: 44px;
  padding: 0 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  /* La règle `button, .btn` de cette feuille met TOUT bouton nu en
     `width: 100%` (§9). Sans cette ligne, les quatre icônes se posent l'une
     sous l'autre sur toute la largeur. */
  width: auto;
}

.ci-item--act {
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.ci-item--act:hover,
.ci-item--act:focus-visible {
  color: var(--pj-ink);
  border-color: var(--pj-ink);
}

/* Le compteur, inerte : ni bordure au survol ni curseur de main. */
.ci-item--mute {
  cursor: default;
}

/* Déjà signalé : visible et inerte. Le faire disparaître laisserait croire
   qu'on peut recommencer. */
.ci-item--done {
  cursor: default;
  color: var(--pj-danger);
  border-color: var(--pj-danger);
}

/* Le cœur à moi. La couleur ET `aria-pressed` disent l'état : un remplissage
   seul ne se lit pas à voix haute. */
.ci-item.is-on {
  color: var(--pj-orange);
  border-color: var(--pj-orange);
}

.ci-count {
  font-variant-numeric: tabular-nums;
}

/* Un compteur vide ne laisse pas d'espace fantôme à côté de son icône. */
.ci-count:empty {
  display: none;
}

/* ---- le partage ---------------------------------------------------------- */

.ci-share {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

/* `.ci-net` DOUBLEE, et c est le garde `check-link-colors` qui l a exige :
   `.pj-app a { color: inherit }` pese (0,1,1) et bat une classe unique
   (0,1,0), donc ces liens auraient herite la couleur de leur parent -- ce qui
   ne se voit pas, jusqu au jour ou ce parent porte la couleur du fond. */
.ci-net.ci-net {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-muted);
  width: auto;
}

.ci-net.ci-net:hover,
.ci-net.ci-net:focus-visible {
  color: var(--pj-ink);
  border-color: var(--pj-ink);
}

/* ---- le formulaire de signalement --------------------------------------- */

.ci-form {
  display: grid;
  gap: 8px;
  margin-top: 12px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.ci-form__lead {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.ci-form__label {
  margin: 0;
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  color: var(--pj-ink);
}

.ci-form__err {
  margin: 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-danger);
}

/* Les deux boutons se suivent et gardent leur largeur propre — la règle
   `button, .btn` les étirerait sinon chacun sur toute la ligne. */
.ci-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ci-form__actions .btn {
  width: auto;
}

/* ===========================================================================
   « MES FAVORIS » (PO, 2026-10-02) — une vue de /profil, à la maquette
   `Model pages/Annuaire/favoris_ok.png` (2026-10-05)
   ---------------------------------------------------------------------------
   Une liste, pas une grille : les types de contenu n'ont rien de comparable à
   aligner côte à côte, et ce qu'on vient chercher ici est un titre et un
   chemin pour y retourner. Chaque favori est une carte dont la tuile et la
   pastille portent la couleur de son type — deux variables par teinte, prises
   dans les jetons, donc le thème sombre suit sans une ligne de plus.
   =========================================================================== */

.fav-card {
  display: grid;
  gap: 20px;
}

/* ---- l'en-tête ----------------------------------------------------------- */

.fav-head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.fav-head__ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}

.fav-head__text {
  flex: 1 1 auto;
  min-width: 0;
}

.fav-head__line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
}

.fav-head__title {
  margin: 0;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  color: var(--pj-ink);
}

.fav-head__count {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
  white-space: nowrap;
}

.fav-head__intro {
  margin: 4px 0 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

/* ---- les onglets par type ----------------------------------------------- */

.fav-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* 44px, mesuré et non supposé (§9). `width: auto` parce que la règle
   `button, .btn` de cette feuille étire tout bouton nu sur la ligne entière. */
.fav-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.fav-tab i {
  color: var(--pj-muted);
}

.fav-tab--active {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 600;
}

.fav-tab--active i {
  color: var(--pj-orange);
}

/* Sur téléphone : le libellé court, et « … » pour les autres types. */
.fav-tab__long { display: none; }
.fav-tab--extra { display: none; }

.fav-tab--more {
  justify-content: center;
  min-width: 44px;
  padding: 0;
}

/* ---- la liste ------------------------------------------------------------ */

.fav-list {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* La teinte du type : une paire fond / encre par famille de jetons. */
.fav-item { --fav-bg: var(--pj-neutral-soft); --fav-fg: var(--pj-neutral-ink); }
.fav-item--orange { --fav-bg: var(--pj-orange-soft); --fav-fg: var(--pj-orange-text); }
.fav-item--warning { --fav-bg: var(--pj-warning-soft); --fav-fg: var(--pj-warning-ink); }
.fav-item--success { --fav-bg: var(--pj-success-soft); --fav-fg: var(--pj-success); }
.fav-item--info { --fav-bg: var(--pj-info-soft); --fav-fg: var(--pj-info-ink); }
.fav-item--danger { --fav-bg: var(--pj-danger-soft); --fav-fg: var(--pj-danger); }
.fav-item--accent { --fav-bg: var(--pj-accent-soft); --fav-fg: var(--pj-accent-ink); }

.fav-item {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
}

.fav-item__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: var(--pj-radius-sm);
  background: var(--fav-bg);
  color: var(--fav-fg);
  font-size: var(--pj-fs-card);
}

/* `min-width: 0` : sans lui un titre d'un seul mot très long pousse la ligne
   hors de la carte au lieu de se couper — un élément flex refuse par défaut de
   descendre sous sa largeur de contenu. */
.fav-item__main {
  display: grid;
  gap: 8px;
  min-width: 0;
  flex: 1 1 auto;
  align-self: center;
}

/* Classe DOUBLÉE : `.pj-app a { color: inherit }` pèse (0,1,1) et battrait une
   classe unique (0,1,0). Le garde `check-link-colors` refuse le simple. */
.fav-item__title.fav-item__title {
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

.fav-item__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.fav-item__chip {
  padding: 2px 12px;
  border-radius: var(--pj-radius-pill);
  background: var(--fav-bg);
  color: var(--fav-fg);
}

.fav-item__date {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Dépublié : dit, et pas seulement teinté. Un favori qui n'est plus en ligne
   reste dans la liste — c'est souvent la raison de l'avoir mis de côté. */
.fav-item__off {
  justify-self: start;
  padding: 2px 8px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
  font-size: var(--pj-fs-xs);
}

/* Le cœur : un rond cerclé d'orange, comme sur la fiche publique. */
.fav-item__heart {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: center;
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1.5px solid var(--pj-orange);
  border-radius: 50%;
  background: var(--pj-card);
  color: var(--pj-orange);
  font-size: var(--pj-fs-lg);
}

.fav-item__heart[disabled] {
  opacity: 0.5;
}

.fav-empty,
.fav-loading {
  padding: 24px 0;
  color: var(--pj-muted);
  text-align: center;
}

.fav-empty p {
  margin: 0;
}

.fav-foot {
  display: flex;
  justify-content: center;
}

@media (min-width: 768px) {
  .fav-head { gap: 24px; }
  .fav-head__ico { width: 80px; height: 80px; font-size: var(--pj-fs-display); }

  .fav-tab__long { display: inline; }
  .fav-tab__short { display: none; }
  .fav-tab--extra { display: inline-flex; }
  .fav-tab--more { display: none; }

  .fav-item { align-items: center; gap: 20px; padding: 18px 20px; }
  .fav-item__icon { width: 64px; height: 64px; }
  .fav-item__title.fav-item__title { font-size: var(--pj-fs-lg); }
  .fav-item__heart { width: 56px; height: 56px; }

  /* Un trait entre la pastille et la date, comme sur la maquette. */
  .fav-item__date { padding-left: 14px; border-left: 1px solid var(--pj-line); }
}

/* ===========================================================================
   LA FILE DE MODERATION (console d'administration)
   ---------------------------------------------------------------------------
   Une carte par cas : un cas se juge sur ses MOTIFS, qui sont une liste de dix
   au plus avec une note libre chacun. Dans une cellule de tableau ils sont
   illisibles, et sans eux « dix signalements » ne dit pas s'il s'agit de dix
   fois « arnaque » ou de dix personnes relayees sur « hors sujet ».

   `.pj-*` n'existe pas sur cette coquille (§9), d'ou les `card` du gabarit --
   mais les JETONS, eux, sont mirroires au `:root` de prosyjob-app.css et
   valent donc ici aussi.
   =========================================================================== */

.mod-count {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.mod-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

.mod-tab {
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: transparent;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.mod-tab--active {
  border-color: var(--pj-ink);
  color: var(--pj-ink);
  font-weight: 600;
}

.mod-card__head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
}

.mod-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card-2);
  color: var(--pj-muted);
}

.mod-card__title {
  display: grid;
  gap: 2px;
  min-width: 0;
  flex: 1 1 240px;
}

/* Doublee pour la meme raison que le titre d'un favori. */
.mod-card__link.mod-card__link {
  color: var(--pj-ink);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.mod-card__gone {
  color: var(--pj-danger);
  font-weight: 600;
}

.mod-card__meta,
.mod-card__score {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.mod-card__score {
  margin: 12px 0 0;
}

.mod-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Un mot ET une teinte, jamais la teinte seule : la meme regle que
   `AdminListView.badge()` applique, pour la meme raison. */
.mod-badge {
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  white-space: nowrap;
}

.mod-badge--on {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.mod-badge--off,
.mod-badge--upheld {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.mod-badge--dismissed {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

/* ---- les motifs --------------------------------------------------------- */

.mod-reasons {
  margin-top: 12px;
  font-size: var(--pj-fs-sm);
}

.mod-reasons > summary {
  cursor: pointer;
  color: var(--pj-muted);
}

.mod-reasons__list {
  display: grid;
  gap: 8px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

.mod-reason {
  display: grid;
  gap: 2px;
  padding: 8px 10px;
  border-left: 3px solid var(--pj-line);
  background: var(--pj-card-2);
}

.mod-reason__label {
  font-weight: 600;
  color: var(--pj-ink);
}

.mod-reason__note {
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.mod-reason__who {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* ---- la decision -------------------------------------------------------- */

.mod-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

/* 44px au doigt, y compris dans la console : `.layout-admin button` remet
   `min-height: auto` quelques milliers de lignes plus haut dans cette meme
   feuille, et un administrateur peut traiter une file depuis un telephone.
   Specificite (0,2,0) contre (0,2,0), et celle-ci est ecrite plus bas. */
.mod-actions .btn {
  min-height: 44px;
}

.mod-card__verdict {
  margin: 16px 0 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.mod-card__verdict-note {
  display: block;
  margin-top: 4px;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.mod-dialog__hint {
  margin: 0 0 12px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.mod-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 16px;
}

.mod-pager__pos {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* ---- la file : les deux vues ajoutees le 2026-10-03 --------------------- */

/* Les filtres de l'onglet des signaleurs. Ils n'existent que la : les trois
   autres vues n'ont rien a filtrer, et un controle inerte se fait cliquer. */
.mod-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-bottom: 16px;
}

.mod-filter {
  display: grid;
  gap: 4px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.mod-filter .form-control {
  min-height: 44px;
  width: auto;
}

/* La phrase qui dit que cet ecran MESURE et ne sanctionne pas. Elle prend la
   ligne entiere sous 760px plutot que de se tasser entre deux champs. */
.mod-filters__note {
  flex: 1 1 100%;
  margin: 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

@media (min-width: 760px) {
  .mod-filters__note {
    flex: 1 1 auto;
    align-self: center;
  }
}

/* Les motifs d'un contenu sous le seuil : des puces et non un `<details>`.
   Il n'y a pas de note libre a lire ici (la lecture par signalement coute une
   requete par ligne, et cette vue ne decide rien), donc rien a replier. */
.mod-reasons__flat {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 12px 0 0;
}

.mod-chip {
  padding: 2px 10px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* ---- un signaleur ------------------------------------------------------- */

.mod-reporters {
  display: grid;
  gap: 2px;
}

.mod-reporter {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 10px;
  border-bottom: 1px solid var(--pj-line);
}

.mod-reporter:last-child {
  border-bottom: 0;
}

/* Signale, pas accuse : une bordure a gauche et la couleur d'alerte, sans
   icone de danger ni fond rouge. L'ecran mesure, il ne sanctionne pas -- et
   une part ecartee elevee sur trois decisions reste un petit echantillon. */
.mod-reporter--flag {
  border-left: 3px solid var(--pj-orange);
  padding-left: 10px;
  background: var(--pj-orange-soft);
}

.mod-reporter__who {
  display: grid;
  gap: 2px;
  min-width: 0;
  flex: 1 1 200px;
  color: var(--pj-ink);
}

.mod-reporter__mail {
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  overflow-wrap: anywhere;
}

.mod-reporter__nums {
  flex: 1 1 260px;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.mod-reporter__rate {
  flex: 0 0 auto;
  font-size: var(--pj-fs-sm);
  color: var(--pj-ink);
  font-variant-numeric: tabular-nums;
}

/* ---- un moyen de paiement BIENTOT disponible (PO, 2026-10-03) ------------
   « Griser (sans supprimer) la possibilite de se faire payer par Prosyjob » :
   l'encaissement attend le module de commissions et reversements. La carte
   reste donc a sa place, et dit pourquoi elle n'est pas cliquable.

   Le curseur `not-allowed` sur le LABEL et pas seulement sur la case : toute
   la carte est le libelle de la case (c'est la maquette du 2026-09-28), donc
   c'est la carte entiere qui doit se sentir inerte au survol. */
.fsx-pm--soon {
  cursor: not-allowed;
  background: var(--pj-card-2);
  border-color: var(--pj-line);
}

/* L'icone et le nom palissent ; la PHRASE reste lisible. Palir l'explication
   avec le reste serait cacher la seule chose qui rend le grisage comprehensible. */
.fsx-pm--soon .fsx-pm__icon,
.fsx-pm--soon .fsx-pm__text strong {
  opacity: 0.55;
}

.fsx-pm--soon .form-check-input {
  cursor: not-allowed;
}

.fsx-pm__soon {
  display: block;
  margin-top: 2px;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* ==========================================================================
   L'editeur de banniere de l'etape « Contenu » (E60-04), et l'ecran de ses
   modeles dans la console (E60-03). Le dessin lui-meme est un canvas
   (support/bannerRenderer.js) : ces regles ne disposent que ce qui l'entoure.
   ========================================================================== */

/* Le choix entre l'editeur et un fichier. Des pastilles, pas des .btn : un
   choix affiche n'est pas un bouton de l'echelle (cf. les presets de Miles). */
.abe-modes {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 14px;
}

.abe-mode {
    align-items: center;
    background: var(--pj-card);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-pill);
    color: var(--pj-ink);
    cursor: pointer;
    display: inline-flex;
    font-size: var(--pj-fs-sm);
    font-weight: 600;
    gap: 8px;
    min-height: 44px;
    padding: 8px 16px;
    width: auto;
}

.abe-mode.is-on {
    background: var(--pj-orange-soft);
    border-color: var(--pj-orange);
    color: var(--pj-orange-text);
}

.abe {
    display: grid;
    gap: 18px;
}

/* L'apercu, en tete : sur telephone c'est lui qu'on regarde en tapant. */
.abe__stage {
    background: var(--pj-card-2);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius);
    display: grid;
    gap: 8px;
    justify-items: center;
    padding: 14px;
}

.abe__canvas {
    box-shadow: var(--pj-shadow-sm);
    display: block;
    height: auto;
    width: 100%;
}

.abe__notice {
    background: var(--pj-warning-soft);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-warning-ink);
    font-size: var(--pj-fs-sm);
    margin: 0;
    padding: 8px 12px;
}

.abe__section {
    display: grid;
    gap: 10px;
}

.abe__label {
    color: var(--pj-ink);
    font-size: var(--pj-fs-md);
    font-weight: 700;
    margin: 0;
}

/* Les modeles defilent a l'horizontale : une rangee de vignettes plutot qu'une
   colonne qui pousserait les champs sous trois ecrans de pouce. */
.abe__templates {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    padding-bottom: 4px;
    scroll-snap-type: x proximity;
}

.abe__tpl {
    align-items: center;
    background: var(--pj-card);
    border: 2px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-ink);
    cursor: pointer;
    display: grid;
    flex: 0 0 auto;
    gap: 6px;
    justify-items: center;
    min-height: 44px;
    min-width: 132px;
    padding: 8px;
    position: relative;
    scroll-snap-align: start;
    width: auto;
}

.abe__tpl.is-on {
    border-color: var(--pj-orange);
    box-shadow: 0 0 0 3px var(--pj-orange-soft);
}

.abe__tpl.is-locked {
    cursor: not-allowed;
    opacity: 0.6;
}

.abe__thumb {
    border-radius: 4px;
    display: block;
}

.abe__tpl-name {
    font-size: var(--pj-fs-xs);
    font-weight: 600;
}

.abe__tpl-badge {
    background: var(--pj-warning-soft);
    border-radius: var(--pj-radius-pill);
    color: var(--pj-warning-ink);
    font-size: var(--pj-fs-2xs);
    font-weight: 700;
    padding: 2px 8px;
}

.abe__field {
    display: grid;
    gap: 6px;
}

.abe__field-label {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    font-weight: 600;
}

.abe__images {
    display: grid;
    gap: 12px;
}

.abe__image {
    display: grid;
    gap: 6px;
}

.abe__image-actions {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.abe__image-actions .btn {
    min-height: 44px;
    width: auto;
}

.abe__colors {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}

.abe__color,
.abt-color {
    align-items: center;
    color: var(--pj-ink);
    display: flex;
    font-size: var(--pj-fs-sm);
    gap: 10px;
    min-height: 44px;
}

.abe__color input[type="color"],
.abt-color input[type="color"] {
    background: none;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    cursor: pointer;
    height: 40px;
    padding: 2px;
    width: 48px;
}

@media (min-width: 900px) {
    /* A partir d'une largeur d'ordinateur, l'apercu reste a cote des champs. */
    .abe {
        align-items: start;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    }

    .abe__stage {
        grid-column: 2;
        grid-row: 1 / span 4;
        position: sticky;
        top: calc(var(--pj-topbar-h) + 12px);
    }

    .abe__section {
        grid-column: 1;
    }
}

/* -- la console : les modeles (E60-03) ------------------------------------ */

.abt-list__head,
.abt-form__head {
    align-items: center;
    display: flex;
    gap: 10px;
    justify-content: space-between;
    margin-bottom: 14px;
}

/* Deux classes : `.list-group-item` du theme vendu (charge apres cette feuille)
   pose `display: block` a specificite egale. */
.list-group-item.abt-row {
    align-items: center;
    display: flex;
    gap: 12px;
}

.abt-row__thumb {
    border-radius: 3px;
    flex: 0 0 auto;
}

.abt-row__text {
    display: grid;
    gap: 2px;
    min-width: 0;
}

.abt-row__name {
    font-weight: 600;
}

.abt-row__meta {
    font-size: var(--pj-fs-xs);
    opacity: 0.8;
}

.abt-group {
    border: 0;
    margin: 0 0 20px;
    padding: 0;
}

.abt-group legend {
    font-size: var(--pj-fs-md);
    font-weight: 700;
    margin-bottom: 10px;
}

.abt-colors {
    display: grid;
    gap: 8px;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}

.abt-premium {
    align-items: flex-end;
    display: flex;
}

.abt-check {
    align-items: center;
    display: flex;
    gap: 8px;
    min-height: 40px;
}

.abt-layout {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    font-size: var(--pj-fs-xs);
}

.abt-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.abt-preview {
    position: sticky;
    top: 80px;
}

.abt-preview__stage {
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-sm);
    display: grid;
    justify-items: center;
    margin-bottom: 10px;
    padding: 12px;
}

.abt-preview__canvas {
    display: block;
    height: auto;
    width: 100%;
}

/* -- l'emailing par blocs (E60-05) ----------------------------------------
   Les blocs se composent ici ; le message, lui, est dessine par le serveur et
   montre dans le cadre isole habituel (.ads-preview__frame). */

.ebe {
    display: grid;
    gap: 18px;
}

.ebe__section {
    display: grid;
    gap: 10px;
}

.ebe__blocks {
    display: grid;
    gap: 12px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.ebe__block {
    background: var(--pj-card);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: grid;
    gap: 10px;
    padding: 12px;
}

.ebe__block-head {
    align-items: center;
    display: flex;
    gap: 8px;
    justify-content: space-between;
}

.ebe__block-type {
    align-items: center;
    color: var(--pj-ink);
    display: inline-flex;
    font-size: var(--pj-fs-sm);
    font-weight: 700;
    gap: 8px;
}

.ebe__block-tools {
    display: inline-flex;
    gap: 4px;
}

.ebe__tool {
    align-items: center;
    background: var(--pj-card-2);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-ink);
    cursor: pointer;
    display: inline-flex;
    height: 44px;
    justify-content: center;
    width: 44px;
}

.ebe__tool:disabled {
    cursor: default;
    opacity: 0.4;
}

.ebe__tool--danger {
    color: var(--pj-danger);
}

.ebe__block-body {
    display: grid;
    gap: 10px;
}

.ebe__row {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}

.ebe__columns {
    display: grid;
    gap: 12px;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.ebe__column {
    border: 1px dashed var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: grid;
    gap: 8px;
    margin: 0;
    min-width: 0;
    padding: 10px;
}

.ebe__column legend {
    color: var(--pj-muted);
    font-size: var(--pj-fs-xs);
    font-weight: 700;
    padding: 0 4px;
    width: auto;
}

.ebe__thumb {
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: block;
    max-height: 90px;
    max-width: 100%;
    object-fit: contain;
}

.ebe__add {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.ebe__preview .ads-preview__frame {
    width: 100%;
}

/* -- les outils IA payants des editeurs (E60-06) ---------------------------
   Un bouton discret sous le champ, son prix dit avant le clic, et les
   propositions qui s'affichent juste dessous. */

.abe__field-wrap {
    display: grid;
    gap: 6px;
}

.ads-ai {
    display: grid;
    gap: 6px;
}

.ads-ai__btn {
    align-items: center;
    background: var(--pj-accent-soft);
    border: 1px dashed var(--pj-orange);
    border-radius: var(--pj-radius-pill);
    color: var(--pj-orange-text);
    cursor: pointer;
    display: inline-flex;
    font-size: var(--pj-fs-sm);
    font-weight: 600;
    gap: 8px;
    justify-self: start;
    min-height: 44px;
    padding: 6px 14px;
    width: auto;
}

.ads-ai__btn:disabled {
    cursor: progress;
    opacity: 0.6;
}

.ads-ai__cost {
    color: var(--pj-muted);
    font-weight: 400;
}

.ads-ai__cost:not(:empty)::before {
    content: "· ";
}

.ads-ai__form {
    display: grid;
    gap: 8px;
}

.ads-ai__go {
    justify-self: start;
    min-height: 44px;
    width: auto;
}

.ads-ai__picks {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.ads-ai__picks .abe-mode {
    text-align: left;
}

.ads-ai__status {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
    margin: 0;
}

.ads-ai__status--error {
    color: var(--pj-danger);
}

.ads-ai__consent {
    background: var(--pj-card-2);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: grid;
    font-size: var(--pj-fs-sm);
    gap: 8px;
    padding: 10px 12px;
}

.ads-ai__consent p {
    margin: 0;
}

.ads-ai__consent-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.ads-ai__consent-actions .btn {
    min-height: 44px;
    width: auto;
}

/* -- « Confier a l'equipe » (E60-07) : le panneau de l'annonceur ----------- */

.adr {
    display: grid;
    gap: 14px;
}

.adr__offers {
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

.adr__offer {
    background: var(--pj-card);
    border: 2px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-ink);
    cursor: pointer;
    display: grid;
    gap: 4px;
    min-height: 44px;
    padding: 12px;
    text-align: left;
    width: auto;
}

.adr__offer.is-on {
    border-color: var(--pj-orange);
    box-shadow: 0 0 0 3px var(--pj-orange-soft);
}

.adr__offer-name {
    font-size: var(--pj-fs-md);
    font-weight: 700;
}

.adr__offer-desc {
    color: var(--pj-muted);
    font-size: var(--pj-fs-sm);
}

.adr__offer-price {
    color: var(--pj-orange-text);
    font-size: var(--pj-fs-sm);
    font-weight: 700;
}

.adr__refs {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.adr__ref {
    position: relative;
}

.adr__ref img {
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: block;
    height: 72px;
    object-fit: cover;
    width: 96px;
}

.adr__ref .ebe__tool {
    position: absolute;
    right: -8px;
    top: -8px;
}

.adr__go {
    justify-self: start;
    min-height: 44px;
    width: auto;
}

.adr__status {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.adr__brief,
.adr__note {
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-sm);
    font-size: var(--pj-fs-sm);
    margin: 0;
    padding: 10px 12px;
    white-space: pre-line;
}

.adr__delivery {
    display: grid;
    gap: 10px;
}

.adr__delivery,
.adr {
    min-width: 0;
}

/* Shown at the slot's size (the file is often twice it): the inline max-width
   says how wide, width: 100% lets a phone shrink it further. */
.adr__visual {
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: block;
    height: auto;
    width: 100%;
}

.adr__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.adr__actions .btn {
    min-height: 44px;
    width: auto;
}

/* -- la file de l'equipe dans la console (E60-07) ------------------------- */

.list-group-item.adq-row {
    display: grid;
    gap: 2px;
}

.adq-row__title {
    font-weight: 600;
}

.adq-row__meta {
    font-size: var(--pj-fs-xs);
    opacity: 0.8;
}

.adq-row .badge {
    justify-self: start;
}

.adq-head {
    align-items: center;
    display: flex;
    gap: 10px;
    justify-content: space-between;
    margin-bottom: 10px;
}

.adq-facts {
    display: grid;
    gap: 4px 12px;
    grid-template-columns: max-content 1fr;
    margin-bottom: 10px;
}

.adq-facts dt {
    font-weight: 600;
}

.adq-facts dd {
    margin: 0;
}

.adq-brief {
    white-space: pre-line;
}

.adq-refs {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 12px;
}

.adq-img {
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    max-height: 220px;
    max-width: 100%;
}

.adq-actions {
    display: grid;
    gap: 10px;
}

/* -- la mesure de l'editeur dans la console (E60-08) ---------------------- */

.abs__head {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: space-between;
    margin-bottom: 14px;
}

.abs__period {
    max-width: 220px;
}

.abs__grid {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.abs__block h6 {
    font-weight: 700;
}

.abs__block--wide {
    grid-column: span 2;
}

@media (max-width: 720px) {
    .abs__block--wide {
        grid-column: auto;
    }
}

.abs__big {
    font-size: var(--pj-fs-display);
    font-weight: 700;
    line-height: 1;
    margin: 0;
}

.abs__list {
    display: grid;
    gap: 4px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.abs__list li {
    align-items: baseline;
    display: flex;
    gap: 8px;
    justify-content: space-between;
}

/* =====================================================================
   L'ANNUAIRE DES PARTENAIRES CERTIFIES (PO, 2026-10-04)

   Trois familles : `.pd-` l'annuaire, `.pt-` la carte et la fiche, `.ps-`
   le volet du partenaire. Mobile d'abord — l'audience est a ~90 % sur
   telephone — donc la grille part a une colonne.
   ===================================================================== */

/* ---- L'annuaire, à la maquette `partenaires.png` (PO, 2026-10-05) ---- */

.pd-head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.pd-head__ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}

.pd-head__text { min-width: 0; }

.pd-head__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  color: var(--pj-ink);
}

.pd-head__intro {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.pd-filters {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

.pd-field__label {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-ink);
}

.pd-filters .form-control { min-height: 44px; }

/* `width: 100%` sur téléphone (la maquette), sa largeur au-delà. */
.pd-reset.pd-reset {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
}

/* Le titre de la liste et son compteur. */
.pd-listhead {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 2px 14px;
}

.pd-listhead__ico {
  grid-row: span 2;
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}

.pd-listhead__title {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.pd-listhead__long { display: none; }

.pd-listhead__count {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* LE GARDE DES ESPACEMENTS a demandé ce `gap` : `.pj-card` ne porte aucune
   marge. Une colonne sur téléphone, trois dès qu'elles tiennent. */
.pd-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

/* ---- La carte de l'annuaire (`pdc-`) ----------------------------------
   Sur téléphone, une ligne : photo, nom, badge, lieu, chevron. Dès 768px,
   la carte de la maquette : photo et badge en tête, l'identité, « Je peux
   vous aider pour » et le bouton. Toute la carte est le lien. */

.pdc {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px 14px;
  padding: 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease;
}

.pdc:hover,
.pdc:focus-visible { border-color: var(--pj-orange-fill); }

.pdc__head { display: contents; }
.pdc__badge,
.pdc__help,
.pdc__tagline { display: none; }

/* Le bouton porte `.btn`, que le thème (chargé après cette feuille) affiche
   à (0,2,0) : il faut trois classes pour le masquer sur téléphone. */
.pdc .pdc__cta.btn { display: none; }

/* Le badge tient sur une ligne, comme la maquette. */
.pdc__badge-sm .pt-chip,
.pdc__badge .pt-chip { white-space: nowrap; }

.pdc__photo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  object-fit: cover;
  font-size: var(--pj-fs-lg);
  font-weight: 700;
}

.pdc__photo--orange { background: var(--pj-orange-soft); color: var(--pj-orange); }
.pdc__photo--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }

.pdc__ident {
  display: grid;
  justify-items: start;
  gap: 4px;
  min-width: 0;
}

.pdc__name {
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.pdc__tagline {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.pdc__place {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.pdc__chev { color: var(--pj-muted); }

.pdc__help-title {
  display: block;
  margin-bottom: 8px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.pdc__topics {
  display: grid;
  gap: 8px;
}

.pdc__topic {
  display: flex;
  align-items: baseline;
  gap: 12px;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.pdc__topic i {
  width: 18px;
  color: var(--pj-orange);
  text-align: center;
}

.pdc__cta {
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
  margin-top: auto;
}

@media (min-width: 768px) {
  .pd-head { gap: 24px; }
  .pd-head__ico { width: 80px; height: 80px; font-size: var(--pj-fs-display); }

  .pd-filters { grid-template-columns: repeat(3, minmax(0, 1fr)) auto; align-items: end; }
  .pd-reset.pd-reset { width: auto; padding: 0 20px; }

  .pd-listhead { grid-template-columns: auto minmax(0, 1fr) auto; }
  .pd-listhead__ico { grid-row: auto; }
  .pd-listhead__long { display: inline; }
  .pd-listhead__short { display: none; }
  .pd-listhead__title { font-size: var(--pj-fs-title); }

  .pd-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; }

  .pdc {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    padding: 22px;
  }

  .pdc__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
  .pdc__badge { display: block; }
  .pdc__badge-sm { display: none; }
  .pdc__tagline { display: block; }
  .pdc__help { display: block; }
  .pdc .pdc__cta.btn { display: inline-flex; }
  .pdc__chev { display: none; }
  .pdc__photo { width: 64px; height: 64px; font-size: var(--pj-fs-card); }
  .pdc__name { font-size: var(--pj-fs-lg); }
}

/* ---- La carte et la fiche ------------------------------------------ */

.pt-card__head,
/* L EN-TETE DE LA FICHE : L IDENTITE SUR LA COUVERTURE (PO, 2026-10-05).

   « La mise en forme de l'image de couverture doit ressembler au profil
   candidat, legerement transparent, et le pseudo du partenaire, son icone et
   son titre doivent etre a cote du nom par-dessus la couverture. »

   AUCUNE MARGE NEGATIVE, et c'est le troisieme essai. J'ai suppose le
   rembourrage de `.pj-card` deux fois -- 16 px suppose, 43 mesure sur l'image
   en flux du 2026-10-04, 27 mesure sur cette carte-ci -- et j'avais meme
   ecrit ici que « c'est JUSTE ». Un commentaire faux est pire qu'un
   commentaire absent.

   La fiche prend donc `padding: 0` et son CORPS porte le sien : l'en-tete
   remplit la carte parce que la carte ne pousse plus rien vers l'interieur,
   et plus parce qu'on a devine de combien la repousser. */
/* CLASSE DOUBLEE : `.pj-card` pese (0,1,0) et vit dans le theme vendorise,
   charge APRES cette feuille. `.pt-fiche` seule pesait pareil, donc l'ordre
   tranchait et le rembourrage de la carte restait (27 px mesures). Troisieme
   fois que ce mecanisme mord aujourd'hui -- qualifier par la balise EGALISE,
   seul le doublement gagne. */
.pt-fiche.pt-fiche {
  padding: 0;
  overflow: hidden;
}

.pt-fiche__body {
  padding: 0 16px 16px;
}

.pt-hero {
  position: relative;
  margin: 0 0 16px;
  padding: 20px 16px;
  background-color: var(--pj-navy);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  border-radius: 10px 10px 0 0;
  overflow: hidden;
}

/* « Legerement transparent » : un voile qui ASSOMBRIT l'image pour que le texte
   blanc se lise, sans l'effacer. Un `opacity` sur le conteneur aurait pali le
   texte avec elle ; un voile en `::before` ne touche que le fond.

   Le degrade plutot qu'un aplat : le haut de l'image reste lisible, et c'est en
   bas -- la ou vit le texte -- que le voile se renforce. */
.pt-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(15, 20, 27, 0.35) 0%, rgba(15, 20, 27, 0.75) 100%);
}

/* Pas de couverture est un etat NORMAL, pas une image cassee : le meme degrade
   de marque que `.ph-cover--empty` du profil, pour que les deux ecrans se
   repondent. Le voile devient alors superflu et s'allege. */
.pt-hero--vide {
  background-image: linear-gradient(135deg, var(--pj-navy) 0%, var(--pj-navy-dark) 55%, var(--pj-orange-dark) 160%);
}

.pt-hero--vide::before {
  background: none;
}

/* `position: relative` : sans elle, le contenu passerait SOUS le voile. */
.pt-hero__ident {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

.pt-hero__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
}

/* Le texte de l'en-tete est BLANC, en toutes lettres et non par heritage : il
   vit sur une image dont on ne connait pas les couleurs, donc la seule teinte
   sure est celle qu'on impose, avec une ombre pour les photos claires. */
.pt-hero__name,
.pt-hero__tagline,
.pt-hero .pt-card__place {
  margin: 0;
  color: #fff; /* fs-ok : du blanc pur sur une photo, aucun jeton n'en tient lieu */
  text-shadow: 0 1px 3px rgba(15, 20, 27, 0.6);
}

/* Le nom et la pastille de grade cote a cote (PO, 2026-10-05).

   `flex-wrap` et `align-items: baseline` : les deux doivent s'aligner sur la
   ligne d'ecriture, pas sur le haut de leurs boites -- une pastille est plus
   courte qu'un titre, et un alignement par le haut la ferait flotter. Et un
   nom long sur 360 px doit pousser la pastille a la ligne plutot que hors de
   la couverture. */
.pt-hero__line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
}

.pt-hero__name {
  font-size: var(--pj-fs-card);
  overflow-wrap: anywhere;
}

.pt-hero__tagline {
  font-size: var(--pj-fs-sm);
}

/* Le lieu de l'en-tete ne porte PLUS `.text-muted` (le balisage ne la pose
   pas la) : cette classe du theme a un `!important` qu'aucune specificite ne
   bat, et le lieu sortait gris sur une couverture sombre. */
.pt-hero .pt-card__place {
  opacity: 0.85;
}

/* La pastille de grade garde son fond clair : c'est ce qui la detache de
   l'image, et le metal reste lisible dessus. */
.pt-hero .pt-chip {
  background: rgba(255, 255, 255, 0.92);
  color: var(--pj-ink);
}

/* Le portrait prend un cerne blanc : sans lui, une photo sombre sur une
   couverture sombre n'a plus de bord. */
.pt-hero .pt-card__photo {
  border: 2px solid rgba(255, 255, 255, 0.9);
}

.pt-card__photo {
  width: 64px;
  height: 64px;
  flex: 0 0 64px;
  border-radius: 50%;
  object-fit: cover;
}

/* Les initiales, quand il n'y a pas de photo. Une place vide a cote de
   voisines qui en ont se lit comme une image cassee. */
.pt-card__photo--empty {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 700;
  font-size: var(--pj-fs-lg);
}

.pt-card__ident {
  /* `minmax(0, …)` en version flex : sans lui un nom long pousse la carte
     au-dela de sa colonne au lieu de se couper. */
  min-width: 0;
}

.pt-card__name,
.pt-fiche__name {
  margin: 0;
  font-size: var(--pj-fs-lg);
  overflow-wrap: anywhere;
}

.pt-card__tagline {
  margin: 2px 0 6px;
  font-size: var(--pj-fs-sm);
}

.pt-card__place {
  margin: 8px 0 0;
  font-size: var(--pj-fs-sm);
}


/* LES TROIS MOYENS DE CONTACT. En colonne : sur 360 px, trois liens cote a
   cote se chevauchent, et une adresse e-mail ne se coupe pas. */
.pt-contacts {
  display: grid;
  gap: 4px;
  margin: 12px 0 0;
}

/* CLASSE DOUBLEE, et la balise ne suffisait pas : `.pj-app a { color: inherit }`
   (prosyjob.css, chargee APRES cette feuille) pese (0,1,1), et `a.pt-contact`
   pese (0,1,1) aussi -- egalite, donc l ordre tranche et le vendor gagne.
   Mesure du 2026-10-04 : les trois liens sortaient en encre heritee.
   `a.pt-contact.pt-contact` pese (0,2,1) et gagne quel que soit l ordre. */
a.pt-contact.pt-contact {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* 44 px : plancher de cible tactile, et ces trois liens sont ce qu'on vient
     chercher sur la fiche. */
  min-height: 44px;
  color: var(--pj-orange-text);
  font-weight: 600;
  /* Une adresse longue ne doit pas pousser la carte au-dela de l'ecran. */
  overflow-wrap: anywhere;
}

.pt-contact__icon {
  flex: none;
  width: 16px;
  text-align: center;
}

/* WhatsApp garde SA couleur : c'est une marque que les gens reconnaissent au
   vert avant de lire le mot, et la repeindre en orange de marque annulerait
   le seul repere qui rend ce lien immediat. */
a.pt-contact--whatsapp.pt-contact--whatsapp {
  color: var(--pj-success);
}

/* Les trois cases du formulaire de vitrine. */
.ps-contacts {
  display: grid;
  gap: 4px;
  margin-top: 4px;
}

.ps-contact {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

/* Une option que le compte ne peut pas honorer : elle reste LISIBLE et
   desactivee, pas cachee. La cacher ferait croire que la plateforme ne la
   propose pas, la ou le vrai message est « renseignez d'abord votre numero ». */
.ps-contact.is-impossible span {
  color: var(--pj-muted);
}

.ps-contacts__help {
  color: var(--pj-warning-ink);
}

/* LA PASTILLE DE GRADE, et son metal (PO, 2026-10-04).

   Elle remplace `.pt-badge`, qui peignait les cinq paliers dans le MEME
   orange de marque : la pastille disait donc « ce partenaire a un grade »
   sans jamais dire lequel, et c'est exactement ce que la demande corrige.

   La couleur porte le metal et l'icone porte la forme ; le NOM du grade
   reste ecrit a cote, parce qu'une teinte seule ne s'apprend pas et ne se
   distingue pas pour un oeil daltonien. */
/* Le retour vers l'annuaire. Meme piege que les contacts ci-dessus : la
   qualification par la balise EGALISE avec `.pj-app a` au lieu de la battre,
   et l'ordre de chargement donne alors raison au vendor. La classe est donc
   doublee sur le conteneur, ce qui porte le selecteur a (0,2,1). */
.pt-back {
  margin: 0;
}

.pt-back.pt-back a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* 44px : cette page se lit au pouce. */
  min-height: 44px;
  color: var(--pj-orange-text);
  font-weight: 600;
}

/* LES DEUX ONGLETS DU HAUT DU TABLEAU DE BORD (PO, 2026-10-04).

   Un barreau sobre -- pas de carte autour : les deux volets qu'il commande
   portent deja la leur, et un cadre de plus ferait trois bordures pour un
   seul contenu.

   `flex-wrap` : deux libelles longs (« Activite de la periode » et
   « Recommander mes services aux visiteurs du site ») ne tiennent pas sur
   360 px, et un barreau qui deborde horizontalement est un barreau dont on
   ne voit pas le second onglet. */
.cd-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid var(--pj-line);
}

/* `width: auto` : la regle `button, .btn` du haut de cette feuille met tout
   bouton nu a 100 %, et un onglet pleine largeur empile les deux
   verticalement -- ce qui annule l'interet du barreau. */
.cd-tab {
  width: auto;
  /* 44 px : plancher de cible tactile du projet. */
  min-height: 44px;
  padding: 10px 16px;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  background: none;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.cd-tab.is-active {
  color: var(--pj-orange-text);
  border-bottom-color: var(--pj-orange);
}

.pt-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  line-height: 1.6;
}

/* Compacte : la ou il n'y a pas la place d'un mot (l'avatar de la barre
   laterale, une ligne de CVtheque). Le nom reste lisible par un lecteur
   d'ecran et au survol -- une icone muette n'apprend rien a personne. */
.pt-chip--compacte {
  gap: 0;
  padding: 0;
  background: none;
}

.pt-metal {
  font-size: var(--pj-fs-sm);
}

.pt-metal--explorer { color: var(--pj-metal-explorer); }
.pt-metal--silver   { color: var(--pj-metal-silver); }
.pt-metal--gold     { color: var(--pj-metal-gold); }
.pt-metal--platinum { color: var(--pj-metal-platinum); }
.pt-metal--diamond  { color: var(--pj-metal-diamond); }

/* ---- LE MÉTAL PARTOUT OÙ UN PARTENAIRE APPARAÎT ---------------------------
   Demande du PO (2026-10-04), point 8 : « lorsqu'un utilisateur est partenaire,
   mettre systématiquement l'icône de son métal précieux sur son profil où qu'il
   apparaisse, CVthèque, profil, au-dessus du menu qui porte son nom ».

   Ces règles rejoignent la famille `pt-` juste au-dessus parce que c'est la même
   pastille : `framework/utils/partnerBadge` la dessine une fois, et les six
   écrans ne font que l'appeler. Ce qui change d'un écran à l'autre n'est jamais
   le dessin — c'est la PLACE. */

/* La pastille sur l'avatar de la barre du haut.
   ELLE N'EST PAS DANS LE BOUTON, et c'est une mesure qui l'a décidé : le thème
   vendorisé pose `overflow: hidden` sur `.pj-avatar-btn` pour que la photo tienne
   dans le cercle, donc une pastille posée au bord y serait rognée — et posée
   dedans elle chevaucherait le visage. Elle se pose sur `.dropdown`, que
   Bootstrap met en `position: relative`.

   `pointer-events: none` : sans cela elle volerait le clic qui ouvre le menu, sur
   le coin le plus facile à atteindre au pouce. */
.pj-topbar__actions .dropdown > .pt-chip--compacte {
  position: absolute;
  right: -2px;
  bottom: -2px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--pj-card);
  box-shadow: 0 0 0 2px var(--pj-card);
  pointer-events: none;
}

.pj-topbar__actions .dropdown > .pt-chip--compacte .pt-metal {
  font-size: var(--pj-fs-2xs);
}

/* Dans l'en-tête du menu, la pastille COMPLÈTE : le nom du grade en toutes
   lettres. Une icône muette n'apprend rien à qui ne connaît pas encore le
   barème, et le barème est tout neuf. */
.dropdown-menu > .pt-chip {
  margin: 0 1rem 6px;
}

/* Sous le nom, dans les trois en-têtes de fiche. Un bloc à part et non une
   suite du nom : le nom est posé par `textContent` (ProfileHero) ou échappé
   (les deux balisages), et le mélanger à du balisage rouvrirait la porte que
   cet échappement ferme. */
.ph-badge,
.cand-public__badge,
.cvt-badge-line {
  margin: 6px 0 0;
}

/* Dans une ligne de liste, la pastille suit le nom à un demi-cadratin.
   `baseline` et non `center` : une icône centrée sur une ligne de texte dont
   elle n'a pas la hauteur se décale vers le haut, et ça se voit sur une liste
   de vingt lignes bien plus que sur une. */
.cvx-card__name + .pt-chip--compacte,
.commercial-line__title .pt-chip--compacte {
  margin-left: 6px;
  vertical-align: baseline;
}

/* Les sujets portent chacun leur icone (PO, 2026-10-04), donc la puce de
   liste et son retrait disparaissent : deux marqueurs pour une seule ligne
   se lisent comme un defaut d'alignement. */
.pt-card__topics,
.pt-fiche__topics {
  margin: 12px 0 0;
  padding-left: 0;
  list-style: none;
  display: grid;
  gap: 6px;
}

.pt-topic {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

/* Largeur fixe : sans elle, une icone large et une etroite decalent leurs
   libelles l'un par rapport a l'autre, et la colonne de texte ondule. */
.pt-topic__icon {
  flex: none;
  width: 16px;
  text-align: center;
  color: var(--pj-orange);
}

.pt-card__actions {
  margin-top: 16px;
}

/* 44px de haut : le plancher de cible tactile du projet, et cette carte est
   dans une liste qu'on parcourt au pouce. */
.pt-card__actions .btn {
  width: auto;
  min-height: 44px;
}

.pt-fiche__motivation {
  margin: 16px 0 0;
  /* Une colonne de LECTURE : le texte de motivation est de la prose, et une
     ligne de 120 signes se relit trois fois. */
  max-width: 70ch;
  overflow-wrap: anywhere;
}


/* La meme phrase que sur la fiche, au rythme de la carte : celle-ci est une
   vignette dans une grille, et les 20 px de marge du titre de la fiche y
   creeraient un trou entre le lieu et la liste. */
.pt-card__help {
  margin-top: 12px;
}

.pt-card__help-title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-muted);
}

/* La liste n'a plus a porter sa propre marge haute : son conteneur la porte,
   et deux marges empilees feraient le double de l'espace voulu -- le piege du
   `gap` et de la `margin` que CLAUDE.md §9 decrit. */
.pt-card__help .pt-card__topics {
  margin-top: 0;
}

.pt-fiche__help-title {
  margin: 20px 0 4px;
  font-size: var(--pj-fs-body);
}

.pt-fiche__inds {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 12px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
}

.pt-ind {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pt-ind__label {
  font-size: var(--pj-fs-xs);
}

.pt-ind__value {
  font-weight: 600;
}

/* LE SYMBOLE D'INDISPONIBILITE du §5.2 : « si le calcul n'est pas encore
   possible, un symbole specifique doit indiquer que l'indicateur est
   indisponible ». Un tiret cadratin, en gris — pas un zero, qui se lirait
   comme une affirmation. */
.pt-ind__na {
  color: var(--pj-muted);
  cursor: help;
}

/* LA JAUGE DE FORCE DU RESEAU : des segments ENTIERS, et aucun chiffre.

   Decision du produit du 2026-10-04 : « sans chiffre affiche ». Une barre
   remplie en pourcentage -- ce qu il y avait ici la veille -- livrait le
   compte exact a qui mesure les pixels : 44 % entre 5 et 25 donne onze. Des
   segments entiers ne livrent qu un INTERVALLE, ce que le nom du palier dit
   deja a cote.

   `gap` plutot que des bordures : un segment eteint doit se voir comme une
   place vide, pas comme un trait. */
.pt-gauge {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.pt-gauge__seg {
  display: block;
  width: 14px;
  height: 8px;
  border-radius: 2px;
  background: var(--pj-line);
}

.pt-gauge__seg--on {
  background: var(--pj-orange);
}

/* Le nom du palier, a cote de la jauge : c est LUI qui porte le sens. La
   jauge seule demanderait de connaitre l echelle. */
.pt-gauge__label {
  display: block;
  margin-top: 2px;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.pt-fiche__qr {
  margin-top: 20px;
  text-align: center;
}

.pt-fiche__qr-img {
  width: 160px;
  height: 160px;
  cursor: zoom-in;
}

/* ---- La fiche à la maquette `partenaires_detail.png` (PO, 2026-10-05) --
   Ce bloc vient APRÈS les règles de la fiche et les reprend à l'échelle de la
   maquette : un grand rond d'initiales sur la couverture, un nom et une
   motivation plus grands, WhatsApp en bouton vert, des sujets à grandes
   icônes, des indicateurs lisibles et le QR dans son cadre. L'aperçu de la
   vitrine (`PartnerShowcasePanel`) passe par le même rendu, et doit : un
   aperçu qui diffère de la fiche ne promet rien.
   Préfixé `.pt-fiche` pour passer devant les règles communes à la carte. */

.pt-fiche .pt-hero {
  margin-bottom: 20px;
  padding: 22px 20px;
}

.pt-fiche .pt-hero__ident {
  align-items: center;
  gap: 16px;
}

.pt-fiche .pt-card__photo {
  width: 72px;
  height: 72px;
  flex: 0 0 auto;
}

/* Les initiales : orange sur un rond crème, cerclé de blanc, comme la
   maquette. */
.pt-fiche .pt-card__photo--empty {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
  font-weight: 700;
}

.pt-fiche .pt-hero__name {
  font-size: var(--pj-fs-title);
  font-weight: 700;
}

.pt-fiche .pt-hero .pt-card__place {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  font-size: var(--pj-fs-body);
  opacity: 0.92;
}

.pt-fiche .pt-fiche__body {
  display: grid;
  gap: 20px;
  padding: 0 20px 24px;
}

/* 85ch et non 70 : la maquette en montre environ 85 par ligne, et la colonne
   de lecture reste une colonne. */
.pt-fiche .pt-fiche__motivation {
  max-width: 85ch;
  margin: 0;
  font-size: var(--pj-fs-md);
  line-height: 1.6;
  color: var(--pj-ink);
}

/* Le grade, dans l'en-tête comme dans les indicateurs : une vraie pastille. */
.pt-fiche .pt-chip {
  gap: 8px;
  padding: 4px 14px;
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  white-space: nowrap;
}

/* Les moyens de joindre : des boutons pâles. WhatsApp en vert, comme
   l'application qu'il ouvre. */
.pt-fiche .pt-contacts {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.pt-fiche .pt-contact.pt-contact {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
  padding: 0 22px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 600;
  text-decoration: none;
}

.pt-fiche .pt-contact--whatsapp.pt-contact--whatsapp {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.pt-fiche .pt-contact__icon {
  font-size: var(--pj-fs-lg);
}

.pt-fiche .pt-fiche__help-title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.pt-fiche .pt-fiche__topics {
  gap: 12px;
}

.pt-fiche .pt-topic {
  gap: 14px;
  font-size: var(--pj-fs-md);
  color: var(--pj-ink);
}

.pt-fiche .pt-topic__icon {
  width: 22px;
  color: var(--pj-orange);
  font-size: var(--pj-fs-lg);
  text-align: center;
}

.pt-fiche .pt-fiche__inds {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: start;
  margin-top: 0;
  padding-top: 20px;
}

.pt-fiche .pt-ind {
  gap: 6px;
}

.pt-fiche .pt-ind__label {
  font-size: var(--pj-fs-sm);
}

.pt-fiche .pt-ind__value {
  font-size: var(--pj-fs-md);
}

/* Le QR dans son cadre, centré, avec sa phrase dessous. */
.pt-fiche .pt-fiche__qr {
  display: grid;
  justify-items: center;
  gap: 14px;
  text-align: center;
}

.pt-fiche .pt-fiche__qr-img {
  width: 180px;
  height: 180px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  box-shadow: var(--pj-shadow-sm);
  cursor: pointer;
}

.pt-fiche .pt-fiche__qr p {
  margin: 0;
  font-size: var(--pj-fs-body);
}

@media (min-width: 768px) {
  .pt-fiche .pt-hero { padding: 26px 32px; }
  .pt-fiche .pt-card__photo { width: 104px; height: 104px; }
  .pt-fiche .pt-card__photo--empty { font-size: var(--pj-fs-display); }
  .pt-fiche .pt-hero__name { font-size: var(--pj-fs-display); }
  .pt-fiche .pt-fiche__body { padding: 0 40px 32px; }
  .pt-fiche .pt-fiche__motivation { font-size: var(--pj-fs-lg); }
  .pt-fiche .pt-ind__label,
  .pt-fiche .pt-ind__value { font-size: var(--pj-fs-md); }
  .pt-fiche .pt-fiche__qr-img { width: 220px; height: 220px; }
}

/* ---- Le volet du partenaire ---------------------------------------- */

.ps-locked {
  margin: 12px 0 0;
  padding: 12px;
  border-radius: var(--pj-radius-sm, 6px);
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
}

.ps-visible {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 16px 0;
  font-weight: 600;
  /* 44px : la case et son libelle forment une seule cible tactile. */
  min-height: 44px;
}

.ps-topics {
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
  margin-top: 4px;
}

@media (min-width: 576px) {
  .ps-topics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.ps-topic {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
}

/* Une case desactivee parce que la borne de cinq est atteinte : elle doit se
   LIRE comme indisponible, sans quoi on clique trois fois en croyant a une
   panne. */
.ps-topic input:disabled + span {
  color: var(--pj-muted);
}

.ps-actions {
  margin-top: 16px;
}

.ps-actions .btn {
  width: auto;
  min-height: 44px;
}

.ps-preview {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--pj-line);
}

.ps-preview__title {
  margin: 0 0 12px;
  font-size: var(--pj-fs-body);
}

/* =====================================================================
   M VOTE — la rubrique « Vote » (cahier « Module de vote et de sondage »)

   LA FAMILLE `.vt-`. Deux écrans publics : le catalogue (§6) et la page d'un
   vote (§5.2, §5.3, §6). Tout est dimensionné pour 360px d'abord, puis
   enrichi — ~90 % de l'audience arrive sur un téléphone.

   AUCUN HEX EN CLAIR : chaque couleur est un `var(--pj-*)`, ce qui est ce qui
   fait du mode sombre un bloc d'override plutôt qu'une seconde passe sur tout
   le fichier. Et chaque taille est un pas de l'échelle `--pj-fs-*`, que
   `check-type-scale.mjs` refuse de voir écrite en littéral.
   ===================================================================== */

/* ---- L'en-tête de la rubrique --------------------------------------- */

.vt-head__title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-title);
  color: var(--pj-ink);
}

.vt-head__intro {
  margin: 0;
  max-width: 62ch;
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

/* ---- Les deux onglets ------------------------------------------------
   Une bande qui DÉFILE plutôt qu'un retour à la ligne : deux onglets tiennent
   partout, mais la bande est la forme que le reste du produit emploie déjà
   (`.metier-alpha`), et elle ne change pas de hauteur si un troisième état
   arrive un jour. */

.vt-tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.vt-tab {
  /* `width: auto` : la règle `button, .btn` en tête de ce fichier met tout
     bouton nu à 100 %, donc une rangée d'onglets doit le défaire elle-même. */
  width: auto;
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  cursor: pointer;
}

.vt-tab.is-on {
  border-color: var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

/* ---- Une carte du catalogue ------------------------------------------
   LA CARTE ENTIÈRE EST LE LIEN. Un titre cliquable sur un téléphone est une
   cible de quelques millimètres ; la carte en fait une de la largeur de
   l'écran.

   `.vt-card.vt-card` double la classe EXPRÈS : `.pj-app a { color: inherit }`
   vit dans la feuille vendor, chargée APRÈS celle-ci, donc une classe simple
   perd sur l'ordre et tag-qualifier (`a.vt-card`) ne fait qu'égaliser. Le
   doublement est la seule forme qui gagne — leçon payée trois fois le
   2026-10-04. */

.vt-card.vt-card {
  display: block;
  color: var(--pj-ink);
  text-decoration: none;
  transition: box-shadow .15s ease, transform .15s ease;
}

.vt-card.vt-card:hover {
  box-shadow: var(--pj-shadow);
  transform: translateY(-1px);
}

.vt-card__top {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.vt-card__title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-card);
  line-height: 1.3;
  color: var(--pj-ink);
}

.vt-card__intro {
  margin: 0 0 12px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
  /* Trois lignes et pas plus : une accroche de huit lignes repousse
     l'échéance et le nombre de participants hors de l'écran, et ce sont eux
     qui font cliquer. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.vt-card__meta,
.vt-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

.vt-card__meta i,
.vt-hero__meta i {
  margin-right: 6px;
}

.vt-card__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

/* Le squelette du chargement. Un écran vide pendant une requête se lit comme
   « il n'y a rien » sur une connexion lente, qui est celle de la plupart des
   gens ici. */
.vt-card--load {
  min-height: 136px;
  background: linear-gradient(90deg, var(--pj-bg), var(--pj-card), var(--pj-bg));
  background-size: 200% 100%;
  animation: vt-shimmer 1.2s linear infinite;
}

@keyframes vt-shimmer {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .vt-card--load { animation: none; }
  .vt-card.vt-card:hover { transform: none; }
}

.vt-empty {
  color: var(--pj-muted);
  font-size: var(--pj-fs-md);
}

/* ---- Les pastilles --------------------------------------------------- */

.vt-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--pj-radius-pill);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  background: color-mix(in srgb, var(--pj-muted) 12%, transparent);
  color: var(--pj-muted);
}

/* Un SONDAGE consulte, une DÉCISION tranche : deux couleurs, parce que c'est
   la différence que le module tout entier porte, et qu'un lecteur doit la voir
   avant de lire le titre. */
.vt-chip--poll {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.vt-chip--decision {
  background: var(--pj-accent-soft);
  color: var(--pj-accent-ink);
}

/* ---- Le catalogue des votes (`vtc-`), à la maquette du 2026-10-05 -----
   `Model pages/Annuaire/votes_et_sondages.png` : une seule carte qui porte
   l'en-tête, les onglets à compteur et une carte par vote. Une famille à
   part : `vt-head`, `vt-tab`, `vt-card` servent aussi à « Mes votes ». */

/* SANS CADRE SUR TÉLÉPHONE : la coquille ne laisse que 277px à 360px, et la
   carte de `.pj-card` en mangeait encore 50 — deux onglets ne tenaient plus
   côte à côte et un titre courait sur quatre lignes. Sur la maquette mobile,
   les cartes de vote prennent toute la colonne. `.vtc-frame` doublé pour
   passer devant `.pj-card`. */
.vtc-frame.vtc-frame {
  display: grid;
  gap: 20px;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}

.vtc-head {
  display: flex;
  align-items: flex-start;
  gap: 16px;
}

.vtc-head__ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}

.vtc-head__text { min-width: 0; }

.vtc-head__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-display);
  font-weight: 800;
  color: var(--pj-ink);
}

.vtc-head__intro {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.vtc-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* `width: auto` : la règle `button` de cette feuille étire tout bouton nu. */
.vtc-tab {
  width: auto;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.vtc-tab.is-on {
  border: 1.5px solid var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 600;
}

.vtc-list {
  display: grid;
  gap: 12px;
}

/* La carte entière est le lien. */
.vtc-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.vtc-card:hover,
.vtc-card:focus-visible {
  border-color: var(--pj-orange-fill);
  box-shadow: var(--pj-shadow-sm);
}

.vtc-card--load {
  min-height: 132px;
  background: var(--pj-card-2);
}

/* La tuile : la couverture si l'organisateur en a posé une, sinon l'icône
   déduite de ce qu'est le vote, dans une paire de jetons par teinte. */
.vtc-card__tile {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-lg);
}

.vtc-card__tile--cover { object-fit: cover; background: var(--pj-card-2); }
.vtc-card__tile--accent { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.vtc-card__tile--danger { background: var(--pj-danger-soft); color: var(--pj-danger); }
.vtc-card__tile--orange { background: var(--pj-orange-soft); color: var(--pj-orange); }
.vtc-card__tile--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }

.vtc-card__body {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.vtc-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.vtc-card__title {
  margin: 2px 0 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  line-height: 1.3;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

/* Deux lignes sur téléphone, comme la maquette : l'introduction entière est
   sur la page du vote. */
.vtc-card__intro {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  margin: 0;
  overflow: hidden;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.vtc-card__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin-top: 2px;
}

.vtc-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.vtc-card__meta span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* La date passe à la ligne sur téléphone, comme la maquette. */
.vtc-card__when { flex-basis: 100%; }

.vtc-card__cta {
  display: none;
  align-items: center;
  gap: 8px;
  color: var(--pj-orange-text);
  font-weight: 600;
  white-space: nowrap;
}

.vtc-card__chev {
  align-self: center;
  color: var(--pj-muted);
}

.vtc-empty {
  padding: 24px 0;
  color: var(--pj-muted);
  text-align: center;
}

/* Même forme que `.vt-pager` : une boîte posée dans une pile espacée. */
.vtc-pager {
  display: flex;
  justify-content: center;
  gap: 8px;
}

.vtc-pager:empty { display: none; }

@media (min-width: 768px) {
  /* Le cadre ne se dessine qu'à partir de la tablette : sur téléphone, les
     cartes prennent toute la colonne, comme la maquette mobile. */
  .vtc-frame.vtc-frame { padding: 26px; border: 1px solid var(--pj-line); background: var(--pj-card); box-shadow: var(--pj-shadow-sm); }
  .vtc-tab { padding: 0 22px; }
  .vtc-head { gap: 24px; }
  .vtc-head__ico { width: 80px; height: 80px; font-size: var(--pj-fs-display); }

  .vtc-card { grid-template-columns: auto minmax(0, 1fr); gap: 20px; padding: 18px 20px; }
  .vtc-card__tile { font-size: var(--pj-fs-card); }
  .vtc-card__tile { width: 64px; height: 64px; }
  .vtc-card__title { font-size: var(--pj-fs-lg); }
  .vtc-card__intro { -webkit-line-clamp: 3; }
  .vtc-card__when { flex-basis: auto; }
  .vtc-card__cta { display: inline-flex; }
  .vtc-card__chev { display: none; }
}

/* ---- La page d'un vote (`vtp-`), à la maquette du 2026-10-05 ---------
   `Model pages/Annuaire/votes_et_sondages_participer.png`. Famille à part :
   `vt-page`, `vt-back`, `vt-note`, `vt-verdict`, `vt-submit` servent aussi à
   l'assistant de création. */

.vtp-backrow {
  display: flex;
  margin: 0;
}

/* Doublée : le lien est un `<a>`, et `.pj-app a { color: inherit }` pèse
   (0,1,1) — une classe simple perdrait sa couleur (check-link-colors). */
.vtp-back.vtp-back {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 18px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  box-shadow: var(--pj-shadow-sm);
  color: var(--pj-orange-text);
  font-weight: 600;
  text-decoration: none;
}

/* L'en-tête : le texte, et l'illustration à droite dès la tablette. */
.vtp-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 20px;
}

.vtp-hero__text {
  display: grid;
  gap: 10px;
  min-width: 0;
}

.vtp-hero__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.vtp-hero__title {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 800;
  line-height: 1.25;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.vtp-hero__intro {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-muted);
}

.vtp-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.vtp-hero__meta span {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.vtp-note {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0;
  padding: 10px 14px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-info-soft);
  color: var(--pj-info-ink);
  font-size: var(--pj-fs-sm);
}

/* LA PAUSE SE DISTINGUE DES AUTRES NOTES, et c'est voulu : « résultat
   indicatif » et « vote privé » informent, celle-ci EXPLIQUE pourquoi on ne
   peut pas voter maintenant. Les trois au même bleu se seraient lues comme
   trois remarques de même poids, et un votant aurait cherché ailleurs la
   raison du refus. Le ton d'alerte la sépare sans crier. */
.vtp-note--pause {
  background: var(--pj-warning-soft);
  color: var(--pj-warning-ink);
  font-weight: 600;
}

/* Masquée sur téléphone, comme la maquette : la place est au titre. */
.vtp-hero__art { display: none; }

.vtp-hero__art svg {
  display: block;
  width: 100%;
  height: auto;
}

.vtp-hero__art--cover img {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: var(--pj-radius);
  object-fit: cover;
}

/* L'urne, peinte par les jetons : le thème sombre suit sans seconde image. */
.vtp-art__halo { fill: var(--pj-orange-soft); }
.vtp-art__ray { fill: none; stroke: var(--pj-orange); stroke-width: 3; stroke-linecap: round; }
.vtp-art__paper { fill: var(--pj-card); stroke: var(--pj-line); stroke-width: 1.5; }
.vtp-art__seal { fill: var(--pj-info-soft); }
.vtp-art__tick { fill: none; stroke: var(--pj-info-ink); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.vtp-art__slot { fill: var(--pj-orange-dark); }
.vtp-art__box { fill: var(--pj-orange-fill); }
.vtp-art__lid { fill: var(--pj-orange-dark); opacity: 0.35; }

/* Une section : sa tête (tuile, titre, ligne d'aide), puis son contenu. */
.vtp-sec {
  display: grid;
  gap: 16px;
}

.vtp-sec__head {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.vtp-sec__ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-lg);
}

.vtp-sec__text { min-width: 0; }

.vtp-sec__title {
  margin: 0;
  font-size: var(--pj-fs-card);
  font-weight: 700;
  color: var(--pj-ink);
}

.vtp-sec__sub {
  margin: 2px 0 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* Les choix : une option par ligne, un cercle à gauche. */
.vtp-options {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.vtp-option__box {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  margin: 0;
  padding: 10px 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.vtp-option:not(.is-locked) .vtp-option__box:hover { border-color: var(--pj-orange-fill); }

/* L'option choisie : bordure et fond orange, comme la maquette. */
.vtp-option__box:has(.vtp-option__radio:checked) {
  border-color: var(--pj-orange-fill);
  background: var(--pj-orange-soft);
}

.vtp-option.is-locked .vtp-option__box { cursor: default; }

/* Le cercle, dessiné : un `appearance: none` garde l'input (clavier, lecteur
   d'écran, `:checked`) et laisse la forme à la maquette. */
.vtp-option__radio {
  flex: 0 0 auto;
  appearance: none;
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  margin: 0;
  border: 2px solid var(--pj-muted);
  border-radius: 50%;
  background: var(--pj-card);
  cursor: inherit;
}

.vtp-option__radio:checked {
  border: 6px solid var(--pj-orange-fill);
}

.vtp-option__radio:focus-visible {
  outline: 2px solid var(--pj-orange);
  outline-offset: 2px;
}

.vtp-option__radio:disabled { opacity: 0.6; }

/* `flex: 1 1 auto` et non la valeur par défaut `0 1 auto` : sans cela ce bloc
   se dimensionne sur son contenu, donc sur la LONGUEUR DU LIBELLÉ, et la photo
   qu'il porte héritait de cette largeur. Mesuré en production le 2026-10-06 sur
   trois images toutes 32×32 à la source : « Accès libre pour tous » donnait
   140 px, « Accès libre avec avantages de parrainage » 272 px. C'est le texte
   qui dimensionnait l'image. */
.vtp-option__main {
  display: grid;
  flex: 1 1 auto;
  gap: 6px;
  min-width: 0;
}

.vtp-option__title {
  font-size: var(--pj-fs-md);
  font-weight: 600;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.vtp-option__desc {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* La photo d'un choix est le choix : bornée par son conteneur (voir le
   commentaire de `_choix`). */
.vtp-option--photo .vtp-option__box { align-items: flex-start; }

.vtp-option__photo {
  display: block;
  width: min(100%, 320px);
}

/* UN CADRE IDENTIQUE POUR TOUS LES CHOIX, quelle que soit l'image déposée.
   `aspect-ratio` fixe la hauteur sans la faire dépendre du fichier, et
   `contain` montre l'image ENTIÈRE : dans un vote la photo EST le choix, la
   rogner reviendrait à cacher ce sur quoi on vote. Le fond neutre habille les
   bandes laissées par un format qui ne tombe pas juste. */
.vtp-option__img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
}

/* Le verdict : le bandeau bleu-gris de la maquette. */
.vtp-verdict {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin: 0;
  padding: 12px 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-neutral-soft);
  color: var(--pj-neutral-ink);
  font-size: var(--pj-fs-sm);
}

.vtp-verdict i { color: var(--pj-info-ink); }

.vtp-verdict--ok {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.vtp-verdict--ok i { color: var(--pj-success); }

.vtp-submit {
  display: grid;
  gap: 10px;
}

.vtp-submit__btn.vtp-submit__btn {
  justify-self: start;
  width: auto;
  min-height: 44px;
  padding: 0 28px;
}

.vtp-submit__error {
  margin: 0;
  color: var(--pj-danger);
  font-size: var(--pj-fs-sm);
}

@media (min-width: 768px) {
  .vtp-hero { grid-template-columns: minmax(0, 1fr) 180px; align-items: center; gap: 28px; }
  .vtp-hero__art { display: block; }
  .vtp-hero__art--cover { height: 180px; }
  .vtp-hero__title { font-size: var(--pj-fs-display); }
  .vtp-sec__ico { width: 52px; height: 52px; font-size: var(--pj-fs-card); }
  .vtp-sec__title { font-size: var(--pj-fs-title); }
}

/* ---- La page d'un vote ---------------------------------------------- */

.vt-page__back {
  margin: 0;
}

/* Doublée pour la même raison que la carte : `.pj-app a { color: inherit }`
   gagnerait sur une classe simple. */
.vt-back.vt-back {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-body);
  font-weight: 600;
  text-decoration: none;
}

.vt-hero__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.vt-hero__title {
  margin: 0 0 12px;
  font-size: var(--pj-fs-display);
  line-height: 1.2;
  color: var(--pj-ink);
}

.vt-hero__intro {
  margin: 0 0 16px;
  max-width: 68ch;
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
}

.vt-note {
  display: flex;
  gap: 8px;
  margin: 16px 0 0;
  padding: 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-bg);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* ---- Les choix ------------------------------------------------------- */

.vt-choices__title,
.vt-results__title,
.vt-trends__title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-card);
  color: var(--pj-ink);
}

.vt-choices__list {
  display: grid;
  gap: 12px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.vt-choice__box {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  /* 44px de haut au minimum : c'est la cible tactile du projet, et un `label`
     mesure ce qu'il contient — un choix d'un mot ferait 20px. */
  min-height: 44px;
  padding: 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  cursor: pointer;
}

.vt-choice__box:hover {
  border-color: var(--pj-orange);
}

.vt-choice__radio {
  /* La case ne rétrécit pas : une description longue la comprimerait à zéro
     dans un conteneur flex. */
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  accent-color: var(--pj-orange);
}

.vt-choice__main {
  flex: 1 1 auto;
  /* `min-width: 0` : sans lui un mot très long déborde le conteneur flex au
     lieu de se replier — le défaut de `min-width` d'un item flex est `auto`,
     c'est-à-dire la largeur de son contenu. */
  min-width: 0;
}

.vt-choice__title {
  display: block;
  color: var(--pj-ink);
  font-size: var(--pj-fs-md);
  font-weight: 600;
}

.vt-choice__desc {
  display: block;
  margin-top: 4px;
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

/* ---- Le dépôt -------------------------------------------------------- */

.vt-submit {
  margin-top: 20px;
}

.vt-submit__btn,
.vt-submit__btn.vt-submit__btn {
  /* `width: auto` contre la règle `button, .btn` à 100 %, et la classe
     doublée pour la variante `<a class="btn">`, que `.pj-app a` toucherait. */
  width: auto;
  min-height: 44px;
}

.vt-submit__error {
  margin: 12px 0 0;
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
}

.vt-verdict {
  display: flex;
  gap: 8px;
  margin: 20px 0 0;
  padding: 12px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-bg);
  color: var(--pj-muted);
  font-size: var(--pj-fs-body);
}

.vt-verdict--ok {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

/* ---- Les résultats et les tendances ---------------------------------- */

.vt-bars {
  display: grid;
  gap: 12px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

/* UNE LIGNE PAR CHOIX, et sur un téléphone le libellé passe AU-DESSUS de la
   barre : côte à côte, un libellé de six mots laisserait à la barre deux
   centimètres, et la barre est ce qui se lit. */
.vt-bar {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 12px;
  align-items: center;
}

.vt-bar__label {
  grid-column: 1 / -1;
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.vt-bar__track {
  height: 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-bg);
  overflow: hidden;
}

.vt-bar__fill {
  display: block;
  height: 100%;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange);
}

.vt-bar__value {
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-variant-numeric: tabular-nums;
}

.vt-trends__list {
  display: grid;
  gap: 20px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.vt-trend__when {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
}

.vt-bars--sm .vt-bar__label {
  font-weight: 400;
  font-size: var(--pj-fs-sm);
}

.vt-bars--sm .vt-bar__track {
  height: 6px;
}

/* ---- La pagination ---------------------------------------------------- */

.vt-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.vt-pager .btn {
  /* Contre la règle `button, .btn` à 100 % en tête de ce fichier : une rangée
     de boutons de pagination doit la défaire elle-même. */
  width: auto;
  min-height: 44px;
}


/* ---- « Mes votes » (`vtm-`), à la maquette du 2026-10-05 -------------
   `Model pages/Annuaire/mes_votes.png` : l'en-tête à pictogramme, les onglets
   à compteur dans leur carte, une carte par vote dont la tuile dit où il en
   est. Famille à part : `vt-head` et `vt-tab` servent aussi à l'assistant. */

/* L'en-tête : pictogramme, texte, bouton. Sur téléphone le bouton passe SOUS
   le texte, aligné sur lui et non sur le pictogramme — la maquette mobile. */
.vtm-head {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "ico text"
    "ico cta";
  align-items: start;
  gap: 12px 14px;
}

.vtm-head__ico {
  grid-area: ico;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}

.vtm-head__text { grid-area: text; min-width: 0; }

.vtm-head__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
}

.vtm-head__intro {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* Doublée : `.pj-app a { color: inherit }` (vendor, chargée après) gagne sur
   une classe simple, et la règle `button, .btn` de cette feuille étire. */
.vtm-head__cta.vtm-head__cta {
  grid-area: cta;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

/* Les onglets DÉFILENT sur téléphone plutôt que de se replier : quatre
   pastilles sur deux lignes mangeraient la carte. */
.vtm-tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
}

.vtm-tabs::-webkit-scrollbar { display: none; }

.vtm-tab {
  flex: 0 0 auto;
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.vtm-tab.is-on {
  border: 1.5px solid var(--pj-orange);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 600;
}

.vtm-list {
  display: grid;
  gap: 12px;
}

/* La carte. Quatre zones nommées, parce que le bouton ne se range pas au même
   endroit selon le vote : sur téléphone, « Ouvrir » d'un brouillon se met à
   droite de « Prêt à publier », « Voir la page publique » prend toute la
   largeur sous le corps ; au-delà, les deux montent en haut à droite. */
.vtm-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "tile body body"
    "tile act  act";
  align-items: start;
  gap: 10px 12px;
}

.vtm-card--draft {
  grid-template-areas:
    "tile body body"
    "tile note act";
  align-items: center;
}

.vtm-card--draft .vtm-card__tile,
.vtm-card--draft .vtm-card__body { align-self: start; }

.vtm-card--load {
  min-height: 132px;
  background: var(--pj-card-2);
}

/* La tuile : une teinte par phase, et la décision toujours en violet. */
.vtm-card__tile {
  grid-area: tile;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: var(--pj-fs-lg);
}

.vtm-card__tile--brouillon { background: var(--pj-success-soft); color: var(--pj-success); }
.vtm-card__tile--a_venir { background: var(--pj-orange-soft); color: var(--pj-orange); }
.vtm-card__tile--en_cours { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.vtm-card__tile--termine { background: var(--pj-warning-soft); color: var(--pj-warning-ink); }
.vtm-card__tile--decision { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }

.vtm-card__body {
  grid-area: body;
  display: grid;
  gap: 6px;
  min-width: 0;
}

.vtm-card__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* « Publié » en vert : c'est le seul état où le vote vit sans son
   organisateur, et la maquette le distingue des deux autres. */
.vtm-chip--live {
  background: var(--pj-success-soft);
  color: var(--pj-success);
}

.vtm-card__title {
  margin: 2px 0 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  line-height: 1.3;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.vtm-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* ELLE SE REPLIE, et c'est une mesure qui l'a exigé.

   La ligne ne portait qu'un bouton ; depuis la demande du PO du 2026-10-05
   (modifier / dépublier / supprimer) elle en porte jusqu'à quatre. Mesuré
   à 356 px avec `flex: 0 0 auto` : le bord droit du dernier bouton tombait
   à 438 px dans une vue de 356 — et `scrollWidth` valait 356, donc la page
   ne débordait pas : les deux derniers boutons étaient simplement ROGNÉS.
   « Dépublier » et « Supprimer » n'existaient pas sur un téléphone, qui est
   l'écran de ~90 % des gens ici.

   `0 1 auto` l'autorise à rétrécir, `wrap` fait passer les boutons à la
   ligne, et le `gap` remplace l'espace blanc entre deux `inline-flex` —
   qui disparaît dès qu'un gabarit n'en laisse pas. */
.vt-row__actions {
  display: flex;
  flex: 0 1 auto;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}

.vtm-card__meta span {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.vtm-card__note { grid-area: note; min-width: 0; }

.vtm-card__ready,
.vtm-card__todo {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: var(--pj-fs-sm);
}

.vtm-card__ready { color: var(--pj-success); }
.vtm-card__todo { color: var(--pj-orange-text); }

/* Jusqu'à quatre gestes depuis le 2026-10-05 (ouvrir, modifier, dépublier,
   supprimer) : la cellule se replie plutôt que de rogner les derniers. */
.vtm-card__act {
  grid-area: act;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.vtm-card__btn.vtm-card__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  /* Une ligne sur téléphone, comme la maquette : à 16px « Voir la page
     publique » se repliait en deux dans les 183px de la colonne. */
  font-size: var(--pj-fs-sm);
  white-space: nowrap;
}

.vtm-card--draft .vtm-card__btn.vtm-card__btn { width: auto; }

.vtm-empty {
  color: var(--pj-muted);
  text-align: center;
}

@media (min-width: 768px) {
  .vtm-head {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "ico text cta";
    align-items: center;
    gap: 24px;
  }

  .vtm-head__ico { width: 80px; height: 80px; font-size: var(--pj-fs-display); }
  .vtm-head__title { font-size: var(--pj-fs-display); }
  .vtm-head__intro { font-size: var(--pj-fs-body); }
  .vtm-tab { padding: 0 22px; font-size: var(--pj-fs-body); }

  .vtm-card,
  .vtm-card--draft {
    grid-template-areas:
      "tile body act"
      "tile note .";
    align-items: start;
    gap: 8px 20px;
  }

  .vtm-card__tile { width: 72px; height: 72px; font-size: var(--pj-fs-card); align-self: center; }
  .vtm-card:not(.vtm-card--draft) .vtm-card__tile { grid-row: 1; }
  .vtm-card--draft .vtm-card__tile { grid-row: 1 / span 2; }
  .vtm-card__title { font-size: var(--pj-fs-lg); }
  .vtm-card__meta { font-size: var(--pj-fs-body); }
  .vtm-card__btn.vtm-card__btn { width: auto; padding: 0 22px; font-size: var(--pj-fs-body); }

  /* Une colonne `auto` se dimensionne sur le contenu MAX : quatre gestes sur
     une ligne écrasaient le corps de la carte à zéro (mesuré à 1366 px). La
     borne fait replier les boutons dans leur colonne plutôt que d'empiéter. */
  .vtm-card__act { max-width: 340px; justify-content: flex-end; }
}

/* Les boutons d'une rangée de l'assistant : pas étirés à 100 %. */
.vt-row__btn,
.vt-row__btn.vt-row__btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
}

/* ---- L'assistant de création (`vtw-`), aux maquettes du 2026-10-05 ---
   `Model pages/Annuaire/mes_votes_ouvrir_*.png` : un en-tête à pictogramme
   dont le titre et l'icône suivent l'étape, la frise des étapes et sa barre,
   puis des cartes où chaque champ porte sa tuile. */

.vtw-head {
  display: grid;
  gap: 16px;
  /* La frise lit la largeur de l'EN-TÊTE, pas celle de l'écran : la colonne
     centrale fait 734px à 1568px de large et 900px à 1920px, et les cinq
     pastilles ne tiennent sur une ligne qu'à partir d'environ 840px. */
  container: vtw-head / inline-size;
}

.vtw-head__top {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.vtw-head__ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: var(--pj-radius);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-title);
}

.vtw-head__text { min-width: 0; }

.vtw-head__title {
  margin: 0 0 4px;
  font-size: var(--pj-fs-card);
  font-weight: 800;
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.vtw-head__intro {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

/* LA FRISE, TÉLÉPHONE D'ABORD : cinq ronds numérotés reliés par un trait, le
   libellé dessous. Cinq colonnes égales, donc elle tient à 360px sans défiler. */
.vtw-steps {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

/* `width: auto` : la règle `button` de cette feuille étire tout bouton nu. */
.vtw-step {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: auto;
  min-height: 44px;
  padding: 0 2px;
  border: 0;
  background: transparent;
  color: var(--pj-muted);
  font-size: var(--pj-fs-2xs);
  line-height: 1.25;
  text-align: center;
  cursor: pointer;
}

/* Le trait qui relie un rond au précédent, sous les ronds. */
.vtw-step + .vtw-step::before {
  content: "";
  position: absolute;
  top: 15px;
  right: 50%;
  left: -50%;
  height: 2px;
  background: var(--pj-line);
}

.vtw-step[disabled] { cursor: default; opacity: 0.6; }

.vtw-step__n {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 1.5px solid var(--pj-line);
  border-radius: 50%;
  background: var(--pj-card);
  color: var(--pj-ink);
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.vtw-step.is-on { color: var(--pj-orange-text); font-weight: 600; }

.vtw-step.is-on .vtw-step__n {
  border-color: var(--pj-orange-fill);
  background: var(--pj-orange-fill);
  color: var(--pj-card);
}

/* Le « ! » d'une étape incomplète, posé sur le rond. */
.vtw-step__todo {
  position: absolute;
  top: -4px;
  left: calc(50% + 8px);
  z-index: 2;
  border-radius: 50%;
  background: var(--pj-card);
  color: var(--pj-orange);
  font-size: var(--pj-fs-sm);
}

.vtw-progress {
  height: 8px;
  overflow: hidden;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-line);
}

.vtw-progress__bar {
  display: block;
  width: 10%;
  height: 100%;
  border-radius: inherit;
  background: var(--pj-orange-fill);
  transition: width 0.3s ease;
}

@media (prefers-reduced-motion: reduce) {
  .vtw-progress__bar { transition: none; }
}

/* ---- Les cartes et leurs champs ---- */

.vtw-card {
  display: grid;
  gap: 20px;
}

/* Un champ : la tuile à gauche, le libellé, l'aide et le contrôle à droite. */
.vtw-field {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
}

.vtw-field__ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange);
  font-size: var(--pj-fs-sm);
}

.vtw-field__main {
  display: grid;
  gap: 8px;
  min-width: 0;
}

.vtw-field__label {
  margin: 4px 0 0;
  font-size: var(--pj-fs-md);
  font-weight: 700;
  color: var(--pj-ink);
}

.vtw-field__hint {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.vtw-count {
  margin: -2px 0 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
  text-align: right;
}

/* Début, clôture, pays. La tuile se range À CÔTÉ du libellé et le contrôle
   prend toute la largeur dessous : une date dans une colonne amputée de sa
   tuile ne tient plus « jj/mm/aaaa --:-- ». */
.vtw-row3 {
  display: grid;
  gap: 16px;
}

.vtw-row3 .vtw-field {
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  row-gap: 8px;
}

.vtw-row3 .vtw-field__main { display: contents; }

.vtw-row3 .vtw-field__label { margin: 0; }

.vtw-row3 .vtw-field .form-control,
.vtw-row3 .vtw-field .vtw-field__hint {
  grid-column: 1 / -1;
}

/* ---- Les choix à cocher (nature, audience) ---- */

.vtw-group {
  display: grid;
  gap: 14px;
}

.vtw-group__title {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
  color: var(--pj-ink);
}

.vtw-group__title i { color: var(--pj-orange); }

.vtw-choices {
  display: grid;
  gap: 12px;
}

.vtw-choice {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 64px;
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
  background: var(--pj-card);
  cursor: pointer;
}

.vtw-choice:has(input:checked) {
  border: 1.5px solid var(--pj-orange);
  background: var(--pj-orange-soft);
}

.vtw-choice:has(input:disabled) { cursor: default; }
.vtw-choice:has(input:disabled:not(:checked)) { opacity: 0.6; }

.vtw-choice input {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: 0;
  accent-color: var(--pj-orange);
}

.vtw-choice__text { min-width: 0; }

.vtw-choice__text strong {
  display: block;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.vtw-choice__text small {
  display: block;
  margin-top: 2px;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.vtw-choice__tile {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--pj-radius-sm);
  font-size: var(--pj-fs-lg);
}

.vtw-choice__tile--accent { background: var(--pj-accent-soft); color: var(--pj-accent-ink); }
.vtw-choice__tile--info { background: var(--pj-info-soft); color: var(--pj-info-ink); }
.vtw-choice__tile--orange { background: var(--pj-orange-soft); color: var(--pj-orange); }
.vtw-choice__tile--success { background: var(--pj-success-soft); color: var(--pj-success); }

/* Sur fond orangé, la tuile orange se détacherait mal : elle passe au fond de carte. */
.vtw-choice:has(input:checked) .vtw-choice__tile--orange { background: var(--pj-card); }

/* ---- Images ---- */

.vtw-up .mu__preview {
  aspect-ratio: auto;
  min-height: 96px;
  border-color: var(--pj-line);
}

.mu__empty-note {
  display: block;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.vtw-up .mu__pick { min-height: 44px; }

.vtw-img {
  display: block;
  max-width: 220px;
  max-height: 140px;
  border-radius: var(--pj-radius-sm);
  object-fit: contain;
  background: var(--pj-card-2);
}

/* ---- Tendances et résultats ---- */

.vtw-sub {
  display: grid;
  gap: 6px;
  margin: 0;
}

.vtw-sub__label {
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  color: var(--pj-ink);
}

.vtw-check {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 4px 0 0;
  padding: 14px 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  cursor: pointer;
}

.vtw-check input {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: 1px 0 0;
  accent-color: var(--pj-orange);
}

.vtw-check__text strong {
  display: block;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.vtw-check__text small {
  display: block;
  margin-top: 4px;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* ---- Les choix proposés ---- */

.vtw-alert {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
}

.vtw-alert__ico { margin-top: 2px; font-size: var(--pj-fs-body); }

.vtw-alert__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.vtw-lead {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.vtw-opts {
  display: grid;
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.vtw-opt {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
}

.vtw-opt__n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
  font-weight: 700;
}

.vtw-opt__main {
  display: grid;
  gap: 6px;
  min-width: 0;
}

.vtw-opt__title {
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
  overflow-wrap: anywhere;
}

.vtw-opt__desc {
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.vtw-opt__rm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: var(--pj-radius-sm);
  background: transparent;
  color: var(--pj-muted);
  cursor: pointer;
}

.vtw-opt__rm:hover,
.vtw-opt__rm:focus-visible {
  background: var(--pj-danger-soft);
  color: var(--pj-danger);
}

.vtw-opt-new {
  display: grid;
  gap: 18px;
  padding: 16px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius);
}

/* Doublée : `.pj-app a { color: inherit }` et la règle `button, .btn`. */
.vtw .vtw-add.vtw-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
}

/* ---- Précédent / Suivant ---- */

.vtw-actions {
  display: flex;
  gap: 12px;
}

.vtw .vtw-btn.vtw-btn {
  display: inline-flex;
  flex: 1 1 0;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 0 18px;
}

/* ---- Le récapitulatif ---- */

.vtw-illu {
  justify-self: center;
  width: 200px;
  height: auto;
}

.vtw-illu__halo { fill: var(--pj-success-soft); }
.vtw-illu__dot--o { fill: var(--pj-orange); }
.vtw-illu__dot--g { fill: var(--pj-success); }

.vtw-illu__spark {
  fill: none;
  stroke: var(--pj-ink);
  stroke-width: 4;
  stroke-linecap: round;
}

.vtw-illu__page {
  fill: var(--pj-card);
  stroke: var(--pj-line);
  stroke-width: 2;
}

.vtw-illu__fold { fill: var(--pj-line); }
.vtw-illu__line { fill: var(--pj-info-soft); }
.vtw-illu__check { fill: var(--pj-success); }

.vtw-illu__tick {
  fill: none;
  stroke: var(--pj-card);
  stroke-width: 6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.vtw-issue {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px;
  border-radius: var(--pj-radius);
}

.vtw-issue__ico { margin-top: 2px; font-size: var(--pj-fs-title); }

.vtw-issue__title {
  margin: 0;
  font-size: var(--pj-fs-lg);
  font-weight: 800;
}

.vtw-issue__text {
  margin: 4px 0 0;
  font-size: var(--pj-fs-body);
  color: var(--pj-ink);
}

.vtw-issue--ok { background: var(--pj-success-soft); }

.vtw-issue--ok .vtw-issue__ico,
.vtw-issue--ok .vtw-issue__title { color: var(--pj-success); }

.vtw-issue--todo { background: var(--pj-orange-soft); }

.vtw-issue--todo .vtw-issue__ico,
.vtw-issue--todo .vtw-issue__title { color: var(--pj-orange-text); }

.vtw-issue--todo .vtw-issue__title { font-size: var(--pj-fs-body); }

.vtw-todo {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.vtw-todo__go {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid currentColor;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-card);
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
  font-weight: 600;
  cursor: pointer;
}

.vtw .vtw-publish.vtw-publish {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  font-size: var(--pj-fs-md);
  font-weight: 700;
}

/* ---- Au-delà du téléphone ---- */

@media (min-width: 768px) {
  .vtw-head { gap: 20px; }
  .vtw-head__top { gap: 24px; }
  .vtw-head__ico { width: 80px; height: 80px; font-size: var(--pj-fs-display); }
  .vtw-head__title { font-size: var(--pj-fs-display); }
  .vtw-head__intro { font-size: var(--pj-fs-body); }

  .vtw-field { grid-template-columns: 40px minmax(0, 1fr); gap: 14px; }
  .vtw-field__ico { width: 40px; height: 40px; font-size: var(--pj-fs-md); }
  .vtw-field__label { margin-top: 8px; }

  .vtw-row3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  .vtw-choices--2 { grid-template-columns: 1fr 1fr; }
  .vtw-choice { padding: 14px 18px; }
  .vtw-choice__text strong { font-size: var(--pj-fs-md); }
  .vtw-group__title { font-size: var(--pj-fs-card); }

  /* La couverture : la boîte à gauche, le bouton et la consigne à droite. */
  .vtw-up--side .mu {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "prev act"
      "prev hint";
    align-items: start;
    column-gap: 20px;
  }

  .vtw-up--side .mu__preview { grid-area: prev; }
  .vtw-up--side .mu__actions { grid-area: act; }
  .vtw-up--side .mu__hint { grid-area: hint; }

  .vtw .vtw-btn.vtw-btn { flex: 0 0 auto; padding: 0 26px; }
  .vtw .vtw-btn--next.vtw-btn--next { margin-left: auto; }

  .vtw-illu { width: 260px; }
  .vtw-sum { padding: 32px; }
}

/* LES PASTILLES À LIBELLÉ, quand l'en-tête peut les tenir sur UNE ligne (la
   maquette). En deçà, la frise à ronds numérotés — la même qu'au téléphone —
   plutôt que deux rangées de pastilles : elle tient à toute largeur. Le
   repli sur deux lignes reste le filet d'une langue aux libellés plus longs. */
@container vtw-head (min-width: 840px) {
  .vtw-steps {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
  }

  .vtw-step {
    flex-direction: row;
    gap: 8px;
    padding: 0 10px 0 5px;
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-pill);
    background: var(--pj-card);
    color: var(--pj-ink);
    font-size: var(--pj-fs-sm);
    white-space: nowrap;
  }

  .vtw-step + .vtw-step::before { display: none; }

  .vtw-step.is-on {
    border: 1.5px solid var(--pj-orange);
    background: var(--pj-orange-soft);
  }

  .vtw-step__n { width: 28px; height: 28px; }

  .vtw-step__todo { position: static; }
}

/* Les champs des filtres d'audience (étape 2) gardent leur forme simple. */
.vt-field {
  display: grid;
  gap: 6px;
  margin: 0;
  /* `min-width: 0` sur un item de grille : sans lui un `<input>` garde sa
     largeur intrinsèque (~20 caractères) et déborde une colonne étroite. */
  min-width: 0;
}

.vt-field__label {
  color: var(--pj-ink);
  font-size: var(--pj-fs-body);
  font-weight: 600;
}

.vt-field__hint {
  margin: 0;
  color: var(--pj-muted);
  font-size: var(--pj-fs-sm);
}

/* Deux champs côte à côte dès qu'il y a la largeur, empilés sinon. */
.vt-field__row {
  display: grid;
  gap: 16px;
}

@media (min-width: 560px) {
  .vt-field__row {
    grid-template-columns: 1fr 1fr;
  }
}

.vt-filters-box {
  display: grid;
  gap: 16px;
  padding: 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-bg);
}

/* Le lien d'un vote privé, au récapitulatif. */
.vt-share {
  display: grid;
  gap: 8px;
  padding: 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-bg);
}

.vt-share__row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.vt-share__row .form-control {
  flex: 1 1 14rem;
  min-width: 0;
}


/* ---- Le compteur d'audience (§4.2) -----------------------------------
   Un BOUTON et pas un comptage automatique : la requête coûte de 15 ms à
   1 149 ms de travail de base sur les 70 237 comptes, mesuré. À chaque frappe,
   ce serait une seconde de base par caractère. */

.vt-count {
  display: grid;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--pj-line);
}

.vt-count__out:empty {
  display: none;
}

.vt-count__ok,
.vt-count__warn,
.vt-count__bad {
  display: flex;
  gap: 8px;
  margin: 0 0 8px;
  font-size: var(--pj-fs-body);
}

.vt-count__ok {
  color: var(--pj-ink);
}

.vt-count__warn {
  color: var(--pj-orange-text);
  font-size: var(--pj-fs-sm);
}

/* ZÉRO N'EST PAS « PEU » : c'est un vote que personne ne pourra déposer, et il
   a sa propre couleur autant que son propre message. */
.vt-count__bad {
  color: var(--pj-orange-text);
  font-weight: 600;
}


/* ---- Un choix qui porte une PHOTO (PO, 2026-10-05) --------------------
   « Le choix peut porter sur une photo, ou il peut être nécessaire de mettre
   la photo des candidats à une élection. » Dans les deux cas l'image EST le
   choix, ou presque : une vignette de 72 px à côté du texte ne laisse
   reconnaître ni un visage ni un objet, et c'est pourtant sur elle qu'on vote.

   Elle passe donc AU-DESSUS du libellé, sur toute la largeur de la carte, avec
   une hauteur bornée pour qu'une photo verticale ne pousse pas les autres
   choix hors de l'écran. */

/* LE CONTENEUR PORTE LA BORNE DE LARGEUR, et pas l'image.

   `prosyjob.css` pose `.pj-app .pj-main img { max-width: 100% }` — spécificité
   (0,2,1), et cette feuille-là est chargée APRÈS celle-ci. Une classe simple
   sur l'image perdait donc, et il aurait fallu tripler la classe pour gagner.
   Borner le parent ne demande rien à la cascade : l'image reste à 100 % de ce
   qui la contient, et c'est le conteneur qui dit combien.

   Mesuré et pas supposé — la règle gagnante a été cherchée dans les feuilles
   réellement chargées, après trois erreurs de spécificité payées le 2026-10-04.

   Pourquoi une borne : sur un écran large la boîte faisait 780 px pour une
   photo portrait de 480×600, soit 224 px d'image au milieu de 556 px de gris.
   Sur un téléphone elle ne joue pas, la carte étant plus étroite qu'elle. */
.vt-choice__photo {
  display: block;
  max-width: 420px;
  margin: 0 auto 8px;
}

.vt-choice__img {
  display: block;
  width: 100%;
  max-height: 220px;
  border-radius: var(--pj-radius-sm);
  /* `contain` et non `cover` : recadrer la photo d'un candidat peut lui couper
     le visage, et c'est le visage qui fait reconnaître. Le fond comble ce que
     la photo ne remplit pas. */
  object-fit: contain;
  background: var(--pj-bg);
}

/* La case du choix reste alignée en haut, mais une carte qui porte une photo
   gagne de l'air : elle se lit comme une vignette et plus comme une ligne. */
.vt-choice--photo .vt-choice__box {
  padding: 16px;
}

@media (min-width: 768px) {
  .vt-choice__img {
    max-height: 280px;
  }
}

/* ---- La couverture d'un vote (PO, 2026-10-05) ------------------------
   Elle ne fait PAS le même travail que la photo d'un choix, donc elle ne se
   présente pas pareil : l'image d'un choix EST le choix et se place au-dessus
   de son libellé ; la couverture HABILLE le vote et coiffe sa carte.

   `cover` et non `contain`, à l'inverse du choix : une couverture est un décor,
   et un décor se recadre sans rien perdre d'essentiel. Une photo de candidat,
   elle, se couperait le visage — c'est la même raison lue dans les deux sens.

   ELLE NE DÉBORDE PAS DU REMBOURRAGE DE LA CARTE, et c'est délibéré. Un bandeau
   qui touche les bords demanderait une marge négative égale au rembourrage de
   `.pj-card` — mesuré à 26 px, pas aux 16 que j'allais écrire. Ce nombre
   n'appartient pas à ce bloc : le jour où il change, le bandeau dépasserait ou
   laisserait une bande blanche, et personne ne ferait le lien. On supprime la
   dépendance plutôt que de la deviner — c'est la leçon payée trois fois le
   2026-10-04 sur la couverture d'un partenaire.

   `aspect-ratio` plutôt qu'une hauteur fixe : la boîte garde sa place avant que
   l'image n'arrive, donc le texte ne saute pas sous les yeux au chargement. */

.vt-card__cover,
.vt-hero__cover {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 6;
  margin-bottom: 16px;
  border-radius: var(--pj-radius-sm);
  object-fit: cover;
  background: var(--pj-bg);
}

.vt-hero__cover {
  aspect-ratio: 16 / 5;
}

/* ---- Au-delà du téléphone -------------------------------------------- */

@media (min-width: 768px) {
  /* Le libellé reprend sa place à côté de la barre dès qu'il y a la largeur
     pour les deux. */
  .vt-bar {
    grid-template-columns: minmax(0, 14rem) 1fr auto;
  }

  .vt-bar__label {
    grid-column: auto;
  }
}

/* ---- Les annexes du contrat partenaire ------------------------------- */
/* Un texte de regles, pas un tableau de bord : la mesure de la ligne compte
   plus que la densite. `max-width` en ch pour que la lecture tienne meme sur
   un grand ecran -- au-dela de 75 caracteres l'oeil perd sa ligne. */
.cd-annexes__title {
  margin: 0 0 8px;
  font-size: var(--pj-fs-card);
}

.cd-annexes__sub {
  margin: 20px 0 6px;
  font-size: var(--pj-fs-lg);
}

.cd-annexes__lead {
  max-width: 75ch;
  margin: 0 0 10px;
  color: var(--pj-muted);
}

.cd-annexes__rules {
  max-width: 75ch;
  margin: 0;
  padding-left: 22px;
}

.cd-annexes__rules li {
  margin-bottom: 10px;
  line-height: 1.5;
}

.cd-annexes__rules strong {
  color: var(--pj-ink);
}

/* Ce qui n'est pas encore arrete se dit, plutot que de laisser croire que
   l'annexe 3 est la seule. */
.cd-annexes__pending {
  max-width: 75ch;
  margin: 18px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* L'annexe 2 : des chiffres, donc une liste a deux colonnes plutot qu'un
   paragraphe. Meme forme que les exceptions du bareme, pour que les deux
   annexes se lisent de la meme facon. */
.cd-annexes__list {
  max-width: 75ch;
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
}

.cd-annexes__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--color-border);
}

.cd-annexes__item strong {
  white-space: nowrap;
}

/* CE QUI MANQUE SE DIT, et se voit. Une annexe a qui il manque une clause,
   sans le signaler, est pire qu'une annexe absente : le lecteur n'a aucun
   moyen de savoir qu'elle est incomplete. */
.cd-annexes__gaps {
  max-width: 75ch;
  margin: 14px 0 0;
  padding: 12px 14px;
  border-left: 3px solid var(--pj-info-ink);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
}

.cd-annexes__gaps p {
  margin: 0 0 8px;
  font-size: var(--pj-fs-sm);
}

.cd-annexes__gaps p:last-child {
  margin-bottom: 0;
}

/* ------------------------------------------------------------------
   Console : le test d'envoi d'e-mail (2026-10-10, .mtest-)
   Le formulaire, le relais et la configuration à gauche ; le résultat
   à droite à partir de 1200px, en dessous sinon. Les blocs de
   débogage se replient (<details>) : sur un téléphone, on ouvre la
   section qu'on lit. Les <pre> défilent dans leur boîte et coupent
   les longues lignes plutôt que d'élargir la page.
   ------------------------------------------------------------------ */
.mtest .card {
  margin-bottom: 16px;
}

.mtest-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.mtest-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.mtest-actions .btn,
.mtest-head .btn,
.mtest-section .btn {
  width: auto;
  min-height: 44px;
}

.mtest-section {
  border-top: 1px solid var(--pj-line);
  padding: 12px 0;
}

.mtest-section > summary,
.mtest-sub > summary {
  cursor: pointer;
  font-weight: 600;
  min-height: 44px;
  display: flex;
  align-items: center;
}

.mtest-sub {
  margin-top: 8px;
}

.mtest-dl {
  display: grid;
  grid-template-columns: minmax(0, max-content) minmax(0, 1fr);
  gap: 4px 12px;
  margin: 0 0 12px;
  font-size: var(--pj-fs-sm);
}

.mtest-dl dt {
  font-weight: 600;
  color: var(--pj-muted);
}

.mtest-dl dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.mtest-dl--keys dt code {
  font-size: var(--pj-fs-xs);
}

.mtest-pre {
  max-height: 420px;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 0 0 8px;
  padding: 10px 12px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card-2);
  color: var(--pj-ink);
  font-size: var(--pj-fs-xs);
}

.mtest-frame {
  display: block;
  width: 100%;
  height: 560px;
  border: 1px solid var(--pj-line);
  border-radius: var(--pj-radius-sm);
}

/* ── LA PAGE D'ACCUEIL PROSYWEB ────────────────────────────────────────────

   Seconde entree de la plateforme, ouverte sur le parcours de creation de
   site. Les trois offres viennent du plan de lancement, et la mise en page
   sert un seul geste : comparer trois colonnes d'un coup d'oeil.

   `auto-fit` et non une bascule a une largeur donnee : cette page vit dans la
   coquille publique, dont la largeur utile change avec la fenetre mais aussi
   avec ce que la coquille affiche a cote. Une requete media regarde la
   fenetre, pas la place reellement disponible. */
.pw-offres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-top: 18px;
}

.pw-offre {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 20px;
  border: 1px solid var(--color-border);
  border-radius: var(--pj-radius-sm);
  background: var(--color-surface);
}

/* L'offre centrale a recommander (plan, 2.3). Un lisere et non une couleur de
   fond : la carte doit se distinguer sans que les deux autres aient l'air
   desactivees. */
.pw-offre--phare {
  border-color: var(--pj-orange);
  box-shadow: inset 0 0 0 1px var(--pj-orange);
}

.pw-offre__ruban {
  position: absolute;
  top: -10px;
  left: 20px;
  padding: 2px 10px;
  border-radius: var(--pj-radius-pill);
  background: var(--pj-orange-fill);
  color: white;
  font-size: var(--pj-fs-xs);
  font-weight: 700;
  letter-spacing: .02em;
}

.pw-offre__nom {
  margin: 0;
  font-size: var(--pj-fs-card);
}

/* Le prix est ce qu'on lit en deuxieme, juste apres le nom de l'offre. */
.pw-offre__prix {
  margin: 0;
  font-size: var(--pj-fs-title);
  font-weight: 700;
  line-height: 1.1;
  color: var(--pj-orange-text);
}

/* La remise de Premium : le plan demande qu'elle soit DITE, c'est l'argument
   qui justifie le passage depuis Pro. Elle a donc sa ligne, et pas une
   parenthese dans la promesse. */
.pw-offre__remise {
  margin: 0;
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  color: var(--pj-orange-text);
}

.pw-offre__cible {
  margin: 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

.pw-offre__promesse {
  margin: 4px 0 0;
  font-size: var(--pj-fs-body);
}

.pw-inclus {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-top: 14px;
}

.pw-inclus__item h3 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-lg);
}

/* Les etapes gardent leur numerotation native : une liste ordonnee dit l'ordre
   aux lecteurs d'ecran, ce qu'un chiffre dessine ne fait pas. */
.pw-etapes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin: 14px 0 20px;
  padding-left: 20px;
}

.pw-etapes h3 {
  margin: 0 0 4px;
  font-size: var(--pj-fs-lg);
}

/* Le lancement de la recherche de nom de domaine.

   Le champ et le bouton sur une ligne tant qu'il y a la place, l'un sous
   l'autre sinon. `flex-wrap` et non une requete media : ce bloc vit dans une
   carte dont la largeur depend de la coquille autant que de la fenetre. */
.pw-domaine {
  margin-top: 14px;
}

.pw-domaine__label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  color: var(--pj-muted);
}

.pw-domaine__ligne {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}

/* Le champ prend la place qui reste, mais ne descend pas sous 220px : en
   dessous, un nom de domaine ne se relit plus pendant qu'on le tape. */
.pw-domaine__champ {
  flex: 1 1 220px;
  min-width: 220px;
}

/* Le bouton garde sa largeur propre.

   `width` ET `flex`, et le premier est le vrai correctif : avec une base
   `auto`, c'est la LARGEUR qui sert de base au calcul flex, et le theme met
   les boutons a 100 %. Le bouton prenait donc toute la ligne, passait seul
   au-dessous, et le champ restait seul au-dessus.

   Constate a l ecran puis mesure : les deux faisaient 1458 px dans une carte
   qui avait la place pour les deux, alors que la direction etait bien `row` et
   que `flex: 0 0 auto` etait deja applique. Sans la mesure, on aurait cherche
   du cote de la direction. */
.pw-domaine__ligne .pj-btn {
  flex: 0 0 auto;
  width: auto;
}

/* Le bouton de chaque offre, pousse en bas de sa carte.

   `margin-top: auto` dans une carte en colonne : les trois cartes n'ont pas la
   meme hauteur de texte — Premium porte une ligne de remise que les autres
   n'ont pas — et sans cela les trois boutons se posaient a trois hauteurs
   differentes. Un rang de boutons qui ondule se compare mal. */
.pw-offre__action {
  margin-top: auto;
  padding-top: 14px;
}

/* Le bouton garde sa largeur propre, pour la raison ecrite plus haut a propos
   du champ de domaine : le theme met les boutons a 100 %. */
.pw-offre__action .pj-btn {
  width: auto;
}

/* ── MAQUETTE : LA VENTE DE SERVEURS ───────────────────────────────────────

   Un montage graphique, et le gabarit vient de la page VPS de Contabo donnee
   en exemple : bande sombre, colonne d'arguments a gauche, trois cartes
   claires a droite.

   LE DEGRADE EST CELUI DE LA MAISON, deja porte par `.ph-cover--empty` et deux
   autres bandes : une seule facon de peindre un aplat de marque, et elle a
   l'avantage d'etre tenue par le theme sombre.

   Premiere version ecrite ici : `linear-gradient(135deg, var(--pj-ink),
   var(--pj-navy-dark))`, en se disant que la bande resterait sombre de nuit
   comme de jour. Mesure : en theme sombre `--pj-ink` vaut #e8edf4 — l'encre
   d'un fond sombre est CLAIRE — et `--pj-navy-dark` se leve a #3d5a7d. La
   bande sortait plus claire que la page, avec son titre blanc dessus. Un
   jeton n'est pas une couleur, c'est un ROLE, et « l'encre » change de camp
   avec le theme.

   LA CLASSE EST DOUBLEE, comme `.dash-journey.dash-journey` et pour la meme
   raison, ecrite dans index.html : `.pj-card` ne vit pas dans cette feuille
   mais dans le theme VENDORISE (`user-template/css/prosyjob.css`), qu'AssetStacks
   insere APRES elle. A egalite de poids — une classe contre une classe — c'est
   donc le fond blanc du theme qui gagne, et il gagnait : la bande s'est affichee
   blanche, avec son titre blanc sur blanc et ses arguments invisibles.

   Les deux defauts ont ete vus a l'ecran, et ils ne pouvaient l'etre que la :
   une page qui rend une carte vide ne casse rien et ne signale rien. */
.pw-serveurs.pw-serveurs {
  overflow: hidden;
  /* La couleur SOUS le degrade : `.pj-card` peint `background` en raccourci,
     donc un fond blanc. Le degrade le couvre, mais un raccourci concurrent
     ajoute un jour quelque part le rendrait a nouveau visible. */
  background-color: var(--pj-navy-dark);
  background-image: linear-gradient(135deg, var(--pj-navy) 0%, var(--pj-navy-dark) 55%, var(--pj-orange-dark) 160%);
  border-color: var(--pj-navy-dark);
  color: white;
}

/* CE QUI N'EST PAS VRAI SE DIT DANS LA PAGE, et non dans un commentaire de
   source. Un montage circule en capture d'ecran, ou il perd tout contexte ;
   la mention doit voyager avec l'image. En haut, avant le titre : elle doit
   etre lue avant les prix, pas apres. */
.pw-serveurs.pw-serveurs .pw-serveurs__mention {
  margin: -20px -20px 18px;
  padding: 8px 20px;
  background: rgba(255, 255, 255, .14);
  border-bottom: 1px solid rgba(255, 255, 255, .22);
  font-size: var(--pj-fs-xs);
  font-weight: 600;
  letter-spacing: .01em;
}

.pw-serveurs.pw-serveurs .pw-serveurs__entete {
  max-width: 70ch;
}

.pw-serveurs.pw-serveurs .pw-serveurs__entete h2 {
  margin: 6px 0 8px;
  color: white;
}

/* BLANC PLEIN, et non un blanc attenue.

   Le degrade de la maison se leve en theme sombre — #4e7099 a son point le
   plus clair. Du blanc y mesure 5,13:1, ce qui passe ; le meme blanc a 82 %
   d'opacite tombe autour de 4,2:1 et ne passe plus pour du texte de 14 px.
   La hierarchie se fait donc a la graisse, pas a l'opacite. */
.pw-serveurs.pw-serveurs .pw-serveurs__entete p {
  margin: 0;
  font-size: var(--pj-fs-body);
  color: white;
}

/* L'oeil surligne du theme ne tiendrait pas sur le fond sombre : l'orange de
   texte est une valeur calculee pour du blanc. */
.pw-serveurs.pw-serveurs .pw-serveurs__tag {
  background: rgba(255, 255, 255, .16);
  color: white;
}

/* Les arguments a gauche, les machines a droite : UN tiers contre DEUX, et les
   deux parts sont ecrites.

   Premiere version en `repeat(auto-fit, minmax(300px, 1fr))` avec un
   `grid-column: span 2` sur les machines — l'idiome du reste de ce fichier.
   Mesure a 1680 px : la grille produisait QUATRE pistes, « 470px 470px 470px
   0px ». Les arguments prenaient la premiere, les machines la deuxieme et la
   troisieme, la quatriere restait vide. Le rendu etait juste par chance, et le
   nombre de pistes — donc la place laissee aux cartes — changeait a chaque
   largeur.

   `auto-fit` sert a repartir des elements SEMBLABLES. Ici les deux colonnes
   n'ont ni le meme role ni la meme taille : la proportion se declare. */
.pw-serveurs.pw-serveurs .pw-serveurs__corps {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) minmax(0, 2fr);
  gap: 24px;
  align-items: center;
  margin-top: 20px;
}

.pw-serveurs.pw-serveurs .pw-serveurs__arguments {
  display: grid;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--pj-fs-body);
  color: white;
}

.pw-serveurs.pw-serveurs .pw-serveurs__arguments strong {
  color: white;
}

/* Trois cartes, et le conteneur en prend deux parts : sur un ecran large, une
   colonne d'arguments contre trois cartes se partagent mal a egalite. */
.pw-serveurs.pw-serveurs .pw-machines {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
}

/* Une carte claire sur la bande sombre : c'est elle qui porte le prix, et un
   prix se lit sur du clair. Les boutons y retrouvent le contraste pour lequel
   ils ont ete mesures — un bouton a liseres sur fond sombre serait illisible,
   et le corriger ici aurait duplique la palette. */
.pw-serveurs.pw-serveurs .pw-machine {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px;
  border-radius: var(--pj-radius-sm);
  background: var(--pj-card);
  color: var(--pj-ink);
  text-align: center;
}

.pw-serveurs.pw-serveurs .pw-machine--phare {
  box-shadow: 0 0 0 2px var(--pj-orange);
}

.pw-serveurs.pw-serveurs .pw-machine__nom {
  margin: 0;
  font-size: var(--pj-fs-md);
  color: var(--pj-muted);
  font-weight: 600;
}

.pw-serveurs.pw-serveurs .pw-machine__cible {
  margin: 0 0 10px;
  font-size: var(--pj-fs-sm);
  font-weight: 700;
}

.pw-serveurs.pw-serveurs .pw-machine__depuis {
  margin: 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* Le prix barre met en scene la mecanique d'une offre d'appel. Il est en gris
   et non en rouge : le rouge dirait une erreur, alors qu'il dit un avant. */
.pw-serveurs.pw-serveurs .pw-machine__barre {
  margin: 0;
  font-size: var(--pj-fs-sm);
  color: var(--pj-muted);
}

.pw-serveurs.pw-serveurs .pw-machine__prix {
  margin: 0;
  font-size: var(--pj-fs-display);
  font-weight: 700;
  line-height: 1.05;
}

.pw-serveurs.pw-serveurs .pw-machine__unite {
  font-size: var(--pj-fs-xs);
  font-weight: 600;
}

.pw-serveurs.pw-serveurs .pw-machine__duree {
  margin: 0 0 12px;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* La fiche technique SOUS le bouton, comme chez Contabo : on choisit sur le
   prix et la promesse, on verifie les caracteristiques ensuite. */
.pw-serveurs.pw-serveurs .pw-machine__fiche {
  margin: 12px 0 0;
  font-size: var(--pj-fs-xs);
  color: var(--pj-muted);
}

/* Un bouton de maquette ne mene nulle part, et il le montre. `disabled` porte
   deja l'information au lecteur d'ecran ; l'opacite la porte a l'oeil. */
.pw-serveurs.pw-serveurs .pw-machine .pj-btn[disabled] {
  width: 100%;
  opacity: .55;
  cursor: not-allowed;
}

/* Sous cette largeur, deux colonnes ne tiennent plus : les arguments passent
   au-dessus des cartes, qui se repartissent alors sur toute la largeur. */
@media (max-width: 860px) {
  .pw-serveurs.pw-serveurs .pw-serveurs__corps {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   LA PORTÉE PAR PAYS — la porte vers les autres pays (2026-10-16).

   Trois écrans la portent : l'annuaire, la recherche d'offres, la recherche
   de formations. Une liste vide sur une façade stricte est indistinguable
   d'une panne, et « ne voir les autres contenus qu'à la demande » suppose
   qu'on puisse demander.

   Le nom du pays est une ÉTIQUETTE et non une phrase à trou : la préposition
   française dépend du pays — « au Cameroun », « en Belgique », « aux
   États-Unis » — et une phrase à trou en produirait une sur trois de travers.
   ───────────────────────────────────────────────────────────────────────── */
.pj-portee-pays {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 4px 0 0;
}

/* `--surface-chip` et `--color-border` plutôt qu'une valeur écrite : ces deux
   noms sont remappés par le thème dans prosyjob-app.css, et une littérale
   resterait claire sur fond sombre. C'est ainsi que `.co-member` a fini par
   peindre #fbfcfe sous du texte blanc, à 1,15:1. */
.pj-portee-pays__nom {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--surface-chip);
  font-weight: 700;
  font-size: var(--pj-fs-sm);
  color: var(--pj-ink);
  white-space: nowrap;
}

.pj-portee-pays__action {
  margin: 10px 0 0;
}

/* Au-dessus d'une liste NON vide : elle dit où l'on se trouve, et elle est
   alignée à gauche parce qu'elle précède des cartes et non un écran vide. */
.pj-portee-pays--tous {
  justify-content: flex-start;
  gap: 4px;
  padding: 8px 2px 12px;
  text-align: left;
}
