/* drillable design system — flattened, served token layer for gateway/site.
   Source of truth: /design-system/tokens/*.css (the bundle). This is the
   no-build, single-file projection the static site links. GENERATED by
   flatten-design-system.py — edit tokens in the bundle, not here, then reflatten
   (CI's `flatten-design-system.py --check` fails on drift). The trailing
   EXTENSIONS block is the gateway's own additions (documented). */

/* Fonts — Newsreader (serif/wordmark), Hanken Grotesk (UI/body), JetBrains Mono (mono).
   All three are Google Fonts. We link Google's hosted CSS, whose @font-face rules
   (with gstatic src URLs) enter the shipped closure. NOTE: binaries are NOT vendored —
   if you need offline/self-hosted fonts, drop the .woff2 files in and replace this import. */
@import url("https://fonts.googleapis.com/css2?family=Hanken+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;700&family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;1,6..72,400;1,6..72,500&display=swap");

/* ===== tokens/colors.css ===== */
/* COLORS — "Flamed Titanium". One warm light field holding a gunmetal core, with a
   cool flame allowed ONLY in the strata — the transitional depths the drill passes
   through. Surfaces, the strike, and the grading triad stay warm; cool never signals
   "verified". Derived from a flame-anodised titanium reference (steel temper colours). */
:root {
  /* Warm surfaces — the light field you drill from (unchanged) */
  --surface-0: #FBF7F0;   /* ivory ground */
  --surface-1: #F5EDE1;
  --surface-2: #EDE2D2;
  --surface-3: #E4D6C2;
  --line:      #DECFB8;    /* hairline */
  --line-soft: #EBE0D0;

  /* Ink — warm dark text on light (unchanged) */
  --ink:   #2A2018;        /* warm near-black */
  --ink-2: #574A3C;        /* body */
  --ink-3: #8A7A66;        /* muted / labels */

  /* Bedrock — gunmetal graphite. The titanium body of the pen, not soil. */
  --bedrock:   #1A1815;
  --bedrock-2: #242019;
  --bedrock-3: #2E2922;

  /* --*-base — the RAW ground the DOMAIN-REACTIVE layer derives from. That layer injects the
     drilled corpus hue while PRESERVING each token's own LIGHTNESS (`oklch(from <base> l C H)`),
     so it must read a base that FLIPS per theme — it cannot read --surface-0 itself, since it
     OVERRIDES --surface-0 and a custom property referencing its own overridden value is a cycle.
     Light = these literals (identical to the tokens above, so light output is unchanged); each
     dark theme re-points them (themes.css), which is what makes domain-reactivity theme-aware. */
  --surface-0-base: #FBF7F0;
  --surface-1-base: #F5EDE1;
  --surface-2-base: #EDE2D2;
  --surface-3-base: #E4D6C2;
  --line-base:      #DECFB8;
  --line-soft-base: #EBE0D0;
  --bedrock-base:   #1A1815;
  --bedrock-2-base: #242019;
  --bedrock-3-base: #2E2922;
  --ink-base:   #2A2018;
  --ink-2-base: #574A3C;
  --ink-3-base: #8A7A66;

  /* Strata — the FLAME ramp: gunmetal blue-grey at depth, through slate and plum,
     warming to amber and ivory as it nears the surface. The one place cool lives. */
  --strata-1: #4B4F52;     /* dimmest / coolest, at depth */
  --strata-2: #5E5860;     /* slate */
  --strata-3: #7A5A5E;     /* plum */
  --strata-4: #A8895F;     /* warming amber */
  --strata-5: #E6D6B6;     /* ivory-on-dark, warm again */

  /* Semantic accents — the metaphor (pulled toward the pen's golden burnt-orange) */
  --mark:    #B26A2A;      /* burnt amber — the drill bit biting in (primary action) */
  --mark-2:  #98531C;      /* pressed */
  --strike:  #D98A2B;      /* warm gold — the verified hit, arrival stays warm */
  --strike-2:#BE7320;

  /* Patina — NEW cool counter-accent. Strata edges, depth rules, transitional UI ONLY.
     Never for status, never for "verified". */
  --patina:   #6E7E80;     /* titanium blue-grey */
  --patina-2: #5E6770;

  /* Brandmark — the drill's three FIXED temper colours (steel heat-tint sequence,
     sampled from the reference). Identity is constant: these do NOT theme. */
  --bit-amber: #9A632D;    /* surface — the bite */
  --bit-ember: #77393C;    /* strata — running hot */
  --bit-plum:  #533E4E;    /* strike — deep, at the point */

  /* Grading triad + flag — stays warm (verified must never read cold) */
  --ok:    #5C7E2E;        /* verified — warm moss, yellow-leaning */
  --seed:  #B6852F;        /* cited — amber/tan */
  --dry:   #9A8772;        /* dry hole — warm taupe, no source */
  --flag:  #BC3A26;        /* warm-red "can't vouch" squiggle */

  /* Code syntax — warm (light surfaces) */
  --syn-key: #B26A2A;
  --syn-str: #5C7E2E;
  --syn-num: #B6852F;
  --syn-com: #8C7B66;
  --syn-fn:  #C77D3A;

  /* On-dark syntax — code blocks live on --bedrock even on the light page, where the light
     --syn-* go too dark to read. One warm value per role, lifted and contrast-clamped for
     WCAG AA on --bedrock / --bedrock-2. Warm family only — ambers, gold, warm moss, taupe. */
  --syn-key-on-dark: #E2974A;  /* keyword  — lifted burnt amber */
  --syn-str-on-dark: #A8C77E;  /* string   — warm moss (yellow-leaning, not a cool green) */
  --syn-num-on-dark: #E6C06A;  /* number   — warm gold */
  --syn-com-on-dark: #9E8E76;  /* comment  — warm taupe, intentionally dimmer */
  --syn-fn-on-dark:  #EFB382;  /* function — warm peach */

  /* Layout */
  --measure: 680px;
}

