/* ==========================================================================
   NG Business — design system stylesheet
   Single vendored file, no build step. See DESIGN.md for the spec.

   Layer order is declared once here so later chunks slot in without
   specificity fights:
     tokens      — :root custom properties (this chunk)
     base        — element defaults, reset, a11y floor (this chunk)
     components  — buttons, forms, chips, tables        (chunk 3)
     public      — the branded client surface           (chunk 4)
     agent       — the neutral staff surface            (chunk 5)
     auth        — login / OTP / password screens       (chunk 6)
     utilities   — single-purpose helpers, always last
   ========================================================================== */

@layer tokens, base, components, public, agent, auth, utilities;

/* --------------------------------------------------------------------------
   Fonts — self-hosted, latin subset. woff2 only (DESIGN.md §1, §3).
   url() is relative to this file: /static/common/app.css -> fonts/…
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "IBM Plex Sans";
  src: url("fonts/ibm-plex-sans-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans";
  src: url("fonts/ibm-plex-sans-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("fonts/ibm-plex-mono-500.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* Landing page faces (mockups money3 / moneyPhone3). Both are variable
   fonts, latin subset, SIL OFL — the same files Google Fonts serves, vendored
   so the CSP's font-src 'self' holds. Bricolage carries opsz 12–96 + wght
   200–800; JetBrains Mono carries wght 400–800. */
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("fonts/bricolage-grotesque-latin.woff2") format("woff2");
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono-latin.woff2") format("woff2");
  font-weight: 400 800;
  font-style: normal;
  font-display: swap;
}
/* Landing type system — Inter, the variable font Google Fonts serves (latin
   subset, SIL OFL): wght 100–900 + opsz 14–32, so large sizes pick up its
   display cut automatically (font-optical-sizing: auto). Vendored for the
   same CSP reason as above. */
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   Tokens (DESIGN.md §2–§4). Light values only in this chunk; the dark block
   is a second set of values added in chunk 2, not a rewrite.
   -------------------------------------------------------------------------- */

@layer tokens {
  :root {
    /* §2.1 Brand — black on yellow, always. Never white on the yellow. */
    --brand:        #FFD028;   /* NG Business yellow (warmer than WU) */
    --brand-ink:    #111111;   /* text + buttons ON brand — always black */
    --brand-deep:   #3A2F00;   /* muted body copy on brand */

    /* §2.2 Neutrals — the agent surface and the light-mode base.
       Structure comes from borders, not shadows. */
    --paper:        #FFFFFF;   /* page background */
    --surface:      #FFFFFF;   /* panels, cards */
    --surface-alt:  #F7F7F8;   /* zebra rows, subtle fills */
    --ink:          #111111;   /* primary text */
    --ink-muted:    #111111;   /* secondary text, labels — black, not gray (clashed with brand yellow) */
    --line:         #111111;   /* hairline borders — black, not gray */
    --line-strong:  #000000;   /* emphasized dividers — pure black */

    /* §2.3 Status — functional, not decorative. Never colour alone.
       Each has a matching tint that carries its text at full contrast. */
    /* Chip fg/bg pairs are all >= 4.5:1 in both themes (verified §8). */
    --status-new:       #B45309;  /* CLAIMED  — amber = act on me */
    --status-new-bg:    #FDF6EE;
    --status-go:        #15803D;  /* CONFIRMED — code issued */
    --status-go-bg:     #EAF7F0;
    --status-stop:      #B91C1C;  /* REJECTED (PaymentClaim) / CANCELLED */
    --status-stop-bg:   #FBE9E8;
    --status-done:      #556070;  /* PAID_OUT — settled, de-emphasised */
    --status-done-bg:   #EDF0F3;
    --status-quoted:    #475569;  /* QUOTED — waiting on the client */
    --status-quoted-bg: #EBEEF2;

    /* §2.4 New-claim highlight — pale brand tint on the newest pending row */
    --highlight-new: #FFF8E0;

    /* §3 Type */
    --font-sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

    /* §4 Spacing — 4px base scale. Use the tokens, don't invent values. */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
    --space-8: 64px;

    --radius:      8px;    /* controls, inputs, buttons */
    --radius-card: 12px;   /* cards, panels */
    --radius-pill: 999px;  /* public CTA buttons only */

    /* Non-spec conveniences used by the base frame */
    --page-max:    1100px;
    --prose-max:   66ch;   /* ~70 chars for prose (§3) */

    color-scheme: light;

    /* --- Public palette (mockups money3/5, moneyPhone3/5) --------------
       The redesigned public pages: the homepage and the quote → claim flow.
       Light-only, like the brand tokens: these pages have no dark variant,
       so none of these are remapped below. */
    --pub-lime:        #c6e86b;  /* primary CTA, logo dot, accents */
    --pub-lime-soft:   rgba(198, 232, 107, 0.35);
    --pub-go:          #62941a;  /* phone "Commencer" button */
    --pub-go-hover:    #557f14;
    --pub-go-shadow:   rgba(98, 148, 26, 0.28);
    --pub-go-ring:     rgba(98, 148, 26, 0.14);   /* focused field */
    --pub-lime-dark:   #7a9c2e;  /* step labels, field icons */
    --pub-lime-ring:   rgba(198, 232, 107, 0.55); /* active step node */
    --pub-lime-wash:   rgba(198, 232, 107, 0.38); /* "being verified" card top */
    --pub-error:       #b91c1c;  /* field + form errors (light-only) */
    --pub-error-bg:    #fbe9e8;
    --pub-sun:         #ffe27a;  /* coins, yellow tile */
    --pub-sun-soft:    rgba(255, 226, 122, 0.25);
    --pub-ink:         #10160a;  /* text, nav bar, dark card cell */
    --pub-card:        #f4f6ee;  /* page background */
    --pub-panel:       #eef1e6;  /* steps, features, FAQ, inputs */
    --pub-line:        #e4e8d9;  /* input + tile borders */
    --pub-line-soft:   #e2e6d6;  /* secondary button border */
    --pub-muted:       #6b7462;  /* body copy, labels */
    --pub-nav-link:    #d6dcc9;  /* nav links on the ink bar */
    --pub-nav-btn:     #2a3620;  /* "Connexion" pill on the ink bar */
    --pub-sky:         #cfe4ff;  /* card cell */
    --pub-coral:       #f08a5d;  /* illustration figure */
    --pub-white:       #ffffff;
    --pub-clear:       rgba(255, 255, 255, 0);
    --pub-shine:       rgba(255, 255, 255, 0.7);
    --pub-panel-shadow: rgba(0, 0, 0, 0.05);
    --pub-font: "Bricolage Grotesque", system-ui, -apple-system, "Segoe UI", sans-serif;
    --pub-mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
    --pub-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif; /* landing */
    --pub-pebble:      #868685;  /* landing input border (3.6:1 on white) */
    /* Landing app mockup (phone screen in the transfer panel) */
    --pub-app-edge:    #3a4630;  /* phone frame highlight */
    --pub-app-screen:  #0b0f07;  /* phone screen */
    --pub-app-island:  #000000;  /* dynamic-island notch */
    --pub-app-glow:    rgba(198, 232, 107, 0.22);
    --pub-app-tint-1:  rgba(255, 255, 255, 0.06);  /* transaction rows */
    --pub-app-tint-2:  rgba(255, 255, 255, 0.08);  /* row icons, frame edge */
    --pub-app-tint-3:  rgba(255, 255, 255, 0.1);   /* header icon buttons */
    --pub-ink-clear:   rgba(16, 22, 10, 0);        /* --pub-ink at 0 alpha */
    /* Landing footer (ink band) */
    --pub-foot-dim:    #9aa38d;  /* small print + sub-labels on ink */
    --pub-foot-line:   rgba(255, 255, 255, 0.1);   /* dividers + outlines on ink */

    /* --- Dark palette (DESIGN.md §6) -----------------------------------
       Defined once here; the two selectors below only remap the live
       tokens to these. Neutrals invert. Status colours SHIFT lighter,
       they do not invert — each still has to hold contrast on a dark
       surface. Brand tokens are deliberately NOT remapped: the yellow
       block has no dark variant. */
    --dark-paper:        #14161A;
    --dark-surface:      #1B1E24;
    --dark-surface-alt:  #23272E;
    --dark-ink:          #ECEDEE;
    --dark-ink-muted:    #ECEDEE;   /* full-contrast, not muted gray — mirrors light theme */
    --dark-line:         #2E333B;
    --dark-line-strong:  #3D444E;

    --dark-status-new:       #F4B366;
    --dark-status-new-bg:    #38290F;
    --dark-status-go:        #5FD08A;
    --dark-status-go-bg:     #123021;
    --dark-status-stop:      #F0908A;
    --dark-status-stop-bg:   #3A1B19;
    --dark-status-done:      #9AA6B4;
    --dark-status-done-bg:   #262B32;
    --dark-status-quoted:    #AEB9C6;
    --dark-status-quoted-bg: #22272F;

    --dark-highlight-new:    #2C2812;
  }

  /* Follow the OS setting unless the visitor pinned "light" via the toggle. */
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      color-scheme: dark;
      --paper:        var(--dark-paper);
      --surface:      var(--dark-surface);
      --surface-alt:  var(--dark-surface-alt);
      --ink:          var(--dark-ink);
      --ink-muted:    var(--dark-ink-muted);
      --line:         var(--dark-line);
      --line-strong:  var(--dark-line-strong);
      --status-new:       var(--dark-status-new);
      --status-new-bg:    var(--dark-status-new-bg);
      --status-go:        var(--dark-status-go);
      --status-go-bg:     var(--dark-status-go-bg);
      --status-stop:      var(--dark-status-stop);
      --status-stop-bg:   var(--dark-status-stop-bg);
      --status-done:      var(--dark-status-done);
      --status-done-bg:   var(--dark-status-done-bg);
      --status-quoted:    var(--dark-status-quoted);
      --status-quoted-bg: var(--dark-status-quoted-bg);
      --highlight-new:    var(--dark-highlight-new);
    }
  }

  /* Manual override wins in both directions. Same remap as above — the
     media query can't be folded into a selector list, so this list is
     duplicated on purpose; the values it points at live once, above. */
  :root[data-theme="dark"] {
    color-scheme: dark;
    --paper:        var(--dark-paper);
    --surface:      var(--dark-surface);
    --surface-alt:  var(--dark-surface-alt);
    --ink:          var(--dark-ink);
    --ink-muted:    var(--dark-ink-muted);
    --line:         var(--dark-line);
    --line-strong:  var(--dark-line-strong);
    --status-new:       var(--dark-status-new);
    --status-new-bg:    var(--dark-status-new-bg);
    --status-go:        var(--dark-status-go);
    --status-go-bg:     var(--dark-status-go-bg);
    --status-stop:      var(--dark-status-stop);
    --status-stop-bg:   var(--dark-status-stop-bg);
    --status-done:      var(--dark-status-done);
    --status-done-bg:   var(--dark-status-done-bg);
    --status-quoted:    var(--dark-status-quoted);
    --status-quoted-bg: var(--dark-status-quoted-bg);
    --highlight-new:    var(--dark-highlight-new);
  }
}

/* --------------------------------------------------------------------------
   Base — element defaults and the accessibility floor (DESIGN.md §8).
   -------------------------------------------------------------------------- */

@layer base {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  html {
    -webkit-text-size-adjust: 100%;
  }

  body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: 16px;              /* §3 — min 16px, clients on phones outdoors */
    line-height: 1.5;
    font-weight: 400;
    -webkit-font-smoothing: antialiased;
  }

  img,
  svg {
    max-width: 100%;
    height: auto;
  }

  /* Headings — sentence case, weights 400/500 only, nothing heavier (§3). */
  h1, h2, h3, h4, h5, h6 {
    margin: 0 0 var(--space-3);
    font-weight: 500;
    line-height: 1.25;
    text-wrap: balance;
  }
  h1 { font-size: 1.625rem; }
  h2 { font-size: 1.25rem; }
  h3 { font-size: 1.0625rem; }
  h4, h5, h6 { font-size: 1rem; }

  p {
    margin: 0 0 var(--space-4);
    max-width: var(--prose-max);
  }

  a {
    color: var(--ink);
    text-decoration: underline;
    text-decoration-color: var(--brand);
    text-decoration-thickness: 2px;
    text-underline-offset: 2px;
  }
  a:hover {
    text-decoration-color: var(--ink);
  }

  /* Visible keyboard focus on every interactive element — never removed
     without a replacement (§8). */
  :focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 2px;
    border-radius: 2px;
  }

  /* Respect users who ask for no motion (§8). */
  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      animation-duration: 0.01ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.01ms !important;
      scroll-behavior: auto !important;
    }
  }

  /* --- minimal page frame -------------------------------------------------
     Real surface styling (hero, dense agent rows) lands in chunks 4–5.
     This is only enough that pages aren't raw while the system is built. */

  .site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--line);
    background: var(--surface);
  }
  .site-header form {
    margin: 0;
  }
  .site-header__actions {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
  }

  /* Server-rendered dark-mode switch (DESIGN.md §6). A plain segmented
     control of submit buttons — no JS. */
  .theme-form {
    display: flex;
    align-items: center;
    gap: var(--space-1);
  }
  .theme-form__label {
    color: var(--ink-muted);
    font-size: 0.8125rem;
    margin-right: var(--space-1);
  }
  .theme-form button {
    font: inherit;
    font-size: 0.8125rem;
    padding: var(--space-1) var(--space-2);
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
    cursor: pointer;
  }
  .theme-form button + button {
    margin-left: -1px;
  }
  .theme-form button[aria-pressed="true"] {
    background: var(--ink);
    color: var(--surface);
    border-color: var(--ink);
  }

  .site-brand {
    font-weight: 500;
    text-decoration: none;
    color: var(--ink);
    white-space: nowrap;
  }
  .site-brand::before {
    content: "";
    display: inline-block;
    width: 0.75em;
    height: 0.75em;
    margin-right: 0.5em;
    border-radius: 3px;
    background: var(--brand);
    vertical-align: baseline;
  }

  .site-main {
    flex: 1;
    width: 100%;
    max-width: var(--page-max);
    margin-inline: auto;
    padding: var(--space-5) var(--space-4);
  }

  /* Skip link — visually hidden until focused (§8). Ink ground so it reads
     against any surface, brand or neutral. */
  .skip-link {
    position: absolute;
    z-index: 10;
    left: var(--space-2);
    top: var(--space-2);
    padding: var(--space-2) var(--space-3);
    background: var(--ink);
    color: var(--paper);
    border-radius: var(--radius);
    text-decoration: none;
    transform: translateY(-150%);
  }
  .skip-link:focus {
    transform: translateY(0);
  }

  /* --- form errors and notices -----------------------------------------
     Retires the inline style="color:#b00" spans (DESIGN.md §1). Text
     colour is never the only signal — the message itself names the problem
     and the field is marked. Fuller form styling is chunk 3. */

  .field-error {
    display: block;
    margin-top: var(--space-1);
    color: var(--status-stop);
    font-size: 0.875rem;
  }

  .alert--warning {
    margin: 0 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    max-width: var(--prose-max);
    border-left: 3px solid var(--status-new);
    background: var(--status-new-bg);
    color: var(--ink);
    border-radius: var(--radius);
  }

  /* django.contrib.messages — rendered once from base.html. */
  .messages {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: grid;
    gap: var(--space-2);
  }
  .notice {
    padding: var(--space-3) var(--space-4);
    border-left: 3px solid var(--line-strong);
    background: var(--surface-alt);
    color: var(--ink);
    border-radius: var(--radius);
  }
  .notice--success { border-left-color: var(--status-go);   background: var(--status-go-bg); }
  .notice--warning { border-left-color: var(--status-new);  background: var(--status-new-bg); }
  .notice--error   { border-left-color: var(--status-stop); background: var(--status-stop-bg); }
}

/* --------------------------------------------------------------------------
   Components — buttons, form controls, status chips, tables + card switcher.
   Surface-agnostic here; the public/agent layers only re-skin (chunks 4–5).
   -------------------------------------------------------------------------- */

