/* =====================================================================
   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;
  --color-border: #e2e5ea;
  --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. */
.field input,
.field select,
.field textarea {
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  font: inherit;
  font-size: 1rem;
  background: var(--color-surface);
  color: var(--color-text);
  width: 100%;
}

.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);
}

/* ── Earn-money option cards ─────────────────────────────────────────── */

.option-card {
  position: relative;
}

/* La marge du titre viendrait s'ajouter au padding de .pj-card. */
.option-card > h2:first-child,
.option-card > .option-card__badge + h2 {
  margin-top: 0;
}

/*
  Toute rangée de boutons dans la couche connectée doit reprendre sa largeur
  elle-même : la règle `button, .btn` en haut de cette feuille les met à
  `width: 100%`, et un bouton pleine largeur collé aux bords de sa carte est
  exactement ce que cette page affichait.
*/
.option-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 18px;
}

.option-card__actions .btn {
  width: auto;
}

.option-card--disabled {
  opacity: 0.6;
}

.option-card--disabled h2 {
  padding-right: 100px;
}

.option-card__badge {
  position: absolute;
  top: 12px;
  right: 12px;
  font-size: 0.75rem;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 999px;
  padding: 2px 10px;
  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: 959px) {
}

@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%, #eff4fb 100%);
}

#auth-header {
  position: sticky;
  top: 0;
  z-index: 30;
}

.connected-header {
  display: grid;
  grid-template-columns: auto minmax(220px, 320px) minmax(280px, 1fr) auto;
  align-items: center;
  gap: 18px;
  padding: 14px 18px;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(223, 231, 242, 0.9);
}

.connected-header__brand {
  display: inline-flex;
  align-items: center;
}

.connected-header__logo {
  width: 154px;
  max-width: none;
}

.connected-header__search {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  height: 48px;
  padding: 0 16px;
  border-radius: 999px;
  background: #eef3fb;
  color: var(--connected-muted);
}

.connected-header__search i {
  font-size: 0.95rem;
}

.connected-header__search input {
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  color: var(--connected-text);
}

.connected-header__search input::placeholder {
  color: #7b889f;
}

.connected-header__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
}

.connected-header__nav-item {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 84px;
  padding: 10px 14px 16px;
  border: 0;
  background: transparent;
  color: #6d7688;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
}

.connected-header__nav-item i {
  font-size: 1.2rem;
}

.connected-header__nav-item span {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.connected-header__nav-item.is-active {
  color: var(--connected-primary);
}

.connected-header__nav-item.is-active::after {
  content: "";
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 0;
  height: 4px;
  border-radius: 999px 999px 0 0;
  background: var(--connected-primary);
}

.connected-header__actions {
  display: flex;
  align-items: center;
  justify-content: right;
  gap: 10px;
}

.connected-header__actions #lang-switcher {
  min-width: 92px;
}

.connected-header__actions .lang-switcher {
  min-height: 44px;
  padding: 10px 38px 10px 12px;
  border-radius: 999px;
  box-shadow: none;
  background-color: #f6f8fc;
}

.connected-header__icon,
.connected-profile-menu__trigger {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid var(--connected-border);
  background: var(--connected-surface);
  color: #556273;
  cursor: pointer;
}

.connected-profile-menu {
  position: relative;
}

.connected-profile-menu__trigger {
  border: 2px solid rgba(47, 124, 243, 0.25);
  background: #fdfefe;
}


.connected-profile-menu__panel {
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  width: 278px;
  padding: 18px;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.98);
  border: 1px solid rgba(223, 231, 242, 0.95);
  box-shadow: 0 22px 50px rgba(22, 35, 59, 0.18);
}

.connected-profile-menu__summary {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-bottom: 16px;
  margin-bottom: 10px;
  border-bottom: 1px solid #edf2f8;
}

.connected-profile-menu__summary strong,
.connected-profile-menu__summary span {
  display: block;
}

.connected-profile-menu__summary span:last-child {
  margin-top: 4px;
  color: var(--connected-muted);
  font-size: 0.92rem;
}

.connected-profile-menu__badge {
  width: 54px;
  height: 54px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: linear-gradient(145deg, #fff7f2, #eef5ff);
}

.connected-profile-menu__badge img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.connected-profile-menu__item {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: left;
  gap: 12px;
  padding: 14px 12px;
  margin-top: 6px;
  border: 0;
  border-radius: 16px;
  background: transparent;
  color: var(--connected-text);
  font: inherit;
  font-size: 1rem;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}

.connected-profile-menu__item i {
  color: var(--connected-primary);
}

.connected-profile-menu__item:hover {
  background: #f5f8fe;
}

.connected-profile-menu__item--danger {
  color: #d7493f;
}

.connected-profile-menu__item--danger i {
  color: inherit;
}

.connected-shell {
  display: grid;
  grid-template-columns: 308px minmax(0, 1fr) 312px;
  gap: 18px;
  padding: 18px;
  align-items: start;
}

.connected-shell__sidebar,
.connected-shell__rail {
  position: sticky;
  top: 88px;
}

.connected-sidebar,
.connected-rail__stack,
.connected-surface-card,
.dashboard-hero-card,
.dashboard-stat-card,
.profile-panel,
.companies-panel,
.connected-info-card {
  border-radius: var(--connected-radius-lg);
  background: var(--connected-surface);
  border: 1px solid rgba(223, 231, 242, 0.95);
  box-shadow: var(--connected-shadow);
}

.connected-sidebar {
  padding: 18px;
}

.connected-sidebar__identity {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 10px 8px 20px;
}

.connected-sidebar__identity-mark {
  width: 48px;
  height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 16px;
  background: linear-gradient(135deg, #fff3ee 0%, #eef5ff 100%);
}

.connected-sidebar__identity-mark img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.connected-sidebar__identity strong,
.connected-sidebar__identity span {
  display: block;
}

.connected-sidebar__identity strong {
  font-size: 1.15rem;
}

.connected-sidebar__identity span {
  margin-top: 4px;
  color: var(--connected-muted);
  font-size: 0.94rem;
}

.connected-sidebar__menu {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.connected-sidebar__item,
.connected-sidebar__logout {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 14px;
  border: 0;
  border-radius: 18px;
  background: transparent;
  color: var(--connected-text);
  font: inherit;
  font-size: 1.02rem;
  font-weight: 700;
  text-align: left;
  justify-content: left;
  cursor: pointer;
}

.connected-sidebar__item-icon {
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: #f2f6fd;
  color: var(--connected-primary);
}

.connected-sidebar__item.is-active {
  background: var(--surface-chip);
}

.connected-sidebar__item.is-active .connected-sidebar__item-icon {
  background: #ffffff;
}

.connected-sidebar__session {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid #e6edf6;
}

.connected-sidebar__title {
  display: block;
  margin-bottom: 10px;
  color: var(--connected-muted);
  font-size: 0.92rem;
  font-weight: 700;
}

.connected-sidebar__logout {
  color: #23334d;
}

.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. */
.btn--primary {
  color: #ffffff;
  background: linear-gradient(135deg, #2f7cf3 0%, #ff7b57 100%);
  box-shadow: 0 18px 32px rgba(47, 124, 243, 0.18);
}

.btn--ghost {
  color: var(--connected-text);
  background: #ffffff;
  border-color: #d8e2f0;
}

.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);
  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,
.connected-info-row__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,
.connected-info-row:nth-child(1) .connected-info-row__icon {
  background: #e9f1ff;
  color: var(--connected-primary);
}

.dashboard-stat-card--orange .dashboard-stat-card__icon,
.connected-info-row:nth-child(2) .connected-info-row__icon {
  background: #fff1ea;
  color: var(--connected-accent);
}

.dashboard-stat-card--slate .dashboard-stat-card__icon,
.connected-info-row:nth-child(3) .connected-info-row__icon,
.connected-info-row:nth-child(4) .connected-info-row__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,
.connected-info-card h2,
.profile-panel h2,
.companies-panel h2,
.connected-surface-card h2 {
  margin-bottom: 10px;
  font-size: 1.18rem;
}

.connected-surface-card,
.connected-info-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 #e6edf7;
}

.connected-overview-card span,
.profile-fields span,
.profile-status-item span,
.companies-kpis span,
.connected-info-row span:last-child {
  display: block;
  color: var(--connected-muted);
  font-size: 0.92rem;
}

.connected-overview-card strong,
.profile-fields strong,
.profile-status-item strong,
.companies-kpis strong,
.connected-info-row strong {
  display: block;
  margin-top: 8px;
  font-size: 1.06rem;
}

.connected-overview-card small {
  display: block;
  margin-top: 6px;
  color: #7d879b;
}

.connected-rail__stack {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.connected-info-card__items {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.connected-info-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px;
  border-radius: 18px;
  background: #f6f9fe;
}

.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);
}

/* ── /profil, edit mode (E12-04) ───────────────────────────────────────
   Deliberately plain: this page renders inside the admin console too, where
   the front theme — and every `.pj-*` class — is switched off. Only classes
   both vendor themes define are used, and the layout is done here. */
.pf-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0 16px;
}

.pf-locked {
  margin: -6px 0 18px;
}

.pf-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* `button, .btn` near the top of this sheet makes every button full width, and
   `.layout-admin` is the only shell that neutralises it — so a row of buttons
   in the connected layout has to opt out itself. 44px is E10-01's floor. */
.pf-btn {
  width: auto;
  min-height: 44px;
}

/* ── Mes connexions (E16-02) ────────────────────────────────────────────── */

