/*
  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:   #857B68;   /* oklch(.55 .018 82)  — labels, ticks · 4.7:1 on --page (WCAG AA) */
  --ember:       #DD7A37;   /* oklch(.69 .145 52)  — the one live accent */
  --alert:       #B14A33;   /* restrained oxblood — RESERVED state alert (vitals run-down /
                               out-of-range only). NEVER encodes a falling direction. */
  --alert-wash:  color-mix(in oklch, var(--alert) 11%, transparent);
  --alert-line:  color-mix(in oklch, var(--alert) 45%, transparent);

  /* 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: #6F6757;   /* oklch(.48 .015 84) · 4.9:1 on --page (WCAG AA) */
    --ember:     #A34E13;   /* AA-compliant on paper — 5.0:1 on #F4EFE4 (small ember text: nav, footer headers, labels) */
    --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: #6F6757;   /* 4.9:1 on --page (WCAG AA) */
  --ember:     #A34E13;
  --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; }

/* Screen-reader-only — visually hidden, available to AT (e.g. a page's <h1> landmark). */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

: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;
  }
}

/* Dual-device dumbbell (sleep §2, P0.3) — A=ember dot, B=muted dot, connector = the spread.
   "Agreement, not truth." Reuses the .suf-row grid. */
.db-track { position: relative; height: 10px; }
.db-track::before { content: ""; position: absolute; left: 0; right: 0; top: 4px; height: 2px; background: var(--surface-2, var(--surface)); border-radius: 2px; }
.db-bar { position: absolute; top: 4px; height: 2px; background: var(--ink-faint); border-radius: 2px; }
.db-dot { position: absolute; top: 0; width: 9px; height: 9px; border-radius: 50%; transform: translateX(-50%); top: 1px; }
.db-dot.db-a, .sbar-dot.db-a { background: var(--ember); }
.db-dot.db-b, .sbar-dot.db-b { background: var(--ink-muted); }

/* Per-group trend small-multiples (habits §6, P0.7) — low/floor groups muted, never red. */
.gt-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-3); margin-top: var(--sp-3); }
.gt-card { border: 1px solid var(--rule); border-radius: var(--radius-sm); padding: var(--sp-3); }
.gt-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.gt-name { font-weight: var(--weight-med); font-size: var(--fs-small); }
.gt-pct { color: var(--ink-faint); }
.gt-thin { color: var(--ink-faint); }
.gt-low { opacity: 0.85; }
.gt-low .chart-line { stroke: var(--ink-muted); }

/* Effort map (habits §5, P0.6) — ranked dot-strip: size = habit count, ember = adherence. */
.em-strip { display: flex; flex-direction: column; gap: var(--sp-3); margin-top: var(--sp-3); }
.em-row { display: flex; align-items: center; gap: var(--sp-3); }
.em-dot { border-radius: 50%; flex: 0 0 auto; border: 1px solid var(--rule);
  background: color-mix(in oklch, var(--ember) calc(var(--heat, 0.12) * 100%), var(--surface-2, var(--surface))); }
.em-l { font-weight: var(--weight-med); }
.em-meta { color: var(--ink-faint); margin-left: auto; white-space: nowrap; }

/* Habit state taxonomy (habits §4, P0.5) — ONE ember+ink ramp + markers, NO rainbow, no red.
   Automatic = full ember · Holding = ember tint · Needs-attention = muted + marker ·
   Backlog = dashed outline (shown, honestly empty). */
.st-lane { margin-top: var(--sp-3); }
.st-lanehead { display: flex; align-items: baseline; gap: var(--sp-2); }
.st-marker { width: 10px; height: 10px; border-radius: 2px; display: inline-block; flex: 0 0 auto; }
.st-name { font-weight: var(--weight-med); }
.st-desc { color: var(--ink-faint); }
.st-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-2); }
.st-chip { display: inline-flex; align-items: center; gap: var(--sp-1); border-radius: var(--radius-xs); padding: 2px 8px; font-size: var(--fs-small); border: 1px solid var(--rule); }
.st-pct { font-family: var(--font-mono); font-size: 0.65rem; color: var(--ink-faint); }
.st-chip.st-auto { background: var(--ember); border-color: var(--ember); color: var(--page); }
.st-chip.st-auto .st-pct { color: var(--page); }
.st-marker.st-auto { background: var(--ember); }
.st-chip.st-hold { background: var(--ember-wash); border-color: var(--ember); }
.st-marker.st-hold { background: color-mix(in oklch, var(--ember) 55%, var(--surface)); }
.st-chip.st-need { background: var(--surface-2, var(--surface)); border-color: var(--ink-muted); }
.st-marker.st-need { background: var(--ink-muted); }
.st-chip.st-backlog { background: transparent; border: 1px dashed var(--rule); color: var(--ink-faint); }
.st-marker.st-backlog { background: transparent; border: 1px dashed var(--ink-faint); }

/* P1.1 — auto-derived per-habit context tags in the registry list. One ink+ember
   ramp, muted: these are heuristic reads, not loud signals. */
.hb-tax-row { display: inline-flex; gap: var(--sp-1); margin-left: var(--sp-2); vertical-align: middle; }
.hb-tax { font-family: var(--font-mono); font-size: 0.58rem; text-transform: uppercase; letter-spacing: var(--tracking-label);
  border-radius: var(--radius-xs); padding: 1px 6px; border: 1px solid var(--rule); color: var(--ink-faint); white-space: nowrap; }
.hb-tax-time { color: var(--ink-muted); }
.hb-tax-type { border-color: color-mix(in oklch, var(--ember) 40%, var(--rule)); color: var(--ember); }

/* P1.2 — friction tag from real adherence. Ember=automatic (earned), fading to a muted
   outline as friction rises. Never red — high friction is information, not failure. */
.hb-fr { font-family: var(--font-mono); font-size: 0.58rem; text-transform: uppercase; letter-spacing: var(--tracking-label);
  border-radius: var(--radius-xs); padding: 1px 6px; margin-left: var(--sp-2); white-space: nowrap; vertical-align: middle; border: 1px solid var(--rule); }
.hb-fr.fr-auto { background: var(--ember-wash); border-color: var(--ember); color: var(--ember); }
.hb-fr.fr-mid { color: var(--ink-muted); }
.hb-fr.fr-hard { border-style: dashed; border-color: var(--ink-muted); color: var(--ink-faint); }

/* P1.3 drivers table + P1.4 misses — honest-empty cells read faint/italic, never alarming. */
.rd-drv th { font-family: var(--font-mono); font-size: 0.6rem; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-faint); text-align: left; font-weight: var(--weight-reg); padding-bottom: var(--sp-1); }
.drv-empty { color: var(--ink-faint); font-style: italic; font-size: var(--fs-small); }
.wm-list { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
.wm-row { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; padding-bottom: var(--sp-2); border-bottom: 1px solid var(--rule); }
.wm-name { font-weight: var(--weight-med); }
.wm-n { color: var(--ink-muted); font-size: var(--fs-small); }
.wm-why { margin-left: auto; }

/* Cross-source signal board (sleep §8, Phase 2) — self-policing cards: n + overlap +
   confidence; direction-only under 2 weeks. Muted/honest, never alarm. */
.cb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--sp-3); margin-top: var(--sp-3); }
.cb-card { border: var(--honest-border); border-radius: var(--radius-sm); padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-2); }
.cb-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap; }
.cb-pair { font-size: var(--fs-small); font-weight: var(--weight-med); margin: 0; }
.cb-arrow { color: var(--ember); }
.cb-tag { font-family: var(--font-mono); font-size: 0.6rem; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-faint); white-space: nowrap; }
.cb-note { color: var(--ink-muted); font-size: var(--fs-small); margin: 0; }
.cb-read { display: flex; flex-direction: column; gap: var(--sp-1); }
.cb-dir { margin: 0; color: var(--ink); font-size: var(--fs-small); }
.cb-withheld { color: var(--ink-muted); font-style: italic; }
.cb-noise { color: var(--ink-muted); font-size: 0.7rem; font-family: var(--font-mono); }
.cb-meta { color: var(--ink-faint); }