@layer components {

  /* --- Buttons (DESIGN.md §7.1) --------------------------------------
     Default target is 44px (public). Agent rows add .btn--sm (32px).
     A destructive action must read as deliberate — never the same weight
     as the affirmative button beside it, so .btn--danger is outlined. */
  .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 44px;
    padding: var(--space-2) var(--space-5);
    font: inherit;
    font-weight: 500;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: transparent;
    color: var(--ink);
    cursor: pointer;
  }
  .btn:disabled,
  .btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
  }

  .btn--primary {
    background: var(--ink);
    color: var(--paper);
    border-color: var(--ink);
  }
  .btn--secondary {
    background: transparent;
    color: var(--ink);
    border-color: var(--line-strong);
  }
  .btn--danger {
    background: transparent;
    color: var(--status-stop);
    border-color: var(--status-stop);
    font-weight: 400;
  }

  /* Black pill on brand — public CTA, one per screen (§5.1). Wired here,
     applied to the quote/claim submits in chunk 4. */
  .btn--public-primary {
    background: var(--brand-ink);
    color: var(--brand);
    border-color: var(--brand-ink);
    border-radius: var(--radius-pill);
    padding-inline: var(--space-6);
  }

  .btn--sm {
    min-height: 32px;
    padding: var(--space-1) var(--space-3);
    font-size: 0.875rem;
  }
  .btn--block {
    display: flex;
    width: 100%;
  }

  /* --- Form controls (DESIGN.md §7.2) ------------------------------------
     Scoped to .site-main so Django's class-less widgets pick this up with
     no template change, and the header's own controls are untouched. */
  .site-main label {
    display: block;
    font-weight: 500;
    margin-bottom: var(--space-1);
  }
  .site-main input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]):not([type="submit"]),
  .site-main select,
  .site-main textarea {
    display: block;
    width: 100%;
    max-width: 28rem;
    min-height: 44px;
    padding: var(--space-2) var(--space-3);
    font: inherit;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius);
  }
  .site-main input:focus,
  .site-main select:focus,
  .site-main textarea:focus {
    border-color: var(--ink);
  }
  /* Money amounts, payout/OTP codes and operator references are read
     character-by-character — fixed width genuinely helps (§3, §7.2). */
  .site-main #id_receiver_amount,
  .site-main #id_amount_claimed,
  .site-main #id_amount,
  .site-main #id_code,
  .site-main #id_operator_ref {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
  }
  /* Per-field paragraph spacing (templates wrap each field in <p>). */
  .site-main form p {
    margin-bottom: var(--space-4);
  }
  .form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-5);
  }

  /* --- Status chips (DESIGN.md §2.3, §7.4) -----------------------------
     Tint background + darker text from the same family + the word. Never
     colour alone. Two sizes: rows (default) and detail views (.chip--lg). */
  .chip {
    display: inline-block;
    padding: 2px var(--space-2);
    font-size: 0.8125rem;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
    border-radius: var(--radius);
  }
  .chip--lg {
    font-size: 0.9375rem;
    padding: var(--space-1) var(--space-3);
  }
  .chip--new    { background: var(--status-new-bg);    color: var(--status-new); }
  .chip--go     { background: var(--status-go-bg);     color: var(--status-go); }
  .chip--stop   { background: var(--status-stop-bg);   color: var(--status-stop); }
  .chip--done   { background: var(--status-done-bg);   color: var(--status-done); }
  .chip--quoted { background: var(--status-quoted-bg); color: var(--status-quoted); }

  /* --- Data table (DESIGN.md §7.3) -----------------------------------
     One <table class="data-table"> per list. On wide screens it is a
     table; below 640px each <tr> becomes a card (label/value pairs from
     td[data-label]). One DOM, no JS, no dual render — so an HTMX row swap
     (hx-swap="outerHTML" on a <tr>) works at every width. */
  .data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
  }
  .data-table th,
  .data-table td {
    padding: var(--space-2) var(--space-3);
    text-align: left;
    border-bottom: 1px solid var(--line);
    vertical-align: top;
  }
  .data-table th {
    font-weight: 500;
    color: var(--ink-muted);
    border-bottom-color: var(--line-strong);
  }
  .data-table--zebra tbody tr:nth-child(even) {
    background: var(--surface-alt);
  }
  .data-table .num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  .data-table .mono {
    font-family: var(--font-mono);
  }
  .data-table tbody tr.is-new {
    background: var(--highlight-new);
  }
  .data-table__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
  }
  .data-table__empty {
    padding: var(--space-4) var(--space-3);
    color: var(--ink-muted);
  }

  /* Primary cell — the operator reference is the row's anchor: the collector
     verifies it against their operator account before confirming. Mono and
     larger, with the operator name muted directly beneath. */
  .data-table__primary .ref {
    font-family: var(--font-mono);
    font-size: 1rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--ink);
    word-break: break-all; /* operator_ref is up to 128 chars */
  }
  .data-table__sub {
    display: block;
    margin-top: 2px;
    font-size: 0.8125rem;
    font-weight: 400;
    color: var(--ink-muted);
  }
  .data-table td.amount {
    font-weight: 500;
    color: var(--ink);
  }
  .data-table__meta {
    color: var(--ink-muted);
    font-size: 0.875rem;
  }

  /* New pending claims: an amber left rule ("act on me", DESIGN.md §2.3) on
     top of the existing --highlight-new row tint. */
  .data-table tbody tr.is-new td:first-child {
    border-left: 3px solid var(--status-new);
  }

  @media (max-width: 640px) {
    .data-table,
    .data-table thead,
    .data-table tbody,
    .data-table tr,
    .data-table td {
      display: block;
      width: 100%;
    }
    .data-table thead {
      /* header labels move onto each cell via data-label */
      position: absolute;
      clip: rect(0 0 0 0);
      overflow: hidden;
      height: 1px;
      width: 1px;
    }
    .data-table tbody tr {
      margin-bottom: var(--space-3);
      border: 1px solid var(--line);
      border-radius: var(--radius-card);
      padding: var(--space-2);
      background: var(--surface);
    }
    .data-table tbody tr.is-new {
      border-color: var(--status-new);
    }
    .data-table td {
      display: flex;
      justify-content: space-between;
      gap: var(--space-4);
      border: 0;
      padding: var(--space-1) var(--space-2);
      text-align: right;
    }
    .data-table td::before {
      content: attr(data-label);
      color: var(--ink-muted);
      text-align: left;
      font-weight: 400;
    }
    .data-table td.num {
      text-align: right;
    }
    /* The operator reference leads the card as a heading, not a label/value row. */
    .data-table td.data-table__primary {
      display: block;
      text-align: left;
      padding-bottom: var(--space-2);
    }
    .data-table td.data-table__primary::before {
      display: none;
    }
    .data-table td.data-table__primary .ref {
      font-size: 1.0625rem;
    }
    .data-table tbody tr.is-new td:first-child {
      border-left: 0; /* the card border already carries the new-claim colour */
    }
    .data-table td:has(.data-table__actions) {
      display: block;
    }
    .data-table td:has(.data-table__actions)::before {
      display: none;
    }
    .data-table__actions {
      margin-top: var(--space-2);
    }
    .data-table__actions .btn {
      flex: 1;
    }
  }
}

/* --------------------------------------------------------------------------
   Public — the branded client surface (DESIGN.md §5.1). Bold: a full-bleed
   brand hero, black type on it, one black pill CTA, a dark trust strip.
   Spend boldness here and in the status system; everything else stays quiet.
   -------------------------------------------------------------------------- */

@layer public {
  /* Pages opt out of the reading-width <main> and lay out their own bands. */
  .site-main--bleed {
    max-width: none;
    padding: 0;
  }

  /* Re-introduce the reading width inside a band. */
  .wrap {
    max-width: var(--page-max);
    margin-inline: auto;
    padding-inline: var(--space-4);
  }

  /* The public header flows into the hero — same brand ground, black mark.
     Force black on the yellow in both themes (never white on brand, §2.1). */
  .page--public .site-header {
    background: var(--brand);
    border-bottom-color: rgba(0, 0, 0, 0.15);
  }
  .page--public .site-header .site-brand {
    color: var(--brand-ink);
  }
  .page--public .site-brand::before {
    background: var(--brand-ink);
  }

  /* Hero — full-bleed brand block, black heading, muted-black subtitle.
     Stays yellow in dark mode (the brand block has no dark variant, §6). */
  .hero {
    background: var(--brand);
    color: var(--brand-ink);
    padding-block: var(--space-7);
  }
  .hero h1 {
    margin: 0;
    color: var(--brand-ink);
    font-size: 1.875rem;
  }
  .hero__sub {
    margin: var(--space-2) 0 0;
    max-width: 46ch;
    color: var(--brand-deep);
    font-size: 1.0625rem;
  }

  /* Trust strip — the reassurance a stranger needs, and the agency number a
     stuck client must never have to hunt for. Dark in both modes. */
  .trust-strip {
    background: var(--brand-ink);
    color: #f2f2f2;
    font-size: 0.9375rem;
  }
  .trust-strip__inner {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-5);
    padding-block: var(--space-3);
  }
  .trust-strip__item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
  }
  .trust-strip a {
    color: #fff;
    text-decoration-color: var(--brand);
    font-weight: 500;
    white-space: nowrap;
  }
  /* Default focus ring is var(--ink) — invisible on the dark strip. */
  .trust-strip a:focus-visible {
    outline-color: var(--brand);
  }

  /* Body of a public page — the form, the status detail. Quiet neutral
     surface; darkens with the OS in dark mode. */
  .public-body {
    padding-block: var(--space-6);
  }
  .public-body > :first-child {
    margin-top: 0;
  }
  .public-body h2 {
    margin-top: var(--space-6);
  }

  /* Space the "back to status" link out from the claim form's submit
     button above it — no natural gap between the two otherwise. */
  .claim-back {
    margin-top: var(--space-5);
  }

  #quote-preview {
    margin-block: var(--space-4);
  }
  .quote-preview-empty {
    margin: 0;
    color: var(--ink-muted);
  }

  .status-line {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: 500;
  }

  /* Quote preview — fee and total, money right-aligned and tabular. */
  .quote-preview {
    margin: var(--space-4) 0;
    padding: var(--space-4);
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface-alt);
  }
  .quote-preview > div {
    display: flex;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-1) 0;
  }
  .quote-preview dt {
    color: var(--ink-muted);
  }
  .quote-preview dd {
    margin: 0;
    font-variant-numeric: tabular-nums;
  }
  .quote-preview .is-total {
    margin-top: var(--space-2);
    padding-top: var(--space-2);
    border-top: 1px solid var(--line-strong);
    font-weight: 500;
  }
  .quote-preview .is-total dd {
    font-size: 1.125rem;
  }

  /* "Save this reference" — a callout the client should not skim past. */
  .callout {
    margin: var(--space-4) 0;
    padding: var(--space-3) var(--space-4);
    border-left: 3px solid var(--brand);
    background: var(--highlight-new);
    color: var(--ink);
    border-radius: var(--radius);
  }

  /* Payout code / reference — read aloud, character by character (§3). */
  .code-block {
    margin: var(--space-3) 0;
    padding: var(--space-4);
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-card);
    background: var(--surface-alt);
    text-align: center;
  }
  .code-block__value {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-size: 1.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    word-break: break-all;
  }
  .code-block__label {
    margin: 0 0 var(--space-1);
    color: var(--ink-muted);
    font-size: 0.875rem;
  }

  /* Money figure in running text. */
  .money {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }

  .pay-list {
    margin: var(--space-3) 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: var(--space-2);
  }
  .pay-list li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
  }
  .pay-list .pay-list__account {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
  }
  .copy-btn {
    flex-shrink: 0;
  }
}

/* --------------------------------------------------------------------------
   Landing page (public homepage, templates/common/landing.html).
   One DOM, two layouts — structure from the approved mockups:
     < 600px   moneyPhone3.html — one-screen splash: logo, tile collage,
               headline, one "Commencer" button. No scrolling.
     ≥ 600px   money3.html — the page fills the screen, content centred at
               1200px: nav bar, hero + transfer panel, steps, features, FAQ,
               footer (single column again at ≤ 800px).
   Colours are the --pub-* tokens (light-only). The base layer's defaults
   (line-height 1.5, p max-width, balanced headings, underlined links) are
   reset here.

   Type system — Inter everywhere (--pub-sans), "calt" on:
     text      Inter 400–700. Every size carries its own tracking:
                 12px −.003em · 14px −.005em · 16px −.006em · 18px −.007em
                 25px −.009em · 36px −.011em · 61px −.015em
               scale: micro 12/1.63 · caption 14/1.55 · body-sm 16/1.5 ·
                 body 18/1.5 · body-lg 25/1.3 · subheading 36/1.25
     display   Inter Black 900, −.04em, line-height .85–1: the hero and the
               section openers only — the page's one loud voice.
   Spacing on a 4px grid: 12px between elements, 24px inside cards, 80px
   between sections. Radii: pills (buttons, nav segments) 9999px, cards and
   inputs 10px, large cards 28px.
   -------------------------------------------------------------------------- */