.pf-sessions {
  margin-top: 24px;
}

.pf-session {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-border);
}

.pf-session:last-child {
  border-bottom: none;
}

.pf-session__meta {
  display: block;
  font-size: 0.875rem;
}

.pf-session__current {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-success);
}

/* Same opt-out as .pf-btn, and the same 44px floor. */
.pf-session__close,
.pf-sessions__all {
  width: auto;
  min-height: 44px;
}

@media (max-width: 1280px) {
  .connected-shell {
    grid-template-columns: 270px minmax(0, 1fr);
  }

  .connected-shell__rail {
    grid-column: 1 / -1;
    position: static;
  }

  .connected-rail__stack {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .connected-overview-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 1080px) {
  .connected-header {
    grid-template-columns: 1fr;
    justify-items: stretch;
  }

  .connected-header__nav {
    justify-content: flex-start;
    overflow-x: auto;
    padding-bottom: 2px;
  }

  .connected-header__actions {
    justify-content: space-between;
  }

  .connected-shell {
    grid-template-columns: 1fr;
  }

  .connected-shell__sidebar,
  .connected-shell__rail {
    position: static;
  }

  .dashboard-hero-card,
  .profile-grid,
  .companies-grid,
  .dashboard-stats-grid,
  .connected-overview-grid,
  .profile-fields,
  .profile-status-list,
  .connected-rail__stack,
  .companies-kpis {
    grid-template-columns: 1fr;
  }

}

@media (max-width: 720px) {
  .connected-shell,
  .connected-header {
    padding-left: 14px;
    padding-right: 14px;
  }

  .connected-shell {
    padding-top: 14px;
  }

  .connected-header__logo {
    width: 130px;
  }

  .dashboard-hero-card,
  .dashboard-stat-card,
  .connected-surface-card,
  .profile-panel,
  .companies-panel,
  .connected-info-card,
  .connected-sidebar {
    padding: 18px;
  }

  .dashboard-hero-card__visual {
    min-height: 210px;
  }

  .dashboard-hero-card__visual-sun {
    width: 240px;
    height: 240px;
    right: 10px;
    bottom: -120px;
  }

  .connected-header__actions {
    flex-wrap: wrap;
  }

  .connected-header__actions #lang-switcher {
    order: 2;
    width: 100%;
  }
}

.commercial-activate-grid,
.commercial-dashboard-grid {
  display: grid;
  gap: 18px;
}

.commercial-activate-grid {
  grid-template-columns: minmax(0, 1.05fr) minmax(320px, 0.95fr);
}

.commercial-dashboard-grid {
  grid-template-columns: minmax(0, 0.95fr) minmax(0, 1.05fr);
}

/*
  Même raison que .dashboard-hero-card ci-dessus : deux colonnes fixes dans
  une carte déjà étranglée donnaient deux puces de 23px, où « Nom public
  affiché » descendait un mot par ligne. Les puces se rangent maintenant
  côte à côte quand il y a la place, l'une sous l'autre sinon.
*/
.commercial-hero-card__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: 14px;
  margin-top: 20px;
}

.commercial-hero-card__fact {
  padding: 16px;
  border-radius: 18px;
  background: var(--surface-sunken);
  border: 1px solid #e6edf7;
}

.commercial-hero-card__fact span {
  display: block;
  color: var(--connected-muted);
  font-size: 0.92rem;
}

.commercial-hero-card__fact strong {
  display: block;
  margin-top: 8px;
  font-size: 1rem;
}

.commercial-hero-card__visual {
  min-height: 280px;
}

.commercial-hero-card__seal {
  position: relative;
  z-index: 1;
  width: 116px;
  height: 116px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 36px;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 24px 40px rgba(22, 35, 59, 0.1);
}

.commercial-hero-card__seal img {
  width: 42px;
  height: 42px;
}

.commercial-hero-card__mini-card {
  position: absolute;
  right: 18px;
  bottom: 22px;
  z-index: 1;
  max-width: 210px;
  padding: 18px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.94);
  box-shadow: 0 18px 34px rgba(22, 35, 59, 0.14);
}

.commercial-hero-card__mini-card strong,
.commercial-hero-card__mini-card span {
  display: block;
}

.commercial-hero-card__mini-card span {
  margin-top: 8px;
  color: var(--connected-muted);
  font-size: 0.94rem;
  line-height: 1.55;
}

/*
  Le panneau illustré de la carte hero est bâti sur des éléments en position
  absolue : il lui faut donc une bande de hauteur fixe (280px) pour exister.
  C'est juste tant qu'il se tient À CÔTÉ du texte.

  Sur /commercial/activer, la carte est imbriquée dans une grille à deux
  colonnes ; depuis que sa grille se replie sur la largeur du conteneur, le
  panneau passe SOUS le texte, et ses 280px deviennent une bande vide de la
  largeur de la carte — le défaut de départ déplacé d'un cran.

  Ici le panneau repasse donc en flux : le sceau et le halo décoratifs
  disparaissent (ils n'ont plus de place utile), et la vignette « prêt à
  recommander », qui elle porte du texte, redevient un bloc normal.

  Mesuré : hauteur de la carte 796px -> 630px, bande du visuel 280px -> 114px.
*/
.commercial-activate-grid .dashboard-hero-card__visual,
.commercial-activate-grid .commercial-hero-card__visual {
  min-height: 0;
  display: block;
}

.commercial-activate-grid .dashboard-hero-card__visual-sun,
.commercial-activate-grid .commercial-hero-card__seal {
  display: none;
}

.commercial-activate-grid .commercial-hero-card__mini-card {
  position: static;
  max-width: none;
}

.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);
  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 #e6edf7;
}

.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 #d9e3f0;
  color: var(--connected-muted);
}

@media (max-width: 1080px) {
  .commercial-activate-grid,
  .commercial-dashboard-grid,
  .commercial-dashboard-stats-grid,
  .commercial-hero-card__facts {
    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;
  }
}

/* --- Commercial wallet (E3-08): commissions, withdrawals, transfer --- */
.commercial-wallet-hero__balance {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 22px 26px;
  border-radius: 28px;
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 26px 46px rgba(22, 35, 59, 0.14);
  text-align: center;
}

.commercial-wallet-hero__balance span {
  color: var(--connected-muted);
  font-size: 0.9rem;
}

.commercial-wallet-hero__balance strong {
  color: var(--connected-primary);
  font-size: 1.6rem;
  font-weight: 800;
  overflow-wrap: anywhere;
}

.commercial-wallet-stats-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.commercial-wallet-form .field {
  margin-bottom: 14px;
}

.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 #e6edf7;
}

.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 #d9e3f0;
  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: #fff3e0;
  color: #b26a00;
}

.cm-badge--available,
.wd-badge--validated {
  background: #e3f2fd;
  color: #1565c0;
}

.cm-badge--paid,
.wd-badge--paid {
  background: #e6f7ed;
  color: #1b7a43;
}

.cm-badge--reversed,
.cm-badge--cancelled,
.wd-badge--refused {
  background: #fdecea;
  color: #c0392b;
}

/* ── Les trois portes de la création d'organisme (E18-04) ───────────────
   « L'entreprise existante doit être proposée comme premier choix » et
   « Je forme moi-même » : des cartes, pas une liste déroulante — ce sont
   trois départs différents, pas trois valeurs d'un même champ. */
.tp-source {
  display: grid;
  gap: 14px;
  padding: 22px;
}

.tp-source__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 800;
}

.tp-source__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
  gap: 12px;
}

/* `text-align: left` et `width: auto` : ce sont des <button>, donc la règle
   `button { width: 100% }` du haut de cette feuille les prendrait, et le
   centrage par défaut d'un bouton rendrait ces cartes illisibles. */
.tp-source__card {
  width: auto;
  display: grid;
  gap: 6px;
  padding: 16px;
  text-align: left;
  border: 2px solid var(--color-border);
  border-radius: var(--pj-radius-sm, 12px);
  background: var(--surface-sunken);
  color: var(--color-text);
  cursor: pointer;
  min-height: 44px;
}

.tp-source__card strong {
  font-weight: 700;
}

.tp-source__card span {
  color: var(--connected-muted);
  font-size: 0.875rem;
}

.tp-source__card i {
  color: var(--connected-primary);
}

.tp-source__card.is-chosen {
  border-color: var(--connected-primary);
  background: var(--pj-card);
}

.tp-source__from {
  margin: 0 0 4px;
  color: var(--connected-muted);
  font-size: 0.875rem;
  font-weight: 600;
}

/* ── 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;
}

/* `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;
}

.cg-ladder__now-label,
.cg-ladder__now-miles {
  color: var(--connected-muted);
  font-size: 0.85rem;
}

.cg-ladder__now-grade {
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--connected-primary);
}

.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-ladder__buy {
  width: auto;
  justify-self: start;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

@media (max-width: 720px) {
  .cg-ladder__now {
    text-align: left;
    margin-left: 0;
  }

  .cg-ladder__buy {
    width: 100%;
    justify-content: center;
  }
}

/* ── 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;
  }
}

/* ── 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-wallet-stats-grid {
    grid-template-columns: 1fr;
  }

  .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 --- */
.cvtheque-filter-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
}

.cvtheque-filter-grid .field--wide {
  grid-column: 1 / -1;
}

.cvtheque-filter-actions {
  grid-column: 1 / -1;
  display: flex;
  gap: 12px;
}

.cvtheque-filter-actions .btn {
  width: auto;
}

.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 #e6edf7;
}

.cvtheque-card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.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;
}

