/* fonts.css */
/* ============================================================================
   HEARTH — fonts.css · the single self-hosted @font-face source (D1/D7)
   ----------------------------------------------------------------------------
   No external origin. Every AETHER surface gets its type from here — either via
   colors_and_type.css (which @imports this) or by linking ../../fonts.css directly
   (brand kits that don't want the full Hearth token layer). url() is relative to
   THIS file (repo root), so /fonts resolves the same from any kit depth.

   Canon: Newsreader (display) · Hanken Grotesk (UI/body) · JetBrains Mono (code) ·
   Sora (wordmark) · Syne (sub-brand/eyebrows). Fraunces, Plus Jakarta Sans + Manrope are
   self-hosted sub-brand/drop faces so those surfaces also ship CDN-free. All permissive OFL, latin-subset variable woff2.
   ============================================================================ */
@font-face{font-family:'JetBrains Mono';font-style:normal;font-weight:100 800;font-display:swap;src:url('fonts/jetbrains-mono-latin-var.woff2') format('woff2');}
@font-face{font-family:'Syne';font-style:normal;font-weight:400 800;font-display:swap;src:url('fonts/syne-latin-var.woff2') format('woff2');}
@font-face{font-family:'Sora';font-style:normal;font-weight:300 800;font-display:swap;src:url('fonts/sora-latin-var.woff2') format('woff2');}
/* --- P2A · the public site's specified faces (vendored 2026-08-30bq, §13 row 88 leg ①) ------
   Both SIL OFL 1.1, verified at google/fonts `ofl/<family>/OFL.txt` before download:
     Newsreader     — Copyright 2020 The Newsreader Project Authors (productiontype/Newsreader)
     Hanken Grotesk — Copyright 2021 The Hanken Grotesk Project Authors (marcologous/hanken-grotesk)
   Latin subset, variable, same convention as the canon faces above.

   ⚠ NEWSREADER CARRIES ITS OPTICAL-SIZE AXIS ON PURPOSE, and it is why this file is the largest
   here (128.7 KB against Fraunces' 65.7). A wght-only build was measured at 56.7 KB — 55% smaller —
   and REJECTED: `font-optical-sizing: auto` is the CSS *initial* value, so a browser drives `opsz`
   by itself with no declaration anywhere, and a grep for `font-variation-settings` cannot see that.
   Newsreader's opsz exists for display sizes, which is exactly how the public site uses it (the
   hero runs at ~56px). Dropping the axis would have been a silent visual downgrade of the direction
   we were asked to apply. ⭐ If the 72 KB ever needs trading, the wght-only URL is
   `.../s/newsreader/v26/cY9VfjOCX1hbuyalUrK49dLac06G1ZGsZBtoBAbNJYQ5ayZC.woff2` — trade it with
   LCP evidence, not on the file size alone. */
@font-face{font-family:'Newsreader';font-style:normal;font-weight:200 800;font-display:swap;src:url('fonts/newsreader-latin-var.woff2') format('woff2');}
@font-face{font-family:'Hanken Grotesk';font-style:normal;font-weight:100 900;font-display:swap;src:url('fonts/hanken-grotesk-latin-var.woff2') format('woff2');}
/* --- P2B · the ENTERPRISE direction's pair (vendored 2026-09-05c, §13 row 120, closing it) -------
   Both SIL OFL 1.1, verified at google/fonts `ofl/<family>/OFL.txt` before download:
     Instrument Serif  — Copyright 2022 The Instrument Serif Project Authors (Instrument/instrument-serif)
     Schibsted Grotesk — Copyright 2023 The Schibsted-Grotesk Project Authors (schibsted/schibsted-grotesk)

   ⚠ THESE TWO ARE NOT THE SAME KIND OF FILE, AND THE NAMES SAY SO. Schibsted Grotesk is VARIABLE
   (`wght` 400..900, 45.8 KB) and takes the `-latin-var` suffix. **Instrument Serif has NO WEIGHT AXIS
   AT ALL** — a `:wght@400..700` request to Google Fonts returns an HTML error page rather than CSS, and
   fontTools finds no `fvar` — so it is a STATIC single-weight face at 400 (14.7 KB) and takes the
   `-latin-regular` suffix, the same convention as Architects Daughter.

   ⛔ SO P2B's `--font-display-weight: 400` IS NOT A STYLISTIC CHOICE — it is the only weight this face
   HAS. Any rule that asks Instrument Serif for 500/600/700 gets a SYNTHETIC bold from the rasteriser,
   which on a high-contrast display serif is exactly the smeared result the weight axis exists to avoid.
   A surface adopting P2B must read `--font-display-weight`, never hard-code a display weight
   ([[applying-a-type-token-needs-a-reader]] — the defect 09-05b found in the consumer kit). */

