/* GENERATED by scripts/build-design-css.mjs from docs/design-tokens.json.
 * Do not edit. Edit the JSON and rebuild, or CI will tell you off.
 *
 * Active direction: C · PLASMA
 * The live GladHub brand: plasma purple for navigation and intent, ion blue for measurement. Taken from gh.css, not invented for a mock. Only palette with a genuinely different second accent.
 */

:root {
  /* type */
  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", monospace;
  --t-h1: clamp(31px, 5.6cqw, 46px);
  --t-h2: clamp(25px, 3.9cqw, 33px);
  --t-h3: 17px;
  --t-body: 15px;
  --t-sm: 13.5px;
  --t-xs: 12.5px;
  --t-label: 11px;
  --lh-display: 1.1;
  --lh-body: 1.62;
  --lh-prose: 1.7;
  --track-display: -0.025em;
  --track-body: 0;
  --track-label: 0.07em;

  /* space: a 4px base, and nothing between the steps */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 20px;
  --s-6: 24px;
  --s-8: 32px;
  --s-10: 40px;
  --s-13: 52px;

  /* radius */
  --rad-sharp: 0px;
  --rad-soft: 4px;
  --rad-pill: 999px;
  --rad-large: 13px;

  /* surface highlights that sit on the accent fill, not on a ground */
  --on-acc-sheen: rgba(255,255,255,0.22);
  --on-acc-sheen-hover: rgba(255,255,255,0.28);
  --on-acc-hover: #ffffff;
  --sweep: rgba(255,255,255,0.3);
  --scrim-top: rgba(0,0,0,0.50);
  --scrim-mid: rgba(0,0,0,0.60);
  --scrim-base: rgba(0,0,0,0.93);
  --card-meta: #c9c6d8;
  --glow-rim: rgba(255,255,255,0.55);
  --glow-ring: rgba(255,255,255,0.28);
  --glow-soft: rgba(255,255,255,0.42);
  --glow-shade: rgba(0,0,0,0.90);

  /* motion: one curve, three everyday durations, four earned exceptions */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --t-tint: 0.16s;
  --t-move: 0.38s;
  --t-enter: 0.55s;
  --t-step: 0.055s;
  --t-reveal: 0.7s;
  --t-bloom: 0.9s;
  --t-grow: 1.1s;
  --t-sheen: 0.6s;
  --t-ambient: 34s;

  /* colour: direction C, PLASMA */
  --bg: #08060f;
  --sur: #0f0c1d;
  --inp: #0a0816;
  --hov: #151129;
  --fg: #efedfa;
  --mut: #8b87ad;
  --rank: #7e7e7e;
  --ln: #1d1738;
  --barbg: #1d1738;
  --tick: #0b0917;
  --acc: #8b5cf6;
  --acc-txt: #a78bfa;
  --acc2: #38bdf8;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(190,175,255,.075);
  --spot: rgba(139,92,246,.13);
  --sheen: rgba(190,175,255,.035);
  --bloom: rgba(139,92,246,.3);
}

/* The other directions stay reachable for a side-by-side without a rebuild.
 * Set data-direction on <html> to compare. Neither is the default. */
:root[data-direction="A"] {
  /* APEX: Crimson light on graphite. The accent is a light source, not a text colour. */
  --bg: #0c0c0d;
  --sur: #111113;
  --inp: #08080a;
  --hov: #151518;
  --fg: #f2f2f3;
  --mut: #84878b;
  --rank: #7c7c7c;
  --ln: #242427;
  --barbg: #1c1c1f;
  --tick: #0a0a0b;
  --acc: #e0142f;
  --acc-txt: #e9344c;
  --on-acc: #ffffff;
  --ok: #5aa87f;
  --warn: #c9982c;
  --edge: rgba(255,255,255,.055);
  --spot: rgba(224,20,47,.09);
  --sheen: rgba(255,255,255,.028);
  --bloom: rgba(224,20,47,.24);
  --acc2: #e9344c;
}

:root[data-direction="B"] {
  /* GRID: Blue light over a blueprint. The only palette whose accent is legal as text unmodified. */
  --bg: #0a0c10;
  --sur: #0e1116;
  --inp: #070910;
  --hov: #111722;
  --fg: #e8ecf1;
  --mut: #79828e;
  --rank: #7c7c7c;
  --ln: #1c2129;
  --barbg: #161c25;
  --tick: #080a0e;
  --acc: #4d86ff;
  --acc-txt: #4d86ff;
  --on-acc: #04060a;
  --ok: #3fa87a;
  --warn: #c99a2e;
  --edge: rgba(190,215,255,.07);
  --spot: rgba(77,134,255,.1);
  --sheen: rgba(190,215,255,.03);
  --bloom: rgba(77,134,255,.22);
  --acc2: #4d86ff;
}

