/* ==========================================================================
   tokens.css — Prioton Web design tokens
   --------------------------------------------------------------------------
   Load order:  tokens.css -> base.css -> layout.css -> calculator.css

   THEME CONTRACT
   ----------------------------------------------------------------------
   Every colour token is defined on bare :root (the complete LIGHT palette).
   Nothing is defined *only* inside a media query.

     :root                                    complete light palette
     @media (prefers-color-scheme: dark)
       :root:not([data-theme="light"])        system dark, unless user forced light
     :root[data-theme="dark"]                 explicit toggle wins in both directions

   SITE IDENTITY CONTRACT
   ----------------------------------------------------------------------
   The raw accent ramps (--a-50 ... --a-900) are theme-INDEPENDENT: a hue ramp
   is a hue ramp. The site config sets  <html data-site="datetime|fitness|grades">
   which chooses WHICH ramp --a-* points at. The light/dark blocks then only
   decide WHICH STEP of that ramp becomes --accent. That keeps this file at
   3 site blocks + 2 theme blocks instead of 3x3 = 9 permutations.

     <html data-site="fitness" data-theme="dark">

   Default (no data-site) = datetime.
   ========================================================================== */

:root {
  color-scheme: light dark;

  /* ---------------------------------------------------------------------
     TYPE — system stacks only. No webfont CDN: CSP-blocked, and a webfont
     is a render-blocking round trip on a page whose entire job is to show
     one number fast.
     --------------------------------------------------------------------- */
  --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji",
    "Segoe UI Emoji";
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono",
    "Segoe UI Mono", Menlo, Consolas, "Liberation Mono", monospace;

  /* Numeric display: same stack, but every consumer sets
     font-variant-numeric: tabular-nums so digits do not jitter on recalc. */
  --font-num: var(--font-sans);

  /* Type scale — 1.200 minor third, anchored at 16px.
     Only the two display sizes are fluid; body text stays fixed so line
     length stays predictable. */
  --fs-2xs: 0.75rem;    /* 12px  legal / ad label            */
  --fs-xs: 0.8125rem;   /* 13px  meta, breadcrumbs           */
  --fs-sm: 0.875rem;    /* 14px  secondary results, captions */
  --fs-base: 1rem;      /* 16px  body, form controls (16px stops iOS zoom) */
  --fs-md: 1.0625rem;   /* 17px  article prose               */
  --fs-lg: 1.125rem;    /* 18px  lead paragraph              */
  --fs-xl: 1.25rem;     /* 20px  h3                          */
  --fs-2xl: 1.5rem;     /* 24px  h2                          */
  --fs-3xl: clamp(1.625rem, 1.25rem + 1.9vw, 2.125rem);  /* h1 */
  --fs-result: clamp(2.25rem, 1.1rem + 8.4vw, 3.75rem);  /* THE answer */
  /* Long textual answers ("Saturday, 17 September 2026"). Ceiling is 2.5rem,
     not 2rem: at 2rem it rendered SMALLER than the h1 on desktop, which
     inverts the hierarchy the whole page is built around. */
  --fs-result-sm: clamp(1.5rem, 0.9rem + 3.2vw, 2.5rem);

  --lh-tight: 1.15;
  --lh-snug: 1.3;
  --lh-normal: 1.55;
  --lh-prose: 1.7;

  --tracking-tight: -0.02em;
  --tracking-normal: 0;
  --tracking-wide: 0.04em;
  --tracking-caps: 0.08em;

  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;

  /* ---------------------------------------------------------------------
     SPACE — 4px base
     --------------------------------------------------------------------- */
  --sp-0: 0;
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.25rem;
  --sp-6: 1.5rem;
  --sp-8: 2rem;
  --sp-10: 2.5rem;
  --sp-12: 3rem;
  --sp-16: 4rem;
  --sp-20: 5rem;

  /* ---------------------------------------------------------------------
     MEASURE
     --------------------------------------------------------------------- */
  --w-page: 72rem;    /* outer shell incl. sidebar */
  --w-main: 46rem;    /* main column               */
  --w-prose: 40rem;   /* ~68ch article body        */
  --w-tool: 100%;     /* calculator fills its column */
  --gutter: var(--sp-4);
  --gutter-lg: var(--sp-8);

  /* ---------------------------------------------------------------------
     RADII / BORDER
     --------------------------------------------------------------------- */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 20px;
  --r-pill: 999px;
  --bw: 1px;
  --bw-thick: 2px;

  /* ---------------------------------------------------------------------
     MOTION — everything is suppressed under prefers-reduced-motion in base.css
     --------------------------------------------------------------------- */
  --ease: cubic-bezier(0.2, 0, 0, 1);
  --dur-fast: 90ms;
  --dur: 160ms;

  /* ---------------------------------------------------------------------
     LAYERS
     --------------------------------------------------------------------- */
  --z-base: 0;
  --z-sticky: 20;
  --z-header: 30;
  --z-toast: 60;

  /* ---------------------------------------------------------------------
     AD SLOT RESERVATIONS — see layout.css and Design-System.md.
     These are the *hard reserved* box heights. They never change after
     load, so an ad that fills, fails, or is blocked all produce CLS = 0.
     --------------------------------------------------------------------- */
  --ad-label-h: 0.875rem;          /* the "Advertisement" caption line */
  --ad-gap: var(--sp-2);
  --ad-h-rect: 250px;              /* 300x250 medium rectangle          */
  --ad-h-rect-lg: 280px;           /* 336x280 large rectangle           */
  --ad-h-leaderboard: 90px;        /* 728x90 / 970x90                   */
  --ad-h-skyscraper: 600px;        /* 300x600 half-page, desktop only   */
  --ad-w-rect: 300px;
  --ad-w-rect-lg: 336px;
  --ad-w-skyscraper: 300px;

  /* =====================================================================
     ACCENT RAMPS — theme independent. data-site picks one into --a-*.
     ===================================================================== */

  /* MERIDIAN — datetime. Petrol / marine teal, hue ~193.
     Reference: marine chronometer dials, instrument panels. Cold, exact,
     zero emotional temperature. This is a site people use to settle a
     factual dispute about a date. */
  --meridian-50:  #eaf6f8;
  --meridian-100: #cfeaef;
  --meridian-200: #a3d7e0;
  --meridian-300: #6bc0ce;
  --meridian-400: #35a3b6;
  --meridian-500: #17869b;
  --meridian-600: #0e6c81;
  --meridian-700: #0b5566;
  --meridian-800: #08404e;
  --meridian-900: #06303a;

  /* EMBER — fitness. Vermilion / heat, hue ~18.
     Exertion and burn. Deliberately NOT the muted-terracotta-on-cream look:
     the ground stays cool neutral grey, the accent is high-chroma signal. */
  --ember-50:  #fff1ec;
  --ember-100: #ffdfd3;
  --ember-200: #ffc0aa;
  --ember-300: #ff9e7b;
  --ember-400: #f97542;
  --ember-500: #e2551f;
  --ember-600: #c24313;
  --ember-700: #9e360f;
  --ember-800: #7c2a0c;
  --ember-900: #5c1f09;

  /* GARNET — grades. Deep crimson-plum, hue ~340.
     Academic seal wax, red pen, university crest. NOT green: green/red on a
     grade page reads as pass/fail and would imply a verdict on the user's
     mark, which we never do. */
  --garnet-50:  #fff0f5;
  --garnet-100: #fcdde8;
  --garnet-200: #f7bacf;
  --garnet-300: #ef8fb0;
  --garnet-400: #e05283;
  --garnet-500: #c62c61;
  --garnet-600: #a81e4e;
  --garnet-700: #8a1740;
  --garnet-800: #6c1132;
  --garnet-900: #500b25;

  /* NEUTRAL — cool grey with a trace of blue so it sits under all three
     accents without going muddy against the warm ones. */
  --n-0:   #ffffff;
  --n-25:  #fafbfc;
  --n-50:  #f4f6f8;
  --n-100: #eaedf1;
  --n-200: #dde2e8;
  --n-300: #c7ced8;
  --n-400: #9aa4b2;
  --n-500: #6b7684;
  --n-600: #55606e;
  --n-700: #3c4552;
  --n-800: #262d38;
  --n-850: #1d232c;
  --n-900: #161a21;
  --n-950: #0e1116;

  /* STATUS — fixed hues, never swapped by site. Chosen to stay legible
     next to all three accents. */
  --status-ok-600: #0e7c57;
  --status-ok-300: #58d3a4;
  --status-warn-600: #a3600a;
  --status-warn-300: #f0b95c;
  --status-err-600: #b3261e;
  --status-err-300: #ff9c92;

  /* ---------------------------------------------------------------------
     ACCENT SELECTION — default site = datetime
     --------------------------------------------------------------------- */
  --a-50:  var(--meridian-50);
  --a-100: var(--meridian-100);
  --a-200: var(--meridian-200);
  --a-300: var(--meridian-300);
  --a-400: var(--meridian-400);
  --a-500: var(--meridian-500);
  --a-600: var(--meridian-600);
  --a-700: var(--meridian-700);
  --a-800: var(--meridian-800);
  --a-900: var(--meridian-900);

  /* =====================================================================
     SEMANTIC TOKENS — LIGHT (complete; the baseline every theme overrides)
     ===================================================================== */
  --bg: var(--n-50);
  --bg-elevated: var(--n-0);
  --surface: var(--n-0);
  --surface-2: var(--n-25);
  --surface-sunken: var(--n-100);
  --surface-inverse: var(--n-900);

  --text: #14181f;
  --text-strong: #0a0d12;
  --text-muted: var(--n-600);
  --text-subtle: var(--n-500);
  --text-inverse: var(--n-25);
  --text-on-accent: #ffffff;

  --border: var(--n-200);
  --border-strong: var(--n-300);
  --border-input: var(--n-300);
  --divider: var(--n-100);

  --accent: var(--a-700);         /* accent as TEXT / link on --surface   */
  --accent-hover: var(--a-800);
  --accent-fill: var(--a-600);    /* accent as a BUTTON BACKGROUND        */
  --accent-fill-hover: var(--a-700);
  --accent-ink: #ffffff;          /* text drawn on --accent-fill          */
  --accent-soft: var(--a-50);     /* tinted panel                          */
  --accent-soft-border: var(--a-200);
  --accent-line: var(--a-400);    /* rules, underlines, chart strokes      */

  --result-bg: var(--a-800);      /* the hero result card                  */
  --result-bg-2: var(--a-900);
  --result-text: #ffffff;
  --result-text-muted: var(--a-200);
  --result-border: var(--a-700);

  --ok: var(--status-ok-600);
  --warn: var(--status-warn-600);
  --err: var(--status-err-600);

  --focus-ring: var(--a-600);
  --focus-ring-contrast: #ffffff; /* second ring so focus survives on any bg */

  --ad-bg: var(--n-100);
  --ad-border: var(--n-200);
  /* n-600 not n-500: the label is 12px uppercase and must clear 4.5:1 on both
     --bg and --ad-bg. n-500 measured 3.93:1 and failed. */
  --ad-label: var(--n-600);

  --shadow-sm: 0 1px 2px rgba(14, 17, 22, 0.06),
               0 1px 1px rgba(14, 17, 22, 0.04);
  --shadow-md: 0 2px 4px rgba(14, 17, 22, 0.05),
               0 6px 16px -6px rgba(14, 17, 22, 0.12);
  --shadow-lg: 0 4px 8px rgba(14, 17, 22, 0.05),
               0 18px 40px -12px rgba(14, 17, 22, 0.18);
  --shadow-result: 0 10px 30px -12px rgba(6, 20, 28, 0.45);

  --selection-bg: var(--a-100);
  --selection-text: var(--a-900);
}