/* Circadian forecast hero (sleep §0, P0.1) — anchors as suf-rows; the lever (weakest
   anchor) labelled ember; at-risk anchors muted ink, NEVER red. */
.fc-anchors { margin-top: var(--sp-3); }
.fc-lever .suf-l { color: var(--ember); }

/* Anatomical body-map (training, P1.4) — muscle zones shaded by ember intensity (--o set
   per zone) = weekly volume vs optimal. ONE hue, never red. */
.bodymap svg { width: 100%; height: clamp(180px, 26vw, 240px); }
.bm-head { fill: var(--ink-faint); opacity: 0.28; }
.bm-m { fill: var(--ember); fill-opacity: var(--o, 0.1); stroke: var(--rule); stroke-width: 0.5; }
.bm-cap { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8px; text-anchor: middle; letter-spacing: 0.12em; text-transform: uppercase; }

/* Per-muscle volume landmark bars (training §5, P1.3) — MEV–MAV band shaded, MRV tick;
   ember in the optimal band, muted ink under/over (never red). Reuses the .suf-row grid. */
.lmk-track { position: relative; height: 10px; border-radius: 5px; background: var(--surface-2, var(--surface)); }
.lmk-band { position: absolute; top: 0; height: 100%; background: var(--ember-wash);
  border-left: 1px dashed var(--ink-faint); border-right: 1px dashed var(--ink-faint); }
.lmk-fill { position: absolute; top: 0; height: 100%; border-radius: 5px; }
.lmk-fill.suf-ember { background: var(--ember); }
.lmk-fill.suf-ink { background: var(--ink-muted); }
.lmk-mrv { position: absolute; top: -2px; width: 1px; height: 14px; background: var(--ink-faint); }

/* The Lift Index (training §2, P0.1) — per-lift load TREND tiles (sparkline + ▲/▼/flat).
   Ember = load up; down = muted ink, NEVER red; under 3 sessions = honest fills-in tile. */
.li-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-3); margin-top: var(--sp-3); }
.li-tile { border: 1px solid var(--rule); border-radius: var(--radius-sm); padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.li-top { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.li-name { font-weight: var(--weight-med); }
.li-tag { font-family: var(--font-mono); font-size: 0.6rem; white-space: nowrap; }
.li-up { color: var(--ember); }
.li-down { color: var(--ink-muted); }
.li-flat { color: var(--ink-faint); }
.li-meta { color: var(--ink-faint); }
.li-thin { opacity: 0.9; justify-content: center; min-height: 4.5rem; }
.li-fill { color: var(--ink-faint); }

/* Ember-intensity steps heat strip (training §1c, P0.6) — saturation = volume; low days
   muted (faint ember), never hidden. ONE hue — intensity, not a second colour. */
.heat-strip { display: flex; flex-wrap: wrap; gap: 4px; margin-top: var(--sp-3); }
.heat-cell { flex: 1 1 2.2rem; min-width: 2.2rem; aspect-ratio: 1 / 1; border-radius: var(--radius-xs);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  background: color-mix(in oklch, var(--ember) calc(var(--heat, 0.1) * 100%), var(--surface-2, var(--surface)));
  border: 1px solid var(--rule); }
.heat-v { font-size: 0.6rem; line-height: 1; color: var(--ink); }
.heat-d { font-size: 0.5rem; color: var(--ink-faint); }
/* Dense GitHub-style calendar (habits §2, P0.3) — saturation only; cut-start ringed ember. */
.heat-strip-compact { gap: 3px; }
.heat-cell.heat-compact { flex: 0 0 auto; width: 13px; min-width: 13px; aspect-ratio: 1 / 1; border-radius: 2px; }
.heat-cell.heat-cut { outline: 1.5px solid var(--ember); outline-offset: 1px; }

/* ── 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-down { stroke: var(--ink-muted); stroke-width: 1.5; stroke-dasharray: 4 3; }
.chart-dot { fill: var(--ember); }
/* Interactive line-chart hover (wired by motion.js, data from data-cpts) — a focus dot
   + cursor-following readout that make every trend chart explorable. */
.chart-focus { position: absolute; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%;
  background: var(--ember); box-shadow: 0 0 0 3px var(--ember-wash); pointer-events: none; z-index: 3; }
.chart-tip { position: absolute; transform: translate(-50%, calc(-100% - 10px)); white-space: nowrap; pointer-events: none;
  background: var(--surface-raised); border: var(--border-hair); border-radius: var(--radius-xs); padding: 2px 8px;
  color: var(--ink); box-shadow: var(--shadow-soft); z-index: 4; }
.chart-focus[hidden], .chart-tip[hidden] { display: none; }
/* P0.1 — trend-weight hero: faint raw daily dots (scale noise) + confident ember trend +
   a muted genesis rule. Ember = the smoothed signal; dots are deliberately faint. */
.wt-trend { stroke: var(--ember); stroke-width: 2.25; stroke-linejoin: round; stroke-linecap: round; }
.wt-raw { fill: var(--ink-faint); opacity: 0.45; }
.wt-genesis { stroke: var(--ink-muted); stroke-width: 1; stroke-dasharray: 2 4; }
.wt-key { white-space: nowrap; }
.wt-swatch { display: inline-block; width: 0.7em; height: 0.7em; vertical-align: baseline; margin-right: 0.25em; border-radius: 2px; }
.wt-swatch-raw { background: var(--ink-faint); opacity: 0.5; border-radius: 50%; }
.wt-swatch-trend { background: var(--ember); height: 0.22em; border-radius: 1px; }
/* P0.2 — the scrub marker the silhouette drives in lockstep; ember dashed, pins to the
   floor (muted) when the scrubbed weight is below the chart's data range (toward goal). */
.wt-marker { stroke: var(--ember); stroke-width: 1.25; stroke-dasharray: 5 4; transition: opacity 0.15s; }
.wt-marker-below { stroke: var(--ink-muted); }
/* P0.4 — milestone ladder: a vertical measuring-rule. A rail (border) with a tick per
   10-lb rung; crossed rungs ember, the live edge marked, future rungs muted. Never red. */
.ml-ladder { display: flex; flex-direction: column; margin: var(--sp-3) 0; border-left: 2px solid var(--rule); padding-left: 0; }
.ml-rung { position: relative; display: flex; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) 0 var(--sp-2) var(--sp-4); min-height: 1.4em; }
.ml-tick { position: absolute; left: -2px; top: 0.7em; width: 14px; height: 2px; background: var(--rule); transform: translateX(-50%); }
.ml-w { font-size: var(--fs-h4, 1.05rem); min-width: 3.4em; }
.ml-cap { text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-faint); }
.ml-meta { color: var(--ink-faint); }
.ml-crossed .ml-tick { background: var(--ember); width: 20px; height: 3px; top: 0.66em; }
.ml-crossed .ml-w { color: var(--ember); }
.ml-future .ml-w, .ml-next .ml-w { color: var(--ink-muted); }
.ml-next .ml-tick { background: var(--ink-muted); width: 16px; }
.ml-now { margin-left: auto; font-family: var(--font-mono); font-size: var(--fs-small); color: var(--ember); border: 1px solid var(--ember); border-radius: var(--radius-xs); padding: 1px 8px; white-space: nowrap; }
/* P0.5 — rate tempo: slope-gauges, ember intensity (width + opacity) = pace. Gain = ink. */
.rt-strip { display: flex; flex-direction: column; gap: var(--sp-3); margin: var(--sp-3) 0; }
.rt-row { display: grid; grid-template-columns: 7.5em 1fr auto; align-items: center; gap: var(--sp-3); }
.rt-label { color: var(--ink); font-weight: var(--weight-med); }
.rt-sub { color: var(--ink-faint); font-family: var(--font-mono); font-size: 0.7rem; }
.rt-gauge { height: 10px; background: var(--surface-2, var(--surface)); border: 1px solid var(--rule); border-radius: 5px; overflow: hidden; }
.rt-fill { display: block; height: 100%; }
.rt-fill.rt-ember { background: var(--ember); }
.rt-fill.rt-ink { background: var(--ink-muted); }
.rt-v { white-space: nowrap; color: var(--ember); }
.rt-v.rt-na { color: var(--ink-faint); }
.rt-flag { grid-column: 3; color: var(--ink-faint); font-size: 0.66rem; text-transform: uppercase; letter-spacing: var(--tracking-label); }
/* P0.6 — projection cone: ember-wash widening band, ember mid-line, muted goal + rung marks. */
.pc-cone { fill: var(--ember-wash); stroke: var(--ember-line); stroke-width: 0.5; }
.pc-mid { stroke: var(--ember); stroke-width: 2; stroke-linejoin: round; }
.pc-goal { stroke: var(--ink-muted); stroke-width: 1; stroke-dasharray: 4 4; }
.pc-rung { stroke: var(--rule); stroke-width: 1; stroke-dasharray: 2 4; }
.pc-bet { display: block; margin-top: var(--sp-2); color: var(--ink-muted); font-style: italic; line-height: 1.5; }
.pc-bet strong { color: var(--ember); font-style: normal; }
/* P0.7 — BMI, de-emphasized: muted, small, never ember. The caption does the talking. */
.rd-bmi { margin: var(--sp-2) 0 0; display: flex; align-items: baseline; gap: var(--sp-2); }
.rd-bmi-v { font-size: var(--fs-h3, 1.5rem); color: var(--ink-muted); }
/* P1.1 — next-DEXA countdown: the arc anchor. Ember number = anticipation, not alarm. */
.dx-count { display: flex; align-items: baseline; gap: var(--sp-3); margin: var(--sp-2) 0; }
.dx-days { font-size: var(--fs-display, 2.4rem); color: var(--ember); line-height: 1; }
.dx-unit { color: var(--ink-muted); }
/* P1.3 — visceral fat: a directional risk gauge. Ember intensity (never red) rises with the
   zone; the marker is an ink tick. Bands are subtle background, the caption does the judging. */
