/* ============================================================================
   TOKENS.CSS — the design constitution (Stage B, 2026-08-14)
   ============================================================================

   ONE source of truth for every design token, replacing the four independent
   copies that used to live in styles.css, index.html, agencies.html, and
   desk.html/desk-journey.html (five different accent blues, four functional
   trios, three sans stacks — see SESSION_NOTES.md 2026-08-14, design/UX audit).

   TWO REGISTERS, one frame:
   - DAYLIGHT (default on :root) — light, calm. The traveller app, forms,
     demo/test, the agencies landing page. Values are the constitutional
     "Cobalt signal" palette (UX_SPEC §10, decided 2026-07-13).
   - NIGHTDESK ([data-register="night"]) — dark, dense. The desk board, its
     journey detail, and the dark traveller landing. Values are the desk
     pages' direction-C set (2026-08-10, contrast-tuned 2026-08-12) — chosen
     as canon because they were the most deliberately tuned dark values.

   The night selector is NOT :root-bound on purpose: put data-register="night"
   on <html> for a whole page, or on any element for a dark island inside a
   light page (agencies.html's "night screen" cards do exactly this).

   RULES THAT BIND ANY EDIT HERE (UX_SPEC §9/§10, INVARIANTS §3):
   - Red/amber/green keep their meanings (confirmed loss / caution / OK) and
     their hue families in BOTH registers. Tune shade, never reassign.
   - One accent per register, same blue family across registers.
   - Every change must pass scripts/verify-contrast.mjs (npm run verify:pages)
     — the WCAG gate §10 asks for "computationally, don't eyeball".
   - Known, documented exception: in Daylight, --dim === --muted. A "quieter
     than muted" grey cannot stay above the 4.5:1 AA floor on a near-white
     page; the tier only genuinely exists in Nightdesk (where --dim passes the
     3:1 decorative gate, and is used only for chrome, never body text).
   ========================================================================== */

:root,
[data-register="daylight"] {
  /* neutrals */
  --bg: #fcfcfd;
  --panel: #ffffff;      /* raised surface: cards, bars                       */
  --panel-2: #f8fafc;    /* second raise: nested panels                       */
  --sunken: #f1f5f9;     /* recessed / hover tint on white (slate-100)        */
  --rail-bg: #f1f5f9;    /* product-rail background (only night pages have a
                            rail today; defined here so the register is total */
  --line: #e2e8f0;       /* standard border (slate-200)                       */
  --line-soft: #eaeff5;  /* hairline border, quieter than --line              */
  /* --ground and --line-firm added 2026-08-24 (agency-page surface pass). Both exist because
     a white card on a near-white page is not a card: --panel on --bg is a 1.03:1 step and
     --line on --panel is 1.23:1, and neither is resolvable at arm's length. The reference
     systems that live on pale grounds separate surfaces by LAYERING them (Carbon layer-01/
     02/03, Primer canvas-default vs canvas-subtle) and by giving the border a value you can
     actually see -- Primer's is #d0d7de, 1.45:1 on white; --line-firm is 1.48:1.
       --ground is BELOW --panel, i.e. the floor cards sit on. That makes the Daylight stack
       --ground -> --panel-2 -> --panel, deepest to lightest.
     THE COUPLED RULE, and the reason the two arrived together: --muted is 4.23:1 on --ground,
     under the AA floor. Text placed directly on --ground must be --bright (9.21:1) or --text;
     --muted stays legal on --panel (4.76) and --panel-2 (4.55), which is where nearly all of
     it lives. verify-contrast.mjs gates the pairs; this comment carries the part a pair list
     cannot express, which is that --muted on --ground is FORBIDDEN rather than merely unlisted.
     Night keeps its own floor: its --bg is already darker than every panel, so --ground is
     --bg's value there and nothing about the night pages changes. */
  --ground: #eef2f7;     /* page floor UNDER --panel cards (slate-150-ish)    */
  --line-firm: #cbd5e1;  /* a border that reads as an edge (slate-300)        */
  --text: #0f172a;
  --muted: #64748b;      /* caption tier — legal ONLY at 12px (§9 Rule 2)     */
  --dim: #64748b;        /* === muted in Daylight; see the exception above    */
  --bright: #334155;     /* "louder than muted, quieter than text"            */

  /* brand */
  --accent: #1d4ed8;
  --accent-wash: #dbeafe;

  /* functional trio — meanings fixed forever (UX_SPEC §10) */
  --red: #b91c1c;        --red-deep: #991b1b;   --red-wash: #fee2e2;
  --amber: #b45309;      --amber-deep: #92400e; --amber-wash: #fef3c7;
  --green: #15803d;                             --green-wash: #dcfce7;

  /* label ink on a filled --accent surface (buttons). A register-tuned pair the
     contrast gate checks explicitly: white ink on Daylight's deep cobalt, near-black
     ink on Nightdesk's lighter blue. Never hardcode #fff/#04101f in a button again. */
  --accent-ink: #ffffff;

  /* control geometry — one radius for every button/input, product-wide (the audit found
     8/10/12px drift across five button vocabularies). Register-independent: defined only
     here; the night block inherits it like the font stacks below. */
  --radius-control: 8px;

  /* type scale — UX_SPEC §9 Rule 1's four sizes plus the ONE dense tier Patrick
     approved 2026-08-14 for space-constrained micro labels (board chrome, strip
     labels). These five are the ONLY font sizes styles.css may use — enforced by
     scripts/verify-type-scale.mjs. Landing-page display typography (hero clamps)
     is deliberately outside this scale; the desk pages' full mapping onto it is
     deferred until it can be eyeballed (fractional sizes are already banned there). */
  --fs-title: 20px;
  --fs-lead: 16px;
  --fs-body: 14px;
  --fs-caption: 12px;
  --fs-dense: 11px;

  /* type — ONE sans stack, ONE mono stack, ONE display stack, product-wide.
     --display (2026-08-23) is the marketing/display face: the narrow, upright signage look of a
     station departure board. It is for HEADLINES ON PUBLIC PAGES ONLY (index, agencies,
     agenturen). The product surfaces -- app, desk, demo -- deliberately do not use it: their
     job is to be read, not to have a personality. Defined here rather than per page so the
     landing pages cannot drift apart the way the four token copies did before Stage B.
     The @font-face rules that back it are at the FOOT of this file; a page that never
     references var(--display) never downloads the font. */
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  --display: "Barlow Condensed", "Arial Narrow", "Helvetica Neue Condensed", system-ui, sans-serif;

  /* (Stage C, 2026-08-14: the pre-Stage-B legacy aliases — --border, --hover-bg,
     --accent-bg, --danger/warning/success-* — are GONE. Every consumer was renamed to
     the canonical vocabulary above; a repo-wide sweep verifies no var() reference to
     the old names remains. Do not reintroduce them.) */
}