/* --- P1I / P2C · the consumer + dark direction's display face (vendored 2026-09-05b, §13 row 120) ---
   EB Garamond — SIL OFL 1.1, Copyright 2017 The EB Garamond Project Authors
   (octaviopardo/EBGaramond12), verified at google/fonts `ofl/ebgaramond/OFL.txt` before download.
   Latin subset, VARIABLE (`wght` 400..800, verified with fontTools — not a static 400 renamed), same
   convention as every face above. 43.1 KB.

   ⭐ THE AXIS IS LOAD-BEARING, NOT A NICETY. P1I sets `--font-display-weight: 500` and P2C sets `400`
   from the SAME family, so a static 400 build would have rendered the consumer display weight as a
   synthesised bold on some engines and as plain 400 on others — a silent visual downgrade of the very
   direction we were asked to apply, and the exact trade the Newsreader note above records refusing.

   ⛔ THIS FACE IS WHY THE PAIRINGS WERE PALETTE-ONLY. P1I and P2C name EB Garamond + Hanken Grotesk +
   JetBrains Mono; the latter two were already here, so this ONE file is what unblocked the type half
   of both scopes. ⚠ P2B (enterprise) is NOT unblocked — it names Instrument Serif + Schibsted Grotesk,
   neither vendored, and stays palette-only with Hearth type standing. Do not read "type applied" as
   covering the enterprise apps. */