.cvtheque-card__actions .btn {
  width: auto;
}

.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: #fdecea;
  color: #c0392b;
}

.cvt-badge--on {
  background: #e6f7ed;
  color: #1b7a43;
}

.cvtheque-notice {
  margin-top: 14px;
  padding: 14px 16px;
  border-radius: 16px;
}

.cvtheque-notice--lock {
  background: #fff7ed;
  border: 1px solid #fde3c3;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cvtheque-notice--lock .btn {
  width: auto;
}

.cvtheque-notice--ok {
  background: #e6f7ed;
  border: 1px solid #c3ecd2;
  color: #1b7a43;
}

/* 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-filter-grid {
    grid-template-columns: 1fr;
  }

  .cvtheque-detail-row {
    flex-direction: column;
    gap: 2px;
  }

  .cvtheque-detail-label {
    flex-basis: auto;
  }
}

/* --- Notifications (E4-04): bell badge, feed, preferences --- */
.connected-header__icon--bell {
  position: relative;
}

.connected-header__badge {
  position: absolute;
  top: 0;
  right: 0;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #e5484d;
  color: #fff;
  font-size: 0.62rem;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
}

.notif-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.notif-item {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border-radius: 16px;
  background: var(--surface-sunken);
  border: 1px solid #e6edf7;
  color: var(--connected-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.notif-item--unread {
  background: var(--surface-chip);
  border-color: #d4e2fb;
}

.notif-item__icon {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: var(--surface-chip);
  color: var(--connected-primary);
}

.notif-item__body {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.notif-item__title {
  font-weight: 700;
}

.notif-item__text {
  color: var(--connected-muted);
  font-size: 0.92rem;
}

.notif-item__date {
  color: var(--connected-muted);
  font-size: 0.8rem;
}

.notif-item__dot {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--connected-primary);
}

.notif-prefs-grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  align-items: center;
  gap: 8px;
}

.notif-prefs-head {
  padding: 8px 4px;
  color: var(--connected-muted);
  font-size: 0.85rem;
  font-weight: 600;
}

.notif-prefs-head span:not(:first-child),
.notif-prefs-cell {
  text-align: center;
  justify-self: center;
}

.notif-prefs-row {
  padding: 12px 4px;
  border-top: 1px solid var(--surface-sunken);
}

.notif-prefs-cat {
  font-weight: 600;
  color: var(--connected-text);
}

/* La case reste petite, la cible ne l'est pas (E25-04). Mesuree a 22x26 sur
   360 px : c'est la commande qu'on vient demander a quelqu'un d'actionner
   depuis un telephone, apres un clic de desinscription. Le label porte la
   surface, l'input garde sa taille. */
.notif-prefs-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  cursor: pointer;
}

.notif-prefs-cell input {
  width: 20px;
  height: 20px;
}

@media (max-width: 720px) {
  .notif-prefs-grid {
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
  }

  .notif-prefs-head,
  .notif-prefs-cat {
    font-size: 0.78rem;
  }
}

/* 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;
}

.notif-prefs-row.is-unsubscribed {
  background: var(--pj-orange-soft);
  border-radius: var(--pj-radius-sm);
}

/* --- Help centre & terms (E4-09) --- */
.help-list {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.help-group__title {
  font-size: 1.1rem;
  margin-bottom: 10px;
  color: var(--connected-text);
}

.help-group__items {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.help-item {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--surface-sunken);
  border: 1px solid #e6edf7;
  color: var(--connected-text);
  text-decoration: none;
}

.help-item__title {
  font-weight: 700;
}

.help-item__excerpt {
  font-size: 0.9rem;
}

.help-article__title {
  margin: 12px 0;
}

.help-article__body,
.terms-body {
  white-space: pre-wrap;
  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;
}

.terms-accepted-ok {
  margin: 0;
  color: #1b7a43;
  font-weight: 700;
}

.connected-context-menu__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.connected-context-menu__item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1px solid #e6edf7;
  border-radius: 18px;
  background: var(--surface-sunken);
  color: var(--connected-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.connected-context-menu__item.is-active {
  background: var(--surface-chip);
  border-color: #d4e2fb;
}

.connected-context-menu__icon {
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 14px;
  background: #ffffff;
  color: var(--connected-primary);
  flex-shrink: 0;
}

.connected-context-menu__copy {
  display: block;
}

.connected-context-menu__copy strong,
.connected-context-menu__copy small {
  display: block;
}

.connected-context-menu__copy small {
  margin-top: 5px;
  color: var(--connected-muted);
  font-size: 0.88rem;
  line-height: 1.45;
}

.connected-ad-banner {
  padding: 22px;
  border-radius: var(--connected-radius-lg);
  background: linear-gradient(145deg, #1f69dd 0%, #4a8cff 42%, #ff764d 100%);
  color: #ffffff;
  box-shadow: var(--connected-shadow);
}

.connected-ad-banner__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  font-size: 0.82rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.connected-ad-banner h2 {
  margin-top: 16px;
  margin-bottom: 10px;
  font-size: 1.35rem;
}

.connected-ad-banner p {
  margin: 0;
  color: rgba(255, 255, 255, 0.92);
  line-height: 1.65;
}

.connected-ad-banner__cta {
  margin-top: 18px;
  width: 100%;
  min-height: 48px;
  border: 0;
  border-radius: 16px;
  background: #ffffff;
  color: #1f5ec8;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}

/* ── Guest home landing ─────────────────────────────────────────────── */

.guest-home-header__actions .lang-switcher {
  min-width: 148px;
  min-height: 50px;
  border-radius: 18px;
  border-color: #d6e0ef;
  box-shadow: none;
}

@media (max-width: 1120px) {
}

@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;
  }

}
.connected-header__mobile-leading {
  display: flex;
  align-items: center;
  gap: 12px;
}

.connected-header__menu-toggle,
.connected-header__logo--mobile,
.connected-header__icon--search-shortcut {
  display: none;
}

@media (max-width: 720px) {
  .layout-auth {
    overflow-x: hidden;
  }

  .connected-header {
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "leading leading actions"
      "nav nav nav";
    align-items: center;
    gap: 10px;
    padding: 12px 14px 8px;
  }

  .connected-header__mobile-leading {
    grid-area: leading;
    display: flex;
    align-items: center;
    gap: 12px;
  }

  .connected-header__menu-toggle {
    width: 42px;
    height: 42px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--connected-border);
    border-radius: 50%;
    background: var(--surface-sunken);
    color: var(--chip-ink);
    cursor: pointer;
  }

  .connected-header__brand {
    min-width: auto;
  }

  .connected-header__logo--desktop {
    display: none;
  }

  .connected-header__logo--mobile {
    display: block;
    width: 18px;
    height: 32px;
  }

  .connected-header__search {
    display: none;
  }

  .connected-header__actions {
    grid-area: actions;
    justify-content: flex-end;
    gap: 8px;
    flex-wrap: nowrap;
  }

  .connected-header__actions #lang-switcher {
    order: 0;
    width: auto;
    min-width: 72px;
  }

  .connected-header__actions .lang-switcher {
    min-height: 40px;
    min-width: 72px;
    padding: 8px 30px 8px 10px;
    font-size: 0.92rem;
    background-position: right 10px center;
  }

  .connected-header__icon,
  .connected-profile-menu__trigger,
  .connected-header__menu-toggle {
    width: 40px;
    height: 40px;
  }

  .connected-header__icon--search-shortcut {
    display: inline-flex;
  }

  .connected-header__nav {
    grid-area: nav;
    justify-content: space-around;
    gap: 6px;
    overflow: visible;
    padding: 0 6px;
    border-top: 1px solid rgba(223, 231, 242, 0.9);
    padding-top: 8px;
  }

  .connected-header__nav-item {
    min-width: 58px;
    padding: 8px 6px 14px;
  }

  .connected-header__nav-item i {
    font-size: 1.35rem;
  }

  .connected-shell {
    padding-top: 14px;
  }

  .connected-shell__sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: min(320px, 84vw);
    padding: 14px;
    z-index: 45;
    transform: translateX(-108%);
    transition: transform 0.22s ease;
    background: rgba(239, 244, 251, 0.96);
    backdrop-filter: blur(12px);
    overflow-y: auto;
  }

  .layout-auth.is-mobile-sidebar-open .connected-shell__sidebar {
    transform: translateX(0);
  }

  .connected-sidebar {
    min-height: calc(100vh - 28px);
  }

  .connected-shell__rail {
    grid-column: auto;
  }

  .layout-auth.is-mobile-sidebar-open::after {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(18, 28, 43, 0.32);
    z-index: 40;
  }
}