[data-register="night"] {
  /* neutrals */
  --bg: #080d17;
  --panel: #0e1626;
  --panel-2: #131d31;
  --sunken: #0a1120;
  --rail-bg: #0a1120;
  --line: #1e2a40;
  --line-soft: #172236;
  /* Night's floor already IS --bg (#080d17 is below every panel value), so --ground repeats
     it rather than introducing a fifth surface; --line-firm is the same idea as Daylight's,
     inverted -- lighter than --line, not darker. Defined here so the register stays total. */
  --ground: #080d17;
  --line-firm: #2c3c58;
  --text: #e8eef7;
  --muted: #8fa0b8;
  --dim: #5c6c84;        /* decorative tier (chrome, "soon" chips) — 3:1 gate */
  --bright: #aebdd3;

  /* brand */
  --accent: #5b8def;
  --accent-wash: #14213c;

  /* functional trio */
  --red: #ff7b7b;        --red-deep: #e05252;   --red-wash: #251117;
  --amber: #f2b95c;      --amber-deep: #b45309; --amber-wash: #241a0d;
  --green: #5fd39a;                             --green-wash: #0f2318;

  --accent-ink: #04101f;
}

/* ============================================================================
   DISPLAY FACE — Barlow Condensed 700, backing the --display token above
   ============================================================================

   SELF-HOSTED ON PURPOSE, and this is not a styling preference. Loading this from
   fonts.googleapis.com would send every visitor's IP address to Google on first paint.
   The landing page's own FAQ says "No ads, no analytics, no tracking" and privacy.html
   names no third party at all, so that request would make both statements false — and it
   is the precise arrangement LG München I held unlawful in Jan 2022 (Az. 3 O 17493/20).

   Two subsets (latin, latin-ext), weight 700 only, ~37 KB total, served from /fonts by the
   whitelist route in httpServer.ts. Barlow is SIL OFL 1.1; the licence ships beside the
   files at public/fonts/OFL.txt.

   font-display: swap — a slow font never blocks a headline; the fallback paints at once and
   is swapped when the face arrives. --display always ends in a real narrow stack, so a
   failed download degrades to Arial Narrow rather than to nothing.

   These rules sit at the FOOT of the file deliberately: scripts/verify-contrast.mjs reads
   the :root and [data-register="night"] blocks by locating the first "{" and "}" after each
   selector, so nothing may be inserted between or before them.
   ========================================================================== */
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/barlow-condensed-700-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Barlow Condensed";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/barlow-condensed-700-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
                 U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
                 U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