@font-face{font-family:'Architects Daughter';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/architects-daughter-v20-latin-regular.woff2') format('woff2');}

/* hearth-tokens.css */
/* ============================================================================
   EVENTLAKE DESIGN — Design Tokens (CSS custom properties)

   ⛔⛔ THE BRAND MOVED AND THE JOIN KEYS DID NOT, WHICH IS THE WHOLE RULE FOR THIS FILE.
   `Hearth` and `AETHER` are both retired (brand.Retired: Hearth -> SurfaceDesign, and the
   product is EventLake), so the SENTENCE a human reads is "EventLake Design". But the
   `--hearth-*` custom properties below, the `.hearth` class every component rule is scoped
   under, and this file's own name are PATHS — measured 2026-09-12: 11,503 `--hearth-*` uses
   across ui_kits/ alone. Renaming them is not a rebrand, it is a rewrite of every kit.
   conduit/brand/brand.go says this in one line: "the files … are paths, so they are join
   keys and do not move."
   Warm · calm · human · editorial — Anthropic/Claude-grade or better.
   See blueprint §14e. Light theme = :root. Dark theme = [data-theme="dark"]
   and prefers-color-scheme fallback. Values are WCAG 2.2 AA+ targets,
   validated in CI (accessibility is an acceptance gate, not a retrofit).
   All fonts are permissive OFL (no proprietary type).
   ============================================================================ */

:root {
  /* ---- Brand: Clay / Coral accent ramp (the "warm signature") ---------- */
  --clay-50:  #FBEFE9;
  --clay-100: #F6DBCF;
  --clay-200: #EEBCA7;
  --clay-300: #E39B7F;
  --clay-400: #D67B57;
  --clay-500: #C56240;   /* brand accent (decorative / large text)          */
  --clay-600: #A94E2E;   /* interactive solid bg (white text ≈ AA)          */
  --clay-700: #8B3E23;   /* active / pressed                                */
  --clay-800: #6E3219;

  /* ---- Warm neutrals: "Sand / Paper" canvas + ink --------------------- */
  --hearth-canvas:        #FAF8F4;  /* app background (warm paper, P2A)     */
  --hearth-surface:       #FFFFFF;  /* cards / panels                       */
  --hearth-raised:        #FFFFFF;  /* popovers / modals (+ warm shadow)    */
  --hearth-sunken:        #F1EEE8;  /* insets / wells                       */

  --hearth-border:        #E7E3DB;  /* default hairline                     */
  --hearth-border-strong: #DAD8D4;  /* = 14% ink on canvas */
  --hearth-border-subtle: #ECEAE6;  /* = 6% ink on canvas */
  /* The EDGE OF A CONTROL a person must find (input · select · textarea), which WCAG 1.4.11
     holds to 3:1 against the ground beside it. `--hearth-border-strong` is a decorative rule at
     1.31–1.57:1 and stays one; this is the smallest step down the same warm ramp that clears
     3:1 on all four grounds (3.03 sunken · 3.23 canvas · 3.48 surface · 3.63 raised).
     B6-D5, 2026-09-16tb — a DESIGN INPUT, not a settled tone. */
  --hearth-border-input:  #8A857C;

  --hearth-text:           #191713; /* primary ink (16.87:1 on canvas)      */
  --hearth-text-secondary: #5A554D;
  --hearth-text-muted:     #6D6355;
  /* NON-TEXT ONLY (owner call 2026-08-28l, tracker §13 row 74). Hairlines, dashed borders,
     dots, disabled affordances — never `color:` and never an SVG <text> fill. It measures
     2.68–3.25:1 on every light ground, and the palette cannot carry a fourth legible text
     tier: every ground sits at luminance 0.79–0.93, which caps an AA ink at ~0.16, and
     text/secondary/muted already fill that span. `--hearth-text-muted` is the lowest text
     ink. check.sh guard 26 fails on a text carrier. */
  --hearth-text-faint:     #928F88;   /* P2A #A3A099 measured 2.46:1 on the canvas, under the 3:1 WCAG 1.4.11 non-text bar
                                        the CI contrast gate holds; darkened along the same hue (3.04:1), 2026-10-05fp */
  --hearth-text-on-accent: #FFFFFF;

  /* ---- Semantic accent mappings --------------------------------------- */
  --accent:           #191713;          /* P2A: ink holds the action          */
  --accent-hover:     #191713;
  --accent-active:    #000000;
  --accent-solid-bg:  #191713;          /* CTA bg; pair with white text     */
  --accent-on-solid:  var(--hearth-text-on-accent);
  --accent-subtle-bg: #F1EEE8;          /* tinted accent surface            */
  --accent-text:      #191713;          /* accent-colored text on light     */
  --accent-border:    #E0DCD4;

  /* ---- Signal emphasis (2026-10-10a) ------------------------------------
     P2A "cool signals": the one blue a page may use to say THIS (a link-like emphasis, the active
     row's marker, a selected tab's rule). Not the action — ink holds the action — and never failure
     (clay). Kits used the literal #27506B; naming it lets the dark theme re-point it. Measured as a
     text ink on every light ground by guard 26 (hearth-contrast-audit MATRIX_INKS). */
  --signal-emphasis:  #27506B;

  /* ---- Severity ramp (earthy, harmonized; never color-alone) ---------- */
  --sev-critical-fg: #A12818;  --sev-critical-bg: #F7E0DA;
  --sev-high-fg:     #AB4E19;  --sev-high-bg:     #F9E6D6;
  --sev-medium-fg:   #88660D;  --sev-medium-bg:   #F6ECCE;
  --sev-low-fg:      #57733B;  --sev-low-bg:      #E9EFDA;
  --sev-info-fg:     #3C6188;  --sev-info-bg:     #E2EAF2;

  /* ---- Status (healthy / degraded / down) ----------------------------- */
  --status-healthy-fg:  #466D49; --status-healthy-bg:  #E5EFDF;
  --status-degraded-fg: #7F5F0C; --status-degraded-bg: #F6ECCE;
  --status-down-fg:     #A12818; --status-down-bg:     #F7E0DA;

  /* ---- Data-viz categorical palette (2026-09-29c) ----------------------
     VALIDATED, not eyeballed: the dataviz six-checks validator passes every check in BOTH themes —
     lightness band, chroma floor, adjacent-pair CVD separation (worst ΔE 10.0, target 8), the
     normal-vision floor (≥15) and 3:1 against the surface. The set it replaced failed in both themes
     (five slots read grey; worst protan pair ΔE 3.5) and FIVE slots were a severity colour exactly
     (light viz-2 = sev-info; dark viz-2/3/4/7 = info/medium/low/high), so a series read as a severity.
     ⛔ Categorical colour is for IDENTITY, never state: severity and status keep their own ramps.
     ⛔ Text never wears a viz colour straight — mix it 70% toward --hearth-text (every slot then clears
     4.5:1 on its own 16% tint); ui_kits/hearth-viz.js draws all chart text in ink. */
  --viz-1: #C4552F;  /* clay */
  --viz-2: #2F6DB5;  /* blue */
  --viz-3: #C24F72;  /* rose */
  --viz-4: #5B5FC7;  /* indigo */
  --viz-5: #4E8A1F;  /* green */
  --viz-6: #0086A8;  /* teal */
  --viz-7: #A87400;  /* ochre */
  --viz-8: #9A4F9E;  /* plum */

  /* ---- Typography ----------------------------------------------------- */
  --font-display:  'Newsreader', Georgia, 'Times New Roman', serif;
  --font-sans:     'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-wordmark: 'Sora', 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-display-weight: 400;  /* Newsreader is drawn at 400 (P2A); consumers fall back to 600 without it */
  --font-mono:     'JetBrains Mono', 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;

  --text-micro: 0.625rem;  /* 10 */
  --text-2xs:   0.6875rem; /* 11 */
  --text-xs:   0.75rem;   /* 12 */
  --text-sm:   0.875rem;  /* 14 */
  --text-base: 1rem;      /* 16 */
  --text-md:   1.125rem;  /* 18 */
  --text-lg:   1.25rem;   /* 20 */
  --text-xl:   1.5rem;    /* 24 */
  --text-2xl:  1.875rem;  /* 30 */
  --text-3xl:  2.25rem;   /* 36 */
  --text-4xl:  3rem;      /* 48 */
  --text-5xl:  3.75rem;   /* 60 (display) */

  --leading-tight:   1.15;
  --leading-snug:    1.3;
  --leading-normal:  1.5;
  --leading-relaxed: 1.65;

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  --tracking-tight:  -0.02em;
  --tracking-normal: 0;
  --tracking-wide:   0.02em;

  /* ---- Spacing (4px base) --------------------------------------------- */
  --space-0: 0;        --space-1: 0.25rem;  --space-2: 0.5rem;
  --space-3: 0.75rem;  --space-4: 1rem;     --space-5: 1.25rem;
  --space-6: 1.5rem;   --space-8: 2rem;     --space-10: 2.5rem;
  --space-12: 3rem;    --space-16: 4rem;    --space-20: 5rem;  --space-24: 6rem;

  /* ---- Radius (rounded / friendly) ------------------------------------ */
  --radius-sm:  6px;  --radius-md: 10px;  --radius-lg: 14px;
  --radius-xl: 20px;  --radius-2xl: 28px; --radius-full: 9999px;

  /* ---- Elevation (soft, warm-tinted shadows) -------------------------- */
  --shadow-sm: 0 1px 2px rgba(61,45,30,.06);
  --shadow-md: 0 2px 8px rgba(61,45,30,.08), 0 1px 2px rgba(61,45,30,.05);
  --shadow-lg: 0 10px 30px rgba(61,45,30,.10), 0 2px 6px rgba(61,45,30,.06);
  --shadow-xl: 0 20px 50px rgba(61,45,30,.14);

  /* ---- Motion (gentle, purposeful) ------------------------------------ */
  --ease-standard:   cubic-bezier(.2, 0, 0, 1);
  --ease-emphasized: cubic-bezier(.3, 0, 0, 1);
  /* D25/M2 — tactile micro-interactions only; never a verdict. A PHYSICAL spring since 2026-09-29mq (owner call):
     the step response of the damped oscillator in hearth-tokens.json `motion.spring` (response 0.36 s, damping
     0.72 → 3.8 % overshoot, one small ring), sampled to linear() over its settle time. ⛔ GENERATED — edit the
     JSON, then `python3 ui_kits/spring-canon.py --write` (check.sh guard 52 fails on drift). Android Motion.kt and
     iOS Motion.swift evaluate the same function from the same two numbers. The duration token sets the speed. */
  --ease-spring: linear(0, 0.0012 0.5%, 0.0075 1.25%, 0.0144 1.75%, 0.0282 2.5%, 0.0396 3%, 0.0597 3.75%, 0.0827 4.5%, 0.1084 5.25%, 0.1558 6.5%, 0.2185 8%, 0.2849 9.5%, 0.4659 13.5%, 0.531 15%, 0.5829 16.25%, 0.6418 17.75%, 0.6877 19%, 0.7306 20.25%, 0.7702 21.5%, 0.8066 22.75%, 0.846 24.25%, 0.8753 25.5%, 0.9065 27%, 0.9293 28.25%, 0.953 29.75%, 0.973 31.25%, 0.9897 32.75%, 1.0108 35.25%, 1.026 38%, 1.035 41%, 1.0384 44.5%, 1.0353 49.25%, 1.0124 63.5%, 1.0031 72.5%, 0.9988 84.5%, 1);
  /* Hearth's other curves all DECELERATE — right for arriving. An exit accelerates away (adopted 2026-09-29mr). */
  --ease-exit:       cubic-bezier(.3, 0, 1, 1);
  --duration-instant:    80ms;   /* press feedback — below the threshold people read as "animation" (29mr) */
  --duration-fast:   120ms;
  --duration-base:   200ms;
  --duration-slow:   320ms;
  --duration-slower: 480ms;
  --duration-deliberate: 720ms;  /* ceremony outcomes; the public-site rise (29mr) */
  /* Distance and rhythm are tokens too (29mr). A list staggers by one step per item and stops growing at the
     cap: from the cap-th item on, the rest arrive together — beyond that, a longer cascade is waiting. */
  --motion-rise:       8px;      /* product entrances */
  --motion-rise-site:  18px;     /* the public site's showpiece entrances */
  --motion-stagger:    30ms;
  --motion-stagger-cap: 6;

  /* ---- Focus ring (clay, always visible) ------------------------------ */
  /* SOLID, not 35 % clay-500: composited, the translucent ring measured 1.49–1.55:1 against
     the grounds it sits on, under the 3:1 a focus indicator needs (WCAG 1.4.11; B6-D5,
     2026-09-16tb). clay-600 (= --accent-solid-bg) clears 4.59 sunken · 4.89 canvas · 5.28
     surface · 5.50 raised. A literal, not var(--clay-600), so the dark blocks can re-point it. */
  --focus-ring: 0 0 0 3px #27506B;   /* P2A signal-link: 7.41 sunken · 8.09 canvas · 8.59 surface */

  /* ---- Density (D8.3) --------------------------------------------------
     Comfortable is the default (editorial Hearth spacing). High-volume triage
     surfaces (SOC portal tables) opt into compact via data-density="compact"
     on a root element; components reference the tokens, never hardcode. */
  --density-row-y:     var(--space-3);   /* table-row vertical padding   */
  --density-row-x:     var(--space-4);   /* table-cell horizontal padding */
  --density-table-fs:  0.95rem;          /* table font size               */
  --density-line:      1.5;              /* table line-height             */

  color-scheme: light;
}

/* Compact density — SOC / high-volume triage surfaces. */
[data-density="compact"] {
  --density-row-y:    var(--space-1);
  --density-row-x:    var(--space-2);
  --density-table-fs: 0.85rem;
  --density-line:     1.35;
}

/* ============================================================================
   DARK THEME — warm espresso (NOT cold black). For war-rooms / big-screens.
   ============================================================================ */
:root[data-theme="dark"] {
  --hearth-canvas:        #101114;
  --hearth-surface:       #191A1E;
  --hearth-raised:        #23242A;
  --hearth-sunken:        #0B0C0E;

  --hearth-border:        #292A30;
  --hearth-border-strong: #303133;
  --hearth-border-subtle: #1E1F21;
  --hearth-border-input:  #73747C;   /* 3.33 raised · 3.74 surface · 4.06 canvas · 4.21 sunken */

  --hearth-text:           #F5F5F3;
  --hearth-text-secondary: #A9AAAF;
  --hearth-text-muted:     #9A9BA1;   /* P2C #85868C fails the chip fills (3.71); this clears all (worst 4.86) */
  --hearth-text-faint:     #65666A;   /* P2C #595A5E measured 2.74:1 — lifted along the same hue to 3.29:1 (CI contrast gate), 2026-10-05fp */
  --hearth-text-on-accent: #101114;

  --accent:           #F5F5F3;
  --accent-hover:     #F5F5F3;
  --accent-active:    #FFFFFF;
  --accent-solid-bg:  #F5F5F3;   /* P2C: paper holds the action; pair with --hearth-text-on-accent */
  --accent-subtle-bg: #23242A;
  --accent-text:      #F5F5F3;
  --accent-border:    #34353C;
  --signal-emphasis:  #E8A489;   /* P2C: the warm signal on ink */

  --sev-critical-fg: #E87C6A;  --sev-critical-bg: #3A2420;
  --sev-high-fg:     #E8975A;  --sev-high-bg:     #3A2C1E;
  --sev-medium-fg:   #D8B45A;  --sev-medium-bg:   #332B1A;
  --sev-low-fg:      #A6C77E;  --sev-low-bg:      #26301E;
  --sev-info-fg:     #86B0DA;  --sev-info-bg:     #20293A;

  --status-healthy-fg:  #8FC78A; --status-healthy-bg:  #21301E;
  --status-degraded-fg: #D8B45A; --status-degraded-bg: #332B1A;
  --status-down-fg:     #E87C6A; --status-down-bg:     #3A2420;

  --viz-1: #D46A42; --viz-2: #4F86CC; --viz-3: #CF6E8B; --viz-4: #7D7FD6;
  --viz-5: #5F9A34; --viz-6: #1A97AE; --viz-7: #B8892A; --viz-8: #A86FB2;

  --shadow-sm: 0 1px 2px rgba(0,0,0,.40);
  --shadow-md: 0 2px 8px rgba(0,0,0,.45), 0 1px 2px rgba(0,0,0,.35);
  --shadow-lg: 0 10px 30px rgba(0,0,0,.50), 0 2px 6px rgba(0,0,0,.40);
  --shadow-xl: 0 20px 50px rgba(0,0,0,.55);

  --focus-ring: 0 0 0 3px #9CC0DC;   /* P2C signal-link: 8.09–10.24:1 on the dark grounds */

  color-scheme: dark;
}

/* System-preference fallback when no explicit data-theme is set */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --hearth-canvas: #101114;        --hearth-surface: #191A1E;
    --hearth-raised: #23242A;        --hearth-sunken: #0B0C0E;
    --hearth-border: #292A30;        --hearth-border-strong: #303133;
    --hearth-border-subtle: #1E1F21; --hearth-border-input: #73747C;
    /* The system-preference dark theme never re-pointed the ring, so it drew the LIGHT
       ring's clay on espresso. Same value as [data-theme="dark"]. */
    --focus-ring: 0 0 0 3px #9CC0DC;
    --hearth-text: #F5F5F3;          --hearth-text-secondary: #A9AAAF;
    --hearth-text-muted: #9A9BA1;    --hearth-text-faint: #65666A;
    --hearth-text-on-accent: #101114;
    --accent: #F5F5F3;               --accent-hover: #F5F5F3;
    --accent-active: #FFFFFF;        --accent-solid-bg: #F5F5F3;
    --accent-subtle-bg: #23242A;     --accent-text: #F5F5F3;
    --accent-border: #34353C;
    --signal-emphasis: #E8A489;
    --sev-critical-fg:#E87C6A; --sev-critical-bg:#3A2420;
    --sev-high-fg:#E8975A;     --sev-high-bg:#3A2C1E;
    --sev-medium-fg:#D8B45A;   --sev-medium-bg:#332B1A;
    --sev-low-fg:#A6C77E;      --sev-low-bg:#26301E;
    --sev-info-fg:#86B0DA;     --sev-info-bg:#20293A;
    --status-healthy-fg:#8FC78A;  --status-healthy-bg:#21301E;
    --status-degraded-fg:#D8B45A; --status-degraded-bg:#332B1A;
    --status-down-fg:#E87C6A;     --status-down-bg:#3A2420;
    --viz-1:#D46A42; --viz-2:#4F86CC; --viz-3:#CF6E8B; --viz-4:#7D7FD6;
    --viz-5:#5F9A34; --viz-6:#1A97AE; --viz-7:#B8892A; --viz-8:#A86FB2;
    /* Elevation: the light theme's warm-brown shadows vanish on ink. These four were set for
       [data-theme="dark"] only, so a dark OS without the toggle drew light shadows (modernization
       audit 2026-10-16 P0-5). ui_kits/audits/theme-parity-audit.py (check.sh guard 63) keeps the blocks equal. */
    --shadow-sm: 0 1px 2px rgba(0,0,0,.40);
    --shadow-md: 0 2px 8px rgba(0,0,0,.45), 0 1px 2px rgba(0,0,0,.35);
    --shadow-lg: 0 10px 30px rgba(0,0,0,.50), 0 2px 6px rgba(0,0,0,.40);
    --shadow-xl: 0 20px 50px rgba(0,0,0,.55);
    color-scheme: dark;
  }
}

