/*
 * Design tokens — the single :root source for the whole app.
 * Loaded before app.css/forms.css/components.css from base.html.
 * Do not declare :root variables in any other stylesheet.
 */
:root{
  /* Palette (values unchanged from the historical app.css/job_pages.css blocks) */
  --bg:#ffffff;
  --panel:#f8fafc;
  --ink:#0f172a;
  --muted:#5b697e;
  --accent:#3b4ff5;
  --accent-ink:#ffffff;   /* readable text on accent */
  --accent-soft:#f0f5ff;  /* soft background for accents */
  /* Ink for text sitting ON --accent-soft, split out of --accent-ink because
     that one token was doing two contradictory jobs: readable-on-the-solid-
     accent (9 rules + the [aria-current] ring) and readable-on-the-pale-tint
     (9 rules). They agree today and stop agreeing the moment a client picks
     a dark accent -- white reads on the fill, dark reads on the tint, and
     one flat swap blanks half of them. Minted at exactly --accent-ink's
     value, so the split renders nothing new. */
  --accent-soft-ink:#2f3de0;
  /* ...and the ONE site that is bare text on the page rather than on either:
     the permissions grid's granted tick (`.authz-cell-granted`, whose cell
     declares background:none). Under a white --accent-ink it would go
     white-on-white while its 'partial' sibling stayed orange -- a grid
     reading 'nothing is granted, some things are partial'. */
  --on-page-accent-ink:#2f3de0;
  --border:#e2e8f0;
  --shadow-color:15 23 42; /* for rgba shadows */

  /* Create-action CTA — the brand lime (--accent family), a touch brighter
     at the top so the page's main action still pops without leaving the
     palette. Dark olive ink: the lime is too light for white text. */
  --danger:#dc2626;
  --danger-soft:#fdecec;
  --danger-ink:#a61b1b;
  --danger-muted:#c0392b; /* archive: a calmer red than the delete red */

  /* GDPR-risk whole-row tint — pale→deeper readable reds (flexi people table) */
  --gdpr-r1:#fdecec;
  --gdpr-r2:#f9cccc;
  --gdpr-r3:#f3a6a6;

  /* Spacing scale */
  --space-1:4px;
  --space-2:8px;
  --space-3:12px;
  --space-4:16px;

  /* Radius scale */
  --r-1:6px;
  --r-2:8px;
  --r-3:10px;
  /* The pill. Written as a literal 20 times and once as `9999px` — two
     spellings of one idiom, which is how the badge family ended up with
     variants nobody intended. Named so it is one decision. */
  --r-pill:999px;

  /* ---- Surfaces: the four client-settable card knobs --------------------
     The theming plan promises a client "card fill, card edge, nested-card fill,
     nested-card edge". Two of those did not exist as concepts: a card nested in
     a section rendered identically to its parent, and card fill was not a
     variable at all -- plain #fff was written 49 times against 7 uses of
     var(--bg).

     Minted at TODAY'S rendered values, so naming them changes nothing:
       --surface            the 49 literal #fff
       --surface-edge       --border's value
       --surface-nested     --tile-bg's value
       --surface-nested-edge  the second, untokenised grey the nested blocks
                              already used (15 sites). Deliberately NOT
                              --border: seeding it at what those blocks render
                              keeps the sweep zero-pixel AND makes the
                              card-edge/nested-edge distinction a real settable
                              thing rather than an accident. */
  --surface:#ffffff;            --surface-edge:#e2e8f0;
  --surface-nested:#f8fafc;     --surface-nested-edge:#e2e8f0;

  /* ---- Control geometry ------------------------------------------------
     Height is DECLARED here, not derived from font metrics, and that is the
     whole point. Before this, `app.css` set padding and borders on controls
     but no typography, so every field fell back to the UA's 13.333px Arial
     inside a 14px system-ui page and four controls with identical declared
     padding rendered at four different heights: input 33.00, select 35.00,
     date 35.33, button 35.59. Adding the typography alone does NOT fix it --
     it lands inputs at 37.6px (19.6 line + 16 padding + 2 border) i.e. TALLER
     than the button's 35.59 -- and `select`/`date` still diverge on their
     intrinsic line boxes. A declared floor is what makes them agree.

     36px = the button's existing 35.59 rounded onto the 4px scale, so the one
     family the previous sprint already unified (and the owner already
     accepted) moves 0.41px and everything else joins IT.

     THEMEABLE: a client wanting a denser or roomier UI is a legitimate future
     knob, which is why these are tokens rather than literals. */
  --control-h:36px;
  --control-h-sm:28px;    /* .btn-sm, pagination */
  --control-h-xs:26px;    /* chips and toggles -- filter_workspace's existing floor */
  --control-pad-x:10px;   /* inputs (today's value) */
  --control-pad-x-lg:12px;/* buttons (today's value) */

  /* How wide a clipped table cell may grow before it ellipsises.
     `tables.css:106` read `var(--flexi-clip-max,14rem)`, and nothing defined
     it — so the fallback was always what rendered, and the value lived in a
     rule rather than here (S-F.7). Same shape as the sprint's three other
     `var(--x, fallback)` claims that turned out to name nothing. */
  --flexi-clip-max:14rem;

  /* Font-size scale */
  --fs-1:12px;
  --fs-2:13px;
  --fs-3:14px;
  --fs-4:16px;
  --fs-5:20px;

  /* Group tones — hue means GROUP IDENTITY on cards/badges.
     THEMEABLE: a client agency may re-skin these.

     The old comment here said "nothing else", and that was false by a wide
     margin — measured before the split: the amber was 2 identity uses against
     ~20 warning/status uses across five sheets, the green 4 against 7, and the
     blue 7 against 4 PLUS every hyperlink in the product. So "re-skin the
     group palette" would have repainted every warning, every success and every
     link. The fixed semantic quartet below now owns those jobs at identical
     values; what remains here really is identity only. */
  --tone-identity:#e8f0ff;  --tone-identity-ink:#0b3d91;
  --tone-contact:#e7f7e9;   --tone-contact-ink:#0b6b2e;
  --tone-languages:#fff6e5; --tone-languages-ink:#7a4e00;
  --tone-system:#f3e8ff;    --tone-system-ink:#6b21a8;
  --tone-finance:#e6fbf3;   --tone-finance-ink:#065f46;
  --tone-compliance:#fef3c7;--tone-compliance-ink:#92400e;
  --tone-danger:#fdecec;    --tone-danger-ink:#a61b1b;

  /* ---- The fixed semantic quartet — NOT THEMEABLE ----------------------
     good / medium / bad / neutral is a universal language; a client may not
     re-skin it. Minted at exactly the values their consumers already
     rendered, so this split is provably zero-pixel (asserted by
     TokenContractTests.test_the_fixed_semantic_tokens_match_their_origin).

     Deliberately NOT `var(--tone-*)` aliases: an alias would keep the two
     coupled, which is the entire defect being removed. Literals here are the
     point, and tokens.css is the one sheet exempt from the hex budget. */
  --warn-bg:#fef3c7;        --warn-ink:#92400e;   /* was --tone-compliance* */
  --ok-bg:#e7f7e9;          --ok-ink:#0b6b2e;     /* was --tone-contact*    */
  --info-bg:#e8f0ff;        --info-ink:#0b3d91;   /* was --tone-identity*   */

  /* Hyperlink ink. `app.css`'s bare `a` rule read --tone-identity-ink, so the
     colour of EVERY link in the product was a group-identity token: re-skinning
     "the identity group" recoloured the whole site's links. Themeable in its own
     right, minted at the value links already rendered. */
  --link:#3b4ff5;

  /* Workflow status ramp — tint/ink pairs per pipeline status.
     Hues match the historical PipelineUtils.statusColor palette. */
  --st-applied:#dbeafe;     --st-applied-ink:#1e40af;     /* was #2563eb */
  --st-prospect:#f3f4f6;    --st-prospect-ink:#374151;    /* was #6b7280 */
  --st-qualified:#f3e8ff;   --st-qualified-ink:#6b21a8;   /* was #7c3aed */
  --st-cv-sent:#e0e7ff;     --st-cv-sent-ink:#3730a3;     /* was #4f46e5 */
  --st-shortlisted:#ccfbf1; --st-shortlisted-ink:#115e59; /* was #0d9488 */
  --st-interview:#ffedd5;   --st-interview-ink:#9a3412;   /* was #ea580c */
  --st-offered:#fef3c7;     --st-offered-ink:#92400e;     /* was #d97706 */
  --st-accepted:#dcfce7;    --st-accepted-ink:#166534;    /* was #16a34a */
  --st-hired:#bbf7d0;       --st-hired-ink:#14532d;       /* was #15803d */
  --st-rejected:#fee2e2;    --st-rejected-ink:#991b1b;    /* was #dc2626 */
  --st-unclarified:#f3f4f6; --st-unclarified-ink:#6b7280; /* was #9ca3af */

  /* Candidate status tones (Sprint1 WP3, P1-2) — a FOURTH semantic axis:
     coarse candidate-facing progress on /applications/. Deliberately NOT
     the --st-* ramp (internal workflow states keyed by data-status, which
     §3.2 forbids in candidate markup) and NOT --tone-* (group identity).
     Three buckets only, so no colour can single out a masked rejection —
     the tone keys off the candidate WORDING, never the internal status.
     Values reuse the ramp's applied/accepted hues + a neutral grey. */
  --ct-active:#dbeafe;      --ct-active-ink:#1e40af;
  --ct-good:#dcfce7;        --ct-good-ink:#166534;
  --ct-closed:#f3f4f6;      --ct-closed-ink:#4b5563;

  /* Button fills (owner-ruled 2026-08-01 from a rendered swatch sheet).

     --btn-neutral-bg is the flattened secondary. Its value is the one --border
     already carries, so the sprint introduces no new neutral colour at all —
     but it is minted as its own role-named token rather than reusing
     var(--border) as a fill: same value, correct semantics, and the two can
     diverge later without a hunt. Its ink is --ink, NOT --muted, which lands
     at 4.17:1 here and fails AA (SR-14).

     --btn-strong-bg is .btn-primary/.btn-cta's distinct step above the accent —
     1.24x against --accent, with --accent-ink at 7.0:1. The owner said
     "noticeably" in the abstract, then chose this after seeing it rendered.
     That IS the ruling: do not "correct" it darker (SR-11). */
  --btn-neutral-bg:#e2e8f0;
  --btn-strong-bg:#2f3de0;

  /* Confirm / accept / execute (owner ruling 2026-08-17). The role is
     distinguished by a slight 3D lift, NOT by hue: it keeps the agency's brand
     lime so the main palette stays consistent. Its own token pair regardless,
     so a client can later give confirm its own colour without dragging the
     create action with it. Seeded at --btn-strong-bg's value. */
  --btn-confirm-bg:#2f3de0;
  --btn-confirm-ink:#ffffff;

  /* Warning border — referenced at components.css's .cw-late since the
     job-closure work but never defined, so the hex fallback is what has always
     rendered. Minted here at exactly that value; nothing changes on screen. */
  --warn-border:#f59e0b;
  /* Softened body ink — referenced as var(--ink-soft, #4b5563) by the flexi
     scheduled-email cell and never defined, so the fallback is what has always
     rendered. THIRD instance of this pattern (see --warn-border above, and
     D-69's --warn-soft/--warn-ink). Minted at exactly that value; nothing
     changes on screen. Deliberately NOT --muted (#5a6a7a), which is a
     different, cooler grey. */
  --ink-soft:#334155;
  /* Staleness of a "days since" figure, moved out of job_editor.js at its
     existing values (SR-9). --age-ageing is 2.16:1 as text on white and fails
     AA; recorded in progress.md D-44 rather than silently recoloured, since
     plan.md §4 puts recolours out of scope. */
  --age-ageing:#ff9800;     --age-stale:#b00020;

  /* Sub-tile fill — the faint blue-white behind a dashed-border tile nested
     inside a card (job-summary overview items, job-editor section blocks).
     Minted at its existing value; deliberately NOT --bg (#ffffff), which
     would be a recolour rather than a tokenisation.
     Two more #fcfdff literals survive as inline styles on
     job_summary.html:109 and :113 (the prospective-deal panels) — ADH-042,
     swept by S-D.3, not reachable from CSS. */
  --tile-bg:#f8fafc;

  /* Field-group bubble — a faint lime-tinted off-white that encloses a label
     with its control. Deliberately NOT --accent-soft: that tint signals
     active/emphasis (chips, count pills, focus rings); this one is passive
     grouping chrome. */
  --bubble-bg:#f0f5ff;
  --bubble-border:#c7d9ff;

  /* Keyboard focus ring — dark brand olive at ≥3:1 on white (the lime
     family is too light to mark focus on its own). */
  --focus-ring:#5271ff;

  /* ==== Theming sprint, phase 3a ====================================
     Every token below is minted at the value that renders TODAY, so naming
     things changes nothing on screen. The literals they replace are swept
     sheet by sheet in the commits that follow, each lowering its own hex
     budget by exactly what it removed.

     Two rules this block follows, both learned the hard way upstream:
     a token is named for the JOB it does, not for the value it happens to
     hold (so `--rule-faint` and `--neutral-soft` are two names at one value
     -- a themer setting a fill must not silently move a separator); and a
     fixed semantic value gets a token WITHOUT becoming settable, because
     tokenising and exposing are different decisions. */

  /* -- Ink ladder. Four greys sat between --muted and --ink with no names. */
  --ink-faint:#5b697e;      /* metadata, timestamps, empty-state notes */
  --ink-strong:#334155;     /* footer links, progress meta */
  --prose-ink:#0f172a;      /* .lead and .prose body copy */
  --ink-disabled:#9ca3af;   /* anonymised rows */

  /* -- Neutral fill vs hairline. Same value, deliberately two tokens. */
  --neutral-soft:#f3f4f6;   /* candidate-skill chips, menu hover */
  --rule-faint:#f3f4f6;     /* the faintest separator */
  --rule-soft:#e5e7eb;      /* one step stronger: modal head/foot, .ruled-top.
                               Same value as --surface-nested-edge and that is the
                               POINT -- those three were spending a SETTABLE card
                               edge on separators, so an agency retinting nested
                               cards silently moved two modal dividers with it. */

  /* -- Danger family. --danger-soft (#fdecec) is the pink tint; these are the
        paler edge, the stronger ink and the near-white wash that were written
        as literals beside it. NOT settable: the status language is fixed. */
  --danger-border:#f3b4b4;
  --danger-strong:#b91c1c;
  --danger-wash:#fff7f7;

  /* -- Warning wash. A second, oranger warn family used by the lock banner
        and the locked badge; distinct from --warn-bg's amber. */
  --warn-wash:#fff7ed;
  --warn-wash-border:#fed7aa;
  --warn-wash-ink:#9a3412;

  /* -- The pale edges the .messages alerts use, which never had names. */
  --ok-border:#b8e6c1;
  --info-border:#c7d7ff;

  /* -- Toasts carried their own five-colour palette, none of it the shared
        status colours. Named here so it is visible; still not settable. */
  --toast-bg:#1a1f29;       --toast-ink:#ffffff;
  --toast-ok-bg:#2e7d32;    --toast-danger-bg:#b00020;
  --toast-warn-bg:#7a5b00;

  /* -- Readable ink ON a solid --danger fill. --danger-ink is the opposite
        job (destructive text on the page), so this needed its own name --
        the same defect the accent inks had. */
  --on-danger-ink:#ffffff;

  /* -- Navbar. The bar borrowed --panel, which ~48 other rules also use, so
        "recolour the navbar" recoloured half the product. The bar and the
        selected item now own their colours; a nav item's RESTING fill stays
        on --btn-neutral-bg, shared with 18 other control families. */
  --nav-bg:#ffffff;         --nav-border:#e2e8f0;
  --nav-active-bg:#3b4ff5;  --nav-active-ink:#ffffff;

  /* -- Tables had no colour tokens at all: row fill was a literal #fff and
        the header read --muted. --table-row-alt-bg is seeded EQUAL to the row
        fill so the zebra rule renders nothing until the palette flips. */
  --table-row-bg:#ffffff;   --table-row-alt-bg:#f8fafc;
  --table-row-hover-bg:#f1f5f9;
  --table-row-border:#e2e8f0;
  --table-head-ink:#64748b;

  /* -- Form controls. Fields were painted with --bg, the PAGE background, so
        an agency could not tint a field without moving the whole page. */
  /* Progress and usage bar tracks. Its value equals --surface-nested-edge's,
     and it is deliberately NOT that token: a track is a FILL. Three bars in
     the tree gave three different answers -- two literals and --panel. */
  --brand-logo-height:44px;
  --track-bg:#e5e7eb;
  /* Progress FILL. Fixed, not settable, and deliberately NOT --accent: a fill is
     only informative if you can see how full it is, so it is governed by WCAG
     1.4.11's 3:1 against --track-bg above. Phase 3's P7 put it on --accent and
     took it from 4.17:1 to 1.30:1 -- invisible against its own track -- which is
     why this is a token with a rule rather than a brand colour with none. */
  --progress-fill:#2563eb;
  --field-bg:#ffffff;       --field-border:#8d9196;
  --field-ink:#0f172a;      --field-readonly-bg:#f8fafc;

  /* -- Channel triples, for values consumed at several alphas. Same idiom as
        --shadow-color. --scrim-color stays TRUE BLACK: the overlays are 35%
        over the whole viewport, where --shadow-color's 16 24 40 is a visible
        blue shift rather than a sub-perceptual one. */
  --scrim-color:0 0 0;      /* modal backdrops */
  --surface-rgb:255 255 255;/* translucent veils over the page */
  --border-rgb:217 224 231; /* the canvas grid, drawn at .42 */
  --panel-rgb:247 248 250;  /* a gradient that fades --panel to transparent */
  --btn-lift-highlight:255 255 255;
  /* ...and the shade below it. Its own token rather than --shadow-color: that is a
     SURFACES knob, so retinting card shadows silently retuned the confirm button's
     bevel -- a cross-group coupling nobody would predict from the editor. */
  --btn-lift-shade:16 24 40; /* the raised confirm button's bevel */
}