@layer public {
  /* The landing is light-only (no dark variant, like the brand hero §6):
     pin the UA to light so form controls and scrollbars don't go dark. */
  :root:has(> body.page--landing) {
    color-scheme: light;
  }

  .page--landing {
    color-scheme: light;
    background: var(--pub-white);
    color: var(--pub-ink);
    font-family: var(--pub-sans);
    font-feature-settings: "calt" 1;
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: -0.006em;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  .page--landing :focus-visible {
    outline-color: var(--pub-ink);
  }
  /* Zero-specificity resets (:where) — they beat the base layer by layer
     order alone, so every landing class below still wins over them. */
  :where(.landing) p {
    max-width: none;
  }
  :where(.landing) a {
    color: inherit;
    text-decoration: none;
  }

  /* --- Brand mark ---------------------------------------------------------- */
  .landing-logo {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 900;
    line-height: 1;
    letter-spacing: -0.02em;
    white-space: nowrap;
  }
  /* NG monogram (from the brand logo): serif "NG" in the text colour, the
     swoosh + plane in --logo-accent (lime on the ink nav bar; the deeper
     --pub-go on the white phone splash, where lime would wash out). */
  .landing-logo {
    --logo-accent: var(--pub-lime);
  }
  .landing-logo__mark {
    flex: none;
    width: auto;
    height: 1.9em;
    overflow: visible;
  }
  .landing-logo__letters {
    fill: currentColor;
    font-family: "Didot", "Bodoni 72", "Playfair Display", Georgia, "Times New Roman", serif;
    font-size: 74px;
    font-weight: 700;
    letter-spacing: -0.02em;
  }
  .landing-logo__swoosh {
    fill: none;
    stroke: var(--logo-accent);
    stroke-width: 3.2;
    stroke-linecap: round;
  }
  .landing-logo__plane {
    fill: var(--logo-accent);
  }
  /* NG Transfert logo (templates/common/_brand_logo.html): script "ng" and
     TRANSFERT in the text colour, swoosh + plane in --logo-accent. Sized so
     the "ng" matches the old serif NG; the g's tail hangs below. */
  .brand-logo {
    flex: none;
    width: auto;
    height: 2.6em;
    overflow: visible;
  }
  .brand-logo__letters {
    fill: currentColor;
  }
  .brand-logo__swoosh {
    fill: none;
    stroke: var(--logo-accent);
    stroke-width: 3.2;
    stroke-linecap: round;
  }
  .brand-logo__plane {
    fill: var(--logo-accent);
  }
  /* Phones get the mark alone ("ng" + plane): TRANSFERT is unreadable there. */
  .brand-logo--mark {
    display: none;
  }
  @media (max-width: 599.98px) {
    .brand-logo--full {
      display: none;
    }
    .brand-logo--mark {
      display: block;
    }
  }
  .landing-logo__word {
    font-size: 0.72em;
    font-weight: 600;
    letter-spacing: 0.28em;
    text-transform: uppercase;
  }

  /* --- Nav bar (desktop) ---------------------------------------------------- */
  .landing-nav__links ul {
    display: flex;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  /* Nav segments: pills that light up under the pointer. */
  .landing-nav__links a {
    display: block;
    padding: 8px 16px;
    border-radius: 9999px;
    color: var(--pub-nav-link);
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.5;
    letter-spacing: -0.006em;
    transition: background-color 0.2s ease, color 0.2s ease;
  }
  .landing-nav__links a:hover {
    background-color: rgb(255 255 255 / 0.08);
    color: var(--pub-white);
  }
  .landing-signin {
    padding: 12px 24px;
    border-radius: 9999px;
    background: var(--pub-nav-btn);
    color: var(--pub-white);
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: -0.006em;
    white-space: nowrap;
    transition: background-color 0.2s ease;
  }
  .landing-signin:hover {
    background: color-mix(in srgb, var(--pub-nav-btn) 82%, var(--pub-white));
  }

  /* --- Hero ------------------------------------------------------------------ */
  /* Display voice: Inter Black. The second line drops to regular weight so
     the black line carries the shout alone. */
  .landing-hero h1 {
    margin: 0;
    color: var(--pub-ink);
    font-weight: 900;
    line-height: 0.85;
    letter-spacing: -0.04em;
  }
  .landing-hero__thin {
    display: block;
    margin-top: 0.3em;
    font-size: 0.5em;
    font-weight: 400;
    line-height: 1.1;
    letter-spacing: -0.011em;
    text-wrap: balance;
  }
  .landing-hero__lede {
    max-width: 440px;
    margin: 0 0 32px;
    color: var(--pub-muted);
    font-size: 1.125rem;
    line-height: 1.5;
    letter-spacing: -0.007em;
  }
  .landing-hero__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
  }

  /* Buttons — pills. */
  .landing-btn {
    display: inline-block;
    padding: 12px 24px;
    border: none;
    border-radius: 9999px;
    font: inherit;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: -0.006em;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
  }
  .landing-btn:active {
    transform: scale(0.98);
  }
  .landing-btn--primary {
    background: var(--pub-lime);
    color: var(--pub-ink);
  }
  .landing-btn--primary:hover {
    background: color-mix(in srgb, var(--pub-lime) 88%, var(--pub-ink));
  }
  .landing-btn--secondary {
    padding: 11px 23px;
    border: 1px solid var(--pub-line-soft);
    background: var(--pub-white);
    color: var(--pub-ink);
  }
  .landing-btn--secondary:hover {
    border-color: var(--pub-ink);
  }
  /* The phone's "Commencer" button. */
  .landing-btn--go {
    display: block;
    width: 100%;
    padding: 16px 24px;
    background: var(--pub-go);
    color: var(--pub-white);
    font-size: 1.125rem;
    letter-spacing: -0.007em;
    box-shadow: 0 10px 24px var(--pub-go-shadow);
  }
  .landing-btn--go:hover {
    background: var(--pub-go-hover);
  }
  .landing-btn--go:focus-visible {
    outline: 3px solid var(--pub-ink);
    outline-offset: 3px;
  }

  .landing-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 24px 40px;
    margin: 48px 0 0;
    padding: 0;
    list-style: none;
  }
  .landing-stats strong {
    display: block;
    font-size: 1.5625rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.009em;
  }
  .landing-stats li {
    white-space: nowrap;
  }
  .landing-stats span {
    color: var(--pub-muted);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }

  /* --- Card + transfer panel (desktop hero, right column) ------------------- */
  .landing-panel {
    padding: 24px;
    border-radius: 28px;
    background: var(--pub-white);
    box-shadow: 0 1px 2px var(--pub-panel-shadow), 0 16px 40px var(--pub-panel-shadow);
  }
  /* App preview (landing panel) — a phone screen in the public
     palette: ink screen, lime accents. Decorative only (aria-hidden); the
     bottom is cropped and fades out, as if the phone ran off the panel. */
  .landing-app {
    position: relative;
    height: 330px;
    overflow: hidden;
    padding: 10px 10px 0;
    border-radius: 30px 30px 14px 14px;
    background: linear-gradient(160deg, var(--pub-app-edge), var(--pub-ink) 45%);
    box-shadow: inset 0 0 0 1px var(--pub-app-tint-2);
  }
  .landing-app::after {
    content: "";
    position: absolute;
    inset: auto 0 0;
    height: 64px;
    background: linear-gradient(to bottom, var(--pub-ink-clear), var(--pub-ink));
    pointer-events: none;
  }
  .landing-app__screen {
    height: 100%;
    padding: 10px 14px 0;
    border-radius: 22px 22px 0 0;
    background:
      radial-gradient(120% 60% at 50% 0%, var(--pub-app-glow), transparent 70%),
      var(--pub-app-screen);
    color: var(--pub-white);
    font-size: 0.75rem;
    letter-spacing: -0.003em;
  }
  .landing-app__status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 0.6875rem;
    font-weight: 600;
  }
  .landing-app__island {
    width: 64px;
    height: 16px;
    border-radius: 999px;
    background: var(--pub-app-island);
  }
  .landing-app__bars {
    display: flex;
    gap: 3px;
    align-items: flex-end;
  }
  .landing-app__bars i {
    display: block;
    width: 3px;
    border-radius: 1px;
    background: var(--pub-white);
  }
  .landing-app__bars i:nth-child(1) { height: 4px; }
  .landing-app__bars i:nth-child(2) { height: 6px; }
  .landing-app__bars i:nth-child(3) { height: 8px; }
  .landing-app__bars i:nth-child(4) { height: 10px; }
  .landing-app__head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 14px;
  }
  .landing-app__avatar {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--pub-lime);
    color: var(--pub-ink);
    font-weight: 800;
  }
  .landing-app__who strong {
    display: block;
    font-size: 0.875rem;
    font-weight: 700;
    line-height: 1.2;
  }
  .landing-app__who span {
    color: var(--pub-nav-link);
    font-family: var(--pub-mono);
    font-size: 0.625rem;
  }
  .landing-app__icons {
    display: flex;
    gap: 6px;
    margin-left: auto;
  }
  .landing-app__icons span {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--pub-app-tint-3);
  }
  .landing-app__icons svg {
    width: 14px;
    height: 14px;
  }
  .landing-app__balance {
    margin-top: 16px;
    text-align: center;
  }
  .landing-app__balance small {
    display: block;
    color: var(--pub-nav-link);
    font-size: 0.6875rem;
  }
  .landing-app__balance strong {
    display: block;
    font-size: 2rem;
    font-weight: 900;
    line-height: 1.1;
    letter-spacing: -0.04em;
  }
  .landing-app__balance em {
    color: var(--pub-lime);
    font-size: 0.6875rem;
    font-style: normal;
  }
  .landing-app__actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: 14px;
  }
  .landing-app__actions span {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 34px;
    border-radius: 999px;
    background: var(--pub-nav-btn);
    font-weight: 600;
  }
  .landing-app__actions span + span {
    background: var(--pub-lime);
    color: var(--pub-ink);
  }
  .landing-app__actions svg {
    width: 14px;
    height: 14px;
  }
  .landing-app__label {
    margin: 16px 0 8px;
    font-size: 0.8125rem;
    font-weight: 700;
  }
  .landing-app__label span {
    float: right;
    color: var(--pub-nav-link);
    font-size: 0.6875rem;
    font-weight: 400;
  }
  .landing-app__row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 6px;
    padding: 8px 10px;
    border-radius: 12px;
    background: var(--pub-app-tint-1);
  }
  .landing-app__row-icon {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: var(--pub-app-tint-2);
  }
  .landing-app__row-icon svg {
    width: 14px;
    height: 14px;
  }
  .landing-app__row b {
    display: block;
    font-weight: 600;
    line-height: 1.2;
  }
  .landing-app__row small {
    color: var(--pub-nav-link);
    font-size: 0.625rem;
  }
  .landing-app__amount {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    font-family: var(--pub-mono);
    font-weight: 700;
  }
  .landing-app__amount::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--pub-lime);
  }
  .landing-app__amount--out::before {
    background: var(--pub-coral);
  }


  .landing-transfer__title {
    margin: 24px 0 0;
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.008em;
    text-wrap: wrap;
  }
  .landing-transfer__fields {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 16px;
  }
  .landing-transfer__amount {
    display: flex;
    gap: 8px;
  }
  /* Inputs: 10px radius, 1px Pebble border, 12/16 padding, Inter 400 16px.
     Focus turns the border ink and doubles it (inset shadow) — no glow, no
     outline ring, but still an unmistakable 2px edge. */
  .landing-transfer input,
  .landing-transfer select {
    width: 100%;
    padding: 12px 16px;
    border: 1px solid var(--pub-pebble);
    border-radius: 10px;
    background: var(--pub-white);
    color: var(--pub-ink);
    font-family: inherit;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: -0.006em;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
  }
  .landing-transfer input::placeholder {
    color: var(--pub-muted);
    opacity: 1;
  }
  .landing-transfer input:focus,
  .landing-transfer select:focus {
    border-color: var(--pub-ink);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--pub-ink);
  }
  .landing-transfer__amount input {
    flex: 1;
  }
  .landing-transfer__amount select {
    width: 104px;
    font-weight: 500;
  }
  .landing-transfer__submit {
    width: 100%;
    margin-top: 4px;
  }

  /* --- Phone tile collage --------------------------------------------------- */
  .landing-collage {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: repeat(8, 1fr);
    gap: 8px;
    min-height: 260px;
    margin: 4px 0 26px;
  }
  .landing-tile {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .landing-tile--a {
    grid-column: 1;
    grid-row: 1 / 5;
    margin-left: -20px;
    border-radius: 0 22px 22px 0;
    background: linear-gradient(155deg, var(--pub-lime) 0%, var(--pub-lime-soft) 55%, var(--pub-clear) 100%);
  }
  .landing-tile--b {
    grid-column: 2;
    grid-row: 1 / 5;
  }
  .landing-tile--c {
    grid-column: 1;
    grid-row: 5 / 8;
    justify-self: end;
    aspect-ratio: 1;
    height: 100%;
    border: 1px solid var(--pub-line);
    border-radius: 18px;
    background: var(--pub-panel);
  }
  .landing-tile--d {
    grid-column: 2;
    grid-row: 5 / 9;
    margin-right: -20px;
    border-radius: 22px 0 0 22px;
    background: linear-gradient(200deg, var(--pub-sun-soft) 0%, var(--pub-sun) 100%);
  }
  .landing-tile svg {
    display: block;
    overflow: visible;
    color: var(--pub-ink);
  }
  .landing-tile--b svg {
    width: 128px;
    animation: landing-float 4s ease-in-out infinite;
  }
  .landing-tile--c svg {
    width: 74%;
    animation: landing-fly 3.6s ease-in-out infinite;
  }

  /* Illustration fills — classes, not SVG hex attributes (tokens only). */
  .landing-fill-sun   { fill: var(--pub-sun); }
  .landing-fill-lime  { fill: var(--pub-lime); }
  .landing-fill-coral { fill: var(--pub-coral); }
  .landing-fill-white { fill: var(--pub-white); }
  .landing-glyph {
    fill: currentColor;
    stroke: none;
    font-family: var(--pub-mono);
    font-weight: 700;
  }

  /* The dotted path between the two people flows continuously. */
  .landing-orbit {
    stroke: var(--pub-muted);
    animation: landing-flow 0.9s linear infinite;
  }
  /* Coins pulse / bob on their own rhythm. */
  .landing-coin,
  .landing-coin-sm {
    transform-box: fill-box;
    transform-origin: center;
  }
  .landing-coin    { animation: landing-pulse 2s ease-in-out infinite; }
  .landing-coin-sm { animation: landing-bob 1.6s ease-in-out infinite; }
  /* The plane's speed lines flicker. */
  .landing-trail { animation: landing-trail 0.8s ease-in-out infinite alternate; }
  .landing-trail + .landing-trail { animation-delay: -0.4s; }

  /* A soft light sweeps across the gradient tiles, then rests. */
  .landing-tile--a::after,
  .landing-tile--d::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background: linear-gradient(115deg, transparent 38%, var(--pub-shine) 50%, transparent 62%);
    background-size: 250% 100%;
    background-repeat: no-repeat;
    animation: landing-shine 4.5s ease-in-out infinite;
  }
  .landing-tile--d::after {
    animation-delay: 1.2s;
  }

  @keyframes landing-float {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50% { transform: translateY(-14px) rotate(-3deg); }
  }
  /* The plane drifts up and forward, like it's flying. */
  @keyframes landing-fly {
    0%, 100% { transform: translate(0, 0) rotate(0deg); }
    50% { transform: translate(8px, -12px) rotate(5deg); }
  }
  @keyframes landing-flow {
    to { stroke-dashoffset: -18; }
  }
  @keyframes landing-pulse {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.14); }
  }
  @keyframes landing-bob {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-7px); }
  }
  @keyframes landing-trail {
    from { opacity: 1; transform: translateX(0); }
    to { opacity: 0.15; transform: translateX(-5px); }
  }
  @keyframes landing-shine {
    0% { background-position: 100% 0; }
    55%, 100% { background-position: 0% 0; }
  }

  @media (prefers-reduced-motion: reduce) {
    .landing-tile svg,
    .landing-orbit,
    .landing-coin,
    .landing-coin-sm,
    .landing-trail {
      animation: none;
    }
    .landing-tile--a::after,
    .landing-tile--d::after {
      display: none;
    }
    .landing-btn--go {
      transition: none;
    }
  }

  /* --- Sections (desktop): steps, features, FAQ ------------------------------ */
  /* 40px top + 40px bottom: consecutive sections sit 80px apart. */
  .landing-section {
    padding: 40px 32px;
  }
  .landing-section__head {
    max-width: 760px;
    margin: 0 auto 48px;
    text-align: center;
  }
  .landing-eyebrow {
    color: var(--pub-muted);
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  /* Section openers — the display voice again. */
  .landing-section__head h2 {
    margin: 12px 0 16px;
    font-size: clamp(2.5rem, 5vw, 3.8125rem);
    font-weight: 900;
    line-height: 1;
    letter-spacing: -0.04em;
    text-wrap: balance;
  }
  .landing-section__head p {
    margin: 0;
    color: var(--pub-muted);
    font-size: 1.125rem;
    line-height: 1.5;
    letter-spacing: -0.007em;
  }

  .landing-steps,
  .landing-features {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
  }
  .landing-steps {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .landing-step,
  .landing-feature {
    padding: 24px;
    border-radius: 28px;
    background: var(--pub-panel);
  }
  .landing-step__num,
  .landing-feature__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-bottom: 24px;
    border-radius: 50%;
  }
  .landing-step__num {
    background: var(--pub-ink);
    color: var(--pub-lime);
    font-size: 1rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
  }
  /* Line icons (receipt / bolt / shield), drawn in the illustrations' stroke. */
  .landing-feature__icon {
    background: var(--pub-white);
    color: var(--pub-ink);
  }
  .landing-feature__icon svg {
    display: block;
    width: 22px;
    height: 22px;
  }
  .landing-step h3,
  .landing-feature h3 {
    margin: 0 0 8px;
    font-size: 1.375rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.008em;
    text-wrap: balance;
  }
  .landing-step p,
  .landing-feature p {
    margin: 0;
    color: var(--pub-muted);
    font-size: 1rem;
    line-height: 1.5;
    letter-spacing: -0.006em;
  }

  .landing-faq {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: 720px;
    margin: 0 auto;
  }
  .landing-faq details {
    padding: 20px 24px;
    border-radius: 10px;
    background: var(--pub-panel);
  }
  .landing-faq summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    list-style: none;
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.44;
    letter-spacing: -0.007em;
    cursor: pointer;
  }
  .landing-faq summary::-webkit-details-marker {
    display: none;
  }
  .landing-faq summary::after {
    content: "+";
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--pub-ink);
    color: var(--pub-lime);
    font-size: 1.25rem;
    font-weight: 500;
    line-height: 1;
    transition: transform 0.46s cubic-bezier(0.22, 1, 0.36, 1);
  }
  /* .is-closing (common/landing-motion.js): the answer is still folding away
     but the "+" already turns back. */
  .landing-faq details[open]:not(.is-closing) summary::after {
    transform: rotate(45deg);
  }
  .landing-faq summary:focus-visible {
    outline: 2px solid var(--pub-ink);
    outline-offset: 4px;
    border-radius: 6px;
  }
  .landing-faq p {
    max-width: 60ch;
    margin: 12px 0 0;
    color: var(--pub-muted);
    font-size: 1rem;
    line-height: 1.5;
    letter-spacing: -0.006em;
  }

  /* --- Scroll reveal (common/landing-motion.js) ---------------------------- */
  /* [data-reveal] rises into place the first time it comes into view: text
     32px, cards ("card") 56px and from 96% scale — a long expo ease-out, so
     it arrives fast and settles slowly. Hidden only once the script has armed
     the page and only until .is-in: no script, no hidden content. The script
     staggers what arrives together through --reveal-delay. */
  .landing-section__head .landing-eyebrow {
    display: block; /* a transform needs a box, not an inline span */
  }
  .landing.is-armed [data-reveal] {
    transition:
      opacity 0.8s cubic-bezier(0.16, 1, 0.3, 1),
      transform 1.1s cubic-bezier(0.16, 1, 0.3, 1);
    transition-delay: var(--reveal-delay, 0ms);
  }
  .landing.is-armed [data-reveal]:not(.is-in) {
    opacity: 0;
    transform: translateY(32px);
  }
  .landing.is-armed [data-reveal="card"]:not(.is-in) {
    transform: translateY(56px) scale(0.96);
  }
  @media print {
    .landing.is-armed [data-reveal]:not(.is-in) {
      opacity: 1;
      transform: none;
    }
  }

  /* ==== Phone: the one-screen splash (moneyPhone3) ========================== */
  @media (max-width: 599.98px) {
    /* Everything the splash doesn't show. display:none also takes it out of
       the accessibility tree, so the phone gets one clean screen. */
    .landing-nav__links,
    .landing-signin,
    .landing-hero__lede,
    .landing-hero__actions .landing-btn--primary,
    .landing-hero__actions .landing-btn--secondary,
    .landing-stats,
    .landing-panel,
    .landing-section {
      display: none;
    }

    /* The screen: tiles grow to fill, headline + button sit at the bottom. */
    .landing {
      display: flex;
      flex-direction: column;
      min-height: 100vh;
      min-height: 100svh;
      padding: env(safe-area-inset-top) 20px calc(20px + env(safe-area-inset-bottom));
      background: var(--pub-white);
    }
    .landing-nav {
      display: flex;
      align-items: center;
      height: 56px;
    }
    .landing-logo {
      --logo-accent: var(--pub-go);
      font-size: 1.25rem;
    }
    .landing-main,
    .landing-hero {
      flex: 1;
      display: flex;
      flex-direction: column;
    }
    /* flex-basis 0px, not flex:1's 0%: in a min-height-only column a
       percentage basis falls back to the content height, so the collage
       could never shrink and short screens (a phone browser with its
       toolbars showing) would scroll. 0px lets it shrink to its 260px floor. */
    .landing-collage {
      order: -1;
      flex: 1 1 0px;
    }
    .landing-hero h1 {
      margin-bottom: 24px;
      font-size: clamp(2.5rem, 12.5vw, 3.25rem);
      text-wrap: balance;
    }
    .landing-hero__actions {
      display: block;
    }
  }

  /* ==== Desktop: full-bleed page, content centred at 1200px (money3) ======== */
  @media (min-width: 600px) {
    .page--landing {
      padding-inline: env(safe-area-inset-left) env(safe-area-inset-right);
      background: var(--pub-card);
    }
    .landing-collage,
    .landing-btn--go {
      display: none;
    }

    .landing {
      width: min(1200px, 100%);
      margin: 0 auto;
      padding: 16px;
    }

    /* Sticky nav. At rest it is the rounded ink pill of the mockup; as the
       page scrolls its backdrop widens to the full viewport, loses its
       corners and turns translucent — progressively: every property below is
       a function of --nav-p, 0 (pill) → 1 (full bar, reached halfway down
       the page), which common/landing-nav.js eases toward the scroll
       position with a little inertia. Only the ::before backdrop morphs — the
       bar's own box and content never move, so nothing below reflows.
       The bar sticks exactly where it rests (--nav-inset, the .landing
       padding above it), so it doesn't budge on the first scroll either; the
       backdrop grows up over that gap — and as much down, so the content
       stays centred in the full bar — as it grows out to the sides.
       Without JavaScript --nav-p stays 0: a sticky pill.
       64px tall: the 48px "Connexion" pill sits 8px in from the right end, so
       the bar's 32px radius is concentric with the button's (24 + 8). */
    .landing-nav {
      --nav-inset: 16px; /* = .landing's top padding: where the bar rests */
      position: sticky;
      top: var(--nav-inset);
      z-index: 50;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 8px 8px 8px 32px;
      color: var(--pub-white);
    }
    .landing-nav::before {
      content: "";
      position: absolute;
      z-index: -1;
      /* Up over the gap above the bar (and as much down), out toward the
         viewport's edges (the script measures the side gaps — not 100vw,
         which would count the scrollbar and overflow). */
      top: calc(var(--nav-inset) * -1 * var(--nav-p, 0));
      bottom: calc(var(--nav-inset) * -1 * var(--nav-p, 0));
      left: calc(var(--nav-gutter-l, 0px) * -1 * var(--nav-p, 0));
      right: calc(var(--nav-gutter-r, 0px) * -1 * var(--nav-p, 0));
      border-radius: calc(32px * (1 - var(--nav-p, 0)));
      background-color: var(--pub-ink);
      box-shadow: 0 10px 30px -14px rgb(16 22 10 / calc(0.45 * var(--nav-p, 0)));
      -webkit-backdrop-filter: blur(calc(14px * var(--nav-p, 0))) saturate(calc(1 + 0.4 * var(--nav-p, 0)));
      backdrop-filter: blur(calc(14px * var(--nav-p, 0))) saturate(calc(1 + 0.4 * var(--nav-p, 0)));
    }
    /* Ink → 78% ink. Guarded: a var() inside an unsupported color-mix()
       would compute to transparent rather than fall back to the ink above. */
    @supports (background-color: color-mix(in srgb, red calc(100% - 22% * 1), transparent)) {
      .landing-nav::before {
        background-color: color-mix(in srgb, var(--pub-ink) calc(100% - 22% * var(--nav-p, 0)), transparent);
      }
    }
    /* Belt and braces: clip any sub-pixel overshoot of the full-width
       backdrop. `clip`, not `hidden`: it creates no scroll container, so the
       nav stays sticky. */
    .page--landing {
      overflow-x: clip;
    }
    /* In-page links (#faq…) land below the full bar (96px), not under it. */
    :root:has(> body.page--landing) {
      scroll-padding-top: 112px;
    }
    .landing-nav :focus-visible {
      outline-color: var(--pub-lime);
    }
    .landing-logo {
      font-size: 1.25rem;
    }

    .landing-main > .messages {
      margin: 16px 32px 0;
    }

    /* 5:4 split, the panel capped at 440px: the copy column keeps room for
       its buttons and stats down to the 800px single-column switch. */
    .landing-hero {
      display: grid;
      grid-template-columns: minmax(0, 5fr) minmax(0, 4fr);
      gap: clamp(40px, 5vw, 64px);
      align-items: center;
      padding: 80px 32px 40px;
    }
    .landing-panel {
      justify-self: end;
      width: 100%;
      max-width: 440px;
    }
    .landing-hero h1 {
      margin-bottom: 32px;
      font-size: clamp(3.25rem, 7.4vw, 5.5625rem);
      text-wrap: wrap;
    }
  }

  @media (min-width: 600px) and (max-width: 800px) {
    .landing-nav__links {
      display: none;
    }
    .landing-hero,
    .landing-steps,
    .landing-features {
      grid-template-columns: 1fr;
    }
    .landing-panel {
      justify-self: stretch;
      max-width: none;
    }
    .landing-stats {
      flex-wrap: wrap;
      gap: 24px;
    }
  }
}

/* --------------------------------------------------------------------------
   Site footer (templates/common/_site_foot.html, on every page) — a dark ink
   band that mirrors the nav bar, so the page is framed in ink top and bottom:
   brand · Service · Aide (+ security notice) · Contact, then © · legal · top.
   Desktop/tablet only (≥ 600px): hidden on phones.
   -------------------------------------------------------------------------- */