/* A browser without CSS linear() (Safari < 17.2, Firefox < 112) would drop every declaration that uses the spring
   and fall back to `ease`. It gets the retired bézier instead — one overshoot, no ring, but the right character.
   Declared AFTER :root so the physical curve stays the first --ease-spring (the native parity tests read the first). */
@supports not (transition-timing-function: linear(0, 1)) {
  :root { --ease-spring: cubic-bezier(.34, 1.4, .5, 1); }
}

/* Honor reduced-motion globally */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-fast: 0ms; --duration-base: 0ms;
    --duration-slow: 0ms; --duration-slower: 0ms;
    /* Every TIME token, not just the four originals — a new duration missing here keeps moving (29mr). */
    --duration-instant: 0ms; --duration-deliberate: 0ms; --motion-stagger: 0ms;
  }
}

/* colors_and_type.css */
/* ============================================================================
   EVENTLAKE DESIGN — colors_and_type.css
   Semantic typography + color roles for the EventLake Design language.
   ⚠ The `.hearth` scope class below and the `hearth-tokens.css` import are JOIN KEYS, not
   brand: see that file's header for the measurement.
   Layers on top of the source-of-truth tokens (hearth-tokens.css).

   Load order:
     1. fonts.css           — self-hosted @font-face (no CDN, no external origin; D1/D7)
     2. hearth-tokens.css   — raw token primitives (palette, neutrals, spacing…)
     3. colors_and_type.css — THIS FILE: semantic aliases + element defaults

   Type canon (P2A, owner-ratified 2026-10-04 — docs/reference/palette-direction.md §0), all
   permissive OFL, no proprietary type — same clean-room rule as code:
     · Newsreader      — display serif (--font-display), drawn at 400
     · Hanken Grotesk  — all UI + body text, and the uppercase eyebrows/labels (--font-sans)
     · JetBrains Mono  — logs / code / identifiers (--font-mono)
     · Sora            — the WORDMARK ONLY (--font-wordmark); matches eventlake-signature*.svg
     · Architects Daughter — sparing handwritten margin annotations (--font-hand)
   The families are defined ONCE, in hearth-tokens.css; this file only aliases them by role.
   Fraunces and Plus Jakarta Sans were the pre-P2A display/UI faces, and Inter before them —
   all retired from every stack. fonts.css still self-hosts the first two for frozen drops and
   sub-brand pages; no role here resolves to them.
   ============================================================================ */


