/* Maths Made Easy — the five dark themes.
 *
 * Promoted out of the untracked developer-review preview (dev-themes.css,
 * reachable only when DEVELOPER_REVIEW_MODE was on) into the real theme
 * system. Same mechanism as Daylight and Sunrise: attribute on <html>, tokens
 * redefined, picker entry in theme.js. dev_review.py and its gate are
 * untouched and still do nothing.
 *
 *   [data-theme="learning"]   Student Learning World
 *   [data-theme="galaxy"]     Mathematics Galaxy
 *   [data-theme="nature"]     Nature Explorer
 *   [data-theme="classroom"]  Interactive Classroom
 *   [data-theme="raxenor"]    Deep Focus
 *
 * WHAT THE PREVIEW SHIPPED, AND WHAT WAS MISSING
 *   The preview set the 33 colour-bearing tokens, which is why it looked
 *   finished. It did not set --surface or --accent (used with hardcoded dark
 *   fallbacks, declared nowhere), nor the three .fx-flow tokens, and it did
 *   nothing about the colour that is painted literally rather than through a
 *   token. Those literals are all Midnight's own navy: the page ground, the
 *   modal, the toast, the game arena and the billing cards. On a dark theme
 *   that does not read as "broken" the way it did on Daylight — it reads as
 *   Midnight navy sitting inside a green or purple theme, which is why a
 *   token-table audit would pass it again. Section 2 fixes that.
 *
 * These are dark themes, so the translucent-WHITE surface tokens that had to
 * be inverted for the light themes are correct here as they stand.
 */

/* ════════════════════════════════════════════════════════════════════════
   1. TOKENS
   Colour only. The preview also re-pointed --radius and --radius-sm, so each
   theme changed the SHAPE of every card and button as well as its hue. That is
   more than a theme, and it left the eight themes disagreeing about the
   geometry of the same UI, so those two declarations are gone: all eight now
   inherit the shipped radii. --font, --font-display, --safe-top and
   --safe-bottom were never touched, matching Daylight and Sunrise.
   ════════════════════════════════════════════════════════════════════════ */

/* ── Student Learning World — bright, friendly, modern ─────────────────── */
html[data-theme="learning"] {
  --bg-deep: #0d1b2a;
  --bg-mid: #16324a;
  --bg-card: rgba(255, 255, 255, 0.09);
  --bg-card-hover: rgba(255, 255, 255, 0.15);
  --text: #f7fbff;
  --text-muted: #b0c4d8;

  /* Was #4cc4ff. The Listen button puts this colour on its own 12% tint,
     which measured 4.49:1 — a hair under. Lightened until that real pairing
     clears, which also lifts every other accent-on-tint pair. */
  --accent-tutorial: #63cdff;
  --accent-practice: #4fd1a5;
  --accent-test: #ffc861;
  --accent-games: #b08bff;
  --accent-progress: #ff8fab;
  --accent-gold: #ffc861;
  --accent-cyan: #4cc4ff;
  --accent-math: #6fd0ff;

  --gradient-brand: linear-gradient(135deg, #4cc4ff 0%, #4fd1a5 46%, #ffc861 100%);
  --gradient-surface: linear-gradient(145deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.04));
  --gradient-hero: linear-gradient(145deg, rgba(76, 196, 255, 0.2) 0%, rgba(79, 209, 165, 0.11) 45%, rgba(255, 200, 97, 0.07) 100%);
  --shadow: 0 18px 46px rgba(3, 12, 22, 0.5);
  --shadow-glow: 0 0 42px rgba(76, 196, 255, 0.2);
  --math-grid-color: rgba(76, 196, 255, 0.07);
  --math-grid-major: rgba(76, 196, 255, 0.12);

  --surface-a05: rgba(255, 255, 255, 0.06);
  --surface-a06: rgba(255, 255, 255, 0.07);
  --surface-a08: rgba(255, 255, 255, 0.1);
  --surface-a10: rgba(255, 255, 255, 0.12);
  --surface-a12: rgba(255, 255, 255, 0.15);
  --shadow-a20: rgba(3, 12, 22, 0.26);
  --shadow-a25: rgba(3, 12, 22, 0.32);
  --accent-a15: rgba(76, 196, 255, 0.17);
  --accent-a20: rgba(76, 196, 255, 0.23);
  --accent-a35: rgba(76, 196, 255, 0.38);
  --accent-a40: rgba(76, 196, 255, 0.44);
  --accent-a50: rgba(76, 196, 255, 0.54);

  /* Declared nowhere on :root, used with a hardcoded dark fallback. The
     preview never set them, so the milestone card stayed Midnight's #1a1f3a. */
  --surface: #16324a;
  --accent: #4cc4ff;

  /* The page ground beneath the scene. See section 2. */
  --bg-top: #070f18;
  --bg-top-2: #0a1420;

  --pip-grad-start: #4cc4ff;
  --pip-grad-mid: #7fb3ff;
  --pip-grad-end: #ff9ec2;
  --pip-accent: #ffc861;
  --pip-face: #08131f;
}