@layer public {
  .site-foot {
    margin-top: 96px;
    border-radius: 28px 28px 0 0;
    background: var(--pub-ink);
    color: var(--pub-nav-link);
    font-family: var(--pub-sans);
    font-size: 0.9375rem;
    line-height: 1.55;
    letter-spacing: -0.006em;
  }
  .site-foot a {
    color: inherit;
    text-decoration: none;
    transition: color 0.15s ease;
  }
  .site-foot a:hover {
    color: var(--pub-lime);
  }
  .site-foot :focus-visible {
    outline: 2px solid var(--pub-lime);
    outline-offset: 3px;
    border-radius: 4px;
  }
  .site-foot__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 64px 32px 28px;
  }

  /* --- Main grid: brand · 3 link columns · contact ------------------------ */
  .site-foot__grid {
    display: grid;
    grid-template-columns: 1.6fr 1fr 1fr 1.4fr;
    gap: 40px 32px;
    padding: 0 0 48px;
  }
  .site-foot__brand .landing-logo {
    --logo-accent: var(--pub-lime); /* lime on ink, phone too */
    color: var(--pub-white);
    font-size: 1.25rem;
  }
  .site-foot__brand p {
    margin: 20px 0 24px;
    max-width: 30ch;
    color: var(--pub-nav-link);
  }
  .site-foot__corridor {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 14px;
    border-radius: 999px;
    background: var(--pub-app-tint-1);
    box-shadow: inset 0 0 0 1px var(--pub-foot-line);
    color: var(--pub-white);
    font-size: 0.8125rem;
    font-weight: 600;
  }
  .site-foot__corridor svg {
    width: 16px;
    height: 16px;
    color: var(--pub-lime);
  }
  .site-foot__col h3 {
    margin: 0 0 16px;
    color: var(--pub-white);
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
  }
  .site-foot__col ul {
    display: grid;
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .site-foot__contact li {
    display: flex;
    gap: 12px;
    align-items: flex-start;
  }
  .site-foot__contact svg {
    flex: none;
    width: 18px;
    height: 18px;
    margin-top: 2px;
    color: var(--pub-lime);
  }
  .site-foot__col li small {
    display: block;
    color: var(--pub-foot-dim);
    font-size: 0.8125rem;
  }
  .site-foot__contact small {
    display: block;
    color: var(--pub-foot-dim);
    font-size: 0.8125rem;
  }

  /* --- Bottom bar -------------------------------------------- */
  .site-foot__bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px 32px;
    flex-wrap: wrap;
    padding-top: 24px;
    border-top: 1px solid var(--pub-foot-line);
    color: var(--pub-foot-dim);
    font-size: 0.8125rem;
  }
  .site-foot__bottom ul {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 24px;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .site-foot .site-foot__top-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 16px;
    border: 1px solid var(--pub-foot-line);
    border-radius: 999px;
    background: transparent;
    color: var(--pub-white);
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    cursor: pointer;
  }
  .site-foot .site-foot__top-btn:hover {
    border-color: var(--pub-lime);
    color: var(--pub-lime);
  }
  .site-foot__top-btn svg {
    width: 14px;
    height: 14px;
  }

  /* --- Responsive ---------------------------------------------------------- */
  @media (max-width: 1000px) {
    .site-foot__grid {
      grid-template-columns: repeat(2, 1fr);
    }
    .site-foot__brand {
      grid-column: 1 / -1;
    }
    .site-foot__contact {
      grid-column: 1 / -1;
    }
    .site-foot__contact ul {
      grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
      gap: 16px 32px;
    }
  }
  /* Phone: no footer — the landing is a one-screen splash, and the other
     pages keep the screen for the task at hand. */
  @media (max-width: 599.98px) {
    .site-foot {
      display: none;
    }
  }
}

/* --------------------------------------------------------------------------
   Public flow pages — quote (step 1, money5 / moneyPhone5) and claim
   (step 2, money7 / moneyPhone7); templates/transfers/public/. One DOM, two
   layouts, same --pub-* palette as the landing:
     ≥ 720px   the desktop mockup as a FULL page — the steps as a full-height
               sidebar, the form in a centred column filling the rest (no
               floating window, no backdrop).
     < 720px   the phone mockup — app bar, horizontal stepper, grouped cards,
               green button pinned to the bottom.
   720px is where the desktop mockups themselves dropped to one column.
   Shared includes: _flow_steps.html (variants "side" / "bar"),
   _flow_appbar.html, _flow_chips.html. Components are .flow-*; a page's own
   bits are .quote-* / .claim-*, and .flow--quote / .flow--claim carry the
   few pixel differences between the mockups.
   Type, spacing and radii follow the landing's system (see "Landing page"):
   Inter with per-size tracking, Inter Black for page titles, a 4px grid,
   pills for buttons/tags, 10px for cards and inputs, 28px for the desktop
   boxes. Monospace is kept only for what people copy or read out — the
   reference, the payout code, account and phone numbers; amounts are Inter
   with tabular figures.
   -------------------------------------------------------------------------- */
