/* tokens.css — the design layer. Every other stylesheet reads from here and defines no colour,
   size, radius or duration of its own.

   Load order matters and is fixed: tokens.css, then site.css, then the page's own sheet, then a
   skin. Nothing below this file may introduce a raw colour; a value that is not in here yet is a
   token that has not been named yet.

   ── The skin contract ──────────────────────────────────────────────────────────────────────────
   A skin is one file that re-declares tokens. It never writes a component rule, so a skin cannot
   break a layout — the worst a bad skin can do is look wrong.

     :root[data-skin="matrix"]                     { --bg: …; --accent: …; }   /* the skin's light */
     :root[data-skin="matrix"][data-theme="dark"]  { --bg: …; }                /* its dark, if any */
     @media (prefers-color-scheme: dark) {
       :root[data-skin="matrix"]:not([data-theme="light"]) { --bg: …; }
     }

   Specificity is the whole reason for the `:root` prefix. This file sets dark at
   `:root[data-theme="dark"]` — (0,2,0). A bare `[data-skin="matrix"]` is (0,1,0) and would lose to
   it, so every skin selector carries `:root` to match, and wins on order because a skin file is
   always loaded after this one. A skin that wants to follow the system theme uses all three blocks;
   a skin that is dark whatever the OS says (Matrix, After Dark) needs only the first.

   Holo is the default skin and is these values — there is no holo.css, and `data-skin` is absent
   until somebody chooses otherwise. That keeps the bundle honest: the skin nobody picked costs
   nothing. See docs/design/skins.md.

   `prefers-color-scheme` is honoured unless `data-theme` says otherwise; theme.js sets both
   attributes before first paint so neither ever flashes. */

@font-face {
  font-family: "Fraunces";
  src: url("../fonts/fraunces.woff2") format("woff2");
  font-weight: 500 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fraunces";
  src: url("../fonts/fraunces-italic.woff2") format("woff2");
  font-weight: 500;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("../fonts/jetbrains-mono.woff2") format("woff2");
  font-weight: 400 600;
  font-display: swap;
}

:root {
  /* ── Surfaces and ink ── */
  --bg: #fbf7f4;
  --surface: #ffffff;
  --text: #1d1520;
  --muted: #6b5d6e;
  --border: #eadfe3;

  /* ── Brand ── */
  --accent: #c2185b;
  --accent-2: #7c3aed;
  --accent-soft: #fce4ee;
  /* Ink on a solid --accent fill. A skin with a pale accent overrides this to something dark;
     six rules across four sheets used to hardcode #fff and would have been unreadable. */
  --on-accent: #ffffff;

  /* ── State ── */
  --good: #0f8a5f;
  --good-ink: #08533a;  /* text on a --good tint: --good itself is only 3.5:1 there, under the 4.5:1 rule */

  /* ── Light ──
     --glow is the page's ambient wash; --glow-strong is what an element glows with when it is the
     thing you are meant to look at. Both are the accent at low alpha so a skin gets them free. */
  --glow: rgba(194, 24, 91, 0.10);
  --glow-strong: rgba(194, 24, 91, 0.22);
  --shadow: 0 1px 2px rgba(29, 21, 32, 0.05), 0 8px 24px rgba(29, 21, 32, 0.05);
  --shadow-lift: 0 2px 4px rgba(29, 21, 32, 0.06), 0 16px 40px rgba(29, 21, 32, 0.08);
  --scrim: rgba(10, 6, 12, 0.45);  /* behind a modal, in both themes: a scrim is darkness, not a colour */

  /* ── Type ──
     Three families and one fluid scale. The clamps are the sizes the pages already shipped with,
     named rather than repeated: --text-4xl is the h1, --text-lg is the lede. */
  --serif: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --text-xs: 0.74rem;
  --text-sm: 0.85rem;
  --text-base: 1rem;
  --text-lg: clamp(1.05rem, 2.2vw, 1.2rem);
  --text-xl: clamp(1.12rem, 2.4vw, 1.3rem);
  --text-2xl: clamp(1.4rem, 3.2vw, 1.8rem);
  --text-3xl: clamp(1.8rem, 4.6vw, 2.6rem);
  --text-4xl: clamp(2.3rem, 6.4vw, 4.1rem);

  --leading-tight: 1.04;
  --leading-snug: 1.3;
  --leading-body: 1.6;
  --tracking-tight: -0.025em;
  --tracking-snug: -0.01em;

  /* ── Space ── 4px base, and the gaps the site already uses. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.4rem;
  --space-6: 2rem;
  --space-7: 2.75rem;
  --space-8: 4rem;

  /* ── Shape ── */
  --radius-sm: 6px;
  --radius: 11px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  /* ── Motion ──
     Durations are named by intent, not by length, so "fast" stays fast if the numbers change.
     Everything animated with these moves only transform, opacity or filter (PLAN.md D8). */
  --dur-fast: 0.15s;
  --dur: 0.3s;
  --dur-slow: 0.6s;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);

  /* ── Effects ──
     The knobs the effects kit reads (effects.css, fx.js). A skin retunes an effect by setting
     these; it never rewrites the keyframes. Set an opacity to 0 and the effect is off for that
     skin without any JS knowing about it. */
  --fx-scanline-color: 0, 0, 0;   /* r,g,b — a dark skin may want the lines drawn in light instead */
  --fx-scanline-opacity: 0.05;
  --fx-scanline-size: 3px;
  --fx-shimmer-opacity: 0.55;
  --fx-shimmer-dur: 6s;
  --fx-glitch-offset: 2px;
  --fx-rain-color: 194, 24, 91;   /* r,g,b — fx.js reads it and sets its own alpha per column */
  --fx-rain-opacity: 0.22;

  --layout-max: 980px;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #140f17;
    --surface: #1d1621;
    --text: #f4ecef;
    --muted: #a898aa;
    --border: #33283a;
    --accent: #ff5c9a;
    --accent-2: #a78bfa;
    --accent-soft: #3a1a2b;
    --on-accent: #1d1520;  /* the dark accent is light: black ink on it, not white */
    --good: #3ddc97;
    --good-ink: #5fe8ab;
    --glow: rgba(255, 92, 154, 0.12);
    --glow-strong: rgba(255, 92, 154, 0.26);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.25);
    --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.35), 0 16px 40px rgba(0, 0, 0, 0.32);
    --scrim: rgba(0, 0, 0, 0.6);
    --fx-scanline-opacity: 0.07;
    --fx-rain-color: 255, 92, 154;
    --fx-rain-opacity: 0.3;
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #140f17;
  --surface: #1d1621;
  --text: #f4ecef;
  --muted: #a898aa;
  --border: #33283a;
  --accent: #ff5c9a;
  --accent-2: #a78bfa;
  --accent-soft: #3a1a2b;
  --on-accent: #1d1520;
  --good: #3ddc97;
  --good-ink: #5fe8ab;
  --glow: rgba(255, 92, 154, 0.12);
  --glow-strong: rgba(255, 92, 154, 0.26);
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 8px 24px rgba(0, 0, 0, 0.25);
  --shadow-lift: 0 2px 4px rgba(0, 0, 0, 0.35), 0 16px 40px rgba(0, 0, 0, 0.32);
  --scrim: rgba(0, 0, 0, 0.6);
  --fx-scanline-opacity: 0.07;
  --fx-rain-color: 255, 92, 154;
  --fx-rain-opacity: 0.3;
  color-scheme: dark;
}