/* Fonts — FULLY SELF-HOSTED via fonts.css (D1/D7): no Google-Fonts CDN, no external
   origin, so the console ships in air-gapped / CSP'd deployments. fonts.css is the single
   @font-face source (the canon faces above, plus the self-hosted sub-brand faces). It is
   @import'd here, and brand kits that skip the Hearth token layer link ../../fonts.css directly. */

:root {
  /* ---- Semantic foreground aliases (fg1 = primary ink … fg4 = faintest) ---- */
  --fg1: var(--hearth-text);            /* primary ink — warm near-black     */
  --fg2: var(--hearth-text-secondary);  /* secondary copy                    */
  --fg3: var(--hearth-text-muted);      /* muted / metadata                  */
  --fg4: var(--hearth-text-faint);      /* faint / placeholder               */
  --fg-on-accent: var(--hearth-text-on-accent);
  --accent-on-solid: var(--hearth-text-on-accent);

  /* ---- Semantic background aliases (bg1 = app canvas … bg-raised = modal) - */
  --hearth-bg: var(--hearth-canvas);
  --bg1: var(--hearth-canvas);          /* app background                    */
  --bg2: var(--hearth-surface);         /* cards / panels                    */
  --bg-raised: var(--hearth-raised);    /* popovers / modals                 */
  --bg-sunken: var(--hearth-sunken);    /* wells / insets / code blocks      */

  /* ---- Font-role aliases ------------------------------------------------- */
  /* UI/body face is Hanken Grotesk (P2A). Inter is RETIRED from the
     stack — it was never self-hosted in fonts/, so it only ever resolved on boxes
     that happened to have it installed, i.e. it rendered the design system
     inconsistently rather than acting as a safety net.

     --font-sans is deliberately NOT re-declared here. It is defined ONCE, in
     hearth-tokens.css (the token layer @import'd at the top of this file), and the
     role aliases below simply point at it. This file used to override it, and the
     two copies silently disagreed for months — tokens said Inter, this file said
     Plus Jakarta — which is exactly how a retired face survived in the shipped
     canon. One definition means a future face change cannot half-land. */
  --serif-display: var(--font-display);
  --sans-ui:       var(--font-sans);
  --mono-logs:     var(--font-mono);

  /* ---- Brand font assignment (uploaded fonts, self-hosted) --------------- */
  /* The wordmark uses Sora (the exact variable face embedded in eventlake-signature*.svg),
     falling back to the canon UI face Hanken Grotesk and system sans-serif. */
  --font-wordmark: 'Sora', 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; /* logotype ONLY (distinctive brand signature) */
  --font-label:    var(--font-sans);                     /* eyebrows / micro-labels — Hanken Grotesk uppercase */
  --font-jakarta:  var(--font-sans);                     /* explicit alias for the UI face */
  --font-hand:     'Architects Daughter', 'Comic Sans MS', cursive; /* handwritten margin notes */
  --font-syne:     'Syne', var(--font-display);          /* back-compat alias */

  /* ---- Semantic type roles (size / weight / leading / tracking / family) -- */
  /* Display — Newsreader, editorial, used for hero & narrative headings */
  --display-font: var(--font-display);
  --display-weight: var(--weight-regular);   /* P2A: Newsreader is drawn at 400 (owner call 2026-10-02) */
  --display-tracking: var(--tracking-tight);
  --display-leading: var(--leading-tight);

  /* h1 / h2 / h3 — Newsreader. h4+ shift to the UI sans for interface chrome */
  --h1-size: var(--text-5xl);   --h1-leading: var(--leading-tight);
  --h2-size: var(--text-3xl);   --h2-leading: var(--leading-tight);
  --h3-size: var(--text-xl);    --h3-leading: var(--leading-snug);
  --h4-size: var(--text-lg);    --h4-leading: var(--leading-snug);

  /* eyebrow — uppercase mini-label above headings */
  --eyebrow-size: var(--text-xs);
  --eyebrow-tracking: var(--tracking-wide);

  /* body / lead / small */
  --p-size: var(--text-base);   --p-leading: var(--leading-normal);
  --lead-size: var(--text-lg);  --lead-leading: var(--leading-relaxed);
  --small-size: var(--text-sm);
  --caption-size: var(--text-xs);

  /* code / log line */
  --code-size: var(--text-sm);
  --code-leading: var(--leading-snug);
}

