/* ==========================================================================
   OCA × Axiom — Design Tokens
   Adapted from the OpenServ style reference ("bright blueprint on frosted
   glass"). Source of record: design/tokens.json.

   This is the ONLY place raw values live. Nothing downstream — not the deck,
   not the hub pages — should hardcode a hex, a radius, or a font stack.

   Three layers, in order:
     1. PRIMITIVES — the extracted OpenServ values, verbatim.
     2. SEMANTIC   — role names. Author against these, not the primitives.
     3. DECK       — fluid overrides for full-bleed presentation surfaces.
   ========================================================================== */

:root {
  /* ------------------------------------------------------------------------
     1. PRIMITIVES
     ------------------------------------------------------------------------ */

  /* Colors — exactly two chromatic notes on a monochrome ramp. Adding a third
     accent breaks the system; see DESIGN.md "Don't". */
  --color-signal-violet: #5f79ff;
  --color-mint-pulse: #01fe93;
  --color-pure-white: #ffffff;
  --color-ink-black: #000000;
  --color-fog-gray: #f5f5f5;
  --color-mist-gray: #a6a6a6;
  --color-ash-gray: #4d4d4d;
  --color-smoke-gray: #9c9c9c;
  --color-slate-gray: #707070;

  /* Font families.
     OS Studio Grotesk and OS Chronik are proprietary and unlicensed here.
     Project decision 2026-08-30 (Lou): ONE modern sans for the whole product —
     Inter — for body and display alike. The serif display voice (Cormorant
     Garamond, standing in for OS Chronik since 2026-08-25) is retired: the
     300 weight now belongs to Inter at display sizes, where its light cut
     reads as composure just as the serif's did. `--font-serif` survives as
     an alias so every headline authored against it keeps working — it is a
     historical name, not a promise of serifs. Author new display type
     against `--font-display`. */
  --font-display: "Inter", ui-sans-serif, system-ui, -apple-system,
    BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-grotesk: var(--font-display);
  --font-serif: var(--font-display);
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;

  /* Type scale — fixed px, sized for a 1200px document page.
     Do NOT use these on the deck; see layer 3.

     Raised from the extracted OpenServ values (12/13/15/20) on 2026-08-25:
     the reference scale read too small on retina laptops. The reference's
     own readable band tops out at 18px body, so 17px stays inside it. */
  --text-caption: 13px;
  --leading-caption: 1.25;
  --text-small: 14px;
  --leading-small: 1.25;
  --text-body: 17px;
  --leading-body: 1.55;
  --text-subheading: 22px;
  --leading-subheading: 1.35;
  --text-heading-sm: 26px;
  --leading-heading-sm: 1.2;
  --text-heading: 32px;
  --leading-heading: 1.18;
  --text-heading-lg: 42px;
  --leading-heading-lg: 1.1;
  --text-display: 72px;
  --leading-display: 0.9;

  /* Tracking — negative at display sizes, relaxing to 0 at body sizes. */
  --tracking-display: -0.03em; /* Inter wants a touch tighter than the serif did */
  --tracking-heading: -0.017em;
  --tracking-body: 0;

  --weight-light: 300;
  --weight-regular: 400;

  /* Spacing — 4px base unit, comfortable density. */
  --spacing-4: 4px;
  --spacing-8: 8px;
  --spacing-12: 12px;
  --spacing-16: 16px;
  --spacing-20: 20px;
  --spacing-24: 24px;
  --spacing-28: 28px;
  --spacing-32: 32px;
  --spacing-40: 40px;
  --spacing-48: 48px;
  --spacing-60: 60px;
  --spacing-64: 64px;
  --spacing-80: 80px;
  --spacing-120: 120px;

  /* Radius. The 100px pill is reserved for buttons and badges ONLY;
     16px is the surface radius for everything else. */
  --radius-input: 12px;
  --radius-surface: 16px;
  --radius-pill: 100px;

  /* Elevation. Exactly one shadow exists, and it belongs to the floating nav.
     Content surfaces are flat with hairline borders instead. */
  --shadow-nav: 0px 0px 48px 0px rgba(0, 0, 0, 0.1);

  /* Layout */
  --page-max-width: 1200px;
  --section-gap: 80px;
  --card-padding: 24px;
  --element-gap: 16px; /* source file had the invalid literal "10-20px" */

  /* ------------------------------------------------------------------------
     2. SEMANTIC ROLES — author against these.
     ------------------------------------------------------------------------ */

  --surface-canvas: var(--color-pure-white);
  --surface-card: var(--color-fog-gray);
  --surface-tint: #d9defc; /* violet-tinted wash, highlighted panels only */

  --text-primary: var(--color-ink-black);
  --text-secondary: var(--color-ash-gray);
  --text-muted: var(--color-mist-gray);
  --text-meta: var(--color-slate-gray);
  --text-on-action: var(--color-pure-white);

  --border-hairline: var(--color-mist-gray);
  --border-subtle: var(--color-fog-gray);
  --border-inactive: var(--color-smoke-gray);
  --border-focus: var(--action-primary);

  /* ---- The working violet ----
     The extracted brand value #5f79ff measures 3.71:1 against white. That
     fails twice over: caption labels set in it, and white text set on it as
     a button fill. Both are AA failures at the smallest and most-clicked
     type in the system.

     #4a63e8 is the same hue two steps down and clears 4.95:1 in both
     directions, so one value now covers every violet on the light surface —
     fills, marks, borders and text alike.

     This does shift the brand value. #5f79ff survives as the primitive, and
     comes back as --accent-text on the dark surface, where the darker cut is
     the one that fails. */
  --action-primary: #4a63e8;
  --accent-status: var(--color-mint-pulse); /* status/highlight — never a CTA fill */

  /* Violet that is READ, as distinct from violet that is a fill or a mark.
     On the light surface the two converge; on ink they must not. */
  --accent-text: var(--action-primary);
}