.vf-wrap { margin: var(--sp-3) 0; }
.vf-fig { display: flex; align-items: baseline; gap: var(--sp-3); }
.vf-v { font-size: var(--fs-h3, 1.5rem); color: var(--ink); }
.vf-band { text-transform: uppercase; letter-spacing: var(--tracking-label); padding: 1px 8px; border-radius: var(--radius-xs); }
.vf-band.vf-low { color: var(--ink-muted); border: 1px solid var(--rule); }
.vf-band.vf-moderate { color: var(--ember); border: 1px solid var(--ember-line); }
.vf-band.vf-elevated { color: var(--ember); border: 1px solid var(--ember); background: var(--ember-wash); }
.vf-gauge { position: relative; display: flex; height: 12px; margin-top: var(--sp-2); border-radius: 6px; overflow: hidden; border: 1px solid var(--rule); }
.vf-zone { height: 100%; }
.vf-z1 { width: 33.33%; background: var(--ember-wash); }
.vf-z2 { width: 33.33%; background: var(--ember-soft); }
.vf-z3 { width: 33.34%; background: var(--ember-line); }
.vf-mark { position: absolute; top: -2px; width: 2px; height: 16px; background: var(--ink); transform: translateX(-50%); }
.vf-scale { display: flex; justify-content: space-between; margin-top: var(--sp-1); color: var(--ink-faint); }
/* P1.5 — PhenoAge: a single transparent biological-age figure (Option A — no chronological).
   Drivers expand; ember = pushing younger, muted = older. Younger-bio-age reads ember-positive. */
.pa-dial { display: flex; align-items: baseline; gap: var(--sp-3); margin: var(--sp-2) 0; }
.pa-v { font-size: var(--fs-display, 2.6rem); color: var(--ember); line-height: 1; }
.pa-unit { color: var(--ink-muted); }
.pa-details { margin-top: var(--sp-3); border-top: 1px solid var(--rule); padding-top: var(--sp-2); }
.pa-sum { cursor: pointer; color: var(--ink-muted); }
.pa-drivers { display: flex; flex-direction: column; gap: 1px; margin-top: var(--sp-3); }
.pa-driver { display: grid; grid-template-columns: 1fr auto 5.5em; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--rule); }
.pa-d-name { font-weight: var(--weight-med); }
.pa-d-val { color: var(--ink-muted); white-space: nowrap; }
.pa-d-dir { text-transform: uppercase; letter-spacing: var(--tracking-label); text-align: right; }
.pa-younger .pa-d-dir { color: var(--ember); }
.pa-older .pa-d-dir { color: var(--ink-muted); }
.pa-neutral .pa-d-dir { color: var(--ink-faint); }
.pa-derived { font-family: var(--font-mono); font-size: 0.58rem; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-faint); border: 1px solid var(--rule); border-radius: var(--radius-xs); padding: 0 5px; }
/* P1.6 — full-scan expander + the suppressed-artifact flag (muted ember, never red). */
.fs-exp { margin: var(--sp-2) 0; }
.fs-body { margin-top: var(--sp-3); }
.fs-body .hb-group { margin-top: var(--sp-4); }
.rd-flag-note { color: var(--ember); border: 1px dashed var(--ember-line); border-radius: var(--radius-xs); padding: var(--sp-2) var(--sp-3); background: var(--ember-wash); }
/* P2.1–P2.5 — capture backlog cards: honest pending states, never alarmist. */
.cap-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--sp-3); margin: var(--sp-3) 0; }
.cap-card { border: var(--honest-border); border-radius: var(--radius-sm); padding: var(--sp-3); }
.cap-h { margin: 0 0 var(--sp-2); display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap; font-size: var(--fs-small); }
.cap-tag { font-family: var(--font-mono); font-size: 0.58rem; text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ink-faint); border: 1px solid var(--rule); border-radius: var(--radius-xs); padding: 0 6px; white-space: nowrap; }
.cap-tag.cap-private { color: var(--ember); border-color: var(--ember-line); }
/* RQA-05 — deficit-sustainability five-channel read. Strain = ember (look here), holding =
   muted ink, too-few = faint. Verdict header ember-toned on attention, calm otherwise. No red. */
