/*
  tokens.css — averagejoematt.com v4 — "The Measured Life" (Direction 05)
  ----------------------------------------------------------------------------
  Source of truth: docs/DESIGN_SYSTEM_V4_THE_MEASURED_LIFE.md (§2 palette, §3 type),
  visual reference: docs/v4_art_direction_05_the_measured_life.html.
  Locked board-unanimous 2026-06-01.

  The concept: a measured life rendered as a beautifully made instrument log kept
  by a real person. Warm, crafted, honest — the opposite of clinical biohacking
  gloss AND of generic AI-template aesthetics.

  RULES (enforced everywhere downstream):
    - Never hardcode a colour, font, radius, or spacing outside this file.
    - Palette: locked hexes are the primitives; tints are derived with
      color-mix(in oklch, …) so the ramp stays perceptually even.
    - One ember accent only, used sparingly for "this is alive / this is up".
      Down / flat states use muted ink, NEVER red.
    - Type triad has fixed jobs: Fraunces = human voice, Instrument Sans =
      interface, IBM Plex Mono = machine voice & data (always tabular-nums).
    - No Inter / Roboto / system fonts. No purple gradients. No shadcn cards.

  The two ownable signatures (protect — do not let them metastasise):
    1. the measuring-rule spine     → --rule, --tick, --spine-* tokens (§ Spine)
    2. the machine ↔ human dialogue → --voice-* tokens (§ Two-voice)

  Fonts are <link>ed in each door's <head> (preconnect + the css2 request from the
  visual reference). This file only declares the family tokens.

  SECTIONS
    1. Palette — dark (primary)
    2. Typography
    3. Spacing & layout
    4. The measuring-rule spine (signature 1)
    5. The two-voice dialogue (signature 2)
    6. Honesty vocabulary
    7. Radii, borders, elevation
    8. Motion & z-index
    9. Light mode (Daybook-informed)
   10. Minimal base (applies the tokens)
*/

/* ── 1. Palette — dark (primary) ─────────────────────────────────────────── */
:root {
  color-scheme: dark;

  /* Locked primitives (DESIGN_SYSTEM §2). Hex is the source of truth;
     OKLCH equivalents noted for reference. */
  --page:        #0E0C08;   /* oklch(.15 .008 75)  — behind the paper */
  --surface:     #16130E;   /* oklch(.19 .010 75)  — paper / panels   */
  --ink:         #ECE3D2;   /* oklch(.91 .022 88)  — primary text      */
  --ink-muted:   #A99F8C;   /* oklch(.69 .020 84)  — secondary         */
  --ink-faint:   #6B6253;   /* oklch(.46 .018 82)  — labels, ticks     */
  --ember:       #DD7A37;   /* oklch(.69 .145 52)  — the one live accent */

  /* Derived tints (OKLCH mixing keeps the ramp even). */
  --surface-raised: color-mix(in oklch, var(--surface) 88%, var(--ink) 12%);
  --surface-sunken: color-mix(in oklch, var(--surface) 80%, var(--page) 20%);
  --ink-dim:        color-mix(in oklch, var(--ink) 70%, transparent);
  --ember-soft:     color-mix(in oklch, var(--ember) 18%, transparent);
  --ember-line:     color-mix(in oklch, var(--ember) 42%, transparent);
  --ember-wash:     color-mix(in oklch, var(--ember) 9%, transparent);

  /* Hairlines & ticks (the rule system) */
  --rule:        rgba(236, 227, 210, 0.12);   /* structural hairline */
  --rule-strong: rgba(236, 227, 210, 0.20);
  --tick:        rgba(236, 227, 210, 0.28);   /* measuring-rule ticks */

  /* Muted category tints for the two glance domains (low-sat, calm). */
  --body-tint: color-mix(in oklch, var(--ember) 6%, var(--surface));   /* Body domain */
  --mind-tint: color-mix(in oklch, var(--ink) 5%, var(--surface));     /* Mind domain */

  /* Semantic aliases (components reference these, not raw primitives). */
  --bg:          var(--page);
  --fg:          var(--ink);
  --accent:      var(--ember);
  --signal:      var(--ember);   /* "this is alive / this is up" */
}