@layer public {
  /* Light-only, like the landing: pin the UA so fields don't go dark. */
  :root:has(> body.page--flow) {
    color-scheme: light;
  }

  .page--flow {
    color-scheme: light;
    background: var(--pub-card);
    color: var(--pub-ink);
    font-family: var(--pub-sans);
    font-feature-settings: "calt" 1;
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: -0.006em;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  .page--flow :focus-visible {
    outline-color: var(--pub-ink);
  }
  /* Zero-specificity resets: beat the base layer by layer order only. */
  :where(.flow) p {
    max-width: none;
  }
  :where(.flow) a {
    color: inherit;
    text-decoration: none;
  }
  :where(.flow) input,
  :where(.flow) button {
    font-family: inherit;
  }

  /* --- Steps list (shared markup, two variants) ------------------------------ */
  .flow-steps {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  /* --- Quote head --------------------------------------------------------------- */
  /* Page titles: the display voice (Inter Black). */
  .flow-head h1 {
    color: var(--pub-ink);
    font-size: 2.5rem;
    font-weight: 900;
    line-height: 1;
    letter-spacing: -0.04em;
    text-wrap: wrap;
  }
  .flow-head p {
    margin: 0;
    color: var(--pub-muted);
  }

  /* --- Fields --------------------------------------------------------------------- */
  .flow-form input,
  .flow-form select {
    width: 100%;
    color: var(--pub-ink);
    font-weight: 400;
  }
  .flow-form input::placeholder {
    color: var(--pub-muted);
    font-weight: 400;
    opacity: 1;
  }
  /* The amount is a number input (the server wants a decimal): drop the
     spinner arrows the mockups never had. */
  .flow-form input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
  }
  .flow-form input[type="number"]::-webkit-inner-spin-button,
  .flow-form input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  /* Phone numbers and amounts: same-width digits, so they don't jiggle. */
  .flow-row--mono input,
  .quote-amount input {
    font-variant-numeric: tabular-nums;
  }

  .flow .field-error {
    margin: 8px 0 0;
    color: var(--pub-error);
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .flow-alert {
    margin: 0 0 12px;
    padding: 12px 16px;
    border-radius: 10px;
    background: var(--pub-error-bg);
    color: var(--pub-error);
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }

  /* Live fee preview (HTMX swaps _quote_preview.html into #quote-preview). */
  .flow #quote-preview {
    margin: 0;
  }
  .flow-hint {
    margin: 12px 0 0;
    color: var(--pub-muted);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .flow .quote-preview {
    margin: 12px 0 0;
    padding: 12px 16px;
    border: 0;
    border-radius: 10px;
    background: var(--pub-panel);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .flow .quote-preview > div {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
  }
  .flow .quote-preview dt {
    color: var(--pub-muted);
  }
  .flow .quote-preview dd {
    margin: 0;
    font-variant-numeric: tabular-nums;
    font-weight: 500;
  }
  .flow .quote-preview .is-total {
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid var(--pub-line);
    font-weight: 600;
  }
  .flow .quote-preview .is-total dt {
    color: var(--pub-ink);
  }
  .flow .quote-preview .is-total dd {
    font-size: 1.125rem;
    font-weight: 700;
    letter-spacing: -0.007em;
  }

  .flow-form .cf-turnstile {
    margin-bottom: 12px;
  }

  .flow-submit {
    display: block;
    width: 100%;
    border: 1px solid transparent;
    cursor: pointer;
    text-align: center;
  }

  .flow-note strong,
  .flow-fineprint strong {
    color: var(--pub-ink);
  }

  /* ==== Phone: moneyPhone5 ================================================== */
  @media (max-width: 719.98px) {
    .flow-side,
    .flow-close,
    .flow-chips,
    .flow-box__title,
    .flow-desk,
    .flow-note {
      display: none;
    }
    /* The amount field's label is the group heading above it; keep the real
       <label> text for screen readers only. */
    .quote-amount__label {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
    }

    .flow-screen {
      display: flex;
      flex-direction: column;
      min-height: 100vh;
      min-height: 100svh;
      max-width: 560px;
      margin-inline: auto;
      padding: env(safe-area-inset-top) 20px calc(20px + env(safe-area-inset-bottom));
    }
    .flow-main,
    .flow-form {
      flex: 1;
      display: flex;
      flex-direction: column;
    }

    /* App bar */
    .flow-appbar {
      display: grid;
      grid-template-columns: 40px 1fr 40px;
      align-items: center;
      height: 60px;
    }
    .flow-appbar__title {
      font-size: 1rem;
      font-weight: 700;
      letter-spacing: -0.006em;
      text-align: center;
    }
    .flow-icon-btn {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 40px;
      height: 40px;
      border: 1px solid var(--pub-line);
      border-radius: 50%;
      background: var(--pub-white);
      color: var(--pub-ink);
    }

    /* Horizontal stepper */
    .flow-steps--bar {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      margin: 16px -8px 0;
    }
    .flow-steps--bar .flow-step {
      position: relative;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 8px;
    }
    /* connector line to the previous step */
    .flow-steps--bar .flow-step + .flow-step::before {
      content: "";
      position: absolute;
      top: 13px;
      left: calc(-50% + 20px);
      right: calc(50% + 20px);
      height: 2px;
      border-radius: 2px;
      background: var(--pub-line);
    }
    .flow-steps--bar .flow-step.is-done + .flow-step::before {
      background: var(--pub-lime-dark);
    }
    .flow-steps--bar .flow-step__node {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 28px;
      height: 28px;
      border: 1.5px solid var(--pub-line);
      border-radius: 50%;
      background: var(--pub-white);
      color: var(--pub-muted);
      font-size: 0.75rem;
      font-variant-numeric: tabular-nums;
      font-weight: 600;
      line-height: 1;
    }
    .flow-steps--bar .is-active .flow-step__node {
      border-color: var(--pub-ink);
      background: var(--pub-ink);
      color: var(--pub-lime);
      box-shadow: 0 0 0 4px var(--pub-lime-ring);
    }
    .flow-steps--bar .is-done .flow-step__node {
      border-color: var(--pub-lime);
      background: var(--pub-lime);
      color: var(--pub-ink);
    }
    .flow-steps--bar .flow-step__kicker {
      display: none;
    }
    .flow-steps--bar .flow-step__name {
      color: var(--pub-muted);
      font-size: 0.75rem;
      font-weight: 500;
      line-height: 1.5;
      letter-spacing: -0.003em;
    }
    .flow-steps--bar .is-active .flow-step__name {
      color: var(--pub-ink);
      font-weight: 600;
    }

    /* Intro */
    .flow-head {
      margin: 32px 0 24px;
    }
    .flow-head h1 {
      margin: 0 0 12px;
    }
    .flow-head p {
      max-width: 320px;
      font-size: 1rem;
      line-height: 1.5;
    }

    /* Grouped cards */
    .flow-group {
      margin-bottom: 24px;
    }
    .flow-group__label {
      margin: 0 0 8px;
      font-size: 1rem;
      font-weight: 600;
      line-height: 1.5;
      letter-spacing: -0.006em;
    }
    /* The card is the input here (its rows are borderless fields), so it
       takes the input rules: 10px, 1px Pebble, and on focus an ink edge
       doubled by an inset shadow — no glow. */
    .flow-card {
      border: 1px solid var(--pub-pebble);
      border-radius: 10px;
      background: var(--pub-white);
      transition: border-color 0.15s ease, box-shadow 0.15s ease;
    }
    .flow-card:focus-within {
      border-color: var(--pub-ink);
      box-shadow: inset 0 0 0 1px var(--pub-ink);
    }
    .flow-row {
      display: flex;
      align-items: center;
      gap: 12px;
      padding: 12px 16px;
      cursor: text;
    }
    .flow-row ~ .flow-row {
      border-top: 1px dashed var(--pub-line);
    }
    .flow-row__icon {
      display: flex;
      flex: none;
      align-items: center;
      justify-content: center;
      width: 36px;
      height: 36px;
      border-radius: 50%;
      background: var(--pub-panel);
      color: var(--pub-lime-dark);
    }
    .flow-row__body {
      flex: 1;
      min-width: 0;
    }
    .flow-row__label {
      display: block;
      color: var(--pub-muted);
      font-size: 0.75rem;
      font-weight: 500;
      line-height: 1.5;
      letter-spacing: -0.003em;
    }
    /* Field focus shows on the whole card (:focus-within) instead. */
    .flow-card input,
    .flow-card select {
      padding: 0;
      border: none;
      outline: none;
      background: none;
      font-size: 16px; /* 16px stops iOS zooming into the field */
      line-height: 1.5;
    }
    /* 64px = the row's 16px padding + 36px icon + 12px gap. */
    .flow-card .flow-row__error {
      margin: 0;
      padding: 0 16px 12px 64px;
    }

    .quote-amount {
      display: block;
      padding: 16px;
      cursor: text;
    }
    .quote-amount input {
      font-size: 2.25rem;
      font-weight: 700;
      line-height: 1.25;
      letter-spacing: -0.011em;
    }
    .quote-amount input::placeholder {
      color: var(--pub-line);
      font-weight: 700;
    }
    .quote-amount + .flow-row__error {
      margin-left: 0;
    }

    /* Bottom action — pinned to the bottom of the screen. */
    .flow-bottom {
      margin-top: auto;
      padding-top: 12px;
    }
    /* 16px, not the landing's 18px: "Déjà payé ? Soumettez votre
       réclamation" must still fit one line on a 390px phone. */
    .flow-submit {
      padding: 16px;
      border: none;
      border-radius: 9999px;
      background: var(--pub-go);
      color: var(--pub-white);
      font-size: 1rem;
      font-weight: 600;
      line-height: 1.5;
      letter-spacing: -0.006em;
      text-wrap: balance;
      box-shadow: 0 10px 24px var(--pub-go-shadow);
      transition: background 0.15s ease, transform 0.15s ease;
    }
    .flow-submit:hover {
      background: var(--pub-go-hover);
    }
    .flow-submit:active {
      transform: scale(0.98);
    }
    .flow-submit:focus-visible {
      outline: 3px solid var(--pub-ink);
      outline-offset: 3px;
    }
    .flow-fineprint {
      margin: 12px 0 0;
      color: var(--pub-muted);
      font-size: 0.875rem;
      line-height: 1.55;
      letter-spacing: -0.005em;
      text-align: center;
      text-wrap: balance;
    }
    .flow-fineprint strong {
      font-weight: 600;
    }

    @media (prefers-reduced-motion: reduce) {
      .flow-card,
      .flow-submit {
        transition: none;
      }
    }
  }

  /* ==== Desktop: money5 as a full page ====================================== */
  @media (min-width: 720px) {
    .flow-appbar,
    .flow-bar,
    .flow-group__label,
    .flow-row__icon,
    .flow-fineprint {
      display: none;
    }

    .flow {
      display: grid;
      grid-template-columns: 280px 1fr;
      min-height: 100vh;
    }

    /* Sidebar — full height, the steps. */
    .flow-side {
      padding: 32px;
      border-right: 1px solid var(--pub-line);
      background: var(--pub-panel);
    }
    .flow-side__title {
      margin: 0 0 24px;
      font-size: 1.25rem;
      font-weight: 700;
      line-height: 1.3;
      letter-spacing: -0.009em;
    }
    .flow-steps--side {
      display: flex;
      flex-direction: column;
      gap: 20px;
    }
    /* dot + "Étape n/4" on one line, the name under the label */
    .flow-steps--side .flow-step {
      display: grid;
      grid-template-columns: 14px 1fr;
      column-gap: 8px;
      align-items: center;
      color: var(--pub-muted);
    }
    .flow-steps--side .flow-step__node {
      position: relative;
      width: 14px;
      height: 14px;
      border: 2px solid var(--pub-line);
      border-radius: 50%;
      font-size: 0; /* the dot carries no number */
    }
    .flow-steps--side .is-active .flow-step__node {
      border-color: var(--pub-lime-dark);
    }
    .flow-steps--side .is-done .flow-step__node {
      border-color: var(--pub-lime);
      background: var(--pub-lime);
    }
    .flow-steps--side .is-done .flow-step__node::after {
      content: "✓";
      position: absolute;
      inset: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      color: var(--pub-ink);
      font-size: 9px;
    }
    .flow-steps--side .flow-step__kicker {
      font-size: 0.75rem;
      font-weight: 500;
      line-height: 1.63;
      letter-spacing: -0.003em;
    }
    .flow-steps--side .is-done .flow-step__kicker {
      color: var(--pub-lime-dark);
    }
    .flow-steps--side .is-active .flow-step__kicker {
      color: var(--pub-ink);
    }
    .flow-steps--side .flow-step__name {
      grid-column: 2;
      color: var(--pub-muted);
      font-size: 1rem;
      font-weight: 400;
      line-height: 1.5;
      letter-spacing: -0.006em;
    }
    .flow-steps--side .is-active .flow-step__name,
    .flow-steps--side .is-done .flow-step__name {
      color: var(--pub-ink);
      font-weight: 600;
    }

    /* Main area — the form in a centred column. */
    .flow-screen {
      padding: 40px 48px;
    }
    .flow-main {
      max-width: 560px;
      margin: 0 auto;
    }

    .flow-head {
      display: flex;
      align-items: flex-start;
      justify-content: space-between;
      gap: 12px;
      margin-bottom: 24px;
    }
    .flow-head h1 {
      margin: 0 0 12px;
    }
    .flow-head p {
      max-width: 440px;
      font-size: 1rem;
      line-height: 1.5;
    }
    .flow-close {
      flex: none;
      margin: -4px -4px 0 0;
      padding: 4px;
      color: var(--pub-muted);
      font-size: 1.1rem;
      line-height: 1;
    }

    .flow-chips {
      display: flex;
      flex-wrap: wrap;
      gap: 8px;
      margin: 0 0 24px;
      padding: 0;
      list-style: none;
    }
    .flow-chips li {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 4px 12px;
      border: 1px solid var(--pub-line);
      border-radius: 9999px;
      background: var(--pub-panel);
      color: var(--pub-ink);
      font-size: 0.875rem;
      font-weight: 500;
      line-height: 1.55;
      letter-spacing: -0.005em;
    }
    .flow-chips__phone {
      font-family: var(--pub-mono);
    }

    /* The form sits on a white large card, like the landing's panel. */
    .flow-box {
      margin-bottom: 16px;
      padding: 24px;
      border-radius: 28px;
      background: var(--pub-white);
      box-shadow: 0 1px 2px var(--pub-panel-shadow), 0 16px 40px var(--pub-panel-shadow);
    }
    .flow-box__title {
      margin: 0 -24px 20px;
      padding: 0 24px 16px;
      border-bottom: 1px solid var(--pub-line);
      font-size: 1.125rem;
      font-weight: 600;
      line-height: 1.44;
      letter-spacing: -0.007em;
    }
    .flow-group + .flow-group,
    .flow-row ~ .flow-row {
      margin-top: 16px;
    }
    .flow-row,
    .quote-amount {
      display: block;
    }
    .flow-row__label {
      display: block;
      margin-bottom: 8px;
      color: var(--pub-ink);
      font-size: 0.875rem;
      font-weight: 500;
      line-height: 1.55;
      letter-spacing: -0.005em;
    }
    /* Inputs: 10px, 1px Pebble, 12/16 padding, Inter 400 16px. Focus: an
       ink border doubled by an inset shadow — no glow ring. */
    .flow-form input,
    .flow-form select {
      padding: 12px 16px;
      border: 1px solid var(--pub-pebble);
      border-radius: 10px;
      outline: none;
      background: var(--pub-white);
      font-size: 1rem;
      line-height: 1.5;
      letter-spacing: -0.006em;
      transition: border-color 0.15s ease, box-shadow 0.15s ease;
    }
    .flow-form input:focus,
    .flow-form select:focus {
      border-color: var(--pub-ink);
      box-shadow: inset 0 0 0 1px var(--pub-ink);
    }

    .flow-submit {
      margin-bottom: 16px;
      padding: 12px 24px;
      border-color: var(--pub-lime);
      border-radius: 9999px;
      background: var(--pub-lime);
      color: var(--pub-ink);
      font-size: 1rem;
      font-weight: 600;
      line-height: 1.5;
      letter-spacing: -0.006em;
      transition: background-color 0.2s ease, transform 0.15s ease;
    }
    .flow-submit:hover {
      background: color-mix(in srgb, var(--pub-lime) 88%, var(--pub-ink));
    }
    .flow-submit:active {
      transform: scale(0.98);
    }

    .flow-note {
      margin: 0 0 24px;
      padding: 16px;
      border-radius: 10px;
      background: var(--pub-panel);
      color: var(--pub-muted);
      font-size: 0.875rem;
      line-height: 1.55;
      letter-spacing: -0.005em;
    }
    .flow-note strong {
      font-weight: 600;
    }
  }
}

/* --------------------------------------------------------------------------
   Public flow pages, continued — pieces the claim page (money7 /
   moneyPhone7) added: the operator dropdown, the desktop head's reference row
   and progress bar, help text, the back link, the step hint, the rejected-
   claim warning. Generic ones are .flow-*, reusable by later flow pages.
   -------------------------------------------------------------------------- */
@layer public {
  /* Amounts inline in copy — Inter, tabular, ink. */
  .flow-money {
    color: var(--pub-ink);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
  }
  /* References / phone numbers inline in copy — the things people read out
     or type back, so monospace (0 vs O, 1 vs l). */
  .flow-code {
    color: var(--pub-ink);
    font-family: var(--pub-mono);
    font-weight: 700;
    letter-spacing: 0;
  }

  /* Dropdown — the mockups' borderless select with a lime chevron. The
     chevron is a data: SVG (CSP img-src allows data:); its stroke is
     --pub-lime-dark (#7a9c2e) — CSS variables can't reach inside a data URI,
     so keep the two in step by hand. */
  .flow-form select {
    -webkit-appearance: none;
    appearance: none;
    cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%237a9c2e' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    text-overflow: ellipsis;
  }
  /* Nothing chosen yet: the placeholder option reads as a placeholder. */
  .flow-form select:invalid {
    color: var(--pub-muted);
    font-weight: 400;
  }
  .flow-form select option {
    color: var(--pub-ink);
    font-weight: 400;
  }

  .flow-help {
    color: var(--pub-muted);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }

  .flow-alert--warn {
    background: var(--pub-sun-soft);
    color: var(--pub-ink);
  }
  .flow-alert--warn strong {
    font-weight: 600;
  }

  /* ==== Phone ================================================================ */
  @media (max-width: 719.98px) {
    .flow-steps--bar .flow-step__hint,
    .flow-head__aside,
    .claim-ref,
    .flow-back {
      display: none;
    }
    .flow-steps--bar .is-done .flow-step__name {
      color: var(--pub-lime-dark);
    }

    .flow-row--select {
      cursor: pointer;
    }
    .flow-card select {
      padding-right: 24px;
      background-position: right 2px center;
    }

    .flow-help {
      margin: 8px 0 0;
    }
    .flow-head .flow-alert--warn {
      margin: 0;
    }

    /* moneyPhone7's spacing (a touch tighter than moneyPhone5's). */
    .flow--claim .flow-head {
      margin: 28px 0 24px;
    }
  }

  /* ==== Desktop ============================================================== */
  @media (min-width: 720px) {
    .flow-steps--side .flow-step__hint {
      grid-column: 2;
      margin-top: 4px;
      color: var(--pub-muted);
      font-size: 0.875rem;
      line-height: 1.55;
      letter-spacing: -0.005em;
    }

    .flow-form select {
      padding-right: 40px;
      background-position: right 16px center;
    }

    .flow-help {
      margin: 8px 0 0;
    }

    /* Head, right side: "1/4", the progress track, the close link. */
    .flow-head > div:first-child {
      min-width: 0;
    }
    .flow-head__aside {
      display: flex;
      flex: none;
      align-items: center;
      gap: 12px;
    }
    .flow-head__aside .flow-close {
      margin: 0 -4px 0 0;
    }
    .flow-progress__label {
      color: var(--pub-muted);
      font-size: 0.75rem;
      font-variant-numeric: tabular-nums;
      font-weight: 500;
      letter-spacing: -0.003em;
      white-space: nowrap;
    }
    .flow-progress {
      width: 72px;
      height: 6px;
      overflow: hidden;
      border-radius: 999px;
      background: var(--pub-line);
    }
    .flow-progress__fill {
      display: block;
      width: 25%;
      height: 100%;
      background: var(--pub-lime);
    }
    .flow-head .flow-alert--warn {
      max-width: 440px;
      margin: 0;
    }

    .flow-back {
      display: block;
      margin-bottom: 24px;
      color: var(--pub-lime-dark);
      font-size: 0.875rem;
      font-weight: 600;
      line-height: 1.55;
      letter-spacing: -0.005em;
      text-align: center;
    }
    .flow-back:hover {
      text-decoration: underline;
    }

    /* The claim page's own head: the reference under the title. */
    .claim-ref {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      gap: 8px;
      margin: 0 0 8px;
    }
    .claim-ref__label {
      color: var(--pub-muted);
      font-size: 0.875rem;
      letter-spacing: -0.005em;
    }
    .claim-ref__code {
      color: var(--pub-ink);
      font-family: var(--pub-mono);
      font-size: 1rem;
      font-weight: 700;
      letter-spacing: 0.02em;
    }
    /* "— cela devrait être 835,28" inside the amount label: a quieter aside. */
    .claim-expected {
      color: var(--pub-muted);
      font-weight: 400;
    }

    /* money7's spacing. */
    .flow--claim .flow-head h1 {
      margin-bottom: 12px;
    }
    .flow--claim .flow-submit {
      margin-bottom: 12px;
    }
  }
}

/* --------------------------------------------------------------------------
   Public flow pages, continued — the status page (money6 / moneyPhone6;
   templates/transfers/public/_status_body.html): status chip, copy buttons,
   the reference, the amount to pay, the recap, the accounts to pay, the
   payout code. Only QUOTED has a mockup; other states reuse these pieces.
   -------------------------------------------------------------------------- */
@layer public {
  .flow-tiny {
    color: var(--pub-muted);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.63;
    letter-spacing: -0.003em;
  }
  .flow-alert--info {
    background: var(--pub-panel);
    color: var(--pub-ink);
  }

  /* --- Status chip: a dot + the word (never colour alone) ------------------ */
  .flow-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 4px 12px;
    border-radius: 9999px;
    background: var(--pub-lime);
    color: var(--pub-ink);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: -0.003em;
    white-space: nowrap;
  }
  .flow-chip::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--pub-ink);
  }
  /* CLAIMED — waiting on an agent (money8): outlined, the dot breathes. */
  .flow-chip--new {
    background: var(--pub-white);
    box-shadow: inset 0 0 0 1px var(--pub-lime-dark);
  }
  .flow-chip--new::before {
    background: var(--pub-lime-dark);
    animation: flow-pulse 1.6s ease-in-out infinite;
  }
  /* CONFIRMED — the code is ready. */
  .flow-chip--go {
    background: var(--pub-ink);
    color: var(--pub-lime);
  }
  .flow-chip--go::before {
    background: var(--pub-lime);
  }
  /* PAID_OUT — settled, quiet. */
  .flow-chip--done {
    background: var(--pub-panel);
  }
  .flow-chip--done::before {
    background: var(--pub-muted);
  }
  /* CANCELLED */
  .flow-chip--stop {
    background: var(--pub-error-bg);
    color: var(--pub-error);
  }
  .flow-chip--stop::before {
    background: var(--pub-error);
  }
  @keyframes flow-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.35; transform: scale(0.7); }
  }
  @media (prefers-reduced-motion: reduce) {
    .flow-chip--new::before {
      animation: none;
    }
  }

  /* --- Copy button --------------------------------------------------------- */
  .flow-copy {
    flex: none;
    color: var(--pub-ink);
    font-family: inherit;
    cursor: pointer;
  }
  .flow-copy__icon--done {
    display: none;
  }

  /* --- Progress bar: n steps done out of 4 --------------------------------- */
  .flow-progress__fill--0 { width: 0; }
  .flow-progress__fill--1 { width: 25%; }
  .flow-progress__fill--2 { width: 50%; }
  .flow-progress__fill--3 { width: 75%; }
  .flow-progress__fill--4 { width: 100%; }

  /* --- Recap rows + accounts (shared bits) --------------------------------- */
  .status-section__body {
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .status-recap__row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    border-top: 1px dashed var(--pub-line);
    color: var(--pub-muted);
    font-size: 1rem;
    letter-spacing: -0.006em;
  }
  .status-recap__row:first-child {
    border-top: none;
  }
  .status-recap__row dd {
    margin: 0;
    color: var(--pub-ink);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
  }
  .status-recap__row.is-total {
    color: var(--pub-ink);
    font-weight: 600;
  }
  .status-recap__row.is-total dd {
    font-weight: 700;
    letter-spacing: -0.011em;
  }

  .status-pay__row {
    display: flex;
    align-items: center;
  }
  .status-pay__avatar {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--pub-panel);
    color: var(--pub-lime-dark);
    font-weight: 600;
    letter-spacing: 0;
  }
  .status-pay__info {
    flex: 1;
    min-width: 0;
  }
  .status-pay__name {
    font-weight: 600;
  }
  .status-pay__account {
    color: var(--pub-ink);
    font-family: var(--pub-mono);
  }
  .status-pay__holder {
    color: var(--pub-muted);
  }

  /* --- Payout code (CONFIRMED / PAID_OUT) ---------------------------------- */
  .status-code {
    padding: 16px;
    border: 1px solid var(--pub-line);
    border-radius: 10px;
    background: var(--pub-white);
  }
  .status-code__label {
    margin: 0 0 8px;
    color: var(--pub-muted);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .status-code__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .status-code__value {
    min-width: 0;
    color: var(--pub-ink);
    font-family: var(--pub-mono);
    font-size: 1.75rem;
    font-variant-numeric: tabular-nums;
    font-weight: 700;
    letter-spacing: 0.08em;
    word-break: break-all;
  }

  /* ==== Phone: moneyPhone6 ================================================== */
  @media (max-width: 719.98px) {
    .status-recap--desk,
    .status-pay__intro,
    .flow--status .flow-head > div > p {
      display: none;
    }
    /* No visible title on the phone (the reference card leads) — keep the
       <h1> for screen readers. */
    .flow--status .flow-head h1 {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
    }
    .flow--status .flow-head {
      margin: 24px 0 0;
    }

    /* Reference card: "Référence" + chip / code + copy. */
    .status-ref {
      display: grid;
      grid-template-columns: 1fr auto;
      grid-template-areas: "label chip" "code copy";
      align-items: center;
      gap: 4px 12px;
      padding: 16px;
      border: 1px solid var(--pub-line);
      border-radius: 10px;
      background: var(--pub-white);
    }
    .status-ref__label {
      grid-area: label;
      color: var(--pub-muted);
      font-size: 0.75rem;
      font-weight: 500;
      line-height: 1.63;
      letter-spacing: -0.003em;
    }
    .status-ref .flow-chip {
      grid-area: chip;
      justify-self: end;
    }
    .status-ref__code {
      grid-area: code;
      color: var(--pub-ink);
      font-family: var(--pub-mono);
      font-size: 1.25rem;
      font-weight: 700;
      letter-spacing: 0.02em;
    }
    .status-ref .flow-copy {
      grid-area: copy;
      justify-self: end; /* the chip above makes this column wider */
    }

    /* Copy buttons are icons on the phone (✓ once copied). */
    .flow-copy {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 36px;
      height: 36px;
      padding: 0;
      border: 1px solid var(--pub-line);
      border-radius: 50%;
      background: var(--pub-card);
      color: var(--pub-lime-dark);
      transition: background 0.15s ease, border-color 0.15s ease;
    }
    .flow-copy:hover {
      border-color: var(--pub-lime-dark);
    }
    .flow-copy:focus-visible {
      outline: 2px solid var(--pub-ink);
      outline-offset: 2px;
    }
    .flow-copy__text {
      display: none;
    }
    .flow-copy.is-copied {
      border-color: var(--pub-lime);
      background: var(--pub-lime);
      color: var(--pub-ink);
    }
    .flow-copy.is-copied .flow-copy__icon--copy {
      display: none;
    }
    .flow-copy.is-copied .flow-copy__icon--done {
      display: block;
    }

    .status-message,
    .status-code {
      margin: 16px 0 0;
    }
    .status-message {
      font-size: 1rem;
    }

    /* The amount to pay, big (QUOTED) — the display voice, tabular. */
    .status-topay {
      margin: 28px 0;
    }
    .status-topay__amount {
      display: block;
      margin: 4px 0 8px;
      color: var(--pub-ink);
      font-size: 3.25rem;
      font-variant-numeric: tabular-nums;
      font-weight: 900;
      line-height: 1;
      letter-spacing: -0.03em;
    }
    .status-topay__detail {
      margin: 0;
      color: var(--pub-muted);
      font-size: 0.875rem;
      line-height: 1.55;
      letter-spacing: -0.005em;
    }

    /* Sections: a heading over a white card. */
    .status-section__title {
      margin: 0 0 8px;
      font-size: 1rem;
      font-weight: 600;
      line-height: 1.5;
      letter-spacing: -0.006em;
    }
    .status-section__body {
      padding: 0 16px;
      border: 1px solid var(--pub-line);
      border-radius: 10px;
      background: var(--pub-white);
    }
    .status-recap {
      margin-top: 24px;
    }
    .status-recap__row {
      padding: 12px 0;
    }
    .status-recap__row.is-total dd {
      font-size: 1.125rem;
      letter-spacing: -0.007em;
    }

    .status-pay__row {
      gap: 12px;
      padding: 12px 0;
    }
    .status-pay__row + .status-pay__row {
      border-top: 1px dashed var(--pub-line);
    }
    .status-pay__avatar {
      width: 36px;
      height: 36px;
      font-size: 0.75rem;
    }
    /* name ··· account on one line, the holder under them */
    .status-pay__info {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto;
      align-items: baseline;
      column-gap: 8px;
    }
    .status-pay__name {
      font-size: 1rem;
    }
    .status-pay__account {
      font-size: 0.875rem;
      white-space: nowrap;
    }
    .status-pay__holder {
      grid-column: 1 / -1;
      overflow: hidden;
      font-size: 0.75rem;
      white-space: nowrap;
      text-overflow: ellipsis;
    }

    .flow--status .flow-bottom {
      padding-top: 20px;
    }

    @media (prefers-reduced-motion: reduce) {
      .flow-copy {
        transition: none;
      }
    }
  }

  /* ==== Desktop: money6 as a full page ====================================== */
  @media (min-width: 720px) {
    .status-topay,
    .status-ref__label,
    .flow-copy__icon {
      display: none;
    }
    .flow--status .flow-head h1 {
      margin-bottom: 10px;
    }

    /* Reference row: code · chip · "Copier". */
    .status-ref {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      gap: 8px;
      margin-bottom: 8px;
    }
    .status-ref__code {
      order: -1;
      color: var(--pub-ink);
      font-family: var(--pub-mono);
      font-size: 1rem;
      font-weight: 700;
      letter-spacing: 0.02em;
    }

    .flow-copy {
      padding: 4px 12px;
      border: 1px solid var(--pub-line);
      border-radius: 9999px;
      background: var(--pub-card);
      font-size: 0.875rem;
      font-weight: 600;
      line-height: 1.55;
      letter-spacing: -0.005em;
      transition: border-color 0.15s ease, background-color 0.15s ease;
    }
    .flow-copy:hover {
      border-color: var(--pub-lime-dark);
    }
    .flow-copy.is-copied {
      border-color: var(--pub-lime);
      background: var(--pub-lime);
    }
    /* The reference's "Copier" is a text link. */
    .flow-copy--link,
    .flow-copy--link:hover,
    .flow-copy--link.is-copied {
      padding: 0;
      border: none;
      background: none;
      color: var(--pub-lime-dark);
    }

    .status-message,
    .status-code {
      margin: 0 0 16px;
    }
    .status-message {
      font-size: 1rem;
    }

    /* Sections (and the payout code) are white large cards with a ruled
       title — the same card as the quote form. */
    .status-section,
    .status-code {
      padding: 24px;
      border: none;
      border-radius: 28px;
      background: var(--pub-white);
      box-shadow: 0 1px 2px var(--pub-panel-shadow), 0 16px 40px var(--pub-panel-shadow);
    }
    .status-section {
      margin-bottom: 16px;
    }
    .status-section__title {
      margin: 0 -24px 16px;
      padding: 0 24px 16px;
      border-bottom: 1px solid var(--pub-line);
      font-size: 1.125rem;
      font-weight: 600;
      line-height: 1.44;
      letter-spacing: -0.007em;
    }
    .status-recap__row {
      padding: 12px 0;
    }
    .status-recap__row:first-child {
      padding-top: 0;
    }
    .status-recap__row:last-child {
      padding-bottom: 0;
    }
    .status-recap__row.is-total dd {
      font-size: 1.5625rem;
      letter-spacing: -0.009em;
    }

    .status-pay__intro {
      margin: 0 0 8px;
      color: var(--pub-muted);
      font-size: 0.875rem;
      line-height: 1.55;
      letter-spacing: -0.005em;
    }
    .status-pay__row {
      gap: 12px;
      padding: 12px 0;
      border-top: 1px dashed var(--pub-line);
    }
    .status-pay__row:first-child {
      border-top: none;
    }
    .status-pay__row .flow-copy {
      margin-left: 2px;
    }
    .status-pay__avatar {
      width: 40px;
      height: 40px;
      border: 1px solid var(--pub-line);
      font-size: 0.75rem;
    }
    .status-pay__name,
    .status-pay__account,
    .status-pay__holder {
      display: block;
    }
    .status-pay__name {
      font-size: 1rem;
    }
    .status-pay__account {
      font-size: 0.875rem;
    }
    .status-pay__holder {
      font-size: 0.75rem;
      overflow-wrap: anywhere;
    }
  }
}