@media (max-width: 480px) {
  .connected-header {
    padding: 10px 12px 6px;
  }

  .connected-header__actions {
    gap: 6px;
  }

  .connected-header__actions #lang-switcher {
    min-width: 64px;
  }

  .connected-header__actions .lang-switcher {
    min-width: 64px;
    padding-left: 8px;
    padding-right: 26px;
    font-size: 0.88rem;
  }

  .connected-header__nav-item {
    min-width: 52px;
    padding-left: 4px;
    padding-right: 4px;
  }

  .connected-header__nav-item i {
    font-size: 1.28rem;
  }
}
.connected-avatar-image {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.connected-profile-menu__trigger {
  overflow: hidden;
}


.connected-profile-menu__badge {
  overflow: hidden;
  background: var(--surface-chip);
}

.connected-profile-menu__badge img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.connected-sidebar__identity-mark {
  overflow: hidden;
  background: var(--surface-chip);
}

.connected-sidebar__identity-mark img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.connected-header__logo--mobile {
  width: 22px;
  height: 22px;
  object-fit: contain;
}

.dashboard-hero-card__mark,
.commercial-hero-card__seal img,
.logo.logo-small img {
  object-fit: contain;
}
.connected-avatar-image--default {
  object-fit: contain;
  object-position: center;
  padding: 4px;
  background: #f3f5f8;
  box-sizing: border-box;
}
.connected-profile-menu__trigger.is-default-avatar {
  background-size: 74%;
  background-color: #f3f5f8;
}
.connected-profile-menu__trigger {
  background-color: #fdfefe;
  background-image: var(--profile-trigger-image);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
/* ══════════════════════════════════════════════════════════════════════════
   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 #e2e5ea 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: #cfd8e3;
}

/* 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;
}

.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: #fff7e8;
  border: 1px solid #ffe2b3;
  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.
*/
.cand-editor {
  display: grid;
  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: #cbd3de;
  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;
}

.cand-preview {
  display: inline-block;
  margin-top: 8px;
  font-size: 0.9rem;
  font-weight: 600;
}

/* ── 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;
}

.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;
}

.cand-danger__btn {
  color: var(--color-error);
  border-color: #f3c9cc;
}

/* ── 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__head h1 {
  margin: 0 0 4px;
}

.cand-public__headline {
  font-weight: 600;
  margin: 0 0 6px;
}

.cand-public__facts {
  margin: 0 0 12px;
}

.cand-public__locked {
  margin: 0;
  padding: 10px 12px;
  background: #fff7e8;
  border: 1px solid #ffe2b3;
  border-radius: var(--radius);
  font-size: 0.86rem;
}

.cand-public__list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.cand-public__row h4 {
  margin: 0 0 2px;
}

.cand-public__row p {
  margin: 0;
}

.cand-public__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.cand-public__notice {
  text-align: center;
  padding: 40px 20px;
}

/* ── 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;
}

/* ── 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 {
  background: var(--surface-track);
  color: var(--color-muted);
}

.cv-badge--featured {
  background: #fff2d6;
  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 #d6e4ff;
  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: #f3c9cc;
}

.cv-empty {
  text-align: center;
  padding: 40px 22px;
  display: grid;
  gap: 10px;
  justify-items: center;
}

.cv-empty h2 {
  margin: 0;
}

/* ── Composition editor ─────────────────────────────────────────────────── */

.cv-editor__topbar {
  display: grid;
  gap: 4px;
}

.cv-back {
  font-size: 0.9rem;
  font-weight: 600;
}

.cv-editor__title {
  margin: 0;
  font-size: clamp(1.4rem, 3.5vw, 1.9rem);
}

.cv-section {
  padding: 20px;
}

.cv-hint {
  display: block;
  margin-top: 4px;
  font-size: 0.82rem;
}

/* One pick-list per section. */
.cv-pick {
  padding: 14px 0;
  border-bottom: 1px solid var(--color-border);
}

.cv-pick:last-child {
  border-bottom: 0;
}

.cv-pick__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 12px;
  margin-bottom: 10px;
}

.cv-pick__head h3 {
  margin: 0;
  font-size: 1rem;
}

.cv-pick__count {
  font-weight: 500;
  color: var(--color-muted);
  font-size: 0.85rem;
}

.cv-pick__toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
  color: var(--color-muted);
}

.cv-linkbtn {
  border: 0;
  background: none;
  padding: 6px 2px;
  color: var(--color-primary);
  font-weight: 600;
  cursor: pointer;
  font-size: 0.85rem;
}

.cv-pick__items {
  display: grid;
  gap: 2px;
}

.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;
}

.cv-pick__empty {
  font-size: 0.88rem;
  padding: 4px 8px;
}

.cv-interests-row {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--color-border);
  justify-content: flex-start;
}

.cv-editor__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 4px 0 8px;
}

.cv-editor__actions .btn--primary {
  flex: 1 1 auto;
}

/* ── Preview (the rendered CV document) ─────────────────────────────────── */

.cv-preview__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cv-preview__note {
  margin: 0;
  font-size: 0.85rem;
}

.cv-doc {
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.cv-doc__head {
  padding-bottom: 16px;
  border-bottom: 2px solid var(--color-border);
}

.cv-doc__name {
  margin: 0;
  font-size: clamp(1.6rem, 4vw, 2.2rem);
}

.cv-doc__title {
  margin: 4px 0 0;
  font-weight: 600;
  color: var(--color-primary);
}

.cv-doc__contact {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin-top: 10px;
  font-size: 0.86rem;
  color: var(--color-muted);
}

.cv-doc__block h2 {
  margin: 0 0 10px;
  font-size: 1.05rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-primary);
}

.cv-doc__summary {
  margin: 0;
  white-space: pre-line;
}

.cv-doc__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.cv-doc__entry h4 {
  margin: 0 0 2px;
  font-size: 1rem;
}

.cv-doc__line,
.cv-doc__dates {
  margin: 0;
  font-size: 0.86rem;
}

.cv-doc__desc {
  margin: 6px 0 0;
  font-size: 0.92rem;
  white-space: pre-line;
}

.cv-doc__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

/* Layout variants — light differentiation over one clean base. */
.cv-doc--modern .cv-doc__head {
  border-bottom-color: var(--color-primary);
}

.cv-doc--compact {
  gap: 14px;
  padding: 22px;
}

.cv-doc--compact .cv-doc__list {
  gap: 10px;
}

.cv-doc--classic .cv-doc__block h2 {
  color: var(--color-text);
  text-transform: none;
  letter-spacing: 0;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 4px;
}

.cv-doc--classic .cv-doc__title {
  color: var(--color-text);
}

@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, #fff0eb);
  color: var(--connected-accent, #ff592d);
  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;
}

.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: #e7f5ed;
  color: var(--color-success);
}

.co-badge--suspended {
  background: #fdeaea;
  color: var(--color-error);
}

.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;
}

/* ── Creation ───────────────────────────────────────────────────────────── */

.co-create__intro {
  padding: 22px;
}

.co-create__intro h1 {
  margin: 0 0 6px;
  font-size: clamp(1.4rem, 3.5vw, 1.9rem);
}

.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: 0.92rem;
}

.co-create__points i {
  margin-top: 3px;
  color: var(--connected-accent, #ff592d);
}

.co-form-card,
.co-section {
  padding: 20px;
}

.co-form {
  display: grid;
  gap: 14px;
}

.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: 0.8rem;
  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: 0.8rem;
  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: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
}

/* 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;
}

/* 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 {
  display: flex;
  gap: 2px;
  padding: 6px;
  background: var(--pj-card-2, var(--pj-bg));
  border-bottom: 1px solid var(--pj-line);
}

.rte__btn {
  width: 32px;
  height: 32px;
  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));
}

/* 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;
}

.co-gps__hint {
  margin: 6px 0 0;
  font-size: 0.85rem;
}

.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: 0.8rem;
  white-space: nowrap;
}

.wp-menu-check {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 0.85rem;
  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: 0.9rem;
}

.co-hours__row input[type="time"] {
  flex: 1 1 110px;
  min-width: 100px;
}

.co-hours__sep {
  color: var(--color-muted);
  font-size: 0.85rem;
}

.co-hours__hint {
  margin: 4px 0 0;
  font-size: 0.85rem;
}

/* ── 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);
}

/* 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: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pj-muted);
}

.wpnav__group-items {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.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: 0.88rem;
  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: 0.8rem;
  cursor: pointer;
}

.wp-gallery-item__visibility.is-public {
  color: var(--color-primary);
  border-color: var(--color-primary);
}

.mu__empty {
  color: var(--color-muted);
  font-size: 0.875rem;
}

.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: 0.8125rem;
}

.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) — several .mu slots side by side ────────────────── */

.pg__slots {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.pg__slot {
  flex: 0 0 auto;
  max-width: 160px;
}

/* ── 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: 1.2rem;
  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: 0.72rem;
  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: 0.82rem;
  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: 0.82rem;
  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: 1.2rem;
  font-weight: 600;
}

.ml-card__body {
  min-width: 0;
}

.ml-card__title {
  margin: 0 0 4px;
  font-size: 1rem;
  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: 0.875rem;
  /* 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: 0.8125rem;
}

/* ── 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: clamp(1.3rem, 4vw, 1.8rem);
  overflow-wrap: anywhere;
}

.co-space__ident p {
  margin: 2px 0 8px;
  font-size: 0.88rem;
}

.co-space__switcher {
  display: grid;
  gap: 6px;
}

.co-space__switcher label {
  font-size: 0.82rem;
  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: 0.95rem;
}

.co-task__status {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 3px;
  font-size: 0.82rem;
  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: #e7f5ed;
  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: 0.72rem;
  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;
}

.co-section__head h2 {
  margin: 0;
  font-size: 1.15rem;
}

/* 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: 0.86rem;
}

.co-readonly {
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-chip);
  color: var(--chip-ink);
  font-size: 0.76rem;
  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: 0.78rem;
  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);
}

.co-form__subhead {
  margin: 8px 0 0;
  font-size: 0.95rem;
}

/* ── 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: 1.05rem;
}

.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 #f3d2d2;
}

.co-danger h2 {
  margin: 0 0 4px;
  font-size: 1.05rem;
  color: var(--color-error);
}

.co-danger__btn,
.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, #dfe7f2);
  border-radius: var(--radius);
  background: #fbfcfe;
}

.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: 0.84rem;
  overflow-wrap: anywhere;
}

.co-member__role {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.co-member__custom {
  font-size: 0.76rem;
  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, #dfe7f2);
  border-radius: var(--radius);
  background: var(--surface-sunken);
}

.co-rights__frame h3 {
  margin: 0 0 12px;
  font-size: 1rem;
}

.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: 0.84rem;
}

.co-rights__hint {
  margin: 12px 0;
  font-size: 0.86rem;
}

.co-rights__groups {
  display: grid;
  gap: 12px;
}

.co-rights__group {
  margin: 0;
  padding: 12px 14px;
  border: 1px solid var(--connected-border, #dfe7f2);
  border-radius: var(--radius);
  background: var(--color-surface);
}

.co-rights__group legend {
  padding: 0 6px;
  font-size: 0.82rem;
  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: 0.92rem;
  cursor: pointer;
}

.co-rights__perm {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
}

.co-rights__deviation {
  margin-left: auto;
  font-size: 0.72rem;
  font-weight: 700;
  font-style: normal;
  color: var(--color-warning);
  white-space: nowrap;
}

/* ── Invitations ────────────────────────────────────────────────────────── */

.co-invite__heading {
  margin: 20px 0 10px;
  font-size: 1rem;
}

.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, #dfe7f2);
  border-radius: var(--radius);
}