/* ── 2. Typography ───────────────────────────────────────────────────────── */
:root {
  /* The triad — each font has one job (DESIGN_SYSTEM §3). */
  --font-serif: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;        /* human voice */
  --font-sans:  "Instrument Sans", ui-sans-serif, "Helvetica Neue", Arial, sans-serif; /* interface */
  --font-mono:  "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;      /* machine & data */

  /* Fraunces variable axes */
  --fraunces-opsz-display: 144;
  --fraunces-opsz-text:    24;

  /* Fluid type scale. editorial display → data display → body → label. */
  --fs-display:  clamp(2.6rem, 1.4rem + 6vw, 5.5rem);   /* Fraunces, Story heroes */
  --fs-h1:       clamp(2rem, 1.3rem + 3.2vw, 3.25rem);  /* Fraunces */
  --fs-h2:       clamp(1.5rem, 1.1rem + 1.8vw, 2.25rem);
  --fs-h3:       clamp(1.2rem, 1rem + 0.9vw, 1.5rem);
  --fs-data-xl:  clamp(3.5rem, 2rem + 7vw, 5.25rem);    /* Plex Mono, the score */
  --fs-data-lg:  clamp(1.6rem, 1.2rem + 1.6vw, 2.25rem);
  --fs-body:     1.0625rem;                              /* Instrument Sans */
  --fs-body-lg:  1.1875rem;
  --fs-small:    0.875rem;
  --fs-label:    0.6875rem;                              /* Plex Mono uppercase, tracked */
  --fs-quote:    clamp(1.15rem, 1rem + 0.7vw, 1.45rem);  /* Fraunces italic, human reply */

  --lh-tight:    1.05;
  --lh-snug:     1.25;
  --lh-body:     1.6;
  --lh-relaxed:  1.7;

  --tracking-label: 0.16em;   /* uppercase mono labels */
  --tracking-tight: -0.02em;  /* big mono numerals */

  --weight-reg:    400;
  --weight-med:    500;
}

/* ── 3. Spacing & layout ─────────────────────────────────────────────────── */
:root {
  /* 4px base rhythm */
  --sp-1:  0.25rem;  --sp-2:  0.5rem;   --sp-3:  0.75rem;  --sp-4:  1rem;
  --sp-5:  1.5rem;   --sp-6:  2rem;     --sp-7:  3rem;     --sp-8:  4rem;
  --sp-9:  6rem;     --sp-10: 8rem;

  --measure:        68ch;     /* readable body line length */
  --measure-narrow: 46ch;
  --container:      1200px;   /* desktop max */
  --container-read: 760px;    /* Story / longform (matches reference .wrap) */
  --gutter:         clamp(1rem, 0.5rem + 2.5vw, 2.5rem);
  --bento-gap:      clamp(0.75rem, 0.4rem + 1.2vw, 1.25rem);
}

/* ── 4. The measuring-rule spine (SIGNATURE 1) ───────────────────────────── */
/*  A tick-marked rule as a structural element: anchors the Cockpit edge,
    segments the Story timeline, indexes the Evidence. Connective tissue across
    all three doors. Use with intent — not on every element. */
:root {
  --spine-width:   46px;          /* rail width (matches reference) */
  --spine-tick-gap: 15px;         /* distance between ticks */
  --spine-tick-w:   8px;          /* tick length into the rail */
  --spine-ticks: repeating-linear-gradient(
                   to bottom, var(--tick) 0 1px, transparent 1px var(--spine-tick-gap));
  --spine-border: 1px solid var(--rule);
}

/* ── 5. The two-voice dialogue (SIGNATURE 2) ─────────────────────────────── */
/*  Machine voice (mono) and human voice (serif) set in literal conversation —
    the Third Wall turned into the type system. The most on-brand device. */
:root {
  --voice-machine-font: var(--font-mono);
  --voice-machine-size: 0.84375rem;        /* 13.5px @16 */
  --voice-machine-lh:   1.55;
  --voice-machine-ink:  var(--ink);
  --voice-machine-mark: var(--ember);      /* the › lead glyph + emphasis */

  --voice-human-font:   var(--font-serif);
  --voice-human-style:  italic;
  --voice-human-size:   1.1875rem;         /* 19px */
  --voice-human-lh:     1.4;
  --voice-human-ink:    var(--ink);

  --voice-who-font:     var(--font-mono);  /* the speaker label */
  --voice-who-size:     0.5625rem;         /* 9px */
  --voice-who-ink:      var(--ink-faint);
  --voice-who-tracking: var(--tracking-label);
}

/* ── 6. Honesty vocabulary ───────────────────────────────────────────────── */
/*  Down weeks & pauses: muted ink + a DASHED hairline marker + plain language.
    First-class, never alarm-red, never hidden. The anti-Blueprint anchor. */
:root {
  --honest-ink:    var(--ink-muted);
  --honest-border: 1px dashed var(--rule);
  --honest-mark:   "▼";        /* down */
  --flat-mark:     "›";        /* holding */
  --up-mark:       "▲";        /* up — the only place ember is earned on a trend */
  --down-fill:     var(--ink-faint);   /* progress fill for a down pillar (muted, not red) */
  --up-fill:       var(--ember);       /* progress fill for an up pillar */
}

/* ── 7. Radii, borders, elevation ────────────────────────────────────────── */
:root {
  --radius-xs: 3px;    /* honesty chip, tags */
  --radius-sm: 6px;
  --radius:    10px;   /* panels (matches reference) */
  --radius-lg: 16px;

  --border-hair:   1px solid var(--rule);
  --border-strong: 1px solid var(--rule-strong);

  /* Restrained elevation — flat surfaces, soft depth. No neon glow. */
  --shadow-panel: 0 22px 50px rgba(0, 0, 0, 0.32);
  --shadow-soft:  0 6px 18px rgba(0, 0, 0, 0.22);
}