.dsx-verdict { display: flex; align-items: baseline; gap: var(--sp-3); margin: var(--sp-3) 0; padding: var(--sp-3); border: var(--honest-border); border-radius: var(--radius-sm); }
.dsx-verdict.dsx-sev-attn { border-color: var(--ember-line); background: var(--ember-wash); }
.dsx-count { font-size: var(--fs-h3, 1.4rem); color: var(--ember); white-space: nowrap; }
.dsx-vtext { color: var(--ink); }
.dsx-rows { display: flex; flex-direction: column; gap: 1px; margin: var(--sp-3) 0; }
.dsx-row { display: grid; grid-template-columns: 1fr auto 7em; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--rule); }
.dsx-name { font-weight: var(--weight-med); }
.dsx-dir { color: var(--ink-muted); white-space: nowrap; }
.dsx-status { text-align: right; text-transform: uppercase; letter-spacing: var(--tracking-label); }
.dsx-strain .dsx-status, .dsx-strain .dsx-dir { color: var(--ember); }
.dsx-hold .dsx-status { color: var(--ink-muted); }
.dsx-none .dsx-status, .dsx-none .dsx-dir { color: var(--ink-faint); }
/* WQA-06 — coach disagreements: head-to-head positions + the integrator's call. The argument
   is the moat; surfaced not averaged. Ember marks the verdict, never alarm. */
.dis-grid { display: flex; flex-direction: column; gap: var(--sp-4); margin: var(--sp-3) 0; }
.dis-card { border: var(--honest-border); border-radius: var(--radius-sm); padding: var(--sp-4); }
.dis-topic { margin: 0 0 var(--sp-3); font-size: var(--fs-h4, 1.05rem); }
.dis-cols { display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--sp-3); align-items: start; }
.dis-pos { display: flex; flex-direction: column; gap: var(--sp-2); }
.dis-who { text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ember); }
.dis-text { margin: 0; color: var(--ink-muted); line-height: 1.5; font-size: var(--fs-small); }
.dis-vs { align-self: center; font-family: var(--font-mono); color: var(--ink-faint); font-size: 0.7rem; text-transform: uppercase; }
.dis-call { margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--rule); }
.dis-call-k { text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--ember); display: block; margin-bottom: var(--sp-1); }
.dis-call .dis-text { color: var(--ink); }
@media (max-width: 640px) { .dis-cols { grid-template-columns: 1fr; } .dis-vs { justify-self: start; } }
/* ── /evidence/vitals/ — glance-first instrument panel (P0.1+) ───────────────────
   Component rings + status band. tone: ember=good, muted=neutral/forming, alert=RED STATE
   (reserved). Red never encodes a direction. */
.vs-band { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); flex-wrap: wrap; margin: var(--sp-2) 0 var(--sp-3); padding: var(--sp-3); border-radius: var(--radius-sm); border: var(--honest-border); }
.vs-band.vs-ember { border-color: var(--ember-line); background: var(--ember-wash); }
.vs-band.vs-alert { border-color: var(--alert-line); background: var(--alert-wash); }
.vs-word { display: flex; align-items: baseline; gap: var(--sp-3); flex-wrap: wrap; }
.vs-w { font-family: var(--font-serif, Fraunces), serif; font-size: var(--fs-h2, 1.8rem); line-height: 1; }
.vs-ember .vs-w { color: var(--ember); }
.vs-alert .vs-w { color: var(--alert); }
.vs-muted .vs-w { color: var(--ink); }
.vs-line { color: var(--ink-muted); }
.vs-stamp { color: var(--ink-faint); font-family: var(--font-mono); font-size: var(--fs-small); white-space: nowrap; }
.vr-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-3); margin: var(--sp-3) 0; }
.vr { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); position: relative; }
.vr-svg { width: 100%; max-width: 92px; aspect-ratio: 1; }
.vr-track { stroke: var(--rule); stroke-width: 7; }
.vr-arc { stroke: var(--ember); stroke-width: 7; transition: stroke-dasharray 0.4s; }
.vr-muted .vr-arc { stroke: var(--ink-muted); }
.vr-alert .vr-arc { stroke: var(--alert); }
.vr-thin .vr-arc { opacity: 0.72; }
/* P0.4 — thin-data ring state: a dashed track signals the baseline is still forming, so a
   10-day fill never reads as a settled normal. Pairs with the "N days in" band stamp. */
.vr-thin .vr-track { stroke-dasharray: 3 5; opacity: 0.8; }
/* P1.2 — autonomic hero: two ember lines (HRV solid, RHR inverted dashed). Both up = recovery. */
.ah-hrv { stroke: var(--ember); stroke-width: 2.25; stroke-linejoin: round; }
.ah-rhr { stroke: var(--ember); stroke-width: 2; stroke-dasharray: 5 4; opacity: 0.8; stroke-linejoin: round; }
.ah-key { white-space: nowrap; }
.ah-sw { display: inline-block; width: 0.8em; height: 0.18em; vertical-align: middle; margin-right: 0.3em; background: var(--ember); }
.ah-sw-rhr { opacity: 0.7; height: 0; border-top: 2px dashed var(--ember); }
/* P1.3 — readiness driver bars reuse the sufficiency kit; alert tone for a run-down driver. */
.suf-fill.vd-alert { background: var(--alert); }
/* P2.1 — autonomic 2x2 */
.aq-wrap { max-width: 340px; margin: var(--sp-3) auto 0; }
.aq-chart svg { width: 100%; height: auto; }
.aq-div { stroke: var(--rule); stroke-width: 1; stroke-dasharray: 2 4; }
.aq-lab { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8px; letter-spacing: 0.08em; }
.aq-ax { fill: var(--ink-faint); font-family: var(--font-mono); font-size: 8px; }
.aq-dot { fill: var(--ink-muted); opacity: 0.6; }
.aq-dot.aq-today { fill: var(--ember); opacity: 1; }
/* P2.2 — small-multiples grid */
.sm-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-3); margin: var(--sp-3) 0; }
.sm-cell { border: 1px solid var(--rule); border-radius: var(--radius-xs); padding: var(--sp-2) var(--sp-3); }
.sm-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-2); }
.sm-lbl { font-weight: var(--weight-med); text-transform: lowercase; font-size: var(--fs-small); }
.sm-frame { color: var(--ink-faint); font-size: 0.56rem; text-transform: uppercase; letter-spacing: var(--tracking-label); }
.sm-cell .spark { width: 100%; height: 30px; margin: var(--sp-1) 0; }
.sm-foot { display: flex; justify-content: space-between; align-items: baseline; }
.sm-v { font-size: var(--fs-small); }
.sm-trend { color: var(--ink-muted); }
.sm-empty { color: var(--ink-faint); padding: var(--sp-3) 0; text-align: center; }
@media (max-width: 640px) { .sm-grid { grid-template-columns: repeat(2, 1fr); } }
/* P2.4 — hub links */
.vh-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); margin: var(--sp-3) 0; }
.vh-link { display: inline-block; padding: var(--sp-2) var(--sp-3); border: 1px solid var(--rule); border-radius: var(--radius-xs); text-decoration: none; color: var(--ink); font-size: var(--fs-small); }
.vh-link:hover { border-color: var(--ember-line); color: var(--ember); }
.vr-c { position: absolute; top: calc(50% - 0.7em); left: 0; right: 0; display: flex; flex-direction: column; align-items: center; line-height: 1; }
.vr-v { font-size: var(--fs-h4, 1.05rem); }
.vr-ember .vr-v { color: var(--ember); }
.vr-alert .vr-v { color: var(--alert); }
.vr-sub { color: var(--ink-faint); font-size: 0.6rem; }
.vr-l { text-transform: lowercase; color: var(--ink-muted); }
@media (max-width: 520px) { .vr-row { grid-template-columns: repeat(2, 1fr); } }
/* P0.2 — now/7d/30d ladder, aligned under the ring grid. */
.vl-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-3); margin-top: calc(-1 * var(--sp-2)); }
.vl-cell { display: flex; justify-content: center; gap: var(--sp-3); }
.vl-pair { display: flex; flex-direction: column; align-items: center; gap: 1px; }
.vl-k { color: var(--ink-faint); font-size: 0.58rem; text-transform: uppercase; letter-spacing: var(--tracking-label); }
.vl-v { font-size: var(--fs-small); }
.vl-v.vl-base { color: var(--ink-muted); }
@media (max-width: 520px) { .vl-row { grid-template-columns: repeat(2, 1fr); } }
/* ── /evidence/mind/ — restraint (P0.1). NO RED anywhere on this page (the reserved-red rule
   is explicitly excluded here). Ember = held/earned; muted ink = reset/future. No alarm. */