.co-invite-row p {
  margin: 2px 0 0;
  font-size: 0.84rem;
}

.co-invite__empty {
  margin: 0;
  font-size: 0.88rem;
}

.co-invite__link {
  margin-top: 14px;
  padding: 14px;
  border-radius: var(--radius);
  background: var(--connected-accent-soft, #fff0eb);
  display: grid;
  gap: 8px;
}

.co-invite__link p {
  margin: 0;
  font-size: 0.86rem;
}

.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, #fff0eb);
  color: var(--connected-accent, #ff592d);
  font-size: 1.5rem;
}

.co-invitation__card h1 {
  margin: 0;
  font-size: clamp(1.3rem, 4vw, 1.7rem);
}

.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, #dfe7f2);
}

.co-invitation__facts dt {
  font-size: 0.85rem;
  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, #ff592d);
  background: #fafbfd;
  text-align: left;
  font-style: italic;
}

.co-invitation__blocked {
  margin: 0;
  color: var(--color-error);
  font-size: 0.9rem;
}

/* ── 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, #dfe7f2);
  padding-top: 12px;
}

.jo-filters > summary {
  cursor: pointer;
  font-weight: 700;
  font-size: 0.92rem;
  min-height: 44px;
  display: flex;
  align-items: center;
}

.jo-filters__grid {
  display: grid;
  gap: 14px;
  margin: 12px 0;
}

.jo-search__count {
  margin: 0 2px;
  font-size: 0.9rem;
}

.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;
}

.jo-results {
  display: grid;
  gap: 14px;
}

/* Saved searches (M12) --------------------------------------------------- */
.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: 1.05rem;
}

.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: 0.82rem;
}

.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; }

/* 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, #fff0eb);
  color: var(--connected-accent, #ff592d);
  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: 1.05rem;
  overflow-wrap: anywhere;
}

.jo-card__company {
  margin: 2px 0 0;
  font-size: 0.88rem;
  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: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}

.jo-badge--tender {
  background: var(--connected-accent-soft, #fff0eb);
  color: var(--connected-accent, #ff592d);
}

.jo-badge--verified {
  background: #e7f5ed;
  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, #dfe7f2);
  font-size: 0.78rem;
}

.jo-chip--required {
  border-color: #cddcf4;
  background: #f4f8ff;
}

.jo-chip em {
  font-style: normal;
  font-size: 0.7rem;
  color: var(--color-muted);
}

.jo-card__salary {
  margin: 0;
  font-weight: 700;
  font-size: 0.92rem;
}

.jo-card__meta {
  margin: 0;
  font-size: 0.82rem;
}

.jo-empty {
  padding: 28px 22px;
  text-align: center;
}

.jo-empty h2 {
  margin: 0 0 6px;
  font-size: 1.15rem;
}

.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: clamp(1.4rem, 4.5vw, 2rem);
  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: 0.86rem;
}

.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: 0.8rem;
}

.jo-public__block {
  padding: 20px 22px;
}

.jo-public__block h2 {
  margin: 0 0 8px;
  font-size: 1.05rem;
}

.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;
}

/* ── 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: clamp(1.4rem, 3.5vw, 1.9rem);
}

.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, #dfe7f2);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text);
  font-size: 0.88rem;
  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: 1.05rem;
  overflow-wrap: anywhere;
}

.jo-mine-card__meta {
  margin: 2px 0 0;
  font-size: 0.86rem;
}

/* 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: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
}

.jo-status--published {
  background: #e7f5ed;
  color: var(--color-success);
}

.jo-status--pending_payment,
.jo-status--pending_validation {
  background: #fdf3e2;
  color: var(--color-warning);
}

.jo-status--suspended {
  background: #fdeaea;
  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: 0.76rem;
  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, #dfe7f2);
}

.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: clamp(1.3rem, 3.5vw, 1.8rem);
}

.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: #fdf7ec;
}

.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: 1.1rem;
}

.jo-form__grid {
  display: grid;
  gap: 14px;
}

.jo-req {
  color: var(--color-error);
}

.jo-hint {
  display: block;
  margin-top: 4px;
  font-size: 0.8rem;
}

.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: 0.9rem;
  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.
   ═════════════════════════════════════════════════════════════════════════ */

:root {
  --mt-very: #1a8754;
  --mt-very-soft: #e7f4ed;
  --mt-ok: #1a73e8;
  --mt-ok-soft: #e8f0fd;
  --mt-partial: #b7791f;
  --mt-partial-soft: #fdf4e3;
  --mt-low: #6b7280;
  --mt-low-soft: #f1f2f4;
}

/* ── 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, #dfe7f2);
}

.mt-badge__score { font-size: 1.15rem; }
.mt-badge__level { font-size: 0.8rem; font-weight: 500; }

.mt-badge--sm { padding: 3px 10px; }
.mt-badge--sm .mt-badge__score { font-size: 0.95rem; }
.mt-badge--sm .mt-badge__level { font-size: 0.75rem; }

/* ── 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: 1.35rem; }

.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: 1.05rem; }
.mt-card__cv { margin: 2px 0 0; font-size: 0.88rem; }

.mt-card__gap {
  margin: 6px 0 0;
  font-size: 0.85rem;
  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: 1.05rem; }

.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: 0.8rem; }

.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: 0.85rem; }

.mt-skipped {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid var(--connected-border, #dfe7f2);
}

.mt-skipped__title { margin: 0 0 8px; font-size: 0.95rem; }

.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: 0.88rem;
}

.mt-skipped__note { margin: 10px 0 0; font-size: 0.82rem; }

.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: 0.88rem;
  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: 1.1rem; }

.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: 1rem; }
.mt-weights__hint { margin: 0; font-size: 0.85rem; }

.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, #dfe7f2);
  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: 0.82rem; }

.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: 0.78rem; 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, #dfe7f2);
  font-size: 0.9rem;
}

.mt-weights__total strong { font-size: 1.2rem; }

.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, #e2e5ea);
  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: 1rem; }

.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, #e2e5ea);
  border-radius: var(--radius, 10px);
  font-size: 0.88rem;
}

.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: 0.8rem; }

.mt-history__badge {
  grid-column: 2;
  justify-self: start;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--mt-very);
  color: #fff;
  font-size: 0.72rem;
  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.
   ═════════════════════════════════════════════════════════════════════════ */

:root {
  --ap-submitted: #6b7280;
  --ap-submitted-soft: #f1f2f4;
  --ap-viewed: #1a73e8;
  --ap-viewed-soft: #e8f0fd;
  --ap-shortlisted: #7c3aed;
  --ap-shortlisted-soft: #f3ecff;
  --ap-interview: #b7791f;
  --ap-interview-soft: #fdf4e3;
  --ap-hired: #1a8754;
  --ap-hired-soft: #e7f4ed;
  --ap-rejected: #d1373f;
  --ap-rejected-soft: #fdeced;
  --ap-withdrawn: #6b7280;
  --ap-withdrawn-soft: #f1f2f4;
}

/* ── Status chip ────────────────────────────────────────────────────────── */

.ap-status {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--ap-submitted-soft);
  color: var(--ap-submitted);
  font-size: 0.82rem;
  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: 1.05rem; }