/* ── 8. Motion & z-index ─────────────────────────────────────────────────── */
:root {
  --ease-out:   cubic-bezier(0.2, 0.7, 0.2, 1);   /* reveal / rise */
  --ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast:   0.18s;
  --dur:        0.36s;
  --dur-slow:   0.7s;        /* page-load rise (reference) */
  --stagger:    0.06s;       /* between bento items on the orchestrated reveal */

  /* View Transitions: door-to-door + in-place pillar disclosure. */
  --vt-dur:     0.4s;

  --z-base: 0; --z-spine: 5; --z-sticky: 50; --z-overlay: 100; --z-toast: 200;
}

/* ── 9. Light mode (Daybook-informed) ────────────────────────────────────── */
/*  Real, first-class light mode. Activated by [data-theme="light"] OR by the OS
    when the user hasn't explicitly chosen dark. */
:root[data-theme="light"],
:root:not([data-theme="dark"]) {
  /* placeholder so the cascade below can override cleanly */
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --page:      #F4EFE4;   /* oklch(.95 .012 88) */
    --surface:   #FBF8F1;   /* oklch(.98 .008 88) */
    --ink:       #221E17;   /* oklch(.26 .012 78) */
    --ink-muted: #6E665A;   /* oklch(.49 .015 82) */
    --ink-faint: #A39A8A;   /* oklch(.67 .015 84) */
    --ember:     #C2611F;   /* oklch(.58 .145 50) — deepened for AA on paper */
    --rule:        rgba(34, 30, 23, 0.13);
    --rule-strong: rgba(34, 30, 23, 0.22);
    --tick:        rgba(34, 30, 23, 0.30);
    --shadow-panel: 0 18px 44px rgba(34, 30, 23, 0.12);
    --shadow-soft:  0 6px 16px rgba(34, 30, 23, 0.08);
  }
}

/* Explicit user choice always wins over the OS preference. */
:root[data-theme="light"] {
  color-scheme: light;
  --page:      #F4EFE4;
  --surface:   #FBF8F1;
  --ink:       #221E17;
  --ink-muted: #6E665A;
  --ink-faint: #A39A8A;
  --ember:     #C2611F;
  --rule:        rgba(34, 30, 23, 0.13);
  --rule-strong: rgba(34, 30, 23, 0.22);
  --tick:        rgba(34, 30, 23, 0.30);
  --shadow-panel: 0 18px 44px rgba(34, 30, 23, 0.12);
  --shadow-soft:  0 6px 16px rgba(34, 30, 23, 0.08);
}

/* ── 10. Minimal base — applies the tokens so every door starts honest ───── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-size-adjust: 100%;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  font-synthesis: none;
}

/* Headings carry the human voice unless a component opts out. */
h1, h2, h3 {
  font-family: var(--font-serif);
  font-weight: var(--weight-med);
  line-height: var(--lh-tight);
  text-wrap: balance;
}
p { text-wrap: pretty; max-width: var(--measure); }

/* Every number / label is mono + tabular by default. */
.mono, [data-voice="machine"], .data, .num {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* The label primitive (Plex Mono, uppercase, tracked). */
.label {
  font-family: var(--font-mono);
  font-size: var(--fs-label);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--ink-faint);
}

a { color: inherit; text-underline-offset: 0.18em; }

:where(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--ember);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* The orchestrated page-load reveal — motion earns its weight, or it's cut. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Charts (shared, token-driven — see assets/js/charts.js) ──────────────── */
.chart { margin-top: var(--sp-4); }
.chart svg { width: 100%; height: clamp(110px, 8vw + 80px, 150px); display: block; overflow: visible; }
.chart-line { fill: none; stroke: var(--ember); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-fill { fill: var(--ember-wash); stroke: none; }
.chart-goal { stroke: var(--ink-faint); stroke-width: 1; stroke-dasharray: 3 4; }
.chart-dot { fill: var(--ember); }
.chart-cap { display: block; margin-top: var(--sp-2); color: var(--ink-faint); }
.chart--empty { border: var(--honest-border); border-radius: var(--radius-xs); padding: var(--sp-4); text-align: center; }
.chart--empty .chart-cap { margin: 0; }
.spark { width: 96px; height: 28px; vertical-align: middle; }
.spark .chart-line { stroke-width: 1.5; }
.spark--empty { display: inline-block; width: 96px; height: 1px; background: var(--rule); }
.cbars { display: flex; align-items: flex-end; gap: 3px; height: var(--cbar-h, 130px); margin-top: var(--sp-3); }
.cbar { flex: 1; display: flex; flex-direction: column; align-items: center; gap: var(--sp-1); height: 100%; justify-content: flex-end; min-width: 0; }
.cbar-fill { width: 76%; background: var(--ember); border-radius: 2px 2px 0 0; min-height: 3px; }
.cbar-l { color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