/* -------------------------------------------------------------------------
   SITE IDENTITY — pick the ramp. Theme independent.
   ------------------------------------------------------------------------- */
:root[data-site="datetime"] {
  --a-50:  var(--meridian-50);
  --a-100: var(--meridian-100);
  --a-200: var(--meridian-200);
  --a-300: var(--meridian-300);
  --a-400: var(--meridian-400);
  --a-500: var(--meridian-500);
  --a-600: var(--meridian-600);
  --a-700: var(--meridian-700);
  --a-800: var(--meridian-800);
  --a-900: var(--meridian-900);
}

:root[data-site="fitness"] {
  --a-50:  var(--ember-50);
  --a-100: var(--ember-100);
  --a-200: var(--ember-200);
  --a-300: var(--ember-300);
  --a-400: var(--ember-400);
  --a-500: var(--ember-500);
  --a-600: var(--ember-600);
  --a-700: var(--ember-700);
  --a-800: var(--ember-800);
  --a-900: var(--ember-900);
}

:root[data-site="grades"] {
  --a-50:  var(--garnet-50);
  --a-100: var(--garnet-100);
  --a-200: var(--garnet-200);
  --a-300: var(--garnet-300);
  --a-400: var(--garnet-400);
  --a-500: var(--garnet-500);
  --a-600: var(--garnet-600);
  --a-700: var(--garnet-700);
  --a-800: var(--garnet-800);
  --a-900: var(--garnet-900);
}