.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, #dfe7f2);
  border-radius: 999px;
  background: var(--connected-surface, #fff);
  color: var(--connected-text, #16233b);
  font-size: 0.88rem;
  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: 0.78rem;
}

.ap-tab--active .ap-tab__count { background: rgba(255, 255, 255, 0.22); }

/* ── Apply ──────────────────────────────────────────────────────────────── */

.ap-apply__offer,
.ap-apply__form,
.ap-apply__blocked { padding: 20px 22px; }

.ap-apply__eyebrow {
  margin: 0 0 2px;
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.ap-apply__title { margin: 0 0 4px; font-size: 1.3rem; }
.ap-apply__step { margin: 0 0 4px; font-size: 1.05rem; }
.ap-apply__hint { margin: 0 0 14px; font-size: 0.88rem; }
.ap-apply__counter { margin: 4px 0 0; font-size: 0.8rem; text-align: right; }

.ap-apply__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

.ap-cvs {
  list-style: none;
  margin: 0 0 20px;
  padding: 0;
  display: grid;
  gap: 10px;
}

.ap-cv__label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--connected-border, #dfe7f2);
  border-radius: var(--radius, 10px);
  cursor: pointer;
}

/* The chosen CV is the decision of the screen — it has to be obvious. */
.ap-cv__label:has(input:checked) {
  border-color: var(--connected-primary, #264A78);
  background: var(--connected-accent-soft, #fff0eb);
}

.ap-cv__label input {
  width: 20px;
  height: 20px;
  margin-top: 2px;
  flex: 0 0 20px;
  accent-color: var(--connected-primary, #264A78);
}

.ap-cv__body { display: grid; gap: 2px; }
.ap-cv__name { font-weight: 600; }

.ap-cv__default {
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--ap-hired-soft);
  color: var(--ap-hired);
  font-size: 0.74rem;
  font-style: normal;
  font-weight: 600;
}

.ap-cv__summary { font-size: 0.85rem; }

/* ── 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: 1.3rem; }

.ap-pipeline__eyebrow {
  margin: 0 0 2px;
  font-size: 0.78rem;
  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: 1.05rem; }

.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: 0.86rem; }

.ap-row__gap,
.ap-card__gap {
  margin: 6px 0 0;
  font-size: 0.85rem;
  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: 0.86rem;
  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: 1.1rem; }

.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: 0.8rem; }

/* 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: 0.75rem; }

/* 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: 0.8rem; }

.ap-pipeline__sort {
  display: grid;
  gap: 8px;
}

.ap-pipeline__sort-hint { margin: 0; font-size: 0.8rem; }

.ap-pipeline__truncated {
  margin: 0;
  font-size: 0.8rem;
  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-surface-2, var(--pj-bg));
  border-radius: 4px;
  font-size: 0.85rem;
}

.ap-detail__heading {
  margin: 20px 0 8px;
  font-size: 0.95rem;
}

.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: 0.86rem;
}

.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);
  }

  .ap-apply__form { max-width: 720px; }
}

/* ── 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).
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --pay-initiated: #6b7280; --pay-initiated-soft: #f1f2f4;
  --pay-pending:   #b7791f; --pay-pending-soft:   #fdf4e3;
  --pay-succeeded: #1a8754; --pay-succeeded-soft: #e7f4ed;
  --pay-failed:    #d1373f; --pay-failed-soft:    #fdeaea;
  --pay-cancelled: #6b7280; --pay-cancelled-soft: #f1f2f4;
  --pay-refunded:  #1a73e8; --pay-refunded-soft:  #e8f0fd;
}

/* ── Status pill (used on every payment screen) ─────────────────────────────── */
/* Shared field controls used by the tunnel and the history scope switch. */
.pay-checkout .field__label,
.pay-mine .field__label {
  display: block;
  font-size: 0.85rem;
  font-weight: 600;
  margin-bottom: 6px;
  color: var(--connected-text);
}
.pay-checkout .field__control,
.pay-mine .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,
.pay-mine .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,
.pay-mine { display: grid; gap: 16px; }

.pay-checkout__body { display: grid; gap: 16px; }
.pay-list { display: grid; gap: 12px; }
.pay-loading { padding: 20px 4px; }
.pay-empty { padding: 28px 22px; text-align: center; }
.pay-empty h2 { margin: 0 0 6px; font-size: 1.05rem; }

/* Bare <button> is width:100% in this stylesheet — rows of them opt out. */
.pay-mine__head .btn,
.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. */
.pay-return__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.pay-return__title { margin: 0 0 4px; font-size: 1.15rem; }
.pay-return__result { padding: 28px 22px; text-align: center; }
.pay-return__result h2 { margin: 0 0 6px; font-size: 1.05rem; }
.pay-return__cta { width: auto; }
/* 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;
}
/* ── History header, tabs, rows ─────────────────────────────────────────────── */
.pay-mine__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.pay-mine__title { margin: 0; font-size: 1.3rem; }
.pay-mine__scope-field { min-width: 220px; }

.pay-tabs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 2px;
}
.pay-tab {
  width: auto;
  flex: 0 0 auto;
  padding: 9px 16px;
  min-height: 44px;
  border: 1px solid var(--connected-border);
  border-radius: 999px;
  background: var(--connected-surface);
  color: var(--connected-muted);
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.pay-tab--active {
  background: var(--primary-fill);
  border-color: var(--primary-fill);
  color: #fff;
}

.pay-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 12px 16px;
  align-items: center;
}
.pay-row__title { margin: 0; font-size: 1.02rem; }
.pay-row__meta { margin: 3px 0 0; font-size: 0.85rem; }
.pay-row__instructions {
  margin: 8px 0 0;
  font-size: 0.85rem;
  color: var(--pay-pending);
  background: var(--pay-pending-soft);
  padding: 8px 10px;
  border-radius: 10px;
}
.pay-row__amount { font-weight: 700; white-space: nowrap; }

/* ── 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: 1.2rem;
  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: 1.3rem;
  font-weight: 800;
  color: var(--connected-primary);
}

.bm-form__submit {
  min-height: 44px;
}

.bm-note {
  margin: 0;
  font-size: 0.875rem;
}

/* ── Tunnel: summary, method picker, result ─────────────────────────────────── */
.pay-checkout__title { margin: 0; font-size: 1.3rem; }

.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: 1.3rem; font-weight: 700; color: var(--connected-primary); }
.pay-summary__or { color: var(--connected-muted); font-weight: 500; font-size: 0.95rem; }

/* ── 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: 1.05rem; }
.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: #f7faff;
}
.pay-method--disabled { opacity: 0.55; cursor: not-allowed; }
.pay-method input { width: 20px; height: 20px; flex: 0 0 auto; }
.pay-method__body { display: grid; gap: 2px; }
.pay-method__title { font-weight: 600; }
.pay-method__sub { font-size: 0.85rem; }
.pay-method__warn { font-size: 0.82rem; color: var(--pay-failed); font-weight: 600; }

.pay-form__phone { margin-top: 14px; }
.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: 1.25rem; }
.pay-result__amount { margin: 0 0 10px; font-weight: 600; }
.pay-result__text { margin: 0 auto 16px; max-width: 46ch; }
.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, .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 { 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 {
    position: sticky;
    right: 0;
    z-index: 1;
    background: var(--pj-card, #fff);
    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: 0.8rem;
  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; }

.pa-payer__email { font-size: 0.82rem; }
/* 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 { 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 {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  justify-content: space-between;
  gap: 12px;
  margin-top: 4px;
}

.pa-size {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 600;
}

.pa-size .form-control {
  width: auto;
  min-width: 88px;
}

.pa-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 { font-weight: 600; }

/* ── Mobile: rows and admin tables become stacked cards ─────────────────────── */
@media (max-width: 767px) {
  .pay-row {
    grid-template-columns: 1fr;
    gap: 8px;
  }
  .pay-row__amount, .pay-row__state { justify-self: start; }

  .pc-table thead, .pa-table thead { display: none; }
  .pc-table tr, .pa-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 {
    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 { white-space: normal; }

  .pc-table td::before, .pa-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 { justify-content: flex-end; flex-wrap: wrap; }

  /* 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: 1.3rem; }
.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: 0.82rem;
  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: 1.15rem; }
.sub-state__until { margin: 0; font-weight: 600; }
.sub-state__none { margin: 0; }

/* ── Plan cards ─────────────────────────────────────────────────────────────── */
.sub-plans__title { margin: 4px 0 12px; font-size: 1.1rem; }
.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: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--connected-accent);
}
.sub-plan__name { margin: 0; font-size: 1.05rem; }
.sub-plan__price { margin: 0; font-size: 1.3rem; font-weight: 700; color: var(--connected-primary); }
.sub-plan__days { margin: 0; font-size: 0.85rem; }
.sub-plan__noperm { margin: 6px 0 0; font-size: 0.85rem; }

/* ── 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: 1.05rem; }

/* ── 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: 0.85rem; }
.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: 0.8rem;
  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: #fff4e0; color: #9a6a00; }
.tp-status--validated { background: #e7f5ed; color: var(--color-success); }
.tp-status--needs_correction { background: #e6f4fb; color: #1670a0; }
.tp-status--suspended { background: #fdeaea; color: var(--color-error); }
.tp-status--rejected { background: #f0eef5; color: #5b4b7a; }
.tp-status--archived { background: #f1f3f5; color: #8a94a6; }

.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: #1670a0; }
.tp-banner--rejected { border-left-color: #5b4b7a; }
.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: #fbf7ef;
  border-radius: 8px;
  font-size: 0.9rem;
}
.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.
   ============================================================ */

/* Enrolment & certificate status pills (on top of .ap-status base) */
.te-status--info_request     { background: var(--ap-submitted-soft); color: var(--ap-submitted); }
.te-status--preregistered    { background: var(--ap-viewed-soft);    color: var(--ap-viewed); }
.te-status--awaiting_payment { background: var(--ap-interview-soft); color: var(--ap-interview); }
.te-status--paid             { background: var(--ap-viewed-soft);    color: var(--ap-viewed); }
.te-status--enrolled         { background: var(--ap-hired-soft);     color: var(--ap-hired); }
.te-status--waitlisted       { background: var(--ap-interview-soft); color: var(--ap-interview); }
.te-status--attended         { background: var(--ap-shortlisted-soft); color: var(--ap-shortlisted); }
.te-status--completed        { background: var(--ap-hired-soft);     color: var(--ap-hired); }
.te-status--certified        { background: var(--mt-very-soft);      color: var(--mt-very); }
.te-status--cancelled        { background: var(--ap-withdrawn-soft); color: var(--ap-withdrawn); }
.te-status--refunded         { background: var(--ap-rejected-soft);  color: var(--ap-rejected); }

.te-cert--deposited { background: var(--ap-interview-soft); color: var(--ap-interview); }
.te-cert--accepted  { background: var(--ap-viewed-soft);    color: var(--ap-viewed); }
.te-cert--visible   { background: var(--ap-hired-soft);     color: var(--ap-hired); }
.te-cert--hidden    { background: var(--ap-withdrawn-soft); color: var(--ap-withdrawn); }
.te-cert--revoked   { background: var(--ap-rejected-soft);  color: var(--ap-rejected); }

.te-cert__on { display: inline-flex; align-items: center; gap: 6px; margin-top: 6px; color: var(--color-success); }

/* 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; }

/* Enrol page: session picker + kind radios */
.te-enroll__label { display: block; font-weight: 600; margin-bottom: 8px; }
.te-sessions { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.te-session__label { display: flex; gap: 10px; align-items: flex-start; padding: 12px; border: 1px solid var(--connected-border); border-radius: var(--radius); cursor: pointer; }
.te-session__label:hover { border-color: var(--connected-primary); }
.te-session__body { display: flex; flex-direction: column; gap: 2px; }
.te-session__seats { font-size: 0.82rem; }
.te-session__seats--full { color: var(--color-warning); }
.te-radio { display: inline-flex; align-items: center; gap: 8px; margin-right: 16px; }
.te-enroll__actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.te-enroll__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; }

/* Statistics grid */
/* La section elle-même : l'en-tête et le corps sont deux cartes voisines. */
.te-stats { display: grid; gap: 16px; }
.te-stats__grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px; }
.te-stat { display: flex; flex-direction: column; gap: 2px; padding: 12px; border: 1px solid var(--connected-border); border-radius: var(--radius); }
.te-stat__value { font-size: 1.5rem; font-weight: 700; color: var(--connected-primary); }
.te-stat__label { font-size: 0.82rem; }
.te-stats__block { margin-top: 16px; }
.te-statline { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid var(--connected-border); }
.te-statline:last-child { border-bottom: 0; }