/* Bedrock surfaces (code blocks, modals, the dark core) remap the syntax palette to the
   on-dark set. Mark any dark ground with data-surface="bedrock" (or class .on-bedrock); its
   descendants reading var(--syn-*) get the legible warm-on-dark colours automatically — no
   per-surface hardcoding. Independent of page theme: a code block is bedrock even on light. */
[data-surface="bedrock"], .on-bedrock {
  --syn-key: var(--syn-key-on-dark);
  --syn-str: var(--syn-str-on-dark);
  --syn-num: var(--syn-num-on-dark);
  --syn-com: var(--syn-com-on-dark);
  --syn-fn:  var(--syn-fn-on-dark);
}

/* ===== tokens/inst.css ===== */
/* --inst — the runtime hook. JS sets a HUE per drilled domain; L and C are locked
   to the register. Every active accent (entity, send button, drill links, core-sample
   edge, ambient glow) resolves THROUGH --inst. Idle falls back to warm --mark.

   Contract (see readme / Answer component):
     L = .63 (legibility anchor, fixed)
     H = hashOf(domain) % 360            (full wheel)
     C = .11 + slice/255 * .05           (band .11–.16, no greys)

   The derived family below is declared on a UNIVERSAL rule, not :root, on purpose:
   custom properties that contain var(--inst) are substituted at their declaring element,
   so if they lived only on :root they would NOT re-derive when a subtree overrides --inst
   (e.g. a drilled-view container). Declared universally, every element re-derives from its
   own cascaded --inst — so set --inst anywhere and the whole family tracks. */
:root {
  --inst: #C0531A;  /* default = mark (warm brand). JS overrides per domain. */
}