/* --------------------------------------------------------------------------
   Public flow pages, continued — the status page while CLAIMED ("Vérification
   en cours"; money8 / moneyPhone8): the verification card, the auto-refresh
   label, the locked payout-code placeholder, the after-payment recap.
   -------------------------------------------------------------------------- */
@layer public {
  /* "Mise à jour automatique" — a breathing dot + the words. */
  .flow-autorefresh {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--pub-lime-dark);
    font-weight: 500;
    line-height: 1.63;
    letter-spacing: -0.003em;
  }
  .flow-autorefresh::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--pub-lime-dark);
    animation: flow-pulse 1.6s ease-in-out infinite;
  }
  @keyframes flow-spin {
    to { transform: rotate(360deg); }
  }

  .status-verify__title {
    color: var(--pub-ink);
    font-weight: 700;
    text-wrap: wrap;
  }
  .status-verify__text {
    color: var(--pub-muted);
    line-height: 1.5;
  }
  .status-codeslot__label,
  .status-codeslot__hint {
    margin: 0;
  }
  .status-codeslot__label {
    color: var(--pub-muted);
    font-weight: 500;
    letter-spacing: -0.003em;
  }
  .status-codeslot__hint {
    color: var(--pub-muted);
  }
  .status-codeslot__mask {
    flex: none;
    color: var(--pub-line);
    font-family: var(--pub-mono);
    font-weight: 700;
  }

  @media (prefers-reduced-motion: reduce) {
    .flow-autorefresh::before,
    .status-verify__icon,
    .status-verify__icon::before {
      animation: none;
    }
  }

  /* ==== Phone: moneyPhone8 ================================================== */
  @media (max-width: 719.98px) {
    /* The reference moves into the status card in this state. */
    .flow--status.is-claimed .flow-head {
      margin: 0;
    }
    .flow--status.is-claimed .flow-head .status-ref {
      display: none;
    }

    .status-verify {
      margin-top: 24px;
      padding: 24px;
      border: 1px solid var(--pub-line);
      border-radius: 28px;
      background: linear-gradient(180deg, var(--pub-lime-wash) 0%, var(--pub-white) 72%);
      text-align: center;
    }
    /* a static clock inside a spinning ring */
    .status-verify__icon {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 64px;
      height: 64px;
      margin: 0 auto 16px;
      border-radius: 50%;
      background: var(--pub-white);
      color: var(--pub-go);
    }
    .status-verify__icon::before {
      content: "";
      position: absolute;
      inset: 0;
      border: 4px solid var(--pub-line);
      border-top-color: var(--pub-go);
      border-radius: 50%;
      animation: flow-spin 1.1s linear infinite;
    }
    .status-verify__chip {
      display: block;
    }
    .status-verify .flow-chip {
      margin-bottom: 12px;
    }
    .status-verify__title {
      margin: 0 0 8px;
      font-size: 1.5625rem;
      line-height: 1.3;
      letter-spacing: -0.009em;
    }
    .status-verify__text {
      max-width: 300px;
      margin: 0 auto 20px;
      font-size: 1rem;
      text-wrap: balance;
    }
    .status-verify__ref {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      padding: 12px 16px;
      border: 1px solid var(--pub-line);
      border-radius: 10px;
      background: var(--pub-white);
      text-align: left;
    }
    .status-verify__ref .flow-tiny {
      display: block;
    }
    .status-verify__code {
      color: var(--pub-ink);
      font-family: var(--pub-mono);
      font-size: 1.125rem;
      font-weight: 700;
      letter-spacing: 0.02em;
    }
    .status-verify .flow-autorefresh {
      margin-top: 16px;
      font-size: 0.75rem;
    }

    /* Recap after payment (moneyPhone8): received + sent, no fee row. */
    .status-recap {
      margin-top: 24px;
    }
    .status-recap .status-section__body {
      padding: 0;
    }
    .status-recap__row {
      padding: 12px 16px;
    }
    .is-claimed .status-recap__row--fee,
    .is-confirmed .status-recap__row--fee,
    .is-paid_out .status-recap__row--fee {
      display: none;
    }

    /* The payout code's future place — locked. */
    .status-codeslot {
      display: flex;
      align-items: center;
      gap: 12px;
      margin-top: 12px;
      padding: 12px 16px;
      border: 1.5px dashed var(--pub-line);
      border-radius: 10px;
    }
    .status-codeslot__icon {
      display: flex;
      flex: none;
      align-items: center;
      justify-content: center;
      width: 36px;
      height: 36px;
      border-radius: 50%;
      background: var(--pub-panel);
      color: var(--pub-muted);
    }
    .status-codeslot__text {
      flex: 1;
      min-width: 0;
    }
    .status-codeslot__label {
      font-size: 0.75rem;
      line-height: 1.63;
    }
    .status-codeslot__hint {
      font-size: 0.875rem;
      line-height: 1.55;
    }
    .status-codeslot__mask {
      font-size: 1rem;
      letter-spacing: 0.18em;
    }

    /* A footer line on its own (no button above it) sits flush. */
    .flow-bottom > .flow-fineprint:first-child {
      margin-top: 0;
    }
  }

  /* ==== Desktop: money8 ===================================================== */
  @media (min-width: 720px) {
    .flow-phone,
    .status-verify__chip,
    .status-verify__ref,
    .status-verify__icon svg,
    .status-codeslot__icon {
      display: none;
    }

    .status-verify {
      display: flex;
      align-items: flex-start;
      gap: 16px;
      margin-bottom: 16px;
      padding: 24px;
      border: 1px solid var(--pub-lime-dark);
      border-radius: 28px;
      background: var(--pub-white);
      box-shadow: inset 0 0 0 1px var(--pub-lime-dark);
    }
    .status-verify__icon {
      flex: none;
      width: 36px;
      height: 36px;
      border: 3px solid var(--pub-line);
      border-top-color: var(--pub-lime-dark);
      border-radius: 50%;
      animation: flow-spin 1.1s linear infinite;
    }
    .status-verify__title {
      margin: 4px 0;
      font-size: 1.125rem;
      line-height: 1.44;
      letter-spacing: -0.007em;
    }
    .status-verify__text {
      margin: 0;
      font-size: 1rem;
    }
    .status-verify .flow-autorefresh {
      margin-top: 12px;
      font-size: 0.75rem;
    }

    .status-codeslot {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      margin-bottom: 16px;
      padding: 24px;
      border: 1.5px dashed var(--pub-pebble);
      border-radius: 28px;
    }
    .status-codeslot__label {
      font-size: 0.75rem;
      line-height: 1.63;
    }
    .status-codeslot__hint {
      font-size: 0.875rem;
      line-height: 1.55;
    }
    .status-codeslot__mask {
      font-size: 1.1rem;
      letter-spacing: 0.2em;
    }
  }
}

/* --------------------------------------------------------------------------
   Agent — the neutral staff surface (DESIGN.md §5.2). Calm: white / grey /
   black, brand only as a small accent. Dense but breathing — tight rows for
   scanning, money right-aligned. Dark mode is live here.
   -------------------------------------------------------------------------- */

@layer agent {
  .page--agent .site-main {
    max-width: var(--page-max);
  }

  /* Page head — title + optional back link + optional actions row. */
  .agent-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-4);
    margin-bottom: var(--space-5);
  }
  .agent-head h1 {
    margin: 0;
    font-size: 1.375rem;
  }
  .agent-back {
    font-size: 0.9375rem;
  }
  /* Which role this screen belongs to — a quiet pill in the page head. */
  .agent-role {
    align-self: center;
    padding: 2px var(--space-3);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    color: var(--ink-muted);
    font-size: 0.8125rem;
    white-space: nowrap;
  }

  /* "You're signed in as …" line on the landing page. */
  .agent-intro {
    margin-bottom: var(--space-4);
  }

  .agent-section {
    margin-top: var(--space-6);
  }
  .agent-section > h2 {
    padding-bottom: var(--space-2);
    border-bottom: 1px solid var(--line-strong);
    font-size: 1.0625rem;
  }
  .agent-note {
    margin-top: var(--space-1);
    color: var(--ink-muted);
    font-size: 0.9375rem;
  }

  /* Collector totals — today / this week / this month (same visual language
     as .payout-amount: bordered surface-alt panel, muted label, tabular
     value). Auto-fit grid so three cards wrap cleanly on narrow screens. */
  .totals-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-5);
  }
  .totals-card {
    padding: var(--space-4);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-card);
    background: var(--surface-alt);
  }
  .totals-card__label {
    margin: 0 0 var(--space-1);
    color: var(--ink-muted);
    font-size: 0.9375rem;
  }
  .totals-card__value {
    margin: 0;
    font-size: 1.375rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
  }
  .totals-card__count {
    margin: var(--space-1) 0 0;
    color: var(--ink-muted);
    font-size: 0.875rem;
  }

  /* Queue filter / count bar above a table (§7.5). Sits clear of the newest
     row — it never overlaps the first <tr>. */
  .queue-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
    font-size: 0.9375rem;
  }
  .queue-bar__count {
    font-weight: 500;
  }
  .queue-bar .chip {
    vertical-align: middle;
  }

  /* Search bar above a queue/history table — input grows, controls stay put. */
  .search-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
  }
  .search-bar input[type="search"] {
    flex: 1 1 20rem;
    max-width: 24rem;
  }
  .search-bar__clear {
    font-size: 0.875rem;
  }

  /* Prev / page X of Y / Next, under a paginated table. */
  .pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    margin-top: var(--space-4);
  }
  .pagination__status {
    color: var(--ink-muted);
    font-size: 0.875rem;
  }

  /* Simple nav list on the agent landing page. */
  .agent-links {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-3);
    max-width: 22rem;
  }
  .agent-links a {
    display: block;
    padding: var(--space-4);
    border: 1px solid var(--line);
    border-radius: var(--radius-card);
    background: var(--surface);
    text-decoration: none;
    font-weight: 500;
  }
  .agent-links a:hover {
    border-color: var(--line-strong);
  }

  /* Payout confirm screen — the amount is the whole point of the page. */
  .payout-amount {
    margin: var(--space-4) 0;
    padding: var(--space-5);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-card);
    background: var(--surface-alt);
  }
  .payout-amount__label {
    margin: 0 0 var(--space-1);
    color: var(--ink-muted);
    font-size: 0.9375rem;
  }
  .payout-amount__value {
    font-size: 2rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
  }
  /* Releasing cash is deliberate — the button stands alone, with a warning
     line, not shoulder-to-shoulder with anything else (§7.1). */
  .payout-confirm {
    margin-top: var(--space-5);
  }
  .payout-confirm p {
    margin-bottom: var(--space-3);
    color: var(--ink-muted);
  }

  /* Outcome line after a confirm / reject / pay-out row swap. */
  .action-result {
    padding: var(--space-3);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface-alt);
    font-size: 0.9375rem;
  }
}

/* --------------------------------------------------------------------------
   Agent dashboard shell — the dash1.html mockup on the public palette
   (templates/transfers/agent/_dash_sidebar.html + collector_dashboard.html,
   body.page--dash). An ink sidebar (the landing's nav pill, stood on end), a
   display-voice title, white 28px cards, pill buttons and the flow status
   chips — --pub-* tokens and the landing type system (Inter, per-size
   tracking; JetBrains Mono only for what people copy or read out).
   Light-only, like the public pages: no dark remap reaches these tokens.
   In the agent layer, so it outranks the public layer where it resizes
   .landing-btn. No JavaScript: below 900px the sidebar becomes a bar across
   the top; below 640px table rows become stacked label/value blocks from
   td[data-label] — never a sideways-scrolling table on a phone (§7.3).
   -------------------------------------------------------------------------- */