/* ── admin theme presets ──────────────────────────────────────────────
 * Generated from docs/theme-presets.json, which is itself derived from the
 * eleven presets in the admin console and audited against every contrast
 * pair before it is written. Set data-theme on <html> to apply one.
 */

:root[data-theme="original"] {
  /* Original: Dark purple & cyan premium */
  --bg: #0a0f1e;
  --sur: #171c2a;
  --inp: #070a14;
  --hov: #232735;
  --fg: #f3effe;
  --mut: #8f8d95;
  --rank: #8f8e93;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(243,239,254,0.08);
  --tick: rgba(243,239,254,0.16);
  --acc: #8b5cf6;
  --acc-txt: #9e77f8;
  --acc2: #22d3ee;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(209,190,251,0.075);
  --spot: rgba(139,92,246,0.13);
  --sheen: rgba(197,174,251,0.035);
  --bloom: rgba(139,92,246,0.3);
}

:root[data-theme="valentine"] {
  /* Valentine: Romantic pink, red & rose */
  --bg: #120010;
  --sur: #1f0e1d;
  --inp: #0c000a;
  --hov: #2a1a28;
  --fg: #fde9ef;
  --mut: #93878b;
  --rank: #8c8587;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(253,233,239,0.08);
  --tick: rgba(253,233,239,0.16);
  --acc: #e91e63;
  --acc-txt: #ed4780;
  --acc2: #ff6090;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(246,165,193,0.075);
  --spot: rgba(233,30,99,0.13);
  --sheen: rgba(244,143,177,0.035);
  --bloom: rgba(233,30,99,0.3);
}

:root[data-theme="summer"] {
  /* Summer Beach: Ocean & tropical warmth */
  --bg: #04111d;
  --sur: #121e29;
  --inp: #030b13;
  --hov: #1d2934;
  --fg: #e6f8fb;
  --mut: #859092;
  --rank: #8a9192;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(230,248,251,0.08);
  --tick: rgba(230,248,251,0.16);
  --acc: #00b4d8;
  --acc-txt: #00b4d8;
  --acc2: #ffd54f;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(153,225,239,0.075);
  --spot: rgba(0,180,216,0.13);
  --sheen: rgba(128,218,236,0.035);
  --bloom: rgba(0,180,216,0.3);
}

:root[data-theme="cyberpunk"] {
  /* Neon Cyberpunk: Electric city with glitch */
  --bg: #0a0a0f;
  --sur: #17171c;
  --inp: #07070a;
  --hov: #232327;
  --fg: #ffeaf2;
  --mut: #94888c;
  --rank: #918a8d;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(255,234,242,0.08);
  --tick: rgba(255,234,242,0.16);
  --acc: #ff2d7b;
  --acc-txt: #ff347f;
  --acc2: #00fff0;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(255,171,202,0.075);
  --spot: rgba(255,45,123,0.13);
  --sheen: rgba(255,150,189,0.035);
  --bloom: rgba(255,45,123,0.3);
}

:root[data-theme="aurora"] {
  /* Aurora Borealis: Northern lights - green/blue */
  --bg: #02080d;
  --sur: #10161a;
  --inp: #010508;
  --hov: #1b2125;
  --fg: #e6fbf9;
  --mut: #859290;
  --rank: #808988;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(230,251,249,0.08);
  --tick: rgba(230,251,249,0.16);
  --acc: #00d9c0;
  --acc-txt: #00d9c0;
  --acc2: #946eff;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(153,240,230,0.075);
  --spot: rgba(0,217,192,0.13);
  --sheen: rgba(128,236,224,0.035);
  --bloom: rgba(0,217,192,0.3);
}

:root[data-theme="sakura"] {
  /* Cherry Blossom: Soft pink spring petals */
  --bg: #1a0f1a;
  --sur: #271c27;
  --inp: #110a11;
  --hov: #312731;
  --fg: #fff8f9;
  --mut: #949090;
  --rank: #949191;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(255,248,249,0.08);
  --tick: rgba(255,248,249,0.16);
  --acc: #ffb7c5;
  --acc-txt: #ffb7c5;
  --acc2: #ff8fab;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(255,226,232,0.075);
  --spot: rgba(255,183,197,0.13);
  --sheen: rgba(255,219,226,0.035);
  --bloom: rgba(255,183,197,0.3);
}

:root[data-theme="halloween"] {
  /* Halloween: Pumpkin orange & midnight */
  --bg: #0a0500;
  --sur: #17130e;
  --inp: #070300;
  --hov: #231e1a;
  --fg: #fff1e8;
  --mut: #948c87;
  --rank: #8a8581;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(255,241,232,0.08);
  --tick: rgba(255,241,232,0.16);
  --acc: #ff7518;
  --acc-txt: #ff7518;
  --acc2: #a264ff;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(255,200,163,0.075);
  --spot: rgba(255,117,24,0.13);
  --sheen: rgba(255,186,140,0.035);
  --bloom: rgba(255,117,24,0.3);
}