.mr-cum { display: flex; align-items: baseline; gap: var(--sp-3); margin: var(--sp-2) 0 var(--sp-3); }
.mr-cum-v { font-size: var(--fs-display, 2.6rem); color: var(--ember); line-height: 1; }
.mr-cum-k { color: var(--ink-muted); max-width: 34ch; }
.mr-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-3) 0; }
.mr-chip { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--ember); border: 1px solid var(--ember-line); border-radius: var(--radius-xs); padding: 2px 10px; }
.mr-ladder { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: baseline; margin: var(--sp-3) 0; }
.mr-rung { font-family: var(--font-mono); font-size: 0.7rem; padding: 1px 7px; border-radius: var(--radius-xs); }
.mr-rung.mr-crossed { color: var(--ember); border: 1px solid var(--ember); }
.mr-rung.mr-future { color: var(--ink-faint); border: 1px dashed var(--rule); }
.mr-reset { color: var(--ink-muted); font-style: italic; margin-top: var(--sp-2); }
/* P0.2 — the inviting absence: a held, dignified empty state, never a hollow axis. */
.mi-absence { border: 1px dashed var(--ember-line); border-radius: var(--radius-sm); padding: var(--sp-4); background: var(--ember-wash); }
.mi-lead { margin: 0; font-family: var(--font-serif, Fraunces), serif; font-size: var(--fs-h4, 1.1rem); line-height: 1.4; color: var(--ink); }
.mi-sub { margin: var(--sp-3) 0 0; color: var(--ink-muted); line-height: 1.55; }
.mi-entry { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3); margin-top: var(--sp-4); }
.mi-cta { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--ember); background: transparent; border: 1px solid var(--ember); border-radius: var(--radius-xs); padding: var(--sp-2) var(--sp-3); cursor: pointer; }
.mi-cta:hover { background: var(--ember-wash); }
.mi-entry-note { color: var(--ink-faint); }
/* P0.3 — Mind pillar decomposed into its inputs (anti-black-box). */
.mp-rows { display: flex; flex-direction: column; gap: 1px; margin: var(--sp-3) 0; }
.mp-row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--sp-3); padding: var(--sp-2) 0; border-bottom: 1px solid var(--rule); }
.mp-l { color: var(--ink); }
.mp-v { color: var(--ember); }
.mp-v.mp-await { color: var(--ink-faint); font-style: italic; }
/* P0.4 — Third Wall: the held "last word" slot (waiting, not absent). No red. */
.mw-pending { border: 1px dashed var(--ember-line); border-radius: var(--radius-sm); padding: var(--sp-3) var(--sp-4); background: var(--ember-wash); margin-top: var(--sp-3); }
.mw-who { color: var(--ember); text-transform: uppercase; letter-spacing: var(--tracking-label); display: block; margin-bottom: var(--sp-1); }
.mw-lead { margin: 0; font-family: var(--font-serif, Fraunces), serif; font-style: italic; font-size: var(--fs-quote, 1.15rem); color: var(--ink); }
.mw-sub { margin: var(--sp-2) 0 0; color: var(--ink-muted); line-height: 1.5; }
/* P0.3 — earned glyphs: lit ember on real signal, unlit (faint outline) otherwise. */
.vg-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-3) 0; }
.vg { display: inline-flex; align-items: center; gap: var(--sp-2); padding: 3px 10px; border-radius: var(--radius-xs); border: 1px solid var(--rule); text-decoration: none; }
.vg-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--rule); }
.vg-word { font-size: var(--fs-small); text-transform: lowercase; }
.vg-val { font-size: var(--fs-small); color: var(--ink-muted); }
.vg-lit { border-color: var(--ember-line); }
.vg-lit .vg-dot { background: var(--ember); }
.vg-lit .vg-word { color: var(--ember); }
.vg-off { opacity: 0.55; border-style: dashed; }
.vg-off .vg-word { color: var(--ink-faint); }
a.vg-lit:hover { background: var(--ember-wash); }
.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; }
/* Measuring-rule tick spine on a trend chart (SIGNATURE 1, P0.8) — a ticked y-axis rail
   with the max (top) / min (bottom) value. Token-driven ticks; muted ink, never red. */
.chart--spined { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-2); align-items: stretch; }
.chart--spined > svg { grid-column: 2; }
.chart--spined > .chart-cap { grid-column: 1 / -1; }
.chart-spine { grid-column: 1; align-self: stretch; min-height: clamp(110px, 8vw + 80px, 150px);
  width: var(--spine-width); border-right: var(--spine-border); background: var(--spine-ticks);
  display: flex; flex-direction: column; justify-content: space-between; padding: 2px 5px 2px 0;
  text-align: right; }
.chart-spine-v { color: var(--ink-faint); font-size: 0.6rem; line-height: 1; }
/* Serif "what this means" annotation under a chart (SIGNATURE 2 human voice). */
.nut-anno { margin-top: var(--sp-3); }
/* Designed "coming online" empty state (P1.3 hunger/energy, §8 CGM) — honest, flagged. */
.nut-coming { border: var(--honest-border); border-radius: var(--radius-sm); padding: var(--sp-4); margin-top: var(--sp-3); }
.nut-coming .rd-archive { margin: 0; }
/* Ghosted CGM curve placeholder (§8) — muted, dashed, no live data. */
.cgm-ghost .cgm-svg { width: 100%; height: 110px; display: block; opacity: 0.45; margin-bottom: var(--sp-3); }
.cgm-curve { fill: none; stroke: var(--ink-muted); stroke-width: 2; stroke-dasharray: 5 4; }
.cgm-meal { stroke: var(--ember); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.55; }
.cgm-meal-dot { fill: var(--ember); opacity: 0.55; }
/* Loss-rate readout (nutrition §1, P0.9) — rate chain + deficit-intensity flag. Ember on
   "aggressive" = attention, not alarm (never red); moderate/mild are muted ink. */
.nut-lossrate { margin-top: var(--sp-3); }
.nut-flag { display: inline-block; font-family: var(--font-mono); font-size: 0.6rem;
  text-transform: uppercase; letter-spacing: var(--tracking-label); padding: 1px 6px;
  border-radius: var(--radius-xs); border: 1px solid var(--rule); color: var(--ink-muted); white-space: nowrap; }
.nut-flag-aggressive { border-color: var(--ember); color: var(--ember); }
/* Standing-bet verdict chips (P2.1) — pending/confirmed/refuted. Refuted = muted, never red. */
.nut-flag.pj-pending { border-color: var(--rule); color: var(--ink-muted); }
.nut-flag.pj-ok { border-color: var(--ember); color: var(--ember); }
.nut-flag.pj-warn { border-color: var(--ink-muted); color: var(--ink-muted); }
.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%; }