@layer agent {
  :root:has(> body.page--dash) {
    color-scheme: light;
  }
  .page--dash {
    display: block;
    color-scheme: light;
    background: var(--pub-card);
    color: var(--pub-ink);
    font-family: var(--pub-sans);
    font-feature-settings: "calt" 1;
    font-size: 1rem;
    line-height: 1.5;
    letter-spacing: -0.006em;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  .page--dash :focus-visible {
    outline-color: var(--pub-ink);
  }
  /* Zero-specificity resets of the base layer's element defaults. */
  :where(.dash) :is(h1, h2, p) {
    margin: 0;
    max-width: none;
  }
  :where(.dash) a {
    color: inherit;
    text-decoration: none;
  }
  :where(.dash) :is(button, input) {
    font-family: inherit;
    letter-spacing: inherit;
  }
  .page--dash button {
    cursor: pointer;
  }

  /* The base layer's `svg { height: auto }` would size the sprite to 300×150
     and let it sit over the logo — pin it to nothing. */
  .dash-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
  }
  .dash-ico {
    flex: none;
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  .dash {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    min-height: 100vh;
  }

  /* --- Sidebar ------------------------------------------------------------ */
  .dash-side {
    position: sticky;
    top: 16px;
    z-index: 40;
    align-self: start;
    display: flex;
    flex-direction: column;
    width: 256px;
    height: calc(100vh - 32px);
    height: calc(100dvh - 32px);
    margin: 16px 0 16px 16px;
    padding: 24px 12px 16px;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
    border-radius: 28px;
    background: var(--pub-ink);
    color: var(--pub-white);
  }
  .dash-side::-webkit-scrollbar {
    display: none;
  }
  .dash-side :focus-visible {
    outline-color: var(--pub-lime);
  }
  .dash-logo {
    margin: 0 0 28px 16px;
    color: var(--pub-white);
    font-size: 1.25rem;
  }
  /* Sentence case, never tracked-out caps (§3, §9). */
  .dash-label {
    margin: 0 0 6px;
    padding: 0 16px;
    color: color-mix(in srgb, var(--pub-nav-link) 62%, var(--pub-ink));
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.63;
    letter-spacing: -0.003em;
  }
  .dash-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  /* Nav segments: pills that light up under the pointer (landing nav). */
  .dash-link {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 44px;
    padding: 10px 16px;
    border: 0;
    border-radius: 9999px;
    background: transparent;
    color: var(--pub-nav-link);
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.5;
    letter-spacing: -0.006em;
    text-align: left;
    white-space: nowrap;
    transition: background-color 0.2s ease, color 0.2s ease;
  }
  .dash-link:hover {
    background: rgb(255 255 255 / 0.08);
    color: var(--pub-white);
  }
  /* Active = the landing's "Connexion" pill. */
  .dash-link.is-active {
    background: var(--pub-nav-btn);
    color: var(--pub-white);
    font-weight: 600;
  }
  .dash-link.is-active .dash-ico {
    color: var(--pub-lime);
  }
  .dash-link__count {
    min-width: 24px;
    margin-left: auto;
    padding: 0 8px;
    border-radius: 9999px;
    background: var(--pub-lime);
    color: var(--pub-ink);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 22px;
    letter-spacing: 0;
    text-align: center;
    font-variant-numeric: tabular-nums;
  }
  .dash-side__foot {
    margin-top: auto;
    padding-top: 24px;
  }
  .dash-side__foot form {
    margin: 0;
  }

  /* --- Main column + top bar ---------------------------------------------- */
  .dash-main {
    min-width: 0;
    padding: 16px 32px 32px;
  }
  .page--dash .messages {
    margin: 16px 0 0;
  }
  .dash-top {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 16px;
    padding: 24px 0 28px;
  }
  .dash-eyebrow {
    margin-bottom: 8px;
    color: var(--pub-muted);
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  /* Display voice: Inter Black, like the hero and the section openers. */
  .dash-top h1 {
    font-size: clamp(2.5rem, 4.2vw, 3.5rem);
    font-weight: 900;
    line-height: 0.95;
    letter-spacing: -0.04em;
  }
  .dash-top__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-left: auto;
  }

  /* Today's running total — where the mockup had its promo pill. */
  .dash-today {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 48px;
    padding: 0 20px 0 16px;
    border-radius: 9999px;
    background: var(--pub-lime-soft);
    white-space: nowrap;
  }
  .dash-today .dash-ico {
    width: 18px;
    height: 18px;
  }
  .dash-today__label {
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: -0.005em;
  }
  .dash-today__value {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
  }

  /* Signed-in agent — initial, name, role. Never the email (minimal exposure). */
  .dash-user {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 20px 4px 4px;
    border: 1px solid var(--pub-line-soft);
    border-radius: 9999px;
    background: var(--pub-white);
  }
  .dash-user__avatar {
    display: grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--pub-sun);
    color: var(--pub-ink);
    font-weight: 800;
  }
  .dash-user__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
  }
  .dash-user__name {
    max-width: 14rem;
    overflow: hidden;
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .page--dash .agent-role {
    align-self: flex-start;
    padding: 0;
    border: 0;
    border-radius: 0;
    color: var(--pub-muted);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: -0.003em;
  }

  /* --- Buttons: the landing's pills, laid out for an icon ------------------ */
  .dash-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
  }
  .dash-btn--sm {
    padding: 9px 18px;
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .dash-btn--sm.landing-btn--secondary {
    padding: 8px 17px;
  }
  .dash-btn--ink {
    background: var(--pub-ink);
    color: var(--pub-white);
  }
  .dash-btn--ink:hover {
    background: color-mix(in srgb, var(--pub-ink) 82%, var(--pub-white));
  }
  /* Reject reads as deliberate: outlined, error text — never the same
     weight as the lime Confirm beside it (§7.1). */
  .dash-btn--danger {
    color: var(--pub-error);
  }
  .dash-btn--danger:hover {
    border-color: var(--pub-error);
    background: var(--pub-error-bg);
  }
  .htmx-request.dash-btn {
    opacity: 0.6;
    cursor: progress;
  }

  /* --- Inventaire (collector_inventory.html) -------------------------------- */
  /* The agency's collections as a calendar: month tiles, the weeks of a
     month, year tiles. The current period is the ink tile with a lime figure
     (like the landing's dark card cell); the month whose weeks are shown
     gets a lime ring; future periods are outlined and muted. */
  .dash-yearnav {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: auto;
    padding: 3px;
    border-radius: 9999px;
    background: var(--pub-panel);
  }
  .dash-yearnav__btn {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: var(--pub-ink);
    transition: background-color 0.2s ease;
  }
  a.dash-yearnav__btn:hover {
    background: var(--pub-white);
  }
  .dash-yearnav__btn.is-disabled {
    color: var(--pub-muted);
    opacity: 0.4;
  }
  .dash-yearnav__btn .dash-ico {
    width: 18px;
    height: 18px;
  }
  .dash-yearnav__label {
    min-width: 3.5rem;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
  }

  .dash-cal {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px;
    margin: 0;
    padding: 0 8px 8px;
    list-style: none;
  }
  .dash-cal--years {
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  }
  .dash-cal__tile {
    display: flex;
    flex-direction: column;
    gap: 2px;
    height: 100%;
    padding: 16px;
    border-radius: 20px;
    background: var(--pub-panel);
    color: var(--pub-ink);
    transition: background-color 0.2s ease, box-shadow 0.2s ease;
  }
  a.dash-cal__tile:hover {
    background: color-mix(in srgb, var(--pub-panel) 55%, var(--pub-lime));
  }
  .dash-cal__name {
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .dash-cal__value {
    margin-top: 8px;
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: -0.007em;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  .dash-cal__count {
    color: var(--pub-muted);
    font-size: 0.75rem;
    letter-spacing: -0.003em;
  }
  .dash-cal__tile.is-current {
    background: var(--pub-ink);
    color: var(--pub-white);
  }
  a.dash-cal__tile.is-current:hover {
    background: color-mix(in srgb, var(--pub-ink) 85%, var(--pub-white));
  }
  .dash-cal__tile.is-current .dash-cal__value {
    color: var(--pub-lime);
  }
  .dash-cal__tile.is-current .dash-cal__count {
    color: var(--pub-nav-link);
  }
  .dash-cal__tile.is-selected {
    box-shadow: 0 0 0 2px var(--pub-white), 0 0 0 4px var(--pub-lime-dark);
  }
  /* Nothing collected: the figure steps back so real months stand out. */
  .dash-cal__tile.is-empty:not(.is-current) .dash-cal__value,
  .dash-weeks__row.is-empty:not(.is-current) .dash-weeks__value {
    color: var(--pub-muted);
    font-weight: 500;
  }
  .dash-cal__tile.is-future {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--pub-line);
    color: var(--pub-muted);
  }

  .dash-weeks {
    margin: 0;
    padding: 0 8px 8px;
    list-style: none;
  }
  .dash-weeks__row {
    display: grid;
    grid-template-columns: 6rem minmax(0, 1fr) auto 8rem;
    align-items: center;
    gap: 16px;
    min-height: 60px;
    padding: 8px 16px;
    border-bottom: 1px dashed var(--pub-line);
  }
  .dash-weeks__row:last-child {
    border-bottom: 0;
  }
  .dash-weeks__num {
    justify-self: start;
    padding: 2px 10px;
    border-radius: 9999px;
    background: var(--pub-panel);
    font-size: 0.75rem;
    font-weight: 700;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }
  .dash-weeks__range {
    color: var(--pub-muted);
    font-size: 0.875rem;
    letter-spacing: -0.005em;
  }
  .dash-weeks__value {
    font-weight: 700;
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }
  .dash-weeks__count {
    color: var(--pub-muted);
    font-size: 0.75rem;
    text-align: right;
  }
  .dash-weeks__row.is-current {
    border-bottom-color: transparent;
    border-radius: 14px;
    background: var(--pub-lime-soft);
  }
  .dash-weeks__row.is-current .dash-weeks__num {
    background: var(--pub-ink);
    color: var(--pub-lime);
  }
  .dash-weeks__row.is-future .dash-weeks__value {
    color: var(--pub-muted);
    font-weight: 500;
  }

  /* Month grid columns follow the card's width (divisors of 12). */
  @container dash-card (max-width: 959.98px) {
    .dash-cal--months {
      grid-template-columns: repeat(4, minmax(0, 1fr));
    }
  }
  @container dash-card (max-width: 639.98px) {
    .dash-cal--months {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }
    .dash-cal__value {
      font-size: 1rem;
    }
  }
  @container dash-card (max-width: 479.98px) {
    .dash-cal--months {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .dash-weeks__row {
      grid-template-columns: minmax(0, 1fr) auto;
      grid-template-areas:
        "num value"
        "range count";
      row-gap: 2px;
      padding: 10px 12px;
    }
    .dash-weeks__num {
      grid-area: num;
    }
    .dash-weeks__value {
      grid-area: value;
    }
    .dash-weeks__range {
      grid-area: range;
    }
    .dash-weeks__count {
      grid-area: count;
    }
  }

  /* --- Cards (the landing's transfer panel) -------------------------------- */
  .dash-card {
    padding: 8px;
    border-radius: 28px;
    background: var(--pub-white);
    box-shadow: 0 1px 2px var(--pub-panel-shadow), 0 16px 40px var(--pub-panel-shadow);
  }
  .dash-card + .dash-card {
    margin-top: 16px;
  }
  .dash-card__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 16px 12px 20px 20px;
  }
  .dash-card__head h2 {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.375rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.008em;
  }
  .dash-count {
    padding: 2px 10px;
    border-radius: 9999px;
    background: var(--pub-panel);
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    font-variant-numeric: tabular-nums;
  }

  .dash-search {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 0 auto;
  }
  /* Inputs: 10px, 1px Pebble; focus = ink edge doubled by an inset shadow. */
  .dash-field {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 340px;
    height: 40px;
    padding: 0 14px;
    border: 1px solid var(--pub-pebble);
    border-radius: 10px;
    background: var(--pub-white);
    color: var(--pub-muted);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
  }
  .dash-field:focus-within {
    border-color: var(--pub-ink);
    box-shadow: inset 0 0 0 1px var(--pub-ink);
  }
  .dash-field .dash-ico {
    width: 18px;
    height: 18px;
  }
  .dash-field input {
    flex: 1;
    min-width: 0;
    padding: 0;
    border: 0;
    outline: 0;
    background: transparent;
    color: var(--pub-ink);
    font-size: 0.875rem;
    letter-spacing: -0.005em;
  }
  .dash-field input::placeholder {
    color: var(--pub-muted);
    opacity: 1;
  }
  .dash-clear {
    padding: 4px;
    font-size: 0.875rem;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  /* --- Table (the default layout) ------------------------------------------ */
  /* Tables at every width (DESIGN.md §7.3). When a card is narrower than its
     table, the table scrolls sideways inside the card and the actions column
     stays pinned right, so Confirm / Reject / ⋯ are always in reach. The
     header switch pins the card layout instead (.is-cards, further down). */
  .dash-table-wrap {
    overflow-x: auto;
  }
  .dash-table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
  }
  .dash-table--wide:not(.is-cards) {
    min-width: 920px;
  }
  .dash-table thead th {
    height: 44px;
    padding: 0 16px;
    background: var(--pub-panel);
    color: var(--pub-muted);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: -0.005em;
    text-align: left;
    white-space: nowrap;
  }
  .dash-table thead th:first-child {
    border-radius: 10px 0 0 10px;
  }
  .dash-table thead th:last-child {
    border-radius: 0 10px 10px 0;
  }
  .dash-table td,
  .dash-table tbody th,
  .dash-table tfoot th {
    height: 76px;
    padding: 8px 14px;
    border-bottom: 1px dashed var(--pub-line);
    font-weight: inherit;
    text-align: left;
    white-space: nowrap;
    transition: background-color 0.15s ease;
  }
  .dash-table tr > :first-child {
    padding-left: 20px;
  }
  .dash-table tbody tr:last-child > * {
    border-bottom: 0;
  }
  .dash-table tbody tr:hover > td {
    background: color-mix(in srgb, var(--pub-panel) 45%, var(--pub-white));
  }
  /* New since the last visit (§7.5): a warm tint and a sun edge. */
  .dash-table tbody tr.is-new td {
    background: var(--pub-sun-soft);
  }
  .dash-table tbody tr.is-new td:first-child {
    box-shadow: inset 3px 0 0 var(--pub-sun);
  }
  /* Money right-aligned, tabular figures (§5.2). */
  .dash-table .num {
    padding-right: 24px;
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  .dash-table .act {
    text-align: right;
  }
  /* Names may wrap; everything read character by character stays on one line. */
  .dash-table td.dash-strong {
    min-width: 7rem;
    white-space: normal;
  }
  /* The actions column is pinned right at every width: if a table ever runs
     wider than its card, Confirm / Reject / ⋯ never scroll out of reach. Its
     backgrounds are opaque twins of the row tints so nothing shows through. */
  .dash-table--wide:not(.is-cards) .act {
    position: sticky;
    right: 0;
    z-index: 1;
    background: var(--pub-white);
  }
  .dash-table--wide:not(.is-cards) thead .act {
    background: var(--pub-panel);
  }
  .dash-table--wide:not(.is-cards) tbody tr:hover > .act {
    background: color-mix(in srgb, var(--pub-panel) 45%, var(--pub-white));
  }
  .dash-table--wide:not(.is-cards) tbody tr.is-new > .act {
    background: color-mix(in srgb, var(--pub-sun) 25%, var(--pub-white));
  }
  /* Words in the wide table; the icons appear once the buttons compact. */
  .dash-table:not(.is-cards) .dash-actions .dash-btn .dash-ico {
    display: none;
  }

  .dash-lead {
    display: flex;
    align-items: center;
    gap: 12px;
  }
  .dash-op {
    display: grid;
    place-items: center;
    flex: none;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--pub-panel);
    color: var(--pub-ink);
    font-weight: 700;
  }
  .dash-stack {
    display: flex;
    flex-direction: column;
    min-width: 0;
  }
  .dash-lead__ref {
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.4;
  }
  .dash-sub {
    color: var(--pub-muted);
    font-size: 0.75rem;
    line-height: 1.5;
    letter-spacing: -0.003em;
  }
  /* Mono only for what people copy or read out — refs, phone numbers. */
  .dash-mono {
    font-family: var(--pub-mono);
    letter-spacing: 0;
    font-variant-numeric: tabular-nums;
  }
  .dash-strong,
  .dash-amount {
    font-weight: 600;
  }
  .dash-muted {
    color: var(--pub-muted);
    font-size: 0.875rem;
    letter-spacing: -0.005em;
  }
  .dash-actions {
    display: inline-flex;
    gap: 8px;
  }
  .dash-empty td {
    height: 160px;
    color: var(--pub-muted);
    text-align: center;
    white-space: normal;
  }
  /* Outcome line swapped in after confirm / reject (_action_result.html). */
  .page--dash .action-result {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    border: 0;
    border-radius: 9999px;
    background: var(--pub-panel);
    color: var(--pub-ink);
    font-size: 0.875rem;
    font-weight: 500;
    white-space: normal;
  }
  .page--dash .action-result::before {
    content: "";
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--pub-lime-dark);
  }

  .dash-btn--sm .dash-ico {
    width: 16px;
    height: 16px;
  }

  /* --- "⋯" + its detail line (_dash_more.html) ------------------------------ */
  /* A bare <details> toggle in the row; its open state reveals the row's
     .dash-detail sibling — a full-width band under the transaction with its
     dates. Nothing floats, so nothing is clipped by the scrolling table. */
  .dash-actions {
    align-items: center;
    justify-content: flex-end;
  }
  .dash-more__btn {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: var(--pub-ink);
    list-style: none;
    cursor: pointer;
    transition: background-color 0.2s ease, color 0.2s ease;
  }
  .dash-more__btn::-webkit-details-marker {
    display: none;
  }
  .dash-more__btn::marker {
    content: "";
  }
  .dash-more__btn:hover {
    background: var(--pub-panel);
  }
  .dash-more[open] > .dash-more__btn {
    background: var(--pub-ink);
    color: var(--pub-lime);
  }
  .dash-table .dash-detail {
    display: none;
  }
  .dash-table tr:has(.dash-more[open]) + .dash-detail {
    display: table-row;
  }
  .dash-table tr:has(.dash-more[open]) > td {
    border-bottom-color: transparent;
  }
  .dash-table .dash-detail > td {
    height: auto;
    padding: 0 12px 16px 20px;
    background: none;
    white-space: normal;
  }
  /* Stays in view while a narrow table scrolls sideways. */
  .dash-detail__list {
    position: sticky;
    left: 20px;
    display: flex;
    flex-wrap: wrap;
    gap: 10px 32px;
    max-width: calc(100cqi - 56px);
    margin: 0;
    padding: 14px 20px;
    border-radius: 14px;
    background: var(--pub-panel);
  }
  .dash-detail__list div {
    display: flex;
    flex-direction: column;
  }
  .dash-detail__list dt {
    color: var(--pub-muted);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: -0.003em;
  }
  .dash-detail__list dd {
    margin: 0;
    font-size: 0.875rem;
    font-weight: 600;
  }

  /* --- History day headers --------------------------------------------------- */
  .dash-table .dash-day > th {
    height: auto;
    padding: 20px 16px 8px 20px;
    border-bottom: 0;
    background: none;
    color: var(--pub-ink);
    white-space: normal;
  }
  .dash-day__inner {
    position: sticky;
    left: 20px;
    display: inline-block;
    max-width: calc(100cqi - 56px);
  }
  .dash-day__label {
    margin-right: 8px;
    font-size: 0.9375rem;
    font-weight: 700;
    letter-spacing: -0.006em;
  }
  .dash-day__chip {
    display: inline-block;
    margin: 2px 4px 2px 0;
    padding: 2px 10px;
    border-radius: 9999px;
    background: var(--pub-panel);
    font-size: 0.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  /* --- Inventaire tables: row states ----------------------------------------- */
  .dash-table--inv td,
  .dash-table--inv tbody th,
  .dash-table--inv tfoot th {
    height: 56px;
  }
  .dash-table--inv tbody th {
    font-weight: 600;
  }
  .dash-rowlink {
    text-decoration: underline;
    text-decoration-color: var(--pub-line-soft);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
  }
  .dash-rowlink:hover {
    text-decoration-color: var(--pub-ink);
  }
  .dash-table tr.is-current > * {
    background: var(--pub-lime-soft);
  }
  .dash-table tr.is-selected > :first-child {
    box-shadow: inset 3px 0 0 var(--pub-lime-dark);
  }
  .dash-table tr.is-future > * {
    color: var(--pub-muted);
  }
  .dash-table tr.is-empty:not(.is-current) .dash-amount {
    color: var(--pub-muted);
    font-weight: 500;
  }
  .dash-table--inv tbody th .dash-sub {
    display: block;
    margin-top: 2px;
    font-weight: 400;
  }
  @container dash-card (max-width: 479.98px) {
    .dash-table--inv td,
    .dash-table--inv th {
      padding: 8px 10px;
    }
    .dash-table--inv tr > :first-child {
      padding-left: 12px;
    }
    .dash-table--inv .num {
      padding-right: 12px;
      font-size: 0.875rem;
    }
  }
  .dash-table tfoot th,
  .dash-table tfoot td {
    border-top: 1px solid var(--pub-line);
    border-bottom: 0;
    font-weight: 700;
  }
  .dash-table tfoot th {
    white-space: normal;
  }

  /* --- Table / cards switch (_dash_view_switch.html) ------------------------- */
  .dash-switch {
    display: flex;
    gap: 2px;
    margin: 0;
    padding: 3px;
    border-radius: 9999px;
    background: var(--pub-white);
    box-shadow: inset 0 0 0 1px var(--pub-line-soft);
  }
  .dash-switch button {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--pub-muted);
    transition: background-color 0.2s ease, color 0.2s ease;
  }
  .dash-switch button:hover {
    color: var(--pub-ink);
  }
  .dash-switch button[aria-pressed="true"] {
    background: var(--pub-ink);
    color: var(--pub-lime);
  }
  .dash-switch .dash-ico {
    width: 18px;
    height: 18px;
  }

  /* --- Pagination ------------------------------------------------------------ */
  .dash-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 20px 8px 12px;
  }
  .dash-pager__status {
    color: var(--pub-muted);
    font-size: 0.875rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }

  /* --- Payeur (payer_dashboard.html + payout_form.html) --------------------- */
  /* The code lookup is the payer's primary action: a large field + the lime
     pill. The payout screen is one card: the cash figure in the display
     voice (ink tile, lime figure — the inventory's "current" tile), the
     irreversibility warning, then Cancel / Confirm. */
  .dash-card__aside {
    flex-basis: 100%;
  }
  .dash-note {
    color: var(--pub-muted);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .dash-lookup__form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 0;
    padding: 0 20px 20px;
  }
  .dash-lookup__label {
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
  }
  .dash-lookup__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }
  .dash-field--lg {
    flex: 1 1 320px;
    width: auto;
    max-width: 520px;
    height: 52px;
  }
  .dash-field--lg input {
    font-family: var(--pub-mono);
    font-size: 1rem;
    letter-spacing: 0.04em;
  }
  .dash-field--lg input::placeholder {
    font-family: var(--pub-sans);
    letter-spacing: -0.005em;
  }
  .dash-field.is-invalid {
    border-color: var(--pub-error);
  }
  .dash-field.is-invalid:focus-within {
    box-shadow: inset 0 0 0 1px var(--pub-error);
  }
  .dash-lookup__row .dash-btn {
    min-height: 52px;
  }
  .dash-error {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-radius: 10px;
    background: var(--pub-error-bg);
    color: var(--pub-error);
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
  }
  .dash-error .dash-ico {
    width: 18px;
    height: 18px;
  }
  .dash-payout .dash-error {
    margin: 0 12px 12px;
  }

  .dash-back {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    border-radius: 9999px;
  }
  .dash-back:hover {
    color: var(--pub-ink);
  }
  .dash-back .dash-ico {
    width: 16px;
    height: 16px;
  }

  .dash-payout {
    max-width: 640px;
  }
  .dash-payout__amount {
    margin: 0 4px;
    padding: 24px 24px 28px;
    border-radius: 22px;
    background: var(--pub-ink);
    color: var(--pub-white);
  }
  .dash-payout__label {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    color: var(--pub-nav-link);
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
  }
  .dash-payout__label .dash-ico {
    width: 18px;
    height: 18px;
    color: var(--pub-lime);
  }
  .dash-payout__value {
    color: var(--pub-lime);
    font-size: clamp(2.5rem, 6vw, 3.5rem);
    font-weight: 900;
    line-height: 1;
    letter-spacing: -0.04em;
    font-variant-numeric: tabular-nums;
  }
  .dash-payout__warn {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 16px 4px 0;
    padding: 14px 16px;
    border-radius: 16px;
    background: var(--pub-sun-soft);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .dash-payout__warn .dash-ico {
    width: 18px;
    height: 18px;
    margin-top: 1px;
  }
  .dash-payout__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
    margin: 0;
    padding: 16px 12px 12px;
  }
  @media (max-width: 639.98px) {
    .dash-lookup__form {
      padding: 0 12px 12px;
    }
    .dash-field--lg {
      flex-basis: 100%;
      max-width: none;
    }
    .dash-lookup__row .dash-btn {
      width: 100%;
    }
    .dash-payout__amount {
      padding: 20px;
    }
    .dash-payout__actions .dash-btn {
      flex: 1 1 auto;
    }
  }

  /* --- Tablet: the sidebar becomes the landing's top bar -------------------- */
  @media (max-width: 899.98px) {
    .dash {
      display: block;
    }
    .dash-side {
      top: 12px;
      flex-direction: row;
      align-items: center;
      gap: 8px;
      width: auto;
      height: auto;
      margin: 12px 12px 0;
      padding: 8px 8px 8px 20px;
      overflow: visible;
      border-radius: 32px;
    }
    .dash-logo {
      margin: 0 auto 0 0;
    }
    .dash-label {
      display: none;
    }
    .dash-side__nav {
      min-width: 0;
      overflow-x: auto;
      scrollbar-width: none;
    }
    .dash-nav {
      flex-direction: row;
    }
    .dash-link {
      min-height: 44px;
      padding: 10px 14px;
    }
    .dash-side__foot {
      margin: 0;
      padding: 0;
    }
    .dash-side__foot .dash-link__text {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
    }
    .dash-main {
      padding: 8px 16px 24px;
    }
  }

  /* --- Narrow cards: a scrolling table with its actions pinned ---------------- */
  /* Keyed to the card's own width (container query), not the viewport: the
     queue needs ~920px, which a laptop with the sidebar doesn't always have. */
  .dash-card {
    container: dash-card / inline-size;
  }
  @container dash-card (max-width: 959.98px) {
    /* The table now scrolls: an edge shadow marks the pinned column. */
    .dash-table--wide:not(.is-cards) .act {
      box-shadow: -12px 0 12px -12px rgb(16 22 10 / 0.3);
    }
    /* Icon-only Confirm / Reject — the words stay for screen readers. */
    .dash-table--wide:not(.is-cards) .dash-actions .dash-btn .dash-ico {
      display: block;
    }
    .dash-table--wide:not(.is-cards) .dash-btn__text {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
    }
    .dash-table--wide:not(.is-cards) .dash-actions .dash-btn {
      width: 40px;
      height: 40px;
      padding: 0;
    }
  }

  /* --- Cards layout (the header switch: .is-cards) ------------------------------ */
  /* One transfer per block: the lead cell, then its label/value pairs in an
     auto-fit grid, then the actions full width. Bordered rows, not a rounded
     card per row (§9). */
  .dash-table.is-cards thead {
    display: none;
  }
  .dash-table.is-cards,
  .dash-table.is-cards tbody {
    display: block;
  }
  .dash-table.is-cards tr {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
    gap: 12px 16px;
    padding: 16px 12px;
    border-bottom: 1px dashed var(--pub-line);
  }
  .dash-table.is-cards tbody tr:last-child {
    border-bottom: 0;
  }
  .dash-table.is-cards td,
  .dash-table.is-cards tr > :first-child {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    height: auto;
    padding: 0;
    border: 0;
    background: none;
    white-space: normal;
    text-align: left;
  }
  .dash-table.is-cards td[data-label]:not(.dash-cell-lead)::before {
    content: attr(data-label);
    color: var(--pub-muted);
    font-family: var(--pub-sans); /* not the mono of a phone cell */
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: -0.003em;
  }
  .dash-table.is-cards .dash-cell-lead,
  .dash-table.is-cards .act,
  .dash-table.is-cards td:not([data-label]) {
    grid-column: 1 / -1;
  }
  .dash-table.is-cards .num {
    padding-right: 0;
  }
  .dash-table.is-cards .dash-actions {
    display: flex;
    width: 100%;
  }
  .dash-table.is-cards .dash-actions .dash-btn {
    flex: 1 1 0;
    max-width: 16rem;
    min-height: 44px;
  }
  /* New rows keep their tint across the whole block. */
  .dash-table.is-cards tbody tr.is-new {
    background: var(--pub-sun-soft);
    box-shadow: inset 3px 0 0 var(--pub-sun);
  }
  .dash-table.is-cards tbody tr.is-new td {
    background: none;
    box-shadow: none;
  }
  .dash-table.is-cards .dash-day {
    display: block;
    padding: 20px 12px 4px;
    border-bottom: 0;
  }
  .dash-table.is-cards .dash-day > th {
    display: block;
    padding: 0;
  }
  .dash-table.is-cards .dash-detail {
    display: none;
    padding-top: 0;
  }
  .dash-table.is-cards tr:has(.dash-more[open]) {
    border-bottom-color: transparent;
  }
  .dash-table.is-cards tr:has(.dash-more[open]) + .dash-detail {
    display: block;
  }
  .dash-table.is-cards .dash-detail > td {
    padding: 0;
  }
  .dash-table.is-cards .dash-detail__list {
    position: static;
    max-width: none;
  }
  .dash-table.is-cards .dash-empty td,
  .dash-table.is-cards td:not([data-label]):not(.act) {
    align-items: center;
    text-align: center;
  }
  .dash-table.is-cards .dash-empty td {
    padding: 40px 0;
  }
  .dash-table.is-cards .dash-detail > td:not([data-label]) {
    align-items: stretch;
    text-align: left;
  }

  /* --- Phone: icon-only nav, compact head --------------------------------- */
  @media (max-width: 639.98px) {
    .dash-link__text {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0 0 0 0);
      white-space: nowrap;
    }
    .dash-link {
      gap: 6px;
      padding: 10px 12px;
    }
    .dash-top h1 {
      font-size: 2.75rem;
    }
    .dash-top__actions {
      margin-left: 0;
    }
    /* The label may wrap under the icon; the figure never splits. */
    .dash-today {
      flex-wrap: wrap;
      row-gap: 0;
      padding: 6px 18px 6px 14px;
      white-space: normal;
    }
    .dash-today__value {
      white-space: nowrap;
    }
    .dash-card {
      border-radius: 20px;
    }
    .dash-card__head {
      padding: 12px 8px 16px 12px;
    }
    .dash-search {
      width: 100%;
      margin-left: 0;
      flex-wrap: nowrap;
    }
    .dash-field {
      flex: 1 1 auto;
      width: auto;
      min-width: 0;
      height: 44px;
    }
    .dash-search .dash-btn {
      flex: none;
      min-height: 44px;
    }
  }
  /* The bar keeps every entry on narrow phones: the logo drops to its dot
     (the name stays for screen readers). */
  @media (max-width: 479.98px) {
    .dash-logo {
      gap: 0;
      font-size: 0;
    }
    .dash-logo .brand-logo {
      height: 40px;
    }
    .dash-side {
      padding-left: 16px;
    }
  }
}