:root, .hearth {
  --bg: var(--hearth-canvas);
  --fg: var(--hearth-text);
}

:root[data-theme="dark"] {
  --accent-active: #FFFFFF;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --accent-active: #FFFFFF;
  }
}

/* ============================================================================
   ELEMENT DEFAULTS — opt-in by scoping under .hearth (so the design system
   never fights a host app). Apply class="hearth" on <body> or any container.
   ============================================================================ */

.hearth {
  background: var(--bg1);
  color: var(--fg1);
  font-family: var(--sans-ui);
  font-size: var(--p-size);
  line-height: var(--p-leading);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-synthesis: none;
}

.hearth h1, .hearth h2, .hearth h3 {
  font-family: var(--serif-display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: var(--display-leading);
  color: var(--fg1);
  margin: 0;
  text-wrap: pretty;
}
.hearth h1 { font-size: var(--h1-size); line-height: var(--h1-leading); }
.hearth h2 { font-size: var(--h2-size); line-height: var(--h2-leading); }
.hearth h3 { font-size: var(--h3-size); line-height: var(--h3-leading); }

/* h4 and below are interface chrome → humanist sans, not serif */
.hearth h4, .hearth h5, .hearth h6 {
  font-family: var(--sans-ui);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-normal);
  line-height: var(--h4-leading);
  color: var(--fg1);
  margin: 0;
}
.hearth h4 { font-size: var(--h4-size); }
.hearth h5 { font-size: var(--text-base); }
.hearth h6 { font-size: var(--small-size); }