/* Manage drawer certificate lines */
.te-cert-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--connected-border); }
.te-cert-line:last-child { border-bottom: 0; }
.te-cert-line .btn { width: auto; }

/* Fiche additions (M16 public page) */
.tf-enroll-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.tf-enroll-cta .btn { width: auto; }
.tf-reviews__avg { color: var(--color-warning); font-size: 1rem; margin-left: 8px; }
.tf-review { padding: 10px 0; border-bottom: 1px solid var(--connected-border); }
.tf-review:last-child { border-bottom: 0; }
.tf-review__stars { color: var(--color-warning); letter-spacing: 1px; }
.tf-review__comment { margin: 4px 0 0; }

@media (min-width: 640px) {
  .te-stats__grid { grid-template-columns: repeat(3, 1fr); }
}

/* 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: 1.05rem; }
.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: 0.78rem; 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, #d9dee6);
    /* 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: 0.85rem;
    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: #eef1f5; }
.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: 0.8rem; }
.cms-card__cat { background: var(--ap-hired-soft, #e6f4ea); color: var(--connected-primary, #2563eb); border-radius: 4px; padding: 2px 8px; font-weight: 600; }
.cms-card__title { margin: 0; font-size: 1.05rem; line-height: 1.3; }
.cms-card__excerpt { margin: 0; font-size: 0.9rem; }
.cms-card__more { color: var(--connected-primary, #2563eb); font-weight: 600; font-size: 0.85rem; 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: 0.82rem; margin-bottom: 8px; }
.cms-article__title { margin: 0 0 12px; font-size: 1.6rem; line-height: 1.25; }
.cms-article__lead { font-size: 1.05rem; 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: 1.15rem; 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) */
.metier-list__filters { display: flex; flex-wrap: wrap; gap: 10px; }
.metier-list__search { flex: 1 1 220px; min-width: 0; }
.metier-list__sector { flex: 0 1 240px; }
.metier-fiche__grid { display: grid; grid-template-columns: 1fr; gap: 16px; align-items: start; }
.metier-fiche__aside { display: flex; flex-direction: column; gap: 16px; }
.metier-aside__box { padding: 16px; }
.metier-aside__title { font-size: 1rem; margin: 0 0 10px; }
.metier-aside__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.metier-aside__list li { font-size: 0.9rem; line-height: 1.35; }
.metier-aside__list a { color: var(--connected-primary, #2563eb); text-decoration: none; }
.metier-aside__all { display: inline-block; margin-top: 10px; font-weight: 600; font-size: 0.85rem; color: var(--connected-primary, #2563eb); text-decoration: none; }
.metier-section p { margin: 0 0 10px; }

@media (min-width: 1024px) {
    .metier-fiche__grid { grid-template-columns: minmax(0, 1fr) 320px; }
}

/* 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); } }

/* ── Change password (E9-02) ───────────────────────────────────────────
   A short form in a wide column: capped so the three fields stay a form
   rather than becoming a banner. `width: auto` on the buttons is not
   optional — the connected shell makes every bare `<button>` full width,
   so a row of two would otherwise stack into two full-width blocks. */
.cp-card {
  max-width: 560px;
}

.cp-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 18px;
}

.cp-actions .btn {
  width: auto;
}

/* ── /verifier — email et téléphone, variante « compte » ─────────────────
   La variante inscription vit dans la coque d'authentification et n'a besoin
   de rien d'ici ; ces règles ne servent qu'à l'écran atteint depuis le menu
   du compte. `.connected-page` porte déjà le rythme entre les panneaux, et
   `.pj-card` leur padding : il ne reste que l'intérieur d'un panneau. */

.ct-panel__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-bottom: 6px;
}

.ct-panel__head h2 {
  margin: 0;
}

.ct-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: var(--pj-radius-pill);
  font-size: 0.86rem;
  font-weight: 700;
}

.ct-badge--ok {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.ct-badge--todo {
  background: var(--surface-chip);
  color: var(--connected-muted);
}

.ct-current {
  margin: 0 0 18px;
  font-weight: 700;
  word-break: break-word;
}

.ct-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Deux champs côte à côte quand la place existe, l'un sous l'autre sinon —
   `auto-fit` répond sur la largeur du conteneur, pas sur celle du viewport,
   ce qui tient aussi quand la carte est imbriquée. */
.ct-form > .field {
  min-width: 0;
}

.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 {
  width: auto;
}

.ct-confirm {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--pj-line);
}

.ct-sent {
  margin: 0 0 14px;
  color: var(--connected-muted);
}

/* ── 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: 1.5rem;
  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: 1.4rem;
  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);
}

.ph-tab {
  width: auto;
  min-height: 44px;
  padding: 10px 14px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: none;
  color: var(--pj-muted);
  font-weight: 600;
  cursor: pointer;
}

.ph-tab:hover {
  color: var(--pj-ink);
}

.ph-tab.is-active {
  border-bottom-color: var(--pj-orange-fill);
  color: var(--pj-orange-text);
}

@media (min-width: 768px) {
  .ph-cover {
    height: 180px;
  }

  /* From here the identity is a row: portrait, then text, then the actions
     pushed to the far end. */
  .ph-identity {
    flex-direction: row;
    align-items: flex-end;
    padding: 0 24px 20px;
    text-align: left;
  }

  .ph-avatar {
    width: 128px;
    height: 128px;
    margin-top: -64px;
  }

  .ph-identity__text {
    padding-bottom: 4px;
  }

  .ph-actions {
    justify-content: flex-end;
    margin-left: auto;
  }

  .ph-tabs {
    padding: 0 16px;
  }
}

/* ── /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, action underneath — and the
   768px query turns it into the mockup's four-column line. */
.pf-rows {
  padding: 4px 0;
}

.pf-row {
  display: grid;
  grid-template-columns: 28px 1fr;
  align-items: center;
  gap: 4px 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--pj-line);
}

.pf-row:last-child {
  border-bottom: 0;
}

.pf-row__icon {
  color: var(--pj-muted);
  text-align: center;
}

.pf-row__label {
  color: var(--pj-muted);
}

.pf-row__value {
  grid-column: 2;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* `button, .btn { width: 100% }` applies in the connected shell, and a grid
   item needs `justify-self` on top of `width: auto` to stop stretching
   (CLAUDE.md §9). 44px is the measured tap target. */
.pf-row__edit,
.pf-row__actions .btn {
  width: auto;
  min-height: 44px;
  justify-self: start;
}

.pf-row__lock {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  grid-column: 2;
  color: var(--pj-muted);
  font-size: 0.85rem;
}

.pf-row.is-editing {
  background: var(--pj-card-2);
}

.pf-row__form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  grid-column: 2;
}

.pf-row__form .form-control {
  flex: 1 1 180px;
  min-width: 0;
}

.pf-row__form .form-text {
  flex: 1 0 100%;
}

.pf-row__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  grid-column: 2;
}

.pf-row__error {
  grid-column: 2;
  margin: 0;
  color: var(--pj-orange-text);
  font-size: 0.85rem;
}

@media (min-width: 768px) {
  .pf-row {
    grid-template-columns: 28px minmax(140px, 200px) minmax(0, 1fr) auto;
    gap: 8px 16px;
  }

  .pf-row__value,
  .pf-row__lock {
    grid-column: auto;
  }

  .pf-row__form {
    grid-column: 3;
  }

  .pf-row__actions {
    grid-column: 4;
  }

  .pf-row__error {
    grid-column: 3 / -1;
  }
}