/* Stacked composition bar (macro split, etc.) — ember = primary/tracked, muted inks for rest. */
.sbar { display: flex; width: 100%; height: 14px; border-radius: var(--radius-xs); overflow: hidden; margin-top: var(--sp-3); background: var(--surface-2, var(--surface)); }
.sbar-seg { height: 100%; display: block; }
.sbar-ember { background: var(--ember); }
.sbar-ink { background: var(--ink-muted); }
.sbar-faint { background: var(--ink-faint); }
.sbar-legend { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); }
.sbar-key { display: inline-flex; align-items: center; gap: var(--sp-1); }
.sbar-dot { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }

/* Hero energy spine (nutrition §0) — a horizontal measuring-rule 0→maintenance with
   the intake + maintenance ticks and the deficit gap shaded. Reuses SIGNATURE 1. */
.nut-hero { margin-top: var(--sp-4); }
.spine-fig { margin-top: var(--sp-2); }
.hspine { position: relative; height: 58px; margin: var(--sp-6) 0 var(--sp-3); }
.hspine-rule { position: absolute; left: 0; right: 0; top: 34px; height: 7px;
  background: repeating-linear-gradient(to right, var(--tick) 0 1px, transparent 1px var(--spine-tick-gap));
  border-bottom: var(--spine-border); }
.hspine-gap { position: absolute; top: 30px; height: 15px; background: var(--ember-wash);
  border-left: 1px solid var(--ember); border-right: 1px dashed var(--ink-faint); }
.hspine-gap-surplus { background: var(--surface-2, var(--surface)); border-left: 1px dashed var(--ink-faint); }
/* Zero-width anchor at the value's true position; the tick (::after) stays centered on
   it, the label anchors inward near the edges so a far-right value never clips at 390px. */
.hspine-mark { position: absolute; top: 0; bottom: 0; width: 0; }
.hspine-mark::after { content: ""; position: absolute; top: 30px; left: 0; transform: translateX(-50%);
  width: 1px; height: 20px; background: var(--ink-muted); }
.hspine-lab { position: absolute; bottom: 26px; display: flex; flex-direction: column; gap: 2px;
  white-space: nowrap; max-width: 9rem; }
.hspine-c .hspine-lab { left: 0; transform: translateX(-50%); align-items: center; }
.hspine-l .hspine-lab { left: 0; align-items: flex-start; }
.hspine-r .hspine-lab { right: 0; align-items: flex-end; }
.hspine-intake { color: var(--ember); }
.hspine-intake::after { background: var(--ember); }
.hspine-v { font-size: var(--fs-data-lg); line-height: 1; }
.hspine-k { color: var(--ink-faint); }
/* targetSpine only (Zone-2 etc.): taller rail + smaller labels, value ABOVE the rule and
   target BELOW — vertical stagger that prevents the two endpoint labels colliding when
   value≈target horizontally (the "150 min210 min" overlap). Scoped so the nutrition spine
   is untouched. */
.spine-fig--targets .hspine { height: 88px; }
.spine-fig--targets .hspine-rule { top: 42px; }
.spine-fig--targets .hspine-mark::after { top: 38px; height: 22px; }
.spine-fig--targets .hspine-v { font-size: var(--fs-h4, 1.05rem); }
.spine-fig--targets .hspine-lab { bottom: auto; top: 6px; }
.spine-fig--targets .hspine-lab.hspine-lab-below { top: 62px; }

/* Sufficiency bars (nutrient intake vs target, P0.4) — horizontal 0→100%, worst-first.
   Value in its own grid column so it never clips the right edge; the track's right edge
   is the 100% target rule. Ember = worst offenders short of the floor, NOT a win. */
.suf-head { margin-top: var(--sp-3); color: var(--ink-faint); }
.suf-rows { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-2); }
.suf-row { display: grid; grid-template-columns: minmax(4.5rem, 7.5rem) 1fr auto; align-items: center; gap: var(--sp-2) var(--sp-3); }
.suf-l { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-muted); }
.suf-track { position: relative; height: 8px; border-radius: 4px;
  background: var(--surface-2, var(--surface)); border-right: 1px solid var(--ink-faint); }
.suf-fill { display: block; height: 100%; border-radius: 4px; }
.suf-ember { background: var(--ember); }
.suf-ink { background: var(--ink-muted); }
.suf-v { color: var(--ink-faint); white-space: nowrap; font-size: var(--fs-label, 0.78rem); }
.suf-amt { color: var(--ink-faint); margin-left: var(--sp-2); }
@media (max-width: 560px) { .suf-amt { display: none; } .suf-row { grid-template-columns: minmax(4rem, 6rem) 1fr auto; } }

/* Protein lead (nutrition §2, P0.2) — the failing metric weighted as the headline.
   Ember = attention/warning when under floor (giant figure + ▼ + "under floor"),
   NEVER an ember "win" block for a miss (HARD RULE 3). */
.nut-lead { margin-top: var(--sp-5); display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--sp-1) var(--sp-4); }
.nut-lead .lead-fig { display: flex; flex-direction: column; gap: var(--sp-1); }
.nut-lead .lead-v { font-family: var(--font-mono); font-weight: var(--weight-med);
  font-size: clamp(2.4rem, 1.4rem + 5vw, 3.6rem); line-height: 1; }
.nut-lead .lead-k { color: var(--ink-faint); }
.nut-lead .lead-sub { color: var(--ink-muted); }
.nut-lead.lead-warn .lead-v { color: var(--ember); }
.nut-lead.lead-warn .lead-k { color: var(--ember); }
.nut-lead.lead-warn .lead-k::before { content: "▼ "; }
.nut-lead.lead-ok .lead-v { color: var(--ink); }

/* Two-voice verdict (SIGNATURE 2) — mono states, serif judges. */
.two-voice { margin-top: var(--sp-4); display: grid; gap: var(--sp-2);
  border-left: 2px solid var(--ember); padding-left: var(--sp-4); }
.tv-machine { font-family: var(--voice-machine-font); font-size: var(--voice-machine-size);
  line-height: var(--voice-machine-lh); color: var(--voice-machine-ink); }
.tv-mark { color: var(--voice-machine-mark); }
.tv-human { font-family: var(--voice-human-font); font-style: var(--voice-human-style);
  font-size: var(--voice-human-size); line-height: var(--voice-human-lh); color: var(--voice-human-ink);
  max-width: var(--measure); }

/* Eating-window ribbon (nutrition §4, P1.1) — ember = actual window, faint = 16:8 ref. */
.ewin-rows { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-2); }
.ewin-row { display: grid; grid-template-columns: minmax(3rem, 4rem) 1fr auto; align-items: center; gap: var(--sp-2) var(--sp-3); }
.ewin-day { color: var(--ink-muted); white-space: nowrap; }
.ewin-track { position: relative; height: 12px; border-radius: 3px; background: var(--surface-2, var(--surface)); }
.ewin-ref { position: absolute; top: 0; height: 100%; background: var(--ink-faint); opacity: 0.35; border-radius: 3px; }
.ewin-bar { position: absolute; top: 0; height: 100%; background: var(--ember); border-radius: 3px; }
.ewin-v { color: var(--ink-faint); white-space: nowrap; font-size: var(--fs-label, 0.78rem); }
@media (max-width: 560px) { .ewin-v { font-size: 0.6rem; } .ewin-row { grid-template-columns: minmax(2.5rem, 3.5rem) 1fr auto; } }

/* Per-day macro composition columns by energy (nutrition §3, P0.7) — ember = protein
   (the floor), muted inks for carbs/fat. Refuses < 4 points in the chart kit. */