/* ── Mathematics Galaxy — deep space, glow ─────────────────────────────── */
html[data-theme="galaxy"] {
  --bg-deep: #05030e;
  --bg-mid: #150a2e;
  --bg-card: rgba(160, 140, 255, 0.1);
  --bg-card-hover: rgba(160, 140, 255, 0.17);
  --text: #f6f3ff;
  --text-muted: #b6acdf;

  /* Was #8b7bff, which measured 3.93:1 on its own tint behind the Listen
     button — the one genuine contrast failure among the five. Lightened
     within the same violet rather than re-hued. */
  --accent-tutorial: #a394ff;
  --accent-practice: #46e5c8;
  --accent-test: #ffd166;
  --accent-games: #ff6bd6;
  --accent-progress: #ff8fa3;
  --accent-gold: #ffd166;
  --accent-cyan: #46e5c8;
  --accent-math: #9d8cff;

  --gradient-brand: linear-gradient(135deg, #8b7bff 0%, #ff6bd6 45%, #46e5c8 100%);
  --gradient-surface: linear-gradient(145deg, rgba(160, 140, 255, 0.14), rgba(160, 140, 255, 0.04));
  --gradient-hero: linear-gradient(145deg, rgba(139, 123, 255, 0.24) 0%, rgba(255, 107, 214, 0.13) 45%, rgba(70, 229, 200, 0.07) 100%);
  --shadow: 0 18px 52px rgba(0, 0, 0, 0.66);
  --shadow-glow: 0 0 50px rgba(139, 123, 255, 0.3);
  --math-grid-color: rgba(139, 123, 255, 0.08);
  --math-grid-major: rgba(139, 123, 255, 0.14);

  --surface-a05: rgba(180, 165, 255, 0.06);
  --surface-a06: rgba(180, 165, 255, 0.08);
  --surface-a08: rgba(180, 165, 255, 0.1);
  --surface-a10: rgba(180, 165, 255, 0.13);
  --surface-a12: rgba(180, 165, 255, 0.16);
  --shadow-a20: rgba(0, 0, 0, 0.34);
  --shadow-a25: rgba(0, 0, 0, 0.4);
  --accent-a15: rgba(139, 123, 255, 0.2);
  --accent-a20: rgba(139, 123, 255, 0.26);
  --accent-a35: rgba(139, 123, 255, 0.42);
  --accent-a40: rgba(139, 123, 255, 0.48);
  --accent-a50: rgba(139, 123, 255, 0.58);

  --surface: #1a0f38;
  --accent: #8b7bff;

  --bg-top: #030109;
  --bg-top-2: #08041a;

  --pip-grad-start: #8b7bff;
  --pip-grad-mid: #c08cff;
  --pip-grad-end: #ff6bd6;
  --pip-accent: #ffd166;
  --pip-face: #0b0620;
}

/* ── Nature Explorer — matte surfaces, calm ────────────────────────────── */
html[data-theme="nature"] {
  --bg-deep: #071410;
  --bg-mid: #0e2a1c;
  --bg-card: rgba(150, 235, 185, 0.09);
  --bg-card-hover: rgba(150, 235, 185, 0.16);
  --text: #f2fbf5;
  --text-muted: #aecfba;

  --accent-tutorial: #5fd88a;
  --accent-practice: #7fd4ff;
  --accent-test: #ffcf5c;
  --accent-games: #c9a7ff;
  --accent-progress: #ff9a76;
  --accent-gold: #ffcf5c;
  --accent-cyan: #7fd4ff;
  --accent-math: #7ee0a4;

  --gradient-brand: linear-gradient(135deg, #5fd88a 0%, #7fd4ff 48%, #ffcf5c 100%);
  --gradient-surface: linear-gradient(145deg, rgba(150, 235, 185, 0.13), rgba(150, 235, 185, 0.04));
  --gradient-hero: linear-gradient(145deg, rgba(95, 216, 138, 0.2) 0%, rgba(127, 212, 255, 0.11) 45%, rgba(255, 207, 92, 0.06) 100%);
  --shadow: 0 16px 44px rgba(2, 14, 9, 0.5);
  --shadow-glow: 0 0 40px rgba(95, 216, 138, 0.22);
  --math-grid-color: rgba(95, 216, 138, 0.06);
  --math-grid-major: rgba(95, 216, 138, 0.11);

  --surface-a05: rgba(190, 245, 210, 0.05);
  --surface-a06: rgba(190, 245, 210, 0.07);
  --surface-a08: rgba(190, 245, 210, 0.09);
  --surface-a10: rgba(190, 245, 210, 0.12);
  --surface-a12: rgba(190, 245, 210, 0.15);
  --shadow-a20: rgba(2, 14, 9, 0.28);
  --shadow-a25: rgba(2, 14, 9, 0.34);
  --accent-a15: rgba(95, 216, 138, 0.17);
  --accent-a20: rgba(95, 216, 138, 0.23);
  --accent-a35: rgba(95, 216, 138, 0.38);
  --accent-a40: rgba(95, 216, 138, 0.44);
  --accent-a50: rgba(95, 216, 138, 0.54);

  --surface: #0e2a1c;
  --accent: #5fd88a;

  --bg-top: #030b08;
  --bg-top-2: #051710;

  --pip-grad-start: #5fd88a;
  --pip-grad-mid: #7fd4ff;
  --pip-grad-end: #ffcf5c;
  --pip-accent: #ffcf5c;
  --pip-face: #06170f;
}

/* ── Interactive Classroom — flat paper surfaces ───────────────────────── */
html[data-theme="classroom"] {
  --bg-deep: #10161d;
  --bg-mid: #1b2733;
  --bg-card: rgba(255, 255, 255, 0.08);
  --bg-card-hover: rgba(255, 255, 255, 0.14);
  --text: #f6fafd;
  --text-muted: #b3c2cf;

  --accent-tutorial: #4fc3f7;
  --accent-practice: #66d9a0;
  --accent-test: #ffb74d;
  --accent-games: #ba9cff;
  --accent-progress: #ff8ba7;
  --accent-gold: #ffc861;
  --accent-cyan: #57dbe8;
  --accent-math: #6fcbf5;

  --gradient-brand: linear-gradient(135deg, #4fc3f7 0%, #66d9a0 45%, #ffb74d 100%);
  --gradient-surface: linear-gradient(145deg, rgba(255, 255, 255, 0.11), rgba(255, 255, 255, 0.035));
  --gradient-hero: linear-gradient(145deg, rgba(79, 195, 247, 0.19) 0%, rgba(102, 217, 160, 0.1) 45%, rgba(255, 183, 77, 0.06) 100%);
  --shadow: 0 12px 34px rgba(0, 0, 0, 0.42);
  --shadow-glow: 0 0 30px rgba(79, 195, 247, 0.15);
  --math-grid-color: rgba(79, 195, 247, 0.07);
  --math-grid-major: rgba(79, 195, 247, 0.12);

  --surface-a05: rgba(255, 255, 255, 0.05);
  --surface-a06: rgba(255, 255, 255, 0.07);
  --surface-a08: rgba(255, 255, 255, 0.09);
  --surface-a10: rgba(255, 255, 255, 0.11);
  --surface-a12: rgba(255, 255, 255, 0.14);
  --shadow-a20: rgba(0, 0, 0, 0.24);
  --shadow-a25: rgba(0, 0, 0, 0.3);
  --accent-a15: rgba(79, 195, 247, 0.17);
  --accent-a20: rgba(79, 195, 247, 0.22);
  --accent-a35: rgba(79, 195, 247, 0.37);
  --accent-a40: rgba(79, 195, 247, 0.43);
  --accent-a50: rgba(79, 195, 247, 0.52);

  --surface: #1b2733;
  --accent: #4fc3f7;

  --bg-top: #080c11;
  --bg-top-2: #0c1218;

  --pip-grad-start: #4fc3f7;
  --pip-grad-mid: #8fb8ff;
  --pip-grad-end: #ff8ba7;
  --pip-accent: #ffb74d;
  --pip-face: #0b1219;
}

/* ── Deep Focus — refined glass, restrained ────────────────────────────── */
html[data-theme="raxenor"] {
  --bg-deep: #0a0d14;
  --bg-mid: #141b28;
  --bg-card: rgba(255, 255, 255, 0.055);
  --bg-card-hover: rgba(255, 255, 255, 0.1);
  --text: #f4f7ff;
  --text-muted: #aab6cf;

  --accent-tutorial: #5aa9ff;
  --accent-practice: #48d6a8;
  --accent-test: #ffc24b;
  --accent-games: #b08bff;
  --accent-progress: #ff7aa2;
  --accent-gold: #f2c96b;
  --accent-cyan: #56d8f0;
  --accent-math: #7fb0ff;

  --gradient-brand: linear-gradient(135deg, #5aa9ff 0%, #b08bff 50%, #f2c96b 100%);
  --gradient-surface: linear-gradient(145deg, rgba(255, 255, 255, 0.09), rgba(255, 255, 255, 0.025));
  --gradient-hero: linear-gradient(145deg, rgba(90, 169, 255, 0.16) 0%, rgba(176, 139, 255, 0.09) 45%, rgba(242, 201, 107, 0.05) 100%);
  --shadow: 0 20px 56px rgba(0, 0, 0, 0.52);
  --shadow-glow: 0 0 44px rgba(90, 169, 255, 0.16);
  --math-grid-color: rgba(90, 169, 255, 0.05);
  --math-grid-major: rgba(90, 169, 255, 0.09);

  --surface-a05: rgba(255, 255, 255, 0.045);
  --surface-a06: rgba(255, 255, 255, 0.055);
  --surface-a08: rgba(255, 255, 255, 0.075);
  --surface-a10: rgba(255, 255, 255, 0.095);
  --surface-a12: rgba(255, 255, 255, 0.115);
  --shadow-a20: rgba(0, 0, 0, 0.26);
  --shadow-a25: rgba(0, 0, 0, 0.32);
  --accent-a15: rgba(90, 169, 255, 0.15);
  --accent-a20: rgba(90, 169, 255, 0.2);
  --accent-a35: rgba(90, 169, 255, 0.35);
  --accent-a40: rgba(90, 169, 255, 0.4);
  --accent-a50: rgba(90, 169, 255, 0.5);

  --surface: #141b28;
  --accent: #5aa9ff;

  --bg-top: #05070c;
  --bg-top-2: #080b12;

  --pip-grad-start: #5aa9ff;
  --pip-grad-mid: #b08bff;
  --pip-grad-end: #ff7aa2;
  --pip-accent: #f2c96b;
  --pip-face: #090c13;
}

/* ════════════════════════════════════════════════════════════════════════
   2. COLOUR THAT IS PAINTED LITERALLY, NOT THROUGH A TOKEN

   Every rule below is Midnight's own navy written out in a stylesheet rather
   than taken from a variable, which is why redefining variables alone left it
   in place. The light themes hit exactly this and it was obvious there; here
   it is a navy modal inside a green theme, which is easy to miss and was the
   whole point of auditing by rendering instead of by reading.

   Written once against the tokens rather than five times per theme, so each
   theme gets it from its own palette.
   ════════════════════════════════════════════════════════════════════════ */

html[data-theme="learning"] body,
html[data-theme="galaxy"] body,
html[data-theme="nature"] body,
html[data-theme="classroom"] body,
html[data-theme="raxenor"] body {
  /* Shipped rule ends linear-gradient(180deg, #050818, #080d24 40%, var(--bg-deep))
     — only the last stop was ever a token, so the top 40% of every page stayed
     Midnight navy. Visible on the game screen, which has no scene layer, and
     anywhere the scene fails to build. */
  background-image:
    radial-gradient(ellipse 120% 80% at 50% -40%, var(--accent-a20), transparent 55%),
    radial-gradient(ellipse 80% 60% at 100% 20%, var(--accent-a15), transparent 50%),
    linear-gradient(180deg, var(--bg-top) 0%, var(--bg-top-2) 40%, var(--bg-deep) 100%);
}

html[data-theme="learning"] .modal,
html[data-theme="galaxy"] .modal,
html[data-theme="nature"] .modal,
html[data-theme="classroom"] .modal,
html[data-theme="raxenor"] .modal {
  /* math-theme.css: literal #1a2248 -> #0e1430 -> #12102a, plus style.css's
     own literal underneath it. The topics and progress dialogs were Midnight
     no matter which theme was chosen. */
  background: linear-gradient(165deg, var(--bg-mid) 0%, var(--bg-deep) 100%);
  box-shadow:
    0 32px 90px var(--shadow-a25),
    0 0 0 1px var(--surface-a12),
    0 0 80px var(--accent-a15);
}

html[data-theme="learning"] .reward-toast,
html[data-theme="galaxy"] .reward-toast,
html[data-theme="nature"] .reward-toast,
html[data-theme="classroom"] .reward-toast,
html[data-theme="raxenor"] .reward-toast {
  /* literal rgba(20, 24, 48, 0.95) */
  background: var(--surface);
  border-color: var(--surface-a12);
  box-shadow: 0 12px 40px var(--shadow-a25);
}

html[data-theme="learning"] body.game-page,
html[data-theme="galaxy"] body.game-page,
html[data-theme="nature"] body.game-page,
html[data-theme="classroom"] body.game-page,
html[data-theme="raxenor"] body.game-page {
  background: var(--bg-deep);
}

html[data-theme="learning"] .game-arena,
html[data-theme="galaxy"] .game-arena,
html[data-theme="nature"] .game-arena,
html[data-theme="classroom"] .game-arena,
html[data-theme="raxenor"] .game-arena {
  /* literal purple-black, so the game ignored the theme entirely */
  background: linear-gradient(165deg, var(--bg-mid) 0%, var(--bg-deep) 40%, var(--bg-top-2) 100%);
}

/* The two blurred glows over the arena are a literal violet and blue. Themeing
   the arena but leaving these made the green and blue-grey themes read purple
   at the edges — visible on the render, invisible to a token audit. */
html[data-theme="learning"] .game-arena__glow--1,
html[data-theme="galaxy"] .game-arena__glow--1,
html[data-theme="nature"] .game-arena__glow--1,
html[data-theme="classroom"] .game-arena__glow--1,
html[data-theme="raxenor"] .game-arena__glow--1 {
  background: var(--accent-a35);
}

html[data-theme="learning"] .game-arena__glow--2,
html[data-theme="galaxy"] .game-arena__glow--2,
html[data-theme="nature"] .game-arena__glow--2,
html[data-theme="classroom"] .game-arena__glow--2,
html[data-theme="raxenor"] .game-arena__glow--2 {
  background: var(--accent-a20);
}

html[data-theme="learning"] .pricing-card,
html[data-theme="galaxy"] .pricing-card,
html[data-theme="nature"] .pricing-card,
html[data-theme="classroom"] .pricing-card,
html[data-theme="raxenor"] .pricing-card,
html[data-theme="learning"] .account-card,
html[data-theme="galaxy"] .account-card,
html[data-theme="nature"] .account-card,
html[data-theme="classroom"] .account-card,
html[data-theme="raxenor"] .account-card,
html[data-theme="learning"] .success-card,
html[data-theme="galaxy"] .success-card,
html[data-theme="nature"] .success-card,
html[data-theme="classroom"] .success-card,
html[data-theme="raxenor"] .success-card {
  /* billing writes its own navy: rgba(22, 28, 52, .9) and friends */
  background: var(--surface);
  border-color: var(--surface-a12);
}

html[data-theme="learning"] .pricing-card--featured,
html[data-theme="galaxy"] .pricing-card--featured,
html[data-theme="nature"] .pricing-card--featured,
html[data-theme="classroom"] .pricing-card--featured,
html[data-theme="raxenor"] .pricing-card--featured {
  background: linear-gradient(160deg, var(--bg-mid) 0%, var(--surface) 100%);
}

html[data-theme="learning"] .license-input,
html[data-theme="galaxy"] .license-input,
html[data-theme="nature"] .license-input,
html[data-theme="classroom"] .license-input,
html[data-theme="raxenor"] .license-input {
  background: var(--bg-top-2);
  border-color: var(--surface-a12);
}

/* billing's body text is the literal #c8d4f0, a Midnight blue-grey. It stays
   legible on every one of these, but it is the wrong hue on the green and
   purple themes, so it takes the theme's muted ink instead. */
html[data-theme="learning"] .pricing-card__features li,
html[data-theme="galaxy"] .pricing-card__features li,
html[data-theme="nature"] .pricing-card__features li,
html[data-theme="classroom"] .pricing-card__features li,
html[data-theme="raxenor"] .pricing-card__features li,
html[data-theme="learning"] .pricing-license-note,
html[data-theme="galaxy"] .pricing-license-note,
html[data-theme="nature"] .pricing-license-note,
html[data-theme="classroom"] .pricing-license-note,
html[data-theme="raxenor"] .pricing-license-note,
html[data-theme="learning"] .account-row,
html[data-theme="galaxy"] .account-row,
html[data-theme="nature"] .account-row,
html[data-theme="classroom"] .account-row,
html[data-theme="raxenor"] .account-row {
  color: var(--text-muted);
}

/* The lesson flow scopes three surface tokens to .fx-flow and hardcodes them
   as translucent white. White reads fine on all five, but it flattens the
   tint, so they follow the theme like everything else. */
html[data-theme="learning"] .fx-flow,
html[data-theme="galaxy"] .fx-flow,
html[data-theme="nature"] .fx-flow,
html[data-theme="classroom"] .fx-flow,
html[data-theme="raxenor"] .fx-flow {
  --fx-surface: var(--surface-a06);
  --fx-surface-2: var(--surface-a10);
  --fx-line: var(--surface-a12);
}

/* ════════════════════════════════════════════════════════════════════════
   3. SCENE LAYER
   Each theme replaces the shared decorative markup with its own SVG scene,
   built in theme.js and dropped into the existing .bg-scene container. With
   no theme attribute, or on Daylight and Sunrise, none of this applies and
   the shipped scene stands.
   ════════════════════════════════════════════════════════════════════════ */

html[data-theme="learning"] .bg-math-symbol,
html[data-theme="galaxy"] .bg-math-symbol,
html[data-theme="nature"] .bg-math-symbol,
html[data-theme="classroom"] .bg-math-symbol,
html[data-theme="raxenor"] .bg-math-symbol,
html[data-theme="learning"] .bg-orb,
html[data-theme="galaxy"] .bg-orb,
html[data-theme="nature"] .bg-orb,
html[data-theme="classroom"] .bg-orb,
html[data-theme="raxenor"] .bg-orb,
html[data-theme="learning"] .bg-math-geo,
html[data-theme="galaxy"] .bg-math-geo,
html[data-theme="nature"] .bg-math-geo,
html[data-theme="classroom"] .bg-math-geo,
html[data-theme="raxenor"] .bg-math-geo,
html[data-theme="learning"] .bg-math-rays,
html[data-theme="galaxy"] .bg-math-rays,
html[data-theme="nature"] .bg-math-rays,
html[data-theme="classroom"] .bg-math-rays,
html[data-theme="raxenor"] .bg-math-rays,
html[data-theme="learning"] .bg-math-ring,
html[data-theme="galaxy"] .bg-math-ring,
html[data-theme="nature"] .bg-math-ring,
html[data-theme="classroom"] .bg-math-ring,
html[data-theme="raxenor"] .bg-math-ring {
  display: none;
}

html[data-theme="learning"] .bg-math-grid,
html[data-theme="galaxy"] .bg-math-grid,
html[data-theme="nature"] .bg-math-grid,
html[data-theme="classroom"] .bg-math-grid,
html[data-theme="raxenor"] .bg-math-grid {
  opacity: 0.4;
}

/* .bg-scene is position:fixed with z-index:0, and the shipped decoration inside
   it is a handful of blurred, mostly transparent orbs — so nothing noticed that
   a positioned z-index:0 layer paints ABOVE static content. An opaque SVG scene
   does notice: the dashboard survives because .app sets z-index:1, but the nine
   templates that have no .app wrapper — login, register, account, pricing,
   licence redeem, checkout, subscription success, download and the iOS install
   page — had their entire contents hidden behind the scene. Found by looking at
   the renders; no contrast or token probe can see it, because the elements are
   present and correctly coloured, just covered.

   Dropping the layer below the content plane fixes all nine at once. Scoped to
   these five themes, so Midnight's stacking is untouched. */
html[data-theme="learning"] .bg-scene,
html[data-theme="galaxy"] .bg-scene,
html[data-theme="nature"] .bg-scene,
html[data-theme="classroom"] .bg-scene,
html[data-theme="raxenor"] .bg-scene {
  z-index: -1;
}

.mts {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.mts__svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Motion is transform and opacity only, and off entirely for anyone who has
   asked for reduced motion. */
.mts__drift { animation: mts-drift 26s ease-in-out infinite alternate; }
.mts__drift--slow { animation: mts-drift 40s ease-in-out infinite alternate-reverse; }
.mts__twinkle { animation: mts-twinkle 4.5s ease-in-out infinite alternate; }
.mts__twinkle--b { animation: mts-twinkle 6.5s ease-in-out infinite alternate-reverse; }
.mts__sway { animation: mts-sway 18s ease-in-out infinite alternate; transform-origin: 50% 0; }
.mts__float { animation: mts-float 22s ease-in-out infinite alternate; }
.mts__float--b { animation: mts-float 30s ease-in-out infinite alternate-reverse; }
.mts__pulse { animation: mts-pulse 9s ease-in-out infinite alternate; }

@keyframes mts-drift {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(28px, -18px, 0); }
}

@keyframes mts-twinkle {
  from { opacity: 0.25; }
  to   { opacity: 1; }
}

@keyframes mts-sway {
  from { transform: rotate(-1.4deg); }
  to   { transform: rotate(1.4deg); }
}

@keyframes mts-float {
  from { transform: translate3d(0, 10px, 0); }
  to   { transform: translate3d(0, -14px, 0); }
}

@keyframes mts-pulse {
  from { opacity: 0.45; }
  to   { opacity: 0.9; }
}

@media (prefers-reduced-motion: reduce) {
  .mts__drift,
  .mts__drift--slow,
  .mts__twinkle,
  .mts__twinkle--b,
  .mts__sway,
  .mts__float,
  .mts__float--b,
  .mts__pulse {
    animation: none !important;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   4. PICKER, WITH EIGHT OPTIONS IN IT
   Three fitted without thinking about it. Eight does not: the menu is
   anchored under a control in the top-right of the page, so it has to be
   allowed to scroll rather than run off the bottom on a short screen.
   ════════════════════════════════════════════════════════════════════════ */
.theme-picker__menu {
  max-height: min(62vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;

  /* The menu was given `background: var(--bg-card)`, and on every dark theme
     --bg-card is a translucent white tint — rgba(255,255,255,0.07) on Midnight.
     So the menu has always been see-through, with the dashboard reading
     straight through the theme names. It only looked fine on Daylight and
     Sunrise because those set --bg-card to an opaque #ffffff.

     This is pre-existing and not caused by the promotion, but eight options
     cover far more of the page than three did, so it stops being survivable.
     --surface is opaque on every theme, and falls back to the shipped navy
     where it is undeclared, so Midnight gets a solid panel rather than a
     different colour. Found by looking at the render: nothing measures it,
     because every individual colour is correct. */
  background: var(--surface, #1a1f3a);
}

.theme-picker__group {
  margin: 6px 6px 2px;
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  opacity: 0.75;
}

.theme-picker__group:first-child { margin-top: 2px; }

.theme-picker__dot--learning { background: linear-gradient(135deg, #0d1b2a 45%, #4cc4ff); }
.theme-picker__dot--galaxy { background: linear-gradient(135deg, #05030e 45%, #8b7bff); }
.theme-picker__dot--nature { background: linear-gradient(135deg, #071410 45%, #5fd88a); }
.theme-picker__dot--classroom { background: linear-gradient(135deg, #10161d 45%, #4fc3f7); }
.theme-picker__dot--raxenor { background: linear-gradient(135deg, #0a0d14 45%, #5aa9ff); }
