/* ═══════════════════════════════════════════════════════════════════════════
   tokens.css — THE KINGSLEIGH CONSTITUTION  ·  "The Reactor — one system, two voices"
   Design Review, 18 Jul 2026 — THE NORTH STAR (pp.38–40) + Build Order P1.1 (p.56)

   Two voices, one file:
     • REACTOR — black void, one gold light source, IBM Plex Mono instrument labels.
       The operator voice: OS chrome, Command Deck, field app, Jarvis, iOS shell.
     • LEDGER  — cream paper, Cormorant Garamond display, navy ink. The client-facing
       document voice only: estimates, packs, PDFs, verify + satisfaction, ID cards.

   Per the review (p.25 CRIT): light theme in :root, a [data-surface="void"] dark
   block SHARING variable names. A Reactor surface opts in with data-surface="void"
   on its root; documents stay on the light default. This file is ADDITIVE — every
   raw value below is a review-verified hex/size; consuming surfaces migrate to
   var(--kh-*) screen by screen (the 441-literal sweep is phase 2/3).

   Fonts are SELF-HOSTED latin-subset WOFF2 (@font-face below). After this wave NO
   Google Fonts CDN <link> remains anywhere — the privacy pledge becomes literally
   true and offline stops stripping the brand.
   Namespaced --kh-*; a few un-prefixed motion aliases (--t-*, --ease-*) are also
   published because the review's own Fix specs reference them by those exact names.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ══ SURFACES & INK — the void ramp (field.html:26, dock.js:32) ═══════════ */
  --kh-void-0:#05080E;    /* void-0 · page floor              */
  --kh-void-1:#080D16;    /* void-1 · band / surface          */
  --kh-void-2:#0C1424;    /* void-2 · card                    */
  --kh-void-3:#101828;    /* void-3 · raised / chrome         */
  --kh-surface:radial-gradient(130% 120% at 50% 0%,#0C1424 0%,#080D16 55%,#05080E 100%);
  --kh-card:rgba(16,24,40,.72);
  --kh-ink:#F3F0E9;       /* ink · cream text on void         */
  --kh-ink-dim:#8A93A5;   /* muted cream on void              */
  --kh-paper:#F2EFE7;     /* paper · client-document ground   */
  --kh-paper-ink:#20283A; /* canonical navy ink on paper (kh-ui.css:17-22) */
  --kh-paper-dim:#716E62; /* muted ink on paper               */

  /* ══ THE GOLD RAMP — scarcity is the point (#C6A14C, 173 uses, zero drift) ══ */
  --kh-gold-0:#9A7B2E;    /* gold-deep — a TEXT colour, never a fill  */
  --kh-gold-1:#C6A14C;    /* gold · brand — the one light             */
  --kh-gold-2:#D6B160;    /* gold-bright                              */
  --kh-gold-3:#E9C877;    /* gold-glow                                */
  --kh-gold:var(--kh-gold-1);
  --kh-gold-ink:#1A2030;  /* LAW: any gold-family surface carries THIS ink, never white */
  --kh-grad:linear-gradient(180deg,#D6B160,#C6A14C); /* permitted on primary CTAs + reactor orb ONLY */
  --kh-line:rgba(198,161,76,.22);        /* hairline gold                     */
  --kh-ring-track:rgba(198,161,76,.18);  /* Day Ring track (3px gold stroke)  */

  /* ══ SEMANTICS — sage=good · amber=caution · rust=DANGER/LOSS ONLY ═════════
     The North Star converged each role to ONE canonical hex used across both
     voices; the paired -dark aliases carry the SAME review hex so the phase-2
     grep-sweep (rename field --live→--rec, collapse the 5 greens/3 reds) has the
     exact token names the review specifies. rust is NEVER a positive confirm
     ("Raise the invoice" must stop shipping red). */
  --kh-ok:#5FBF7E;        --kh-ok-dark:#5FBF7E;    /* ok · sage        */
  --kh-warn:#C2872C;      --kh-warn-dark:#C2872C;  /* warn · amber     */
  --kh-crit:#B0432E;      --kh-crit-dark:#B0432E;  /* crit · rust      */
  /* review aliases used across surfaces */
  --kh-sage:var(--kh-ok);
  --kh-amber:var(--kh-warn);
  --kh-rust:var(--kh-crit);
  --kh-risk:var(--kh-crit);  --kh-risk-dark:var(--kh-crit-dark);
  --kh-rec:#F5655B;       /* field.html:20 recording red, renamed off --live (p.27) */
  --kh-live:#61C554;      /* presence green (ds.css:21) — presence, NOT success   */

  /* ══ TYPE — three faces, the 8-step ramp, no exceptions ═══════════════════
     Display Cormorant 600 · UI Hanken 400–700 · Instrument IBM Plex Mono 500.
     11px mono is the new minimum, anywhere. Caveat is the boot sign-off /
     printed-document script ONLY — never in app chrome. */
  --kh-font-display:'Cormorant Garamond',Georgia,'Times New Roman',serif;
  --kh-font-ui:'Hanken Grotesk',system-ui,-apple-system,'Segoe UI',sans-serif;
  --kh-font-mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;
  --kh-font-script:'Caveat',ui-rounded,cursive;  /* boot 'homes' + printed docs only */

  /* 8-step ramp (p.36/39): 10 · 11 · 12.5 · 14 · 17 · 20–22 · 28 · 34 */
  --kh-fs-10:10px;        /* mono micro-label — THE floor            */
  --kh-fs-11:11px;        /* legends, chips, anything a user acts on */
  --kh-fs-12-5:12.5px;    /* mono data / reading size               */
  --kh-fs-14:14px;        /* body                                   */
  --kh-fs-17:17px;
  --kh-fs-20:20px;        /* step "20–22" — display base            */
  --kh-fs-22:22px;        /* war-room address (p.61)                */
  --kh-fs-28:28px;
  --kh-fs-34:34px;        /* hero numerals — Plex Mono, tabular      */
  /* UI-face sizes (North Star UI list 13·14·16·19·24) — kept additive */
  --kh-fs-13:13px; --kh-fs-16:16px; --kh-fs-19:19px; --kh-fs-24:24px;
  /* display metrics: 34/44px · -0.01em */
  --kh-display-lh:44px;
  --kh-display-tracking:-0.01em;
  /* mono instrument tracking (+0.14em on all-caps) */
  --kh-mono-track:.14em;
  --kh-num:tabular-nums;  /* pair w/ font-variant-numeric on every money/data column */

  /* weights — 400 body · 500 data · 600 emphasis · 700 labels · 800 numerals/headlines */
  --kh-w-body:400; --kh-w-data:500; --kh-w-emph:600; --kh-w-label:700; --kh-w-hero:800;
  --kh-display-w:600; --kh-mono-w:500;

  /* ══ RADIUS — 6 · 10 · 14 · 999 ══════════════════════════════════════════ */
  --kh-r-1:6px;    /* chips / inputs        */
  --kh-r-2:10px;   /* cards                 */
  --kh-r-3:14px;   /* modals / sheets       */
  --kh-r-pill:999px;

  /* ══ ELEVATION — e1–e4, one shadow ink rgba(8,12,20,α) ═══════════════════ */
  --kh-e1:0 1px 2px rgba(8,12,20,.20);
  --kh-e2:0 4px 12px rgba(8,12,20,.25);
  --kh-e3:0 12px 32px rgba(8,12,20,.35);
  --kh-e4:0 24px 64px rgba(8,12,20,.45);

  /* ══ SPACING LADDER — 4 · 8 · 12 · 16 · 24 · 32 · 48 ═════════════════════ */
  --kh-s-1:4px; --kh-s-2:8px; --kh-s-3:12px; --kh-s-4:16px;
  --kh-s-6:24px; --kh-s-8:32px; --kh-s-12:48px;

  /* ══ MOTION — one signature curve, four durations ════════════════════════
     --kh-swift already shipped inline at portal/app.html:43. Everything eases
     with it. Taps/hovers 120 · element moves 160 · panel/scene 240 · one hero
     moment per screen may take 400. Nothing loops except the reactor. */
  --kh-swift:cubic-bezier(.22,.61,.36,1);
  --kh-t-1:120ms; --kh-t-2:160ms; --kh-t-3:240ms; --kh-t-4:400ms;
  /* North Star role names */
  --kh-t-tap:var(--kh-t-1); --kh-t-move:var(--kh-t-2);
  --kh-t-scene:var(--kh-t-3); --kh-t-hero:var(--kh-t-4);
  /* Flow-Engine spec names (press/state/reveal + cinematic curve + 2.2s ambient) */
  --kh-t-press:var(--kh-t-1); --kh-t-state:var(--kh-t-2); --kh-t-reveal:var(--kh-t-4);
  --kh-ease-swift:var(--kh-swift);
  --kh-ease-cinematic:cubic-bezier(.2,.7,.2,1);  /* the boot curve (p.35) */
  --kh-t-ambient:2.2s;                            /* the ONE ambient reactor pulse */
  /* un-prefixed aliases — the review's Fix specs reference these literal names */
  --t-tap:var(--kh-t-1); --t-move:var(--kh-t-2); --t-scene:var(--kh-t-3); --t-hero:var(--kh-t-4);
  --t-press:var(--kh-t-1); --t-state:var(--kh-t-2); --t-reveal:var(--kh-t-4);
  --ease-swift:var(--kh-swift); --ease-cinematic:var(--kh-ease-cinematic);

  /* ══ VOICE ROLES — default = LEDGER (cream document voice) ════════════════ */
  --kh-bg:var(--kh-paper);
  --kh-text:var(--kh-paper-ink);
  --kh-text-dim:var(--kh-paper-dim);
  --kh-font:var(--kh-font-ui);
}

/* ══ REACTOR VOICE — the dark block, sharing variable names (p.25) ══════════
   Any operational surface sets <html data-surface="void"> (or on any container)
   to wear the void-and-gold instrument look. Semantics are constant across voices. */
[data-surface="void"]{
  --kh-bg:var(--kh-void-0);
  --kh-text:var(--kh-ink);
  --kh-text-dim:var(--kh-ink-dim);
}

/* ══ REDUCED MOTION — the accessibility promise, honoured centrally ═════════
   Copy of the kh-ui.css guard intent: collapse durations so state swaps are
   instant. The reactor canvases additionally pause per their own JS guards. */
@media (prefers-reduced-motion: reduce){
  :root{
    --kh-t-1:0ms; --kh-t-2:0ms; --kh-t-3:0ms; --kh-t-4:0ms; --kh-t-ambient:0ms;
    --t-tap:0ms; --t-move:0ms; --t-scene:0ms; --t-hero:0ms;
    --t-press:0ms; --t-state:0ms; --t-reveal:0ms;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SELF-HOSTED FONTS — latin-subset WOFF2, offline-proof, zero CDN
   Files live in assets/fonts/ beside this stylesheet; url() is resolved relative
   to tokens.css, so every surface that links it (at any path depth) gets the
   fonts. Add these files to the field service-worker SHELL so offline keeps the
   brand. Subset = Google's official /* latin *​/ cut (U+0000-00FF core).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Hanken Grotesk — variable 400–800, UI voice */
@font-face{
  font-family:'Hanken Grotesk'; font-style:normal; font-weight:400 800; font-display:swap;
  src:url('assets/fonts/HankenGrotesk-400-800-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:'Hanken Grotesk'; font-style:italic; font-weight:400 800; font-display:swap;
  src:url('assets/fonts/HankenGrotesk-Italic-400-800-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;
}

/* IBM Plex Mono — 400 · 500 · 600, instrument voice (500 is canonical) */
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:400; font-display:swap;
  src:url('assets/fonts/IBMPlexMono-400-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:'IBM Plex Mono'; font-style:normal; font-weight:500; font-display:swap;
  src:url('assets/fonts/IBMPlexMono-500-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:'IBM Plex Mono'; font-style:normal; font-weight:600; font-display:swap;
  src:url('assets/fonts/IBMPlexMono-600-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;
}

/* Cormorant Garamond — variable latin (serves 500–700), Ledger display voice */
@font-face{
  font-family:'Cormorant Garamond'; font-style:normal; font-weight:500 700; font-display:swap;
  src:url('assets/fonts/CormorantGaramond-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;
}

/* Caveat — variable 400–700, boot sign-off + printed documents ONLY */
@font-face{
  font-family:'Caveat'; font-style:normal; font-weight:400 700; font-display:swap;
  src:url('assets/fonts/Caveat-400-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;
}