/* ==========================================================================
   DARK SURFACE

   An inversion of the semantic layer only — the primitives, spacing, radii,
   type scale and component rules are untouched, so anything authored against
   the tokens works on either ground with no extra code.

   Applied with data-theme="dark" on any container: a whole page, a single
   deck slide, or one section band. Used as punctuation against the white
   canvas rather than as a mode the whole product switches into.

   Mint earns a job here it cannot do on white: 14.7:1 on ink versus 1.35:1
   on paper. On a dark ground it is finally legible as text.
   ========================================================================== */

[data-theme="dark"] {
  --surface-canvas: var(--color-ink-black);
  --surface-card: #141414;
  --surface-tint: #191f3f; /* the violet wash, inverted */

  --text-primary: var(--color-pure-white);
  --text-secondary: #c2c2c2;
  --text-muted: #8a8a8a;
  --text-meta: #9c9c9c;
  --text-on-action: var(--color-pure-white);

  --border-hairline: #2f2f2f;
  --border-subtle: #1f1f1f;
  --border-inactive: #3a3a3a;

  /* On ink the contrast problem reverses: the darkened violet drops to
     4.00:1 and fails, while the brand cut measures 5.67:1 and passes. So
     text-bearing violet goes back up to the brand value here, and fills stay
     on --action-primary, where white type on them still clears 4.95:1. */
  --accent-text: var(--color-signal-violet);
}

/* ==========================================================================
   3. DECK SCALE

   The primitive scale above is built for a 1200px-wide document read at
   arm's length. The deck is full-bleed and read across a room, where 72px is
   a subhead, not a display size. These preserve the OpenServ ratios and
   tracking but let size track the viewport.

   Applied via [data-surface="deck"] so hub pages keep the document scale.
   ========================================================================== */

[data-surface="deck"] {
  --text-caption: clamp(12px, 1.05vw, 17px);
  --text-body: clamp(17px, 1.5vw, 27px);
  --text-subheading: clamp(20px, 1.8vw, 32px);
  --text-heading-sm: clamp(24px, 2.2vw, 38px);
  --text-heading: clamp(28px, 2.8vw, 48px);
  --text-heading-lg: clamp(34px, 4.4vw, 76px);
  --text-display: clamp(58px, 12vw, 196px);
  --leading-display: 0.88;
  --tracking-display: -0.05em;
}
