/* ============================================================
   s-tokens.css — design tokens for /dashboard-story
   -----------------------------------------------------------
   Register: academic / data-journalism (see plan
   docs/plan/todo/2026-04-19-dashboard-story-visual-unification.md §0.1
   in the envistor-data repo).

   Scope: everything is scoped to `.n-page--story` (set on <body>)
   so these tokens do NOT leak into /dashboard-narrative or the
   legacy /realtime-sensor surface.

   Theme convention (matches s-narrative.css):
     - LIGHT is the default (no class).
     - DARK is applied via `body.n-page--story:not(.theme-light)`.

   No component styles here — tokens only. Components live in
   s-components.css and consume these tokens by name.
   ============================================================ */

/* ───── LIGHT (default, primary theme) ─────────────────────── */
.n-page--story {
  /* ── Font families ──────────────────────────────────────── */
  /* Serif is display-only (h1/h2/h3/intro beat). Same type
     family as the sans (IBM Plex Serif + IBM Plex Sans) so
     metrics, x-height, and numerals align. Mono reserved for
     .s-cite / <code>. */
  --font-sans:  "IBM Plex Sans",  -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  --font-serif: "IBM Plex Serif", Georgia, "Times New Roman", Times, serif;
  --font-mono:  "IBM Plex Mono",  ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace;

  /* ── Type scale (atomic) ────────────────────────────────── */
  /* Sizes */
  --fs-11: 11px;
  --fs-12: 12px;
  --fs-13: 13px;
  --fs-15: 15px;
  --fs-17: 17px;
  --fs-18: 18px;
  --fs-22: 22px;
  --fs-28: 28px;
  --fs-34: 34px;
  --fs-display: clamp(34px, 4.5vw, 46px);

  /* Weights */
  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semibold: 600;

  /* Line-heights */
  --lh-tight:    1.15;
  --lh-compact:  1.3;
  --lh-normal:   1.5;
  --lh-relaxed:  1.7;

  /* Letter-spacing */
  --ls-normal: 0;
  --ls-micro:  0.01em;
  --ls-caps:   0.11em;  /* eyebrow uppercase tracking */

  /* ── Spacing (4 px grid) ────────────────────────────────── */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --sp-9: 96px;

  /* ── Radii ──────────────────────────────────────────────── */
  /* Near-geometric corners — academic register, not app-bubble. */
  --r-pill: 999px;   /* status pills */
  --r-sm:   3px;     /* code blocks, chips */
  --r-md:   6px;     /* cards, accordion rows, KPI tiles */
  --r-lg:   10px;    /* intro modal only */

  /* ── Color — UI chrome (warm neutrals, stone undertone) ── */
  --c-ink:   #1c1917;
  --c-ink-2: #44403c;
  --c-ink-3: #78716c;
  --c-ink-4: #a8a29e;

  --c-paper:   #f4f2ed;   /* page background — warm off-white, paper-feel */
  --c-paper-2: #ebe8e1;   /* second-tier band (rare) */
  --c-surface: #fbfaf7;   /* cards — half-tone lighter than paper */
  --c-surface-raised: #efece5;   /* wells, callouts, code blocks */

  --c-line:        rgba(28, 25, 23, 0.10);  /* primary hairline — does all card separation */
  --c-line-strong: rgba(28, 25, 23, 0.18);  /* section rules, active borders */

  /* ── Color — single accent (muted botanical green) ─────── */
  --c-accent:      #3f6b54;
  --c-accent-weak: #e3ebe5;
  --c-accent-ink:  #2d4f3d;

  --c-focus-ring:  rgba(63, 107, 84, 0.45);

  /* ── Color — status (desaturated, journal-grade) ───────── */
  /* Good reuses the accent — "all is well" is unified with the
     one accent token, so good/live/on-time all read the same. */
  --s-good:     #3f6b54;
  --s-moderate: #a7742b;
  --s-poor:     #a13a2c;

  /* ── Color — data encoding (chart marks ONLY) ──────────── */
  /* Palette draws from Our World in Data + Okabe-Ito; survives
     print + colorblind screening; stays recessive relative to
     chrome so the narrative reads first, data second.

     RULE: any element outside <canvas> / .plotly container is
     forbidden from using --d-* tokens. Sensor-chip dots use
     these for the 8 px circle ONLY — the chip text/border
     stay on chrome tokens. */
  --d-pm:    #b25d2a;  /* PM / particulate mass — burnt sienna */
  --d-no2:   #6b4e71;  /* NO₂ — eggplant */
  --d-o3:    #2e5c7a;  /* O₃ — deep ocean */
  --d-wind:  #3a6a7a;  /* wind speed / direction — slate-teal */
  --d-rain:  #4a7085;  /* precipitation — washed navy */
  --d-heat:  #8a2e2e;  /* temperature / WBGT — muted crimson */

  /* ── Elevation (minimal — prefer borders) ──────────────── */
  /* Resting surfaces: 0 shadow. Hairline --c-line carries the
     separation. Shadows only for floating / overlay surfaces. */
  --el-0: none;
  --el-1: 0 1px 0 var(--c-line);
  --el-2: 0 12px 40px -16px rgba(28, 25, 23, 0.14);   /* modal */
  --el-3: 0 24px 60px -20px rgba(28, 25, 23, 0.28);   /* backdrop */

  /* ── Motion ─────────────────────────────────────────────── */
  --ease-standard: cubic-bezier(0.4, 0.0, 0.2, 1);
  --dur-fast: 120ms;   /* hover, color shift */
  --dur-base: 180ms;   /* accordion, tab underline */

  /* ── Layout ─────────────────────────────────────────────── */
  --page-max:    1360px;
  --content-max: 1100px; /* editorial content (sections, footer) */
  --prose-max:   68ch;   /* ideal reading measure for body prose */
}

/* ───── DARK (override) ────────────────────────────────────── */
/* Warm-neutral dark — we deliberately avoid cold slate so the
   theme toggle still feels like "the same publication, dimmed"
   rather than "a different app." */
body.n-page--story:not(.theme-light) {
  --c-ink:   #e7e5e0;
  --c-ink-2: #c7c3bc;
  --c-ink-3: #9c9690;
  --c-ink-4: #6f6a65;

  --c-paper:   #1a1816;
  --c-paper-2: #22201d;
  --c-surface: #24211e;
  --c-surface-raised: #2d2926;

  --c-line:        rgba(231, 229, 224, 0.12);
  --c-line-strong: rgba(231, 229, 224, 0.20);

  --c-accent:      #6b9a82;   /* lifted for contrast on dark paper */
  --c-accent-weak: rgba(107, 154, 130, 0.14);
  --c-accent-ink:  #8fb7a0;

  --c-focus-ring:  rgba(143, 183, 160, 0.55);

  /* Status: good follows accent; moderate/poor lifted slightly */
  --s-good:     #6b9a82;
  --s-moderate: #c79958;
  --s-poor:     #c86057;

  /* Data tokens stay identical in both themes — already balanced
     for contrast against both paper tones. Overriding them would
     break chart legend-color continuity across theme toggles. */

  /* Elevation shadows re-tuned for dark surface (warmer, deeper) */
  --el-2: 0 12px 40px -16px rgba(0, 0, 0, 0.55);
  --el-3: 0 24px 60px -20px rgba(0, 0, 0, 0.70);
}

/* ───── COASTAL / NOAA-STYLE REVIEW THEME ───────────────────── */
body.n-page--story.theme-coastal {
  --c-ink:   #12303a;
  --c-ink-2: #2f5963;
  --c-ink-3: #55727a;
  --c-ink-4: #88a5ac;

  --c-paper:   #eef7f8;
  --c-paper-2: #dceff2;
  --c-surface: #ffffff;
  --c-surface-raised: #e5f4f6;

  --c-line:        rgba(8, 127, 140, 0.15);
  --c-line-strong: rgba(8, 127, 140, 0.28);

  --c-accent:      #087f8c;
  --c-accent-weak: #d9f1f4;
  --c-accent-ink:  #075985;
  --c-focus-ring:  rgba(8, 127, 140, 0.42);

  --s-good:     #087f8c;
  --s-moderate: #b7791f;
  --s-poor:     #b91c1c;
}

/* ───── AQI / PUBLIC-HEALTH REVIEW THEME ────────────────────── */
body.n-page--story.theme-aqi {
  --c-ink:   #2f2418;
  --c-ink-2: #5f4933;
  --c-ink-3: #7d6650;
  --c-ink-4: #b39b82;

  --c-paper:   #fff8ee;
  --c-paper-2: #f8ecd9;
  --c-surface: #ffffff;
  --c-surface-raised: #fff2df;

  --c-line:        rgba(180, 83, 9, 0.14);
  --c-line-strong: rgba(180, 83, 9, 0.26);

  --c-accent:      #b45309;
  --c-accent-weak: #ffedd5;
  --c-accent-ink:  #9a3412;
  --c-focus-ring:  rgba(180, 83, 9, 0.42);

  --s-good:     #15803d;
  --s-moderate: #a16207;
  --s-poor:     #b91c1c;
}

/* ───── Reduced motion ─────────────────────────────────────── */
/* Zero decorative animation already, but respect the OS pref
   for the few motions we DO allow (accordion, intro slide). */
@media (prefers-reduced-motion: reduce) {
  .n-page--story {
    --dur-fast: 0ms;
    --dur-base: 0ms;
  }
}