/* -------------------------------------------------------------------------
   DARK — system preference, unless the user explicitly forced light.
   Only tokens are redefined. No component rules live here.
   ------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: var(--n-950);
    --bg-elevated: var(--n-900);
    --surface: var(--n-900);
    --surface-2: var(--n-850);
    --surface-sunken: #0a0d12;
    --surface-inverse: var(--n-50);

    --text: #e8ecf2;
    --text-strong: #f7f9fb;
    --text-muted: #a0aab8;
    --text-subtle: #808b9a;
    --text-inverse: var(--n-900);
    --text-on-accent: var(--a-900);

    --border: #262c36;
    --border-strong: #39414e;
    --border-input: #3d4551;
    --divider: #20262f;

    --accent: var(--a-300);
    --accent-hover: var(--a-200);
    --accent-fill: var(--a-300);
    --accent-fill-hover: var(--a-200);
    --accent-ink: var(--a-900);
    --accent-soft: color-mix(in srgb, var(--a-500) 14%, var(--n-900));
    --accent-soft-border: color-mix(in srgb, var(--a-400) 30%, var(--n-900));
    --accent-line: var(--a-400);

    --result-bg: color-mix(in srgb, var(--a-800) 55%, var(--n-950));
    --result-bg-2: color-mix(in srgb, var(--a-900) 60%, var(--n-950));
    --result-text: #f7f9fb;
    --result-text-muted: var(--a-200);
    --result-border: color-mix(in srgb, var(--a-500) 45%, var(--n-900));

    --ok: var(--status-ok-300);
    --warn: var(--status-warn-300);
    --err: var(--status-err-300);

    --focus-ring: var(--a-300);
    --focus-ring-contrast: #0a0d12;

    --ad-bg: #171c24;
    --ad-border: #262c36;
    --ad-label: #808b9a;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.4),
                 0 8px 20px -8px rgba(0, 0, 0, 0.6);
    --shadow-lg: 0 4px 10px rgba(0, 0, 0, 0.45),
                 0 22px 48px -16px rgba(0, 0, 0, 0.7);
    --shadow-result: 0 12px 34px -16px rgba(0, 0, 0, 0.85);

    --selection-bg: color-mix(in srgb, var(--a-500) 40%, var(--n-900));
    --selection-text: #f7f9fb;
  }
}

/* -------------------------------------------------------------------------
   DARK — explicit. Identical body; declared last so the toggle wins whatever
   the OS says, in both directions.
   ------------------------------------------------------------------------- */