.scols { display: flex; align-items: flex-end; gap: 4px; height: 150px; margin-top: var(--sp-3); }
.scol { flex: 1; min-width: 0; height: 100%; display: flex; flex-direction: column;
  align-items: center; gap: var(--sp-1); justify-content: flex-end; }
.scol-stack { width: 72%; height: 100%; display: flex; flex-direction: column;
  justify-content: flex-end; border-radius: 2px 2px 0 0; overflow: hidden; }
.scol-seg { width: 100%; display: block; }
/* Modality ramp (training §3, P0.7) — ONE hue: lift = ember, walk/cardio = ember tint,
   mobility = muted ink. seg-<tone> for stackedDayColumns + the legend dots. */
.seg-lift { background: var(--ember); }
.seg-cardio { background: color-mix(in oklch, var(--ember) 52%, var(--surface)); }
.seg-mob { background: var(--ink-muted); }
.sbar-dot.seg-lift, .sbar-dot.seg-cardio, .sbar-dot.seg-mob { border-radius: 2px; }
.scol-l { color: var(--ink-faint); font-size: 0.6rem; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* Correlation chips — strength by bar width, sign by direction word (correlative, N=1). */
.corr-rows { display: flex; flex-direction: column; gap: var(--sp-2); margin-top: var(--sp-3); }
.corr-row { display: grid; grid-template-columns: minmax(0,1fr) 90px auto; align-items: center; gap: var(--sp-2); }
.corr-l { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.corr-bar { height: 6px; border-radius: 3px; background: var(--surface-2, var(--surface)); overflow: hidden; }
.corr-fill { display: block; height: 100%; }
.corr-r { color: var(--ink-faint); font-size: var(--fs-label, 0.78rem); white-space: nowrap; }

/* Accountability ledger — cause cards (shown even at $0 so the rules + personality read). */
.cause-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--sp-3); margin-top: var(--sp-3); }
.cause-card { border: var(--honest-border); border-radius: var(--radius-sm); padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-1); }
.cause-name { font-weight: 600; color: var(--ink); text-decoration: none; }
.cause-name:hover { color: var(--ember); }
.cause-desc { color: var(--ink-faint); }
.cause-why { color: var(--ink-muted); font-style: italic; margin: var(--sp-1) 0 0; font-size: 0.95em; }
.cause-amt { color: var(--ink-faint); margin-top: var(--sp-1); }

/* ── Shared footer mega-menu (CC-05) — on all three doors ─────────────────── */
.site-foot { border-top: var(--border-hair); margin-top: var(--sp-7); padding: var(--sp-6) var(--gutter) var(--sp-5); }
.site-foot-cols { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-5); max-width: var(--container); margin-inline: auto; }
@media (min-width: 720px) { .site-foot-cols { grid-template-columns: repeat(4, 1fr); } }
.sf-col { display: grid; gap: var(--sp-2); align-content: start; }
.sf-col a { font-size: var(--fs-small); color: var(--ink-muted); text-decoration: none; }
.sf-col a:hover { color: var(--ember); }
.sf-h { color: var(--ember); margin-bottom: var(--sp-1); }
.sf-base { max-width: var(--container); margin: var(--sp-5) auto 0; display: flex; justify-content: space-between; gap: var(--sp-3); color: var(--ink-faint); }
.sf-base a { color: var(--ink-faint); text-decoration: none; }
.sf-base a:hover { color: var(--ember); }

/* ── Coach-name popover (CC-04) — progressive disclosure in reader prose ───── */
.coach-chip { font: inherit; color: var(--ember); background: none; border: none; padding: 0; cursor: pointer;
  border-bottom: 1px dotted var(--ember-line); }
.coach-chip:hover, .coach-chip:focus-visible { border-bottom-style: solid; outline: none; }
.coach-pop { position: absolute; z-index: var(--z-overlay, 60); max-width: 280px; padding: var(--sp-3) var(--sp-4);
  background: var(--surface-raised); border: var(--border-hair); border-radius: var(--radius-sm);
  box-shadow: 0 8px 28px rgba(0,0,0,0.18); }
.cp-name { font-family: var(--font-mono); font-size: var(--fs-small); color: var(--ink); }
.cp-role { color: var(--ember); margin-top: 2px; }
.cp-bio { margin-top: var(--sp-2); font-size: var(--fs-small); color: var(--ink-muted); line-height: var(--lh-relaxed); }
.cp-link { display: inline-block; margin-top: var(--sp-2); font-family: var(--font-mono); font-size: var(--fs-label);
  color: var(--ember); text-decoration: none; border-bottom: 1px solid var(--ember-line); }
.cp-link:hover { border-color: var(--ember); }

/* ── Mobile: the three doors become a fixed, thumb-reachable bottom app-bar
   (2026-06-14). Replaces the old top-nav shrink-to-9px. tokens.css loads before
   the per-door CSS, so !important is required to supersede .cockpit-top/.doors. */
@media (max-width: 600px) {
  /* A backdrop-filter / transform / filter ancestor creates a containing block that
     traps position:fixed children — that pinned the door-bar to the .story-top bar
     (top) on Story/Home while it sat at the viewport bottom on Evidence/Cockpit.
     Neutralize those on the top bars at mobile width so the bar is ALWAYS bottom. */
  .story-top, .ev-top, .cockpit-top {
    backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
    transform: none !important; filter: none !important; perspective: none !important;
  }
  .doors {
    position: fixed !important; left: 0; right: 0; bottom: 0; z-index: 60;
    display: flex !important; justify-content: space-around; align-items: stretch;
    gap: 0 !important;
    padding: 0 .25rem env(safe-area-inset-bottom) !important;
    background: var(--surface-raised, #14110b);
    border-top: 1px solid var(--ember-line, rgba(140,120,90,.28));
    box-shadow: 0 -2px 14px rgba(0,0,0,.28);
  }
  .doors a {
    flex: 1; display: flex !important; align-items: center; justify-content: center;
    min-height: 52px; padding: .5rem .25rem !important;
    font-size: .72rem !important; letter-spacing: .04em !important; text-align: center;
  }
  .doors a[aria-current="page"] { border-bottom: 0 !important; color: var(--ember) !important; }
  /* content clears the fixed bar (incl. iOS home-indicator inset) */
  body { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }
}

/* Build stamp — muted deploy fingerprint (git SHA), shown on machine-facing footers. */
/* muted, but NOT below AA: --ink-faint is AA-tuned (4.9:1 on paper); the old opacity:0.6 dropped it to 2.34. */
.build-stamp { display: block; margin-top: var(--sp-2); font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }

/* ════════════════════════════════════════════════════════════════════════════
   11. SHARED CONTENT & PAGE KIT — v5 "Coherence" (docs/DESIGN_SYSTEM_V5.md)
   The pieces that make every door read as one package. Additive: opt a page in
   by adding the class — nothing changes until adopted.
   ════════════════════════════════════════════════════════════════════════════ */

/* ── .prose — the ONE wrapper for all injected / long-form / AI-generated HTML
   (chronicle posts, coach reads, evidence readouts, journal, about pages).
   Apply to the CONTAINER; it pins the triad's jobs on every descendant so
   model-emitted <h2>/<ul>/<blockquote> render identically everywhere. This is
   the fix for "fonts all over the place" — replaces ad-hoc per-section type. */
.prose { color: var(--ink); font-size: var(--fs-body-lg); line-height: var(--lh-relaxed); max-width: var(--measure); }
.prose > :first-child { margin-top: 0; }
.prose > * + * { margin-top: var(--sp-4); }
.prose h2 { font-family: var(--font-serif); font-weight: var(--weight-med); font-size: var(--fs-h2); line-height: var(--lh-snug); margin-top: var(--sp-6); }
.prose h3 { font-family: var(--font-serif); font-weight: var(--weight-med); font-size: var(--fs-h3); line-height: var(--lh-snug); margin-top: var(--sp-5); }
.prose h4 { font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-faint); margin-top: var(--sp-5); }
.prose p { max-width: var(--measure); }
.prose a { color: var(--ember); text-decoration: none; border-bottom: 1px solid var(--ember-line); }
.prose a:hover { border-color: var(--ember); }
.prose strong, .prose b { font-weight: var(--weight-med); color: var(--ink); }
.prose em, .prose i { font-style: italic; }
.prose ul, .prose ol { padding-left: 1.3em; max-width: var(--measure); }
.prose li { line-height: var(--lh-relaxed); }
.prose li + li { margin-top: var(--sp-2); }
.prose blockquote { font-family: var(--font-serif); font-style: italic; font-size: var(--fs-quote); line-height: 1.5; color: var(--ink); border-left: 2px solid var(--ember); padding-left: var(--sp-4); }
.prose code, .prose kbd, .prose samp { font-family: var(--font-mono); font-size: 0.9em; }
.prose hr { border: 0; border-top: var(--honest-border); margin: var(--sp-6) 0; }
.prose figure, .prose img { max-width: 100%; }
.prose small, .prose .prose-meta { color: var(--ink-faint); font-size: var(--fs-small); }
/* compact variant for sidebars / cards / disclosed sub-sections */
.prose.prose-sm { font-size: var(--fs-body); }
.prose.prose-sm > * + * { margin-top: var(--sp-3); }