.hearth p {
  margin: 0;
  color: var(--fg2);
  line-height: var(--p-leading);
  text-wrap: pretty;
  max-width: 68ch;
}

.hearth .display {
  font-family: var(--display-font);
  font-size: var(--text-5xl);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: var(--display-leading);
}

.hearth .eyebrow {
  text-transform: uppercase;
  letter-spacing: var(--eyebrow-tracking);
  font-size: var(--eyebrow-size);
  font-weight: var(--weight-semibold);
  color: var(--accent-text);
  font-family: var(--font-label);
}

.hearth .lead {
  font-size: var(--lead-size);
  line-height: var(--lead-leading);
  color: var(--fg2);
}

.hearth small, .hearth .small { font-size: var(--small-size); }
.hearth .caption { font-size: var(--caption-size); color: var(--fg3); }
.hearth .muted { color: var(--fg3); }
.hearth .faint { color: var(--fg4); }

.hearth code, .hearth kbd, .hearth pre, .hearth .mono {
  font-family: var(--mono-logs);
  font-size: var(--code-size);
  line-height: var(--code-leading);
  font-feature-settings: "liga" 0;
}
.hearth pre {
  background: var(--bg-sunken);
  border: 1px solid var(--hearth-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  overflow: auto;
  color: var(--fg1);
}

.hearth a { color: var(--accent-text); text-underline-offset: 2px; }
.hearth a:hover { color: var(--accent-active); }

.hearth ::selection { background: var(--accent-subtle-bg); color: var(--accent-active); }

/* ⛔ The ring is a box-shadow, and forced-colours mode (Windows High Contrast) DROPS box-shadow — so
   `outline: none` left keyboard focus invisible there on every Hearth surface (2026-10-02o audit, DS-8).
   A TRANSPARENT outline costs nothing in normal rendering and is repainted in the system highlight
   colour in forced-colours mode, which is exactly when the shadow disappears. */
.hearth :focus-visible { outline: 2px solid transparent; outline-offset: 1px; box-shadow: var(--focus-ring); }
/* The ring FOLLOWS THE ELEMENT'S OWN SHAPE (2026-09-29mn, motion-specimen review R4). The radius used to ride in
   the rule above at (0,2,0), which outranked every component's own `border-radius` (0,1,0) — so each Hearth pill
   squared off to 6px while keyboard-focused. It now sits at zero specificity: an element that declares a radius
   keeps it; one that declares none (a link, a bare control) still gets the rounded ring. The ring itself stays at
   (0,2,0) above, so no component rule can quietly remove it. */
:where(.hearth :focus-visible) { border-radius: var(--radius-sm); }