*, *::before, *::after {
  --inst-tint:  color-mix(in oklab, var(--inst) 15%, transparent);   /* entity wash */
  --inst-press: color-mix(in oklab, var(--inst), #000 16%);          /* pressed — darken, keep hue */
  --inst-ink:   var(--bedrock);  /* text ON an --inst fill — constant BECAUSE L is locked */
  --inst-text:  var(--inst);     /* accent AS text. App layer may clamp to >=4.5:1 (see guide). */
  --glow-core:  0 0 0 1px color-mix(in oklab, var(--inst) 45%, transparent),
                0 10px 34px -8px color-mix(in oklab, var(--inst) 38%, transparent);
}

/* ===== tokens/domain-reactive.css ===== */
/* --dh — DOMAIN-REACTIVE PALETTE. Lifts the per-corpus hue (the --inst register, hue =
   hashOf(domain)) out to one animatable number and re-derives the whole page SHELL from it:
   the drilled corpus colours the surfaces, edges, logo, accent and nav, while the text you
   READ and the honesty vocabulary (verified / grading / no-source) stay warm and constant.

   Applied ONLY under `.domain-reactive` — the ask app adds it to <body> (ask-app.js); the
   static pages that link this stylesheet keep the warm Flamed-Titanium tokens untouched.

   Design: the Claude Design handoff "Domain-Reactive Palette"
   (findings/domain-reactive-palette.md). Each token keeps its OWN lightness and takes the
   hue on the chroma channel at a clamped amount (`oklch(from <base> l C H)`), so contrast is
   domain-INVARIANT (measured AAA). One registered @property (--dh) means interpolating it
   cross-fades the entire palette at once. Wrapped in @supports so a browser without relative
   colour syntax simply keeps the static warm palette (progressive enhancement, never broken).

   The knobs (--wash-k field strength, --edge-k edge saturation) are config, not per-drill
   state — tune them here. The primary accent shifts with the domain (`accentMode: shift`);
   the faceted logo re-tints too when a corpus is drilled — but the DrillMark reads --dh +
   data-instance DIRECTLY (a JS palette per facet, since per-facet 3D shading can't ride flat
   vars), so no --mark-* custom property carries the logo. The app only sets --dh + data-instance. */

@property --dh     { syntax: "<number>"; inherits: true; initial-value: 60; }
@property --wash-k { syntax: "<number>"; inherits: true; initial-value: 0.4; }
@property --edge-k { syntax: "<number>"; inherits: true; initial-value: 1; }

@supports (color: oklch(from white l 0.1 200)) {
  .domain-reactive {
    --dh: 60;        /* JS sets this per drilled corpus; 60 = idle/home (warm brand hue). */
    --wash-k: 0.4;   /* field-wash strength (surfaces + bedrock). */
    --edge-k: 1;     /* edge saturation (hairlines / frame). */

    /* ACCENT — the DS --inst contract (L/C locked, hue = --dh): entity, glow, drill links.
       The primary action (Ground it / send) shifts to the domain too. */
    --inst:   oklch(0.63 0.13 var(--dh));
    --mark:   oklch(0.60 0.15 var(--dh));
    --mark-2: oklch(0.52 0.15 var(--dh));

    /* FIELD — keep each surface's own lightness, inject hue at clamped chroma. Derived from the
       per-theme --surface-*-base (colors.css / themes.css): the base carries the LIGHTNESS, so in
       a dark theme the same derivation lands dark surfaces, not a re-tinted ivory (the bug where
       the domain-reactive layer overrode data-theme=dark2 back to a light ground). */
    --surface-0: oklch(from var(--surface-0-base) l calc(0.013 * var(--wash-k)) var(--dh));
    --surface-1: oklch(from var(--surface-1-base) l calc(0.018 * var(--wash-k)) var(--dh));
    --surface-2: oklch(from var(--surface-2-base) l calc(0.026 * var(--wash-k)) var(--dh));
    --surface-3: oklch(from var(--surface-3-base) l calc(0.034 * var(--wash-k)) var(--dh));

    /* EDGES — drop lightness + push chroma so the frame coheres with the field (a warm-tan
       hairline reads stranded on a cool ground). The delta rides the theme's --line-base, so a
       dark theme's already-lifted hairline stays above its surface. */
    --line:      oklch(from var(--line-base) calc(l - 0.055) calc(0.058 * var(--edge-k)) var(--dh));
    --line-soft: oklch(from var(--line-soft-base) calc(l - 0.02)  calc(0.032 * var(--edge-k)) var(--dh));

    /* DARK CORE — bedrock (code, modals) takes the hue at a whisper, stays graphite-deep. */
    --bedrock:   oklch(from var(--bedrock-base) l calc(0.03  * var(--wash-k)) var(--dh));
    --bedrock-2: oklch(from var(--bedrock-2-base) l calc(0.035 * var(--wash-k)) var(--dh));
    --bedrock-3: oklch(from var(--bedrock-3-base) l calc(0.04  * var(--wash-k)) var(--dh));

    /* TEXT — the ink ramp takes a domain undertone too, each tier keeping its OWN lightness
       so contrast holds (AAA): the darkest reading text gets only a whisper of hue, the muted
       labels/hints read clearly domain. Derived from --ink-*-base so a dark theme's LIGHT ink
       reads on the dark ground. This colours the placeholder hint, the model selector, the nav
       links and every metadata label along with everything else. */
    --ink:   oklch(from var(--ink-base) l 0.03 var(--dh));
    --ink-2: oklch(from var(--ink-2-base) l 0.06 var(--dh));
    --ink-3: oklch(from var(--ink-3-base) l 0.11 var(--dh));

    /* HELD WARM — NOT overridden, so they inherit the DS defaults unchanged: the honesty
       vocabulary only, so "verified / cited / no-source" reads the same in every domain.
         --strike --strike-2            the verified hit (arrival stays warm)
         --ok --seed --dry --flag       the grading triad + no-source */

    /* Cross-fade the whole palette by interpolating --dh (a registered @property). */
    transition: --dh 560ms var(--ease-out),
                --wash-k 300ms var(--ease-out),
                --edge-k 300ms var(--ease-out);
  }

  /* LOGO — the faceted drill mark re-tints on drill by reading --dh + data-instance
     DIRECTLY (design-system/components/chrome/Chrome.jsx: a JS palette computed per facet
     from the corpus hue). Per-facet 3D shading can't be expressed as flat strata vars, so
     there is no --mark-s* recipe here anymore — the mark is driven from --dh like the app
     sets it, gated on [data-instance] so the resting brand mark is preserved. */
}

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

/* ===== tokens/typography.css ===== */
/* TYPOGRAPHY — Newsreader (serif: wordmark, display, the answer body),
   Hanken Grotesk (UI/body sans), JetBrains Mono (labels/code).
   Type scale: ~17 ad-hoc inline sizes -> 11 steps on a 1.25 modular scale. */
:root {
  --font-serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-sans:  'Hanken Grotesk', system-ui, -apple-system, sans-serif;
  --font-mono:  'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  --text-2xs: 11px;
  --text-xs:  12.5px;
  --text-sm:  14px;
  --text-base:16px;
  --text-md:  18px;
  --text-lg:  21px;
  --text-xl:  25px;
  --text-2xl: 31px;
  --text-3xl: 39px;
  --text-4xl: 49px;
  --text-5xl: 62px;
}

/* ===== tokens/spacing.css ===== */
/* SPACING — 4px base. No spacing tokens existed pre-consolidation. */
:root {
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
}

/* ===== tokens/radius.css ===== */
/* RADIUS — 11 ad-hoc values -> 6 steps. */
:root {
  --radius-xs:   4px;
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   18px;
  --radius-xl:   28px;
  --radius-pill: 999px;
}

/* ===== tokens/shadow.css ===== */
/* SHADOW + DEPTH — warm-tinted (brown, not black); 3 ad-hoc shadows -> 3 named steps.
   DEPTH fuses surface-step + shadow into the borehole metaphor: deeper UI
   (popover -> modal -> sheet) reads as further down the hole. */
:root {
  --shadow-1: 0 1px 2px rgba(42,28,16,.10);
  --shadow-2: 0 6px 20px -4px rgba(42,28,16,.14);
  --shadow-3: 0 18px 48px -8px rgba(42,28,16,.22);

  --depth-1: var(--shadow-1);  /* card */
  --depth-2: var(--shadow-2);  /* popover */
  --depth-3: var(--shadow-3);  /* modal / sheet */
}

/* ===== tokens/motion.css ===== */
/* MOTION — ~9 ad-hoc durations -> 4 steps + 2 named eases.
   The reduced-motion kill-switch is preserved from the canonical system. */
:root {
  --dur-1: 120ms;
  --dur-2: 200ms;
  --dur-3: 320ms;
  --dur-4: 560ms;
  --ease-out:    cubic-bezier(.2,.7,.2,1);
  --ease-strike: cubic-bezier(.16,1,.3,1);  /* the strike reveal */
}

/* Signature keyframes (ship with the closure so components can reference them). */
@keyframes dq-spin { to { transform: rotate(360deg); } }
@keyframes dq-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(3px); } }
@keyframes dq-strike {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--strike) 55%, transparent), 0 0 22px 4px color-mix(in oklab, var(--strike) 30%, transparent); }
  50%      { box-shadow: 0 0 0 4px color-mix(in oklab, var(--strike) 22%, transparent), 0 0 34px 8px color-mix(in oklab, var(--strike) 45%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ===== tokens/themes.css ===== */
/* THEMES — two dark takes on "Flamed Titanium". Both sit on a GUNMETAL graphite base
   (not a warm-brown one) while keeping mark/strike/grading warm. Cool lives only in
   --patina + the strata ramp. Apply with data-theme="dark1" | "dark2" on a root element.
   Derived tokens (--inst-*, --depth-*) recompute automatically from these overrides. */

/* Take 1 — "Deep Bedrock": restrained gunmetal graphite. Long reading sessions. */
[data-theme="dark1"] {
  --surface-0: #141312;
  --surface-1: #1C1A18;
  --surface-2: #24211E;
  --surface-3: #2E2A26;
  --line:      #38332D;
  --line-soft: #2A2623;
  --ink:   #ECE1CD;
  --ink-2: #C2B197;
  --ink-3: #8C7B66;
  --bedrock:   #0E0D0B;
  --bedrock-2: #141312;
  --bedrock-3: #1C1A18;
  /* re-point the domain-reactive bases so the drilled-corpus hue rides THIS theme's grounds */
  --surface-0-base: #141312;
  --surface-1-base: #1C1A18;
  --surface-2-base: #24211E;
  --surface-3-base: #2E2A26;
  --line-base:      #38332D;
  --line-soft-base: #2A2623;
  --bedrock-base:   #0E0D0B;
  --bedrock-2-base: #141312;
  --bedrock-3-base: #1C1A18;
  --ink-base:   #ECE1CD;
  --ink-2-base: #C2B197;
  --ink-3-base: #8C7B66;
  --mark:   #C87B3A;
  --mark-2: #D8915A;
  --strike: #E0A93E;
  --patina:   #8C9A9E;
  --patina-2: #74838A;
  --ok:   #7DA046;
  --seed: #D0A03E;
  --dry:  #A8957E;
  --flag: #D85138;
  --inst: #C87B3A;
  --shadow-1: 0 1px 2px rgba(0,0,0,.40);
  --shadow-2: 0 6px 20px -4px rgba(0,0,0,.50);
  --shadow-3: 0 18px 48px -8px rgba(0,0,0,.62);
}

/* Take 2 — "Lamplit Strata": gunmetal core lit warm — amber lamplight, lifted browns.
   The active-drilling theme; deliberately warmer than dark1's neutral graphite. */
[data-theme="dark2"] {
  --surface-0: #1A1410;
  --surface-1: #231A12;
  --surface-2: #2F2315;
  --surface-3: #3B2D1B;
  --line:      #4A3826;
  --line-soft: #33271A;
  --ink:   #F4E8D0;
  --ink-2: #D0B894;
  --ink-3: #9E8A6A;
  --bedrock:   #130E09;
  --bedrock-2: #1A1410;
  --bedrock-3: #231A12;
  /* re-point the domain-reactive bases so the drilled-corpus hue rides THIS theme's grounds */
  --surface-0-base: #1A1410;
  --surface-1-base: #231A12;
  --surface-2-base: #2F2315;
  --surface-3-base: #3B2D1B;
  --line-base:      #4A3826;
  --line-soft-base: #33271A;
  --bedrock-base:   #130E09;
  --bedrock-2-base: #1A1410;
  --bedrock-3-base: #231A12;
  --ink-base:   #F4E8D0;
  --ink-2-base: #D0B894;
  --ink-3-base: #9E8A6A;
  --mark:   #E07A36;
  --mark-2: #F0934F;
  --strike: #F4BC46;
  --patina:   #94A0A0;
  --patina-2: #7E8C8E;
  --ok:   #88AC4C;
  --seed: #DCAB44;
  --dry:  #B29C80;
  --flag: #E25A3E;
  --inst: #E07A36;
  --shadow-1: 0 1px 2px rgba(0,0,0,.34);
  --shadow-2: 0 8px 24px -4px rgba(28,12,0,.50);
  --shadow-3: 0 20px 52px -8px rgba(28,12,0,.60);
}

/* ===== EXTENSIONS — gateway additions (not in the bundle) =====
   Two needs the bundle's dot/fill palette doesn't cover for the served site:
   (1) soft tints behind the *-soft fills the old fork used;
   (2) AA-clamped TEXT variants of the grading triad — the bundle's grading
       colors are tuned for status DOTS and fail WCAG-AA at text sizes on cream
       (seed 3.08, dry 3.23, ok 4.39). These mirror the bundle's own --inst-text
       clamp: use --*-text when the grade is set as TEXT, the base token for dots. */
:root {
  /* soft tints (were --mark-soft / --strike-soft / --accent-soft) */
  --mark-tint:   color-mix(in oklab, var(--mark)   16%, var(--surface-0));
  --strike-tint: color-mix(in oklab, var(--strike) 18%, var(--surface-0));

  /* grading-as-TEXT — AA-verified darks (>=4.9:1 on --surface-0) */
  --ok-text:   #3A7449;
  --seed-text: #8A6614;
  --dry-text:  #7C674F;

  /* AA-safe muted body/label text. The bundle's --ink-3 is tuned as a dot/label
     color and only reaches ~3.4:1 on cream (fails AA for <18px text); this warm
     taupe is the legible muted the static pages need (~4.8:1). */
  --ink-muted: #75614C;
}