/* ── /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: 0.85rem;
}

.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;
}

@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: 1.8rem;
  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: 1.35rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.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: 0.8rem;
  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: 0.85rem;
}

.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: 1.05rem;
}

.pe-block__text {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* 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: 0.85rem;
  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: 0.85rem;
}

.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;
}

.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: 1.4rem;
  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: 0.8rem;
  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: 1.05rem;
}

/* 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: 0.85rem;
  overflow-wrap: anywhere;
}

.sr-group__rest {
  margin: 10px 0 0;
  font-size: 0.85rem;
}

/* ================================================================== *
 * 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 ---------------------------------------------------- */

.ads-filters__row {
    display: grid;
    gap: 12px;
    grid-template-columns: 1fr;
}

.ads-filters__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
}

/* 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-filters__actions .btn,
.ads-wizard-actions .btn,
.ads-pagination .btn,
.ads-action {
    width: auto;
}

.ads-card {
    cursor: pointer;
}

.ads-card__head {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: flex-start;
    justify-content: space-between;
}

.ads-card__title {
    font-size: 17px;
    margin: 0 0 4px;
}

.ads-card__meta {
    color: var(--pj-muted);
    display: flex;
    flex-wrap: wrap;
    font-size: 13px;
    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: 12px;
    font-weight: 500;
}

.ads-card__kpis dd {
    font-size: 18px;
    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: 12px;
    font-weight: 600;
    padding: 4px 12px;
    white-space: nowrap;
}

.ads-badge--ok      { background: var(--pj-orange-soft); color: var(--pj-orange-text); }
.ads-badge--warn    { background: var(--pj-card-2); color: var(--pj-ink); }
.ads-badge--bad     { background: var(--pj-navy); color: var(--pj-card); }
.ads-badge--neutral { background: var(--pj-card-2); color: var(--pj-muted); }

.ads-progress__bar {
    background: var(--pj-card-2);
    border-radius: var(--pj-radius-pill);
    height: 6px;
    margin-top: 14px;
    overflow: hidden;
}

.ads-progress__bar span {
    background: var(--pj-orange-fill);
    display: block;
    height: 100%;
}

.ads-progress__label,
.ads-hint {
    color: var(--pj-muted);
    font-size: 13px;
    margin: 6px 0 0;
}

.ads-empty {
    color: var(--pj-muted);
    padding: 24px 0;
    text-align: center;
}

.ads-pagination {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.ads-pagination .is-current {
    background: var(--pj-orange-fill);
    color: var(--pj-card);
}

/* --- l'assistant -------------------------------------------------- */

.ads-steps {
    display: grid;
    gap: 8px;
    grid-template-columns: 1fr;
    list-style: none;
    margin: 0;
    padding: 0;
}

.ads-steps li {
    align-items: center;
    background: var(--pj-card);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    color: var(--pj-muted);
    display: flex;
    gap: 10px;
    padding: 10px 14px;
}

.ads-steps li span {
    align-items: center;
    background: var(--pj-card-2);
    border-radius: 50%;
    display: flex;
    flex: 0 0 26px;
    height: 26px;
    justify-content: center;
    font-size: 13px;
    font-weight: 700;
}

.ads-steps li.is-current { border-color: var(--pj-orange-fill); color: var(--pj-ink); }
.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); }

.ads-formats,
.ads-forfaits {
    display: grid;
    gap: 12px;
    grid-template-columns: 1fr;
    margin: 16px 0;
}

.ads-format,
.ads-forfait {
    background: var(--pj-card);
    border: 1px solid var(--pj-line);
    border-radius: var(--pj-radius-sm);
    display: flex;
    flex-direction: column;
    gap: 4px;
    /* Bien au-delà des 44px tactiles du projet : le padding seul en
       fait 32, le contenu porte le reste. */
    padding: 16px;
    text-align: left;
    width: 100%;
}

.ads-format.is-picked,
.ads-forfait.is-picked {
    border-color: var(--pj-orange-fill);
    box-shadow: var(--pj-shadow-sm);
}

.ads-format small,
.ads-forfait small {
    color: var(--pj-muted);
    font-size: 12px;
}

/* Où l'emplacement s'affiche réellement, dit avant l'achat plutôt que
   découvert après. Un acheteur qui choisit « Bannière verticale » et la
   cherche dans le rail connecté conclut que la plateforme est cassée. */
.ads-format__where {
    color: var(--pj-muted);
    font-size: 12px;
    font-style: normal;
    line-height: 1.45;
    margin-top: 4px;
}

.ads-forfait.is-unavailable {
    opacity: .55;
}

.ads-forfait__price {
    font-size: 17px;
    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: 13px;
    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: 12px;
}

.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: 12px;
}

.ads-history p {
    color: var(--pj-muted);
    font-size: 13px;
    margin: 4px 0 0;
}

.ads-list-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* --- 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: 12px;
    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: 12px;
    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-filters__row  { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ads-card__kpis    { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .ads-summary       { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ads-steps         { grid-template-columns: repeat(4, 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-filters__row  { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .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: 13px;
    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: 15px;
    margin: 0;
}

.ads-reach__count strong {
    font-size: 26px;
    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: 13px;
    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: 13px;
    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: 0.82rem;
    line-height: 1.5;
    color: var(--pj-muted);
}

/* 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: 12px;
}

/* 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: 13px;
    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: 12px;
    /* 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: 12px;
}

.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: 12px;
}

.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;
}

.ads-consent {
    align-items: flex-start;
    display: flex;
    font-size: 13px;
    gap: 10px;
    margin: 0;
}

.ads-consent input {
    flex: 0 0 auto;
    margin-top: 2px;
    min-height: 20px;
    min-width: 20px;
}

@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: 13px;
    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: 15px;
    font-weight: 600;
    margin: 0;
}

.ma-card__state {
    border-radius: var(--pj-radius-pill);
    flex: 0 0 auto;
    font-size: 11px;
    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: 12px;
    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: 11px;
    font-weight: 400;
    margin: 0;
}

.ma-card__facts dd {
    font-size: 13px;
    margin: 0;
    overflow-wrap: anywhere;
}

.ma-card__miles {
    font-size: 18px;
    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: 11px;
    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: 13px;
    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: 12px;
}
/* =====================================================================
   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: 1.05rem;
    font-weight: 700;
    color: var(--pj-navy);
    margin: 0 0 12px;
}

/* ---- La jauge de miles cumulés ---- */

.gr-meter { margin-top: 16px; }

.gr-meter__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.gr-meter__label { font-size: .85rem; color: var(--pj-muted); }

.gr-meter__value {
    font-size: 1.6rem;
    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: .85rem; 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: .85rem; color: var(--pj-muted); }
.gr-level__gap { font-size: .85rem; 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: .8rem;
    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: .95rem; 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: .85rem; 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: .9rem; }

/* ---- Ma zone ---- */

.gr-term__date {
    margin: 0;
    font-size: 1.4rem;
    font-weight: 800;
    color: var(--pj-navy);
    font-variant-numeric: tabular-nums;
}

.gr-term__note { margin: 4px 0 0; font-size: .88rem; 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; }

.gr-rights__state { margin: 0; font-weight: 700; }
.gr-rights__state.is-ok { color: var(--pj-blue); }
.gr-rights__state.is-pending { color: var(--pj-orange-text); }
.gr-rights__note { margin: 6px 0 0; font-size: .88rem; color: var(--pj-muted); }

.gr-rights__list {
    margin: 12px 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 6px;
    font-size: .88rem;
    color: var(--pj-ink);
}

/* ---- 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: .85rem;
    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: .82rem; color: var(--pj-muted); }
.gr-deleg__btn { width: auto; min-height: 44px; }

.gr-invite { display: grid; gap: 12px; }
.gr-invite__hint { margin: 4px 0 0; font-size: .8rem; 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: .82rem; 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: .82rem; color: var(--pj-muted); }
.gr-admin__miles { display: flex; gap: 8px; align-items: baseline; font-size: .85rem; 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: .85rem; 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: .75rem;
    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: .95rem; font-weight: 700; color: var(--pj-navy); }
.gr-where__btn { width: auto; min-height: 44px; justify-self: start; }
.gr-level.is-picked { border-color: var(--pj-orange); box-shadow: var(--pj-shadow-sm); }
/* ── 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: 0.85rem;
  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: 0.85rem;
  margin: 8px 0 0;
}

.zf-scope__label {
  font-size: 0.85rem;
  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: 1rem;
}

.zf-line__meta,
.zf-line__note {
  color: var(--pj-muted);
  font-size: 0.85rem;
}

/* 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: 0.8rem;
}

.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: 1.1rem;
  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: 0.8rem;
  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: 0.8rem;
  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);
}

.zf-btn--validated {
  background: var(--pj-navy);
  color: var(--pj-card);
}

.zf-btn--correction {
  background: var(--pj-orange-soft);
  color: var(--pj-orange-text);
}

.zf-btn--rejected {
  background: var(--pj-orange-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: 1rem;
  margin: 0;
}

.zf-presets__card .btn {
  justify-self: start;
  min-height: 44px;
  width: auto;
}

.zf-presets__lever {
  display: grid;
  gap: 4px;
  font-size: 0.85rem;
}

.zf-presets__figure {
  color: var(--pj-ink);
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0;
}

.zf-presets__result {
  display: grid;
  gap: 2px;
  margin: 0;
}

.zf-presets__result dt {
  color: var(--pj-muted);
  font-size: 0.8rem;
  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));
  }
}