/*
 * Design tokens. Edit values here, never in component CSS.
 *
 * Conventions:
 *   --color-*     foreground / background / state colors
 *   --font-*      typography (family, size, weight)
 *   --space-*     spacing scale (4 px base)
 *   --radius-*    corner radii
 *   --shadow-*    elevation
 *   --motion-*    transition durations
 *   --z-*         z-index scale (named, not raw numbers)
 *   --control-*   form control geometry (height, focus ring)
 *   --layout-*    page-level sizing (gutter, content max, etc.)
 *
 * Anything used in more than one place belongs here.
 */
:root {
    /* Native UA surfaces (form controls, scrollbars, overscroll
       canvas) follow the theme; the dark override flips this so they
       never flash a white scrollbar over the near-black page. */
    color-scheme: light;

    /* ── Color ────────────────────────────────────────────── */
    --color-text-strong: #0f172a;
    --color-text-base: #1e293b;
    --color-text-muted: #475569;
    /* Eyebrow / uppercase labels (card + chart titles, table heads) are
       real titles, so they take the strong ink rather than a faint grey.
       Follows --color-text-strong in both themes; retune here to dial the
       whole eyebrow tier at once. */
    --color-text-uppercase: var(--color-text-strong);
    /* Lightest text tier, slate-500 not slate-400 so the faintest copy
       clears WCAG AA 4.5:1 on white (the old #94a3b8 sat at ~2.6:1). */
    --color-text-subtle: #64748b;

    --color-bg: #ffffff;
    --color-surface: #ffffff;
    --color-border: #e2e8f0;
    /* Slightly darker hairline reserved for floating surfaces
       (dropdown trigger, dropdown panel) where the default
       --color-border washes out against the page background. */
    --color-border-strong: #cbd5e1;
    --color-divider: #f1f5f9;
    --color-track: #f1f5f9;

    --color-accent: #6366f1;
    --color-accent-strong: #4f46e5;
    --color-accent-soft: #c4b5fd;
    --color-success: #10b981;
    --color-neutral: #94a3b8;
    /* Warning hue for the drift chart's Unmapped series. Picked so
       Reassigned (indigo), Newly Mapped (green), and Unmapped (amber)
       read as three distinct categories, not a ranked palette. */
    --color-warning: #d97706;

    /* Categorical palette for multi-series charts. Series 1 reuses the
       accent for tonal consistency; the rest are spaced around the
       wheel to read as distinct categories, not rankings. Ten slots
       because the operator breakdown assigns one stable colour per
       operator in any snapshot's top five (~ten across history). */
    --color-series-1: var(--color-accent);
    --color-series-2: #db2777;
    --color-series-3: #d97706;
    --color-series-4: #0891b2;
    --color-series-5: #059669;
    --color-series-6: #dc2626;
    --color-series-7: #7c3aed;
    --color-series-8: #65a30d;
    --color-series-9: #0f766e;
    --color-series-10: #64748b;

    /* Ink on saturated accent/success/neutral fills (e.g. the stacked
       diff bar segments). Pulled out so theming happens in one place. */
    --color-on-fill: #ffffff;

    /* ── Typography ───────────────────────────────────────── */
    /* One typeface, no web-font dependency: the platform UI font.
       system-ui leads so every OS uses its native face; the rest are
       fallbacks for older engines. Numbers use tabular-nums where they
       need to align - same font, not a separate mono family. */
    --font-sans:
        system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
        Roboto, "Helvetica Neue", Arial, sans-serif;

    /* Two text scales, so the page has exactly two knobs to retune.

       1) Content scale (this block): titles, labels, ledes, and card
          copy. Bumped +2px from the original 12/14/20 so reading text
          is a touch larger. Change xs/sm/lg here to resize all of it.
       2) Compact UI scale (below): controls, chart text, and card
          footnotes that should stay tight while the content grows.

       Body stays 16px to clear the comfort / iOS-zoom floor. */
    --font-size-xs: 14px;
    --font-size-sm: 16px;
    --font-size-base: 16px;
    --font-size-lg: 22px;
    --font-size-xl: 25px;
    --font-size-2xl: 31px;
    --font-size-3xl: 38px;

    /* Compact UI scale. These intentionally do NOT follow the content
       bump above: interactive controls and chart chrome stay dense so
       only the reading text grows. Retune controls in one place here. */
    --font-size-control: 14px; /* switches, buttons, inputs, legend, tooltips */
    --font-size-chart-axis: 12px; /* SVG ticks, gutter labels, tooltip note */

    --font-weight-regular: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;

    /* Line heights kept tight; metric headlines use --line-tight
       so the giant numbers don't push the cards taller than
       they need to be. */
    --line-tight: 1.05;
    --line-snug: 1.25;
    --line-normal: 1.4;

    /* Uppercase labels (section labels, table heads) tighten the
       tracking; the higher value is used on the table heads
       because they sit on a smaller font size. */
    --letter-uppercase: 0.06em;
    --letter-uppercase-tight: 0.04em;

    /* Negative tracking for large display text. UI fonts are drawn
       loose at large sizes; pulling glyphs ~1-2% closer makes them
       read as display type, not blown-up body copy. Body text keeps
       default spacing - tightening small text hurts legibility. */
    --letter-tight: -0.01em;
    --letter-tighter: -0.02em;

    /* ── Spacing ──────────────────────────────────────────── */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-12: 48px;

    /* ── Radius ───────────────────────────────────────────── */
    --radius-sm: 4px;
    --radius: 8px;
    --radius-pill: 999px;

    /* ── Shadow / Elevation ───────────────────────────────── */
    /* Tooltip shadow sits lower (hovers over the chart inline); the
       popover shadow is bigger to read against any background when the
       panel detaches from its trigger. */
    --shadow-tooltip: 0 6px 28px rgba(15, 23, 42, 0.1);
    --shadow-popover: 0 12px 36px rgba(15, 23, 42, 0.18);

    /* ── Motion ───────────────────────────────────────────── */
    /* Three durations: --motion-fast for hover/state colour, base for
       border tints, slow for chevron rotation. */
    --motion-fast: 0.08s;
    --motion-base: 0.12s;
    --motion-slow: 0.16s;
    --motion-ease: ease;
    /* Sliding mode-switch pill: longer and decelerating so the
       highlight glides and settles rather than snapping. */
    --motion-pill: 0.22s;
    /* The mobile info-sheet slides a long way (full sheet height), so it
       gets a slower, more deliberate duration than the in-place UI. */
    --motion-sheet: 0.34s;
    /* Whole-page light/dark cross-fade. Long enough to read as a
       deliberate palette ease (see .theme-transition in base.css),
       short enough not to feel sluggish on a toggle. */
    --motion-theme: 0.36s;
    --ease-decelerate: cubic-bezier(0.22, 1, 0.36, 1);

    /* ── Z-index scale ────────────────────────────────────── */
    /* Tooltip lives inside a card; popover above the layout (can
       overflow card edges). Both far below any future overlay so
       adding one won't require re-numbering. */
    --z-tooltip: 5;
    --z-popover: 30;
    /* Full-screen mobile nav overlay and the sticky header that sits
       above it: the header keeps the burger / close control reachable
       while the menu covers the page beneath it. */
    --z-overlay: 40;
    --z-header: 50;
    /* Mobile info bottom-sheet: a true modal that must cover the
       sticky header too (unlike the nav overlay, which keeps the
       header reachable), so it sits one step above it. */
    --z-modal: 60;

    /* ── Form controls ────────────────────────────────────── */
    --control-height: 36px;
    --control-height-sm: 28px;
    --control-icon-size: 12px;
    --control-panel-gap: 6px;
    --control-panel-max-height: 300px;

    --focus-ring-width: 2px;
    --focus-ring-offset: 1px;

    /* ── Layout ───────────────────────────────────────────── */
    --content-max: 1040px;
    --page-gutter: 40px;
    --header-height: 69px;
    --chart-min-height: 240px;
}

/*
 * Dark theme, applied via ``data-theme="dark"`` on <html> (an inline
 * boot script in index.html resolves the saved preference before
 * first paint; components/theme-switch.js owns the toggle after).
 * Greys follow the transitions.dev palette: a near-black #121212 page
 * with #181818 cards and translucent-white hairlines so borders read
 * as lifts off the surface rather than drawn lines.
 */
html[data-theme="dark"] {
    color-scheme: dark;

    /* Text tiers, each kept above WCAG AA 4.5:1 on the #121212 page
       and #181818 cards (the faintest, -subtle, lands ~6:1). Light
       theme's ordering is preserved: base → muted → subtle. */
    --color-text-strong: #f4f4f5;
    --color-text-base: #dcdce1;
    --color-text-muted: #b4b4bd;
    /* --color-text-uppercase follows --color-text-strong (see :root). */
    --color-text-subtle: #9a9aa4;

    --color-bg: #121212;
    --color-surface: #181818;
    /* Hairlines as translucent white so they brighten with whatever
       sits beneath them (page vs card) instead of a flat drawn line. */
    --color-border: rgba(255, 255, 255, 0.09);
    --color-border-strong: rgba(255, 255, 255, 0.18);
    --color-divider: rgba(255, 255, 255, 0.07);
    --color-track: rgba(255, 255, 255, 0.08);

    /* Neutral lifted off slate-500 so the dashed "total drift"
       overlay and other neutral marks stay legible on near-black. */
    --color-neutral: #94a3b8;

    /* ── Accent & data hues, retuned for dark ──────────────────
       Fully saturated mid-tones glare/halate against a near-black
       canvas, so dark shifts every accent and data colour to a lifted,
       slightly desaturated ~400 tier: same hue, calmer, still clear of
       the contrast floor. The light palette is left as-is. */
    --color-accent: #818cf8;
    --color-accent-strong: var(--color-accent);
    --color-accent-soft: #c4b5fd;
    --color-success: #4cc79a;
    --color-warning: #e0a35c;

    /* The lifted fills are too light for white label text, so on-fill
       ink flips to near-black: it rides the accent pill and the diff
       breakdown segments, all 400-tier tones now. */
    --color-on-fill: #15161d;

    /* Categorical series, same desaturate-and-lift so the operator
       breakdown stays calm rather than ten neons. Series 1 follows
       --color-accent automatically (see :root). */
    --color-series-2: #db8db5;
    --color-series-3: #e0a35c;
    --color-series-4: #5cb6d6;
    --color-series-5: #5cbf9a;
    --color-series-6: #e08585;
    --color-series-7: #a99cf0;
    --color-series-8: #a8c25e;
    --color-series-9: #4fb8ac;
    --color-series-10: #94a3b8;

    /* On a dark canvas the light theme's slate-tinted shadows wash
       out, so these deepen to near-opaque black and gain spread. */
    --shadow-tooltip: 0 6px 28px rgba(0, 0, 0, 0.5);
    --shadow-popover: 0 12px 36px rgba(0, 0, 0, 0.62);
}

/* Mobile reading + control scale. Phones keep the base font sizes
   (16px body also avoids iOS focus auto-zoom) and only open up line
   height and grow controls toward a 44px touch target. Centralised
   so every component scales from one source. */
@media (max-width: 640px) {
    :root {
        --line-normal: 1.5;

        --control-height: 44px;
        --control-height-sm: 40px;
    }
}

/* Reduced-motion override: near-instant variants of every
   transition. Durations are 1ms not 0s because some animations (the
   dropdown chevron) need a non-zero duration to fire transitionend
   reliably. Also collapses the skeleton shimmer to a static
   placeholder. */
@media (prefers-reduced-motion: reduce) {
    :root {
        --motion-fast: 0.001s;
        --motion-base: 0.001s;
        --motion-slow: 0.001s;
        --motion-sheet: 0.001s;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.001s !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001s !important;
        scroll-behavior: auto !important;
    }
}