:root[data-theme="dark"] {
  --bg: var(--n-950);
  --bg-elevated: var(--n-900);
  --surface: var(--n-900);
  --surface-2: var(--n-850);
  --surface-sunken: #0a0d12;
  --surface-inverse: var(--n-50);

  --text: #e8ecf2;
  --text-strong: #f7f9fb;
  --text-muted: #a0aab8;
  --text-subtle: #808b9a;
  --text-inverse: var(--n-900);
  --text-on-accent: var(--a-900);

  --border: #262c36;
  --border-strong: #39414e;
  --border-input: #3d4551;
  --divider: #20262f;

  --accent: var(--a-300);
  --accent-hover: var(--a-200);
  --accent-fill: var(--a-300);
  --accent-fill-hover: var(--a-200);
  --accent-ink: var(--a-900);
  --accent-soft: color-mix(in srgb, var(--a-500) 14%, var(--n-900));
  --accent-soft-border: color-mix(in srgb, var(--a-400) 30%, var(--n-900));
  --accent-line: var(--a-400);

  --result-bg: color-mix(in srgb, var(--a-800) 55%, var(--n-950));
  --result-bg-2: color-mix(in srgb, var(--a-900) 60%, var(--n-950));
  --result-text: #f7f9fb;
  --result-text-muted: var(--a-200);
  --result-border: color-mix(in srgb, var(--a-500) 45%, var(--n-900));

  --ok: var(--status-ok-300);
  --warn: var(--status-warn-300);
  --err: var(--status-err-300);

  --focus-ring: var(--a-300);
  --focus-ring-contrast: #0a0d12;

  --ad-bg: #171c24;
  --ad-border: #262c36;
  --ad-label: #808b9a;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.4),
               0 8px 20px -8px rgba(0, 0, 0, 0.6);
  --shadow-lg: 0 4px 10px rgba(0, 0, 0, 0.45),
               0 22px 48px -16px rgba(0, 0, 0, 0.7);
  --shadow-result: 0 12px 34px -16px rgba(0, 0, 0, 0.85);

  --selection-bg: color-mix(in srgb, var(--a-500) 40%, var(--n-900));
  --selection-text: #f7f9fb;
}

/* Explicit light: bare :root already holds the full light palette, so this
   block only needs to restore the UA colour-scheme hint. */
:root[data-theme="light"] {
  color-scheme: light;
}
:root[data-theme="dark"] {
  color-scheme: dark;
}

/* color-mix() fallback: if unsupported, these flat values apply and the dark
   theme still renders correctly (slightly less tuned). */
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      --accent-soft: var(--n-850);
      --accent-soft-border: var(--n-800);
      --result-bg: var(--a-900);
      --result-bg-2: #0a0d12;
      --result-border: var(--a-800);
      --selection-bg: var(--a-800);
    }
  }
  :root[data-theme="dark"] {
    --accent-soft: var(--n-850);
    --accent-soft-border: var(--n-800);
    --result-bg: var(--a-900);
    --result-bg-2: #0a0d12;
    --result-border: var(--a-800);
    --selection-bg: var(--a-800);
  }
}