/* --------------------------------------------------------------------------
   Auth — login → code → verify-email, logout, password change, 429
   (templates/registration/base_auth.html). The log.html design on the public
   palette: the form in a white 28px card (the landing's transfer panel) on
   the left, the brand's marble-track illustration on the right. Landing type
   system (Inter, per-size tracking, Inter Black for the display voice), the
   4px grid, pill buttons, 10px inputs with the ink focus edge. Light-only,
   like the public pages. Sized to fit a laptop screen without a scrollbar.
   In the auth layer, so it outranks `public` where it resizes .landing-btn.
   -------------------------------------------------------------------------- */

@layer auth {
  :root:has(> body.page--auth) {
    color-scheme: light;
  }
  .page--auth {
    display: block;
    min-height: 100vh;
    min-height: 100dvh;
    color-scheme: light;
    background: var(--pub-card);
    color: var(--pub-ink);
    font-family: var(--pub-sans);
    font-feature-settings: "calt" 1;
    font-size: 1rem;
    line-height: 1.5;
    letter-spacing: -0.006em;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
  .page--auth :focus-visible {
    outline-color: var(--pub-ink);
  }
  /* Zero-specificity resets of the base layer's element defaults. */
  :where(.auth) :is(h1, p) {
    margin: 0;
    max-width: none;
  }
  :where(.auth) a {
    color: inherit;
    text-decoration: none;
  }
  :where(.auth) :is(button, input) {
    font-family: inherit;
    letter-spacing: inherit;
  }

  /* --- Split layout: form | illustration ------------------------------------ */
  .auth {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 16px;
    min-height: 100vh;
    min-height: 100dvh;
    padding: 16px;
  }
  .auth-side {
    display: flex;
    flex-direction: column;
    padding: 16px 16px 16px 32px;
  }
  .auth-logo {
    align-self: flex-start;
    font-size: 1.25rem;
  }
  .auth-main {
    flex: 1;
    display: grid;
    place-items: center;
    padding: clamp(16px, 5vh, 48px) 0;
  }
  .auth-footer {
    color: var(--pub-muted);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  /* Phones only: from 600px up the site footer (_site_foot.html) closes the
     page and carries the © line. */
  @media (min-width: 600px) {
    .auth-footer {
      display: none;
    }
  }

  /* --- The card --------------------------------------------------------------- */
  .auth-card {
    width: 100%;
    max-width: 440px;
    padding: 40px 32px 32px;
    border-radius: 28px;
    background: var(--pub-white);
    box-shadow: 0 1px 2px var(--pub-panel-shadow), 0 16px 40px var(--pub-panel-shadow);
  }
  .auth-eyebrow {
    color: var(--pub-muted);
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.55;
    letter-spacing: -0.005em;
    text-align: center;
  }
  /* Display voice: Inter Black, like the hero and the section openers. */
  .auth-card h1 {
    margin-top: 12px;
    font-size: clamp(2.5rem, 4vw, 3rem);
    font-weight: 900;
    line-height: 1;
    letter-spacing: -0.04em;
    text-align: center;
    text-wrap: balance;
  }
  .auth-lede {
    margin: 12px 0 32px;
    color: var(--pub-muted);
    font-size: 1rem;
    line-height: 1.5;
    letter-spacing: -0.006em;
    text-align: center;
    text-wrap: pretty;
  }

  /* django.contrib.messages inside the card — the flow's info alert. */
  .page--auth .messages {
    margin: 0 0 24px;
    padding: 0;
    list-style: none;
  }
  .page--auth .notice {
    margin: 0;
    padding: 12px 16px;
    border: 0;
    border-radius: 10px;
    background: var(--pub-panel);
    color: var(--pub-ink);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .page--auth .notice + .notice {
    margin-top: 8px;
  }
  .page--auth .notice--error,
  .auth-alert {
    background: var(--pub-error-bg);
    color: var(--pub-error);
  }
  .auth-alert {
    margin: -8px 0 24px;
    padding: 12px 16px;
    border-radius: 10px;
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }

  /* --- Fields ------------------------------------------------------------------ */
  .auth-field {
    margin-bottom: 16px;
  }
  .auth-field label {
    display: block;
    margin-bottom: 8px;
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  /* 10px, 1px Pebble, 12/16 padding, 16px; focus = ink edge doubled by an
     inset shadow (the landing's transfer form). */
  .auth-field input {
    display: block;
    width: 100%;
    max-width: none;
    padding: 12px 16px;
    border: 1px solid var(--pub-pebble);
    border-radius: 10px;
    background: var(--pub-white);
    color: var(--pub-ink);
    font-size: 1rem;
    line-height: 1.5;
    letter-spacing: -0.006em;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
  }
  .auth-field input::placeholder {
    color: var(--pub-muted);
    opacity: 1;
  }
  .auth-field input:focus {
    border-color: var(--pub-ink);
    outline: none;
    box-shadow: inset 0 0 0 1px var(--pub-ink);
  }
  .auth-field input[aria-invalid="true"] {
    border-color: var(--pub-error);
  }
  .auth-field input[aria-invalid="true"]:focus {
    box-shadow: inset 0 0 0 1px var(--pub-error);
  }
  /* The one-time code: read character by character, so mono (§3). */
  .auth-field .auth-code {
    font-family: var(--pub-mono);
    font-size: 1.5rem;
    font-weight: 600;
    letter-spacing: 0.4em;
    text-align: center;
  }
  .auth-error {
    margin-top: 8px;
    color: var(--pub-error);
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  /* Password-validator help (Django renders it as a list). */
  .auth-help {
    margin-top: 8px;
    color: var(--pub-muted);
    font-size: 0.75rem;
    line-height: 1.63;
    letter-spacing: -0.003em;
  }
  .auth-help ul {
    margin: 0;
    padding-left: 18px;
  }

  /* --- Actions ------------------------------------------------------------------ */
  /* The landing's lime pill, full width. */
  .auth-submit {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-top: 24px;
  }
  .auth-lede + .auth-submit {
    margin-top: 0;
  }
  /* "Resend the code" — its own form, set clearly apart, never a second
     primary: a secondary pill sized to its content. */
  .auth-form--secondary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 8px 12px;
    margin-top: 24px;
    padding-top: 24px;
    border-top: 1px dashed var(--pub-line);
  }
  .auth-hint {
    color: var(--pub-muted);
    font-size: 0.875rem;
    letter-spacing: -0.005em;
  }
  .auth-secondary {
    padding: 8px 17px;
    font-size: 0.875rem;
    line-height: 1.55;
    letter-spacing: -0.005em;
  }
  .auth-back {
    margin-top: 16px;
    text-align: center;
  }
  .auth-link {
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    text-decoration: underline;
    text-decoration-color: var(--pub-line-soft);
    text-decoration-thickness: 2px;
    text-underline-offset: 4px;
  }
  .auth-link:hover {
    text-decoration-color: var(--pub-ink);
  }

  /* --- The illustration panel (_auth_art.html) ------------------------------------ */
  /* An inset, rounded panel — like the landing's floating nav — washed in the
     brand lime. Colours are classes on tokens, never hex in the SVG. */
  .auth-art {
    position: relative;
    overflow: hidden;
    min-height: 480px;
    border-radius: 28px;
    background:
      radial-gradient(120% 80% at 18% 8%, var(--pub-white) 0%, transparent 55%),
      linear-gradient(165deg,
        color-mix(in srgb, var(--pub-lime) 22%, var(--pub-card)) 0%,
        color-mix(in srgb, var(--pub-lime) 48%, var(--pub-card)) 100%);
  }
  .auth-art svg {
    position: absolute;
    inset: 0;
    width: 100%;
    max-width: none;
    height: 100%;
  }
  .auth-trk { fill: none; }
  .auth-trk--shadow  { stroke: var(--pub-ink); stroke-opacity: 0.16; }
  .auth-trk--wall-lo { stroke: color-mix(in srgb, var(--pub-lime-dark) 55%, var(--pub-panel)); }
  .auth-trk--wall-hi { stroke: color-mix(in srgb, var(--pub-lime-dark) 32%, var(--pub-panel)); }
  .auth-trk--rim     { stroke: var(--pub-white); }
  .auth-trk--channel { stroke: color-mix(in srgb, var(--pub-lime) 30%, var(--pub-panel)); }
  .auth-trk--floor   { stroke: color-mix(in srgb, var(--pub-lime) 16%, var(--pub-card)); }
  .auth-trk--joint   { stroke: var(--pub-ink); stroke-opacity: 0.16; }
  .auth-ball-shadow  { fill: var(--pub-ink); fill-opacity: 0.32; }
  .auth-ball-hi      { stop-color: color-mix(in srgb, var(--pub-ink) 55%, var(--pub-white)); }
  .auth-ball-mid     { stop-color: color-mix(in srgb, var(--pub-ink) 88%, var(--pub-white)); }
  .auth-ball-lo      { stop-color: var(--pub-ink); }
  .auth-ball-glint   { fill: var(--pub-white); fill-opacity: 0.75; }
  /* The ball rolls the whole track, lap after lap (SMIL, in _auth_art.html).
     SMIL ignores the base layer's reduced-motion rule, so reduced motion
     swaps in the still frame instead (§8). */
  .auth-ball--still { display: none; }
  @media (prefers-reduced-motion: reduce) {
    .auth-ball--moving { display: none; }
    .auth-ball--still { display: inline; }
  }

  /* The trust line the landing's strip carries. */
  .auth-art__caption {
    position: absolute;
    left: 24px;
    bottom: 24px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 8px 16px 8px 12px;
    border-radius: 9999px;
    background: var(--pub-ink);
    color: var(--pub-white);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: -0.005em;
  }
  .auth-art__caption::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--pub-lime);
  }

  /* --- Short screens: fit without a scrollbar ------------------------------------- */
  /* A 1366×768 or 1280×720 laptop leaves ~630–680px once the browser takes
     its bars. Tighten the vertical rhythm (still on the 4px grid) instead of
     scrolling; only a truly tiny window still scrolls rather than clipping. */
  @media (max-height: 820px) {
    .auth-main {
      padding: 16px 0;
    }
    .auth-alert {
      margin-bottom: 16px;
    }
    .auth-card {
      padding: 28px 28px 24px;
    }
    .auth-card h1 {
      margin-top: 8px;
      font-size: 2.25rem;
    }
    .auth-lede {
      margin: 8px 0 20px;
    }
    .auth-field {
      margin-bottom: 12px;
    }
    .auth-submit {
      margin-top: 20px;
    }
    .auth-form--secondary {
      margin-top: 16px;
      padding-top: 16px;
    }
  }
  @media (max-height: 700px) {
    .auth-main {
      padding: 8px 0;
    }
    .auth-card {
      padding: 24px 28px 20px;
    }
    .auth-field .auth-code {
      font-size: 1.25rem;
    }
    .auth-form--secondary {
      margin-top: 12px;
      padding-top: 12px;
    }
    .auth-field label {
      margin-bottom: 6px;
    }
    .auth-field input {
      padding: 10px 16px;
    }
  }

  /* --- Narrow screens ----------------------------------------------------------- */
  @media (max-width: 959.98px) {
    .auth {
      grid-template-columns: 1fr;
    }
    .auth-art {
      display: none;
    }
    .auth-side {
      padding: 8px 4px;
    }
  }
  @media (max-width: 479.98px) {
    .auth {
      padding: 12px;
    }
    .auth-card {
      padding: 32px 20px 24px;
      border-radius: 20px;
    }
  }
}

/* --------------------------------------------------------------------------
   Utilities — single-purpose, always last so they win.
   -------------------------------------------------------------------------- */

@layer utilities {
  /* Money figures, codes and references must align (§3). */
  .tabular {
    font-variant-numeric: tabular-nums;
  }

  /* Payout codes, transaction references, operator refs — only these (§3). */
  .mono {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
  }

  .visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
}