:root[data-theme="christmas"] {
  /* Christmas: Festive red, green & gold */
  --bg: #0a0a0a;
  --sur: #171717;
  --inp: #070707;
  --hov: #232323;
  --fg: #fae7ea;
  --mut: #93888a;
  --rank: #90898a;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(250,231,234,0.08);
  --tick: rgba(250,231,234,0.16);
  --acc: #c8102e;
  --acc-txt: #db6477;
  --acc2: #46996b;
  --on-acc: #ffffff;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(233,159,171,0.075);
  --spot: rgba(200,16,46,0.13);
  --sheen: rgba(228,136,151,0.035);
  --bloom: rgba(200,16,46,0.3);
}

:root[data-theme="lunar"] {
  /* Lunar New Year: Imperial red & gold prosperity */
  --bg: #0a0000;
  --sur: #170e0e;
  --inp: #070000;
  --hov: #231a1a;
  --fg: #ffe6eb;
  --mut: #948588;
  --rank: #8d8385;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(255,230,235,0.08);
  --tick: rgba(255,230,235,0.16);
  --acc: #ff0033;
  --acc-txt: #ff224e;
  --acc2: #ffd700;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(255,153,173,0.075);
  --spot: rgba(255,0,51,0.13);
  --sheen: rgba(255,128,153,0.035);
  --bloom: rgba(255,0,51,0.3);
}

:root[data-theme="galaxy"] {
  /* Galaxy Cosmos: Deep space nebula & stars */
  --bg: #000a14;
  --sur: #0e1721;
  --inp: #00070d;
  --hov: #1a232c;
  --fg: #f2eafe;
  --mut: #8c8893;
  --rank: #8d8a91;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(242,234,254,0.08);
  --tick: rgba(242,234,254,0.16);
  --acc: #7b2ff7;
  --acc-txt: #a36df9;
  --acc2: #38bdf8;
  --on-acc: #ffffff;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(202,172,252,0.075);
  --spot: rgba(123,47,247,0.13);
  --sheen: rgba(189,151,251,0.035);
  --bloom: rgba(123,47,247,0.3);
}

:root[data-theme="forest"] {
  /* Midnight Forest: Autumn deep-green & amber */
  --bg: #06140b;
  --sur: #142118;
  --inp: #040d07;
  --hov: #1f2c23;
  --fg: #eff5f0;
  --mut: #8d908d;
  --rank: #8e908e;
  --ln: rgba(255,255,255,0.085);
  --barbg: rgba(239,245,240,0.08);
  --tick: rgba(239,245,240,0.16);
  --acc: #5d9b6a;
  --acc-txt: #609d6c;
  --acc2: #a3e635;
  --on-acc: #08060f;
  --ok: #34d399;
  --warn: #fbbf24;
  --edge: rgba(190,215,195,0.075);
  --spot: rgba(93,155,106,0.13);
  --sheen: rgba(174,205,181,0.035);
  --bloom: rgba(93,155,106,0.3);
}

/* Reduced motion means arriving without the journey, never arriving at
 * nothing. Durations collapse; end states are still reached. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --t-tint: 0.001s;
    --t-move: 0.001s;
    --t-enter: 0.001s;
    --t-step: 0.001s;
    --t-reveal: 0.001s;
    --t-bloom: 0.001s;
    --t-grow: 0.001s;
    --t-sheen: 0.001s;
    --t-ambient: 0.001s;
  }

  /* And the same for every transition that never asked for a token.
   *
   * Collapsing the tokens only reaches the rules that spend one. A rule that
   * writes its own seconds keeps them, and plenty did: every button on the
   * site moved its colours and its transform over a literal 120ms, the
   * mobile sheet slid over 260ms, and the language and account menus opened
   * over 160ms. All of that kept running for people who had asked the
   * operating system for no animation at all.
   *
   * Animations are not touched here. shell.css already ends with
   * `*, *::before, *::after { animation: none !important }` and handles the
   * one animation whose end state that would strand, so saying it a second
   * time in a second file with a different answer is how a rule ends up
   * being two rules nobody can reason about.
   *
   * Duration and delay, not `transition: none`. A transition that is
   * switched off still applies its end state, but a near-zero duration says
   * the same thing while leaving the property list alone for anything that
   * reads it back. Delay is included because a delayed transition is a
   * quarter-second of nothing happening, which is the same complaint. */
  *, *::before, *::after {
    transition-duration: 0.001s !important;
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}