/* ── .page-hero — the "which part of the loop am I" banner. Identical on all
   five doors so a visitor always orients the same way. */
.page-hero { max-width: var(--container); margin-inline: auto; padding: var(--sp-7) var(--gutter) var(--sp-5); }
.page-hero .ph-kicker { color: var(--ember); }
.page-hero .ph-title { font-family: var(--font-serif); font-weight: var(--weight-med); font-size: var(--fs-h1); line-height: var(--lh-tight); margin-top: var(--sp-3); }
.page-hero .ph-promise { margin-top: var(--sp-3); color: var(--ink-muted); font-size: var(--fs-body-lg); line-height: var(--lh-relaxed); max-width: var(--measure); }

/* ── The loop ribbon — the platform's spine made literal: where you are in
   Data → Coaching → Protocols → Story. Lives in the page-hero and the footer
   so the through-line is on every page. The current door is marked ember. */
.loop-ribbon { margin-top: var(--sp-4); display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center;
  font-family: var(--font-mono); font-size: var(--fs-label); letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-faint); }
.loop-ribbon a { color: var(--ink-faint); text-decoration: none; }
.loop-ribbon a:hover { color: var(--ink-muted); }
.loop-ribbon .lr-here { color: var(--ember); border-bottom: 1px solid var(--ember); }
.loop-ribbon .lr-arrow { color: var(--ember); opacity: 0.55; }

/* ── The loop diagram — the full causal-loop card row (Home + About). */
.loop { display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--sp-2); margin: var(--sp-5) 0; }
.loop-node { flex: 1 1 9rem; min-width: 8rem; border: var(--border-hair); border-radius: var(--radius-sm);
  padding: var(--sp-4); text-decoration: none; color: var(--ink); display: flex; flex-direction: column; gap: var(--sp-1); }
.loop-node:hover { border-color: var(--ember-line); }
.loop-node .ln-name { font-family: var(--font-serif); font-size: var(--fs-h3); line-height: 1.1; }
.loop-node .ln-role { color: var(--ink-muted); font-size: var(--fs-small); line-height: 1.45; }
.loop-arrow { align-self: center; color: var(--ember); font-family: var(--font-mono); flex: 0 0 auto; }
@media (max-width: 720px) { .loop { flex-direction: column; } .loop-arrow { transform: rotate(90deg); } }

/* ── .provenance — every number says where it came from and how fresh. The
   "elite / trustworthy" signal, standardized so it's free on every readout. */
.provenance { margin-top: var(--sp-2); font-family: var(--font-mono); font-size: 0.62rem; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--ink-faint); display: inline-flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); }
.provenance .pv-src { color: var(--ink-muted); }
.provenance .pv-stale { color: var(--ember); }

/* ── .tabset — accessible tab strip (Coaching profiles, Protocols sub-sections).
   Pair buttons (role=tab, aria-selected) with .tabpanel regions. */
.tabset { display: flex; flex-wrap: wrap; gap: var(--sp-1); border-bottom: var(--border-hair); margin-bottom: var(--sp-5); }
.tabset .tab { appearance: none; background: transparent; border: 0; border-bottom: 2px solid transparent; cursor: pointer;
  padding: var(--sp-2) var(--sp-3); margin-bottom: -1px; font-family: var(--font-mono); font-size: var(--fs-label);
  letter-spacing: var(--tracking-label); text-transform: uppercase; color: var(--ink-faint); white-space: nowrap; }
.tabset .tab:hover { color: var(--ink-muted); }
.tabset .tab[aria-selected="true"] { color: var(--ember); border-bottom-color: var(--ember); }
.tabset .tab:focus-visible { outline: 2px solid var(--ember); outline-offset: 2px; border-radius: var(--radius-xs); }
.tabpanel[hidden] { display: none; }

/* ════════════════════════════════════════════════════════════════════════════
   12. MOTION LAYER — v5 "alive". Purposeful, restrained, reduced-motion-aware.
   The hidden state is gated on html.mo (set by a tiny head script ONLY when
   motion is safe) so if motion.js never runs, a failsafe removes .mo and all
   content shows — motion fails OPEN, never hides content.
   ════════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {
  html.mo .hero, html.mo .page-hero, html.mo .ev-head, html.mo .dx-head, html.mo .beat,
  html.mo .loop, html.mo .rd-sec, html.mo .two-voice, html.mo .coach-daily, html.mo .coach-progress,
  html.mo .coach-report, html.mo .coach-stance, html.mo .team-lead, html.mo .team-focus,
  html.mo .team-tension, html.mo .team-huddle, html.mo .supp, html.mo .rd-card, html.mo .cap-card,
  html.mo .vr-row, html.mo .figs, html.mo .ml-ladder {
    opacity: 0; transform: translateY(16px);
    transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  }
  html.mo .is-in { opacity: 1 !important; transform: none !important; }

  /* Hover lifts — pure CSS, zero risk, no flash. */
  .loop-node, .vh-link, .dx-item, .ev-tile, .supp { transition: transform 0.18s var(--ease-out), border-color 0.18s var(--ease-out); }
  .loop-node:hover, .ev-tile:hover { transform: translateY(-2px); }

  /* The pillar constellation breathes (home hero) — barely-there life. */
  .constellation [data-nodes] > * { animation: mo-breathe 6s var(--ease-inout) infinite; }
  @keyframes mo-breathe { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-1.5px); } }

  /* The loop flows — arrows pulse Data → Coaching → Protocols → Story in sequence,
     so the site's core thesis reads as a living cycle, not a static diagram. */
  .loop > .loop-arrow { animation: mo-flow 2.6s var(--ease-inout) infinite; }
  .loop > .loop-arrow:nth-child(4) { animation-delay: 0.35s; }
  .loop > .loop-arrow:nth-child(6) { animation-delay: 0.7s; }
  @keyframes mo-flow { 0%, 100% { opacity: 0.4; } 45% { opacity: 1; transform: translateX(2px); } }
}
