/* ============================================================
   MISSION FLOW — Scenario theme skins (display + voter + admin)
   ============================================================

   Fifteen editorial art directions driven by settings.theme. Serious,
   professional, and deliberately far apart from one another — fifteen
   distinct printed/photographic grounds, not fifteen tints of one dark UI.

     key         world       ground · accent · heading face
     ----------  ----------  -------------------------------------------------
     (none)/cyber Command    steel blue-black · cool blue · Archivo (brand default)
     tactical    Field       matte olive/graphite · olive · Rajdhani (stencil-quiet)
     boardroom   Boardroom   warm paper · charcoal + navy rule · Instrument Serif  LIGHT
     signal      Signal      near-black · amber · Share Tech Mono
     chancery    Chancery    deep navy · gold hairlines · Playfair Display
     incident    Incident    charcoal · signal red + amber · Anton
     blueprint   Blueprint   drafting blue · white hairlines · Rajdhani / Plex Mono
     arena       Arena       black stage · one gold · Anton (broadcast quiz set)
     clinical    Clinical    white/cool grey · teal · IBM Plex Mono            LIGHT
     abyss       Abyss       teal-black water · sonar green · Rajdhani caps (HADAL)
     premiere    Premiere    the storyboard's night · violet · Big Shoulders caps, Courier Prime
     committee   Committee   fluorescent white · committee blue + lanyard red · Archivo caps  LIGHT
     glasshouse  Glasshouse  night river · screen cyan + sodium amber · Instrument Serif (GLASSHOUSE)
     mezzanine   Mezzanine   walnut · brass + operator maroon · Playfair Display (FLOOR 13½)
     aquarium    Aquarium    night tank · glass teal + brass · Playfair Display (EIGHT)

   LEGACY KEYS (old scenarios on other machines still say these — every
   selector below carries the alias so they keep rendering):
     office → boardroom   comms → signal      diplomatic → chancery
     alert → incident     sketchbook → blueprint
     gameshow → arena     biolab → clinical

   HOW IT WORKS
   - All three surfaces share the Daylight token names, so each theme block
     re-declares the full token set (core + legacy aliases — alias var()
     chains freeze where declared, hence the repetition). Admin's own
     aliases (--bg-body/-sidebar/-input, --border) are re-pointed too.
   - Loaded LAST, so a theme beats voter light/dark toggles: each theme
     deliberately commits to ONE look on every device.
   - body.surface-display / -voter / -admin (set in the templates) scale the
     ambient backdrop per surface via --theme-backdrop-strength.
   - Headings swap face via the --theme-font / --theme-track hooks; body
     text stays on Archivo everywhere so long narrative remains readable.
   - Placeholder scenes: display.js stamps .ph-1..4 (node-id hash) on every
     .placeholder-visual; each theme points those at its scene library under
     /static/images/themes/<key>/ (regenerate: tools/make_theme_art.py). The
     art is abstract and non-figurative — layered light, grain, contour and
     drafting linework, waveforms — with a calm centre for the title.
   - Higher/Lower stage dressing: display.css reads --hl-stage,
     --hl-number-font/-ink/-glow, --hl-reveal-ink/-glow, --hl-votebar-radius
     (section at the bottom). Voter HL buttons restyle per world there too.
   - Contrast: body text ≥ 4.5:1 and large headings ≥ 3:1 on every ground;
     --choice-a..h stay mutually distinguishable (CIEDE2000 >= 16.9 between
     any two in a theme, 8 Oct 2026) and the letter's ink (--choice-ink,
     else --accent-ink) reads >= 4.5:1 on each. Every block that declares
     a..d declares e..h too: var() aliases freeze where declared.
   - No marquee bulbs, hazard chevrons, wobbly borders, highlighter swipes
     or scanlines. Texture is grain, vignette and hairline only.
   - Escape rooms keep their own pinned stage look (by design).
   ============================================================ */

/* ---- Placeholder scene rotation (default = cyber set) ------------------- */
.placeholder-visual.ph-1 { background: url('/static/images/themes/cyber/scene_1.svg') center/cover no-repeat; }
.placeholder-visual.ph-2 { background: url('/static/images/themes/cyber/scene_2.svg') center/cover no-repeat; }
.placeholder-visual.ph-3 { background: url('/static/images/themes/cyber/scene_3.svg') center/cover no-repeat; }
.placeholder-visual.ph-4 { background: url('/static/images/themes/cyber/scene_4.svg') center/cover no-repeat; }
/* A real scene replaces the old wash + grid pseudo-layers and data-streams. */
.placeholder-visual[class*="ph-"]::before,
.placeholder-visual[class*="ph-"]::after { display: none; }
.placeholder-visual[class*="ph-"] .data-streams { display: none; }

/* ---- Story scrim recolour ------------------------------------------------
   layout-full's readability gradient is hardcoded navy in display.css; each
   theme repaints it in its own ground so text sits on the theme, not on
   cyber's. Light themes get a paper scrim (dark text per their tokens). */
body.theme-tactical .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(21, 24, 15, 0.95) 30%); }
body.theme-boardroom .story-container.layout-full .story-text-area,
body.theme-office .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(244, 241, 234, 0.96) 30%); }
body.theme-signal .story-container.layout-full .story-text-area,
body.theme-comms .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(12, 12, 14, 0.95) 30%); }
body.theme-chancery .story-container.layout-full .story-text-area,
body.theme-diplomatic .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(15, 26, 51, 0.95) 30%); }
body.theme-incident .story-container.layout-full .story-text-area,
body.theme-alert .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(23, 24, 27, 0.95) 30%); }
body.theme-blueprint .story-container.layout-full .story-text-area,
body.theme-sketchbook .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(23, 58, 112, 0.95) 30%); }
body.theme-arena .story-container.layout-full .story-text-area,
body.theme-gameshow .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(6, 8, 15, 0.95) 30%); }
body.theme-clinical .story-container.layout-full .story-text-area,
body.theme-biolab .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(247, 249, 250, 0.96) 30%); }

/* ---- Heading-font hook (per-theme faces, body text untouched) ----------- */
body[class*="theme-"] .story-title,
body[class*="theme-"] .lobby-title,
body[class*="theme-"] .banner-title,
body[class*="theme-"] .debrief-title,
body[class*="theme-"] .ending-title,
body[class*="theme-"] .timer-countdown-title,
body[class*="theme-"] .video-fallback-title,
body[class*="theme-"] .comparison-col-title,
body[class*="theme-"] .lt-title,
body[class*="theme-"] .screen-eyebrow,
body[class*="theme-"] .lt-eyebrow,
body[class*="theme-"] .quiz-badge,
body[class*="theme-"] .briefing-badge,
body[class*="theme-"] .ending-badge,
body[class*="theme-"] .minigame-banner-verdict,
body[class*="theme-"] .leaderboard-heading,
body[class*="theme-"] .hl-verdict,
body[class*="theme-"] .info-title,
body[class*="theme-"] .quiz-voter-badge,
body[class*="theme-"] .minigame-result-verdict,
body[class*="theme-"] .quiz-result-verdict,
body[class*="theme-"] .hl-result-verdict,
body[class*="theme-"] .ending-title-small,
body[class*="theme-"] .waiting-text,
body[class*="theme-"] .sidebar-brand,
body[class*="theme-"] .section-title {
    font-family: var(--theme-font, var(--font-heading));
    letter-spacing: var(--theme-track, 0.02em);
    font-weight: var(--theme-weight, 700);
}
/* Worlds whose headings set in caps (stencil / drafting / impact faces). */
body.theme-tactical .story-title,      body.theme-tactical .lobby-title,      body.theme-tactical .info-title,      body.theme-tactical .ending-title,      body.theme-tactical .banner-title,
body.theme-blueprint .story-title,     body.theme-blueprint .lobby-title,     body.theme-blueprint .info-title,     body.theme-blueprint .ending-title,     body.theme-blueprint .banner-title,
body.theme-sketchbook .story-title,    body.theme-sketchbook .lobby-title,    body.theme-sketchbook .info-title,    body.theme-sketchbook .ending-title,    body.theme-sketchbook .banner-title {
    text-transform: uppercase;
}

/* Ambient backdrop layer — behind everything, above the body ground. */
body[class*="theme-"]::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: var(--theme-backdrop, none) center / cover no-repeat;
    opacity: var(--theme-backdrop-strength, 1);
}
body.surface-voter[class*="theme-"]::before { opacity: calc(var(--theme-backdrop-strength, 1) * 0.55); }
body.surface-admin[class*="theme-"]::before { opacity: calc(var(--theme-backdrop-strength, 1) * 0.4); }

/* Light worlds: printed paper has no glow — kill inherited text shadows. */
body.theme-boardroom .screen > div,  body.theme-boardroom .info-content,  body.theme-boardroom .quiz-voter-content,
body.theme-office .screen > div,     body.theme-office .info-content,     body.theme-office .quiz-voter-content,
body.theme-clinical .screen > div,   body.theme-clinical .info-content,   body.theme-clinical .quiz-voter-content,
body.theme-biolab .screen > div,     body.theme-biolab .info-content,     body.theme-biolab .quiz-voter-content {
    text-shadow: none;
}

/* ============================================================
   CYBER — "Command" (explicit class matches the classless default)
   Steel blue-black, one cool accent, fine network hairlines. Tokens
   come from each surface's own :root; only the ambient is added.
   ============================================================ */
body.theme-cyber {
    --theme-backdrop: url('/static/images/themes/cyber/backdrop.svg');
    --theme-backdrop-strength: 0.9;
}
/* Display-only ambient for the classless default too. */
body.surface-display:not([class*="theme-"])::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: url('/static/images/themes/cyber/backdrop.svg') center / cover no-repeat;
    opacity: 0.8;
}

/* ============================================================
   TACTICAL — "Field": matte olive/graphite night ops, topographic
   contours, quiet stencil-cut headings (Rajdhani caps, wide tracking).
   ============================================================ */
body.theme-tactical {
    --bg: #15180f;
    --surface: #1f2317;
    --ink: #e6e4d4;
    --mut: #a7a994;
    --faint: #7f826c;
    --line: rgba(230, 228, 212, 0.12);
    --track: #2a2f20;
    --chip: #2a2f20;
    --accent: #a9b466;
    --accent-ink: #15180f;
    --tint: rgba(169, 180, 102, 0.16);
    --choice-a: #a9b466;
    --choice-b: #d9a24a;
    --choice-c: #7fb2c9;
    --choice-d: #cf6a5a;
    --choice-e: #b09be8;
    --choice-f: #5cc6b2;
    --choice-g: #f4a3b4;
    --choice-h: #d8d8d8;
    --secondary: #d9a24a;
    --secondary-dim: rgba(217, 162, 74, 0.18);
    --danger: #cf6a5a;
    --danger-dim: rgba(207, 106, 90, 0.18);
    --success: #8fb06a;
    --success-dim: rgba(143, 176, 106, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Rajdhani', 'Archivo', system-ui, sans-serif;
    --theme-track: 0.12em;
    --theme-weight: 600;
    --theme-backdrop: url('/static/images/themes/tactical/backdrop.svg');
}
body.theme-tactical .placeholder-visual.ph-1 { background-image: url('/static/images/themes/tactical/scene_1.svg'); }
body.theme-tactical .placeholder-visual.ph-2 { background-image: url('/static/images/themes/tactical/scene_2.svg'); }
body.theme-tactical .placeholder-visual.ph-3 { background-image: url('/static/images/themes/tactical/scene_3.svg'); }
body.theme-tactical .placeholder-visual.ph-4 { background-image: url('/static/images/themes/tactical/scene_4.svg'); }

/* ============================================================
   BOARDROOM (alias: office) — warm off-white paper, charcoal ink,
   a single navy accent, editorial serif headings. THE LIGHT THEME.
   ============================================================ */
body.theme-boardroom,
body.theme-office {
    --bg: #f4f1ea;
    --surface: #fffdf8;
    --ink: #1f2328;
    --mut: #5c646d;
    --faint: #858c95;
    --line: rgba(31, 35, 40, 0.13);
    --track: #e5e1d7;
    --chip: #ebe7dd;
    --accent: #1f3a5f;
    --accent-ink: #ffffff;
    --tint: #e4eaf2;
    --choice-a: #1f3a5f;
    --choice-b: #b0781f;
    --choice-c: #3f8f5f;
    --choice-d: #a03535;
    --choice-e: #7a3fb0;
    --choice-f: #0f7a85;
    --choice-g: #6b6a10;
    --choice-h: #5e5e5e;
    --secondary: #8f6320;
    --secondary-dim: rgba(143, 99, 32, 0.14);
    --danger: #a03535;
    --danger-dim: rgba(160, 53, 53, 0.12);
    --success: #2c6a4b;
    --success-dim: rgba(44, 106, 75, 0.12);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Instrument Serif', 'Playfair Display', Georgia, 'Times New Roman', serif;
    --theme-track: 0;
    --theme-weight: 400;
    --theme-backdrop: url('/static/images/themes/boardroom/backdrop.svg');
}
/* Editorial pairing: serif titles sit tight; eyebrows / badges stay a
   tracked grotesk so the small caps don't shrink into the serif. */
body.theme-boardroom .story-title, body.theme-office .story-title,
body.theme-boardroom .lobby-title, body.theme-office .lobby-title,
body.theme-boardroom .info-title,  body.theme-office .info-title {
    line-height: 1.08;
}
body.theme-boardroom .screen-eyebrow, body.theme-office .screen-eyebrow,
body.theme-boardroom .lt-eyebrow,     body.theme-office .lt-eyebrow,
body.theme-boardroom .info-eyebrow,   body.theme-office .info-eyebrow,
body.theme-boardroom .quiz-badge,     body.theme-office .quiz-badge,
body.theme-boardroom .briefing-badge, body.theme-office .briefing-badge,
body.theme-boardroom .ending-badge,   body.theme-office .ending-badge {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 600;
    letter-spacing: 0.16em;
    color: var(--accent);
}
body.theme-boardroom .placeholder-visual.ph-1, body.theme-office .placeholder-visual.ph-1 { background-image: url('/static/images/themes/boardroom/scene_1.svg'); }
body.theme-boardroom .placeholder-visual.ph-2, body.theme-office .placeholder-visual.ph-2 { background-image: url('/static/images/themes/boardroom/scene_2.svg'); }
body.theme-boardroom .placeholder-visual.ph-3, body.theme-office .placeholder-visual.ph-3 { background-image: url('/static/images/themes/boardroom/scene_3.svg'); }
body.theme-boardroom .placeholder-visual.ph-4, body.theme-office .placeholder-visual.ph-4 { background-image: url('/static/images/themes/boardroom/scene_4.svg'); }

/* ============================================================
   SIGNAL (alias: comms) — near-black with amber, monospace headings,
   oscilloscope / waveform linework. No CRT gimmick.
   ============================================================ */
body.theme-signal,
body.theme-comms {
    --bg: #0c0c0e;
    --surface: #151517;
    --ink: #ebe6da;
    --mut: #a49d8d;
    --faint: #7a7564;
    --line: rgba(235, 230, 218, 0.12);
    --track: #1e1e21;
    --chip: #1e1e21;
    --accent: #f0a83a;
    --accent-ink: #0c0c0e;
    --tint: rgba(240, 168, 58, 0.14);
    --choice-a: #f0a83a;
    --choice-b: #e6dfcf;
    --choice-c: #b5c98a;
    --choice-d: #8fb1c9;
    --choice-e: #c8a2ee;
    --choice-f: #62d0c2;
    --choice-g: #f08aa8;
    --choice-h: #fff05a;
    --secondary: #d97b3a;
    --secondary-dim: rgba(217, 123, 58, 0.18);
    --danger: #d95c4a;
    --danger-dim: rgba(217, 92, 74, 0.18);
    --success: #9cb36a;
    --success-dim: rgba(156, 179, 106, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Share Tech Mono', 'IBM Plex Mono', 'Courier New', monospace;
    --theme-track: 0.04em;
    --theme-weight: 400;
    --theme-backdrop: url('/static/images/themes/signal/backdrop.svg');
}
body.theme-signal .placeholder-visual.ph-1, body.theme-comms .placeholder-visual.ph-1 { background-image: url('/static/images/themes/signal/scene_1.svg'); }
body.theme-signal .placeholder-visual.ph-2, body.theme-comms .placeholder-visual.ph-2 { background-image: url('/static/images/themes/signal/scene_2.svg'); }
body.theme-signal .placeholder-visual.ph-3, body.theme-comms .placeholder-visual.ph-3 { background-image: url('/static/images/themes/signal/scene_3.svg'); }
body.theme-signal .placeholder-visual.ph-4, body.theme-comms .placeholder-visual.ph-4 { background-image: url('/static/images/themes/signal/scene_4.svg'); }

/* ============================================================
   CHANCERY (alias: diplomatic) — deep navy + gold hairlines, serif,
   marble / paper-fold textures. Formal and stately.
   ============================================================ */
body.theme-chancery,
body.theme-diplomatic {
    --bg: #0f1a33;
    --surface: #172440;
    --ink: #ede9dc;
    --mut: #aab0c2;
    --faint: #7f869d;
    --line: rgba(201, 164, 79, 0.24);
    --track: #202d4d;
    --chip: #202d4d;
    --accent: #c9a44f;
    --accent-ink: #0f1a33;
    --tint: rgba(201, 164, 79, 0.14);
    --choice-a: #c9a44f;
    --choice-b: #9fb0d4;
    --choice-c: #ece7d8;
    --choice-d: #d07a8a;
    --choice-e: #d59cec;
    --choice-f: #5fd2c6;
    --choice-g: #c2e07a;
    --choice-h: #f39a6a;
    --secondary: #9fb0d4;
    --secondary-dim: rgba(159, 176, 212, 0.16);
    --danger: #d07a8a;
    --danger-dim: rgba(208, 122, 138, 0.18);
    --success: #7fc0b0;
    --success-dim: rgba(127, 192, 176, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Playfair Display', 'Instrument Serif', Georgia, serif;
    --theme-track: 0.02em;
    --theme-weight: 700;
    --theme-backdrop: url('/static/images/themes/chancery/backdrop.svg');
}
/* One gold hairline framing the stage — the only ornament. */
body.surface-display.theme-chancery::after, body.surface-display.theme-diplomatic::after,
body.surface-voter.theme-chancery::after,   body.surface-voter.theme-diplomatic::after {
    content: '';
    position: fixed;
    inset: 14px;
    z-index: 9997;
    pointer-events: none;
    border: 1px solid rgba(201, 164, 79, 0.42);
}
body.surface-voter.theme-chancery::after, body.surface-voter.theme-diplomatic::after { inset: 7px; }
body.theme-chancery .placeholder-visual.ph-1, body.theme-diplomatic .placeholder-visual.ph-1 { background-image: url('/static/images/themes/chancery/scene_1.svg'); }
body.theme-chancery .placeholder-visual.ph-2, body.theme-diplomatic .placeholder-visual.ph-2 { background-image: url('/static/images/themes/chancery/scene_2.svg'); }
body.theme-chancery .placeholder-visual.ph-3, body.theme-diplomatic .placeholder-visual.ph-3 { background-image: url('/static/images/themes/chancery/scene_3.svg'); }
body.theme-chancery .placeholder-visual.ph-4, body.theme-diplomatic .placeholder-visual.ph-4 { background-image: url('/static/images/themes/chancery/scene_4.svg'); }

/* ============================================================
   INCIDENT (alias: alert) — charcoal with signal red / amber,
   condensed impact headings, emergency-light gradients. Urgent, adult.
   ============================================================ */
body.theme-incident,
body.theme-alert {
    --bg: #17181b;
    --surface: #202226;
    --ink: #f0eeeb;
    --mut: #a8a5a0;
    --faint: #7a7772;
    --line: rgba(240, 238, 235, 0.12);
    --track: #2a2c31;
    --chip: #2a2c31;
    --accent: #cf3f34;
    --accent-ink: #ffffff;
    --tint: rgba(232, 87, 76, 0.16);
    --choice-a: #e8574c;
    --choice-b: #f2b038;
    --choice-c: #d9d5cf;
    --choice-d: #6f9fd8;
    --choice-e: #b49cf0;
    --choice-f: #5fd2c6;
    --choice-g: #c2e07a;
    --choice-h: #f58fc0;
    --choice-ink: #17181b;
    --secondary: #f2b038;
    --secondary-dim: rgba(242, 176, 56, 0.18);
    --danger: #cf3f34;
    --danger-dim: rgba(207, 63, 52, 0.2);
    --success: #6aa96e;
    --success-dim: rgba(106, 169, 110, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Anton', 'Archivo', system-ui, sans-serif;
    --theme-track: 0.04em;
    --theme-weight: 400;
    --theme-backdrop: url('/static/images/themes/incident/backdrop.svg');
}
/* A 2px status rule along the top edge, red → amber. Display only. */
body.surface-display.theme-incident::after, body.surface-display.theme-alert::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9997;
    pointer-events: none;
    background: linear-gradient(90deg, #e8574c, #f2a93b) top / 100% 2px no-repeat;
}
body.theme-incident .placeholder-visual.ph-1, body.theme-alert .placeholder-visual.ph-1 { background-image: url('/static/images/themes/incident/scene_1.svg'); }
body.theme-incident .placeholder-visual.ph-2, body.theme-alert .placeholder-visual.ph-2 { background-image: url('/static/images/themes/incident/scene_2.svg'); }
body.theme-incident .placeholder-visual.ph-3, body.theme-alert .placeholder-visual.ph-3 { background-image: url('/static/images/themes/incident/scene_3.svg'); }
body.theme-incident .placeholder-visual.ph-4, body.theme-alert .placeholder-visual.ph-4 { background-image: url('/static/images/themes/incident/scene_4.svg'); }

/* ============================================================
   BLUEPRINT (alias: sketchbook) — architect's drafting sheet: deep
   blueprint blue, white hairline grid, dimension-line art, light
   technical caps. Wildly different texture from the rest.
   ============================================================ */
body.theme-blueprint,
body.theme-sketchbook {
    --bg: #173a70;
    --surface: #1e4480;
    --ink: #f2f6fb;
    --mut: #b7c6dd;
    --faint: #93a7c6;
    --line: rgba(242, 246, 251, 0.24);
    --track: #2a5090;
    --chip: #2a5090;
    --accent: #ffffff;
    --accent-ink: #173a70;
    --tint: rgba(242, 246, 251, 0.14);
    --choice-a: #ffffff;
    --choice-b: #f2c94c;
    --choice-c: #7fe0c8;
    --choice-d: #c4b0ff;
    --choice-e: #ffb09a;
    --choice-f: #8fd4ff;
    --choice-g: #c8f08a;
    --choice-h: #ff98c8;
    --secondary: #f2c94c;
    --secondary-dim: rgba(242, 201, 76, 0.18);
    --danger: #ff9a7a;
    --danger-dim: rgba(255, 154, 122, 0.18);
    --success: #7fe0c8;
    --success-dim: rgba(127, 224, 200, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Rajdhani', 'Archivo', system-ui, sans-serif;
    --theme-track: 0.14em;
    --theme-weight: 500;
    --theme-backdrop: url('/static/images/themes/blueprint/backdrop.svg');
}
/* Drafting-sheet border: double hairline frame. */
body.surface-display.theme-blueprint::after, body.surface-display.theme-sketchbook::after,
body.surface-voter.theme-blueprint::after,   body.surface-voter.theme-sketchbook::after {
    content: '';
    position: fixed;
    inset: 12px;
    z-index: 9997;
    pointer-events: none;
    border: 1px solid rgba(242, 246, 251, 0.45);
    box-shadow: inset 0 0 0 5px transparent, inset 0 0 0 6px rgba(242, 246, 251, 0.2);
}
body.surface-voter.theme-blueprint::after, body.surface-voter.theme-sketchbook::after { inset: 6px; box-shadow: none; }
/* Sharp, technical corners on the tap targets and cards. */
body.theme-blueprint .vote-choice,        body.theme-sketchbook .vote-choice,
body.theme-blueprint .quiz-voter-option,  body.theme-sketchbook .quiz-voter-option,
body.theme-blueprint .poll-voter-option,  body.theme-sketchbook .poll-voter-option,
body.theme-blueprint .hl-voter-btn,       body.theme-sketchbook .hl-voter-btn,
body.theme-blueprint .btn,                body.theme-sketchbook .btn {
    border-radius: 3px;
}
body.theme-blueprint .placeholder-visual.ph-1, body.theme-sketchbook .placeholder-visual.ph-1 { background-image: url('/static/images/themes/blueprint/scene_1.svg'); }
body.theme-blueprint .placeholder-visual.ph-2, body.theme-sketchbook .placeholder-visual.ph-2 { background-image: url('/static/images/themes/blueprint/scene_2.svg'); }
body.theme-blueprint .placeholder-visual.ph-3, body.theme-sketchbook .placeholder-visual.ph-3 { background-image: url('/static/images/themes/blueprint/scene_3.svg'); }
body.theme-blueprint .placeholder-visual.ph-4, body.theme-sketchbook .placeholder-visual.ph-4 { background-image: url('/static/images/themes/blueprint/scene_4.svg'); }

/* ============================================================
   ARENA (alias: gameshow) — broadcast quiz-show stage: black / deep
   navy, ONE gold accent, huge condensed numerals, stage-light beams,
   a spotlight pool. Dramatic and adult — the Higher/Lower live set.
   ============================================================ */
body.theme-arena,
body.theme-gameshow {
    --bg: #06080f;
    --surface: #0f1320;
    --ink: #f3f1ea;
    --mut: #a9a79f;
    --faint: #7c7970;
    --line: rgba(243, 241, 234, 0.12);
    --track: #181d2e;
    --chip: #181d2e;
    --accent: #f2b632;
    --accent-ink: #1a1200;
    --tint: rgba(242, 182, 50, 0.16);
    --choice-a: #f2b632;
    --choice-b: #e9e5dc;
    --choice-c: #5aa9e6;
    --choice-d: #e0563f;
    --choice-e: #a88cf6;
    --choice-f: #4fd1c5;
    --choice-g: #9ae070;
    --choice-h: #ff92c6;
    --secondary: #fff1cc;
    --secondary-dim: rgba(255, 241, 204, 0.16);
    --danger: #e0563f;
    --danger-dim: rgba(224, 86, 63, 0.18);
    --success: #6fcf8a;
    --success-dim: rgba(111, 207, 138, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: rgba(242, 182, 50, 0.3);
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Anton', 'Archivo', system-ui, sans-serif;
    --theme-track: 0.06em;
    --theme-weight: 400;
    --theme-backdrop: url('/static/images/themes/arena/backdrop.svg');
}
/* House lights down: a deep vignette pulls the eye to centre stage. */
body.surface-display.theme-arena::after, body.surface-display.theme-gameshow::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9997;
    pointer-events: none;
    background: radial-gradient(ellipse 70% 64% at 50% 46%, transparent 55%, rgba(0, 0, 0, 0.55) 100%);
}
body.theme-arena .placeholder-visual.ph-1, body.theme-gameshow .placeholder-visual.ph-1 { background-image: url('/static/images/themes/arena/scene_1.svg'); }
body.theme-arena .placeholder-visual.ph-2, body.theme-gameshow .placeholder-visual.ph-2 { background-image: url('/static/images/themes/arena/scene_2.svg'); }
body.theme-arena .placeholder-visual.ph-3, body.theme-gameshow .placeholder-visual.ph-3 { background-image: url('/static/images/themes/arena/scene_3.svg'); }
body.theme-arena .placeholder-visual.ph-4, body.theme-gameshow .placeholder-visual.ph-4 { background-image: url('/static/images/themes/arena/scene_4.svg'); }

/* ============================================================
   CLINICAL (alias: biolab) — white / cool grey, teal accent, monospace
   headings and data labels, thin petri-circle + grid linework.
   THE SECOND LIGHT THEME.
   ============================================================ */
body.theme-clinical,
body.theme-biolab {
    --bg: #f7f9fa;
    --surface: #ffffff;
    --ink: #1b2429;
    --mut: #596670;
    --faint: #7f8b93;
    --line: rgba(27, 36, 41, 0.12);
    --track: #e6ebee;
    --chip: #edf1f3;
    --accent: #0f7c72;
    --accent-ink: #ffffff;
    --tint: #e1f1ee;
    --choice-a: #0f7c72;
    --choice-b: #b06a12;
    --choice-c: #7d4fb0;
    --choice-d: #a7364f;
    --choice-e: #2a5fa8;
    --choice-f: #2f7d3a;
    --choice-g: #5e5e5e;
    --choice-h: #7a6a00;
    --secondary: #2a5fa8;
    --secondary-dim: rgba(42, 95, 168, 0.14);
    --danger: #c2472e;
    --danger-dim: rgba(194, 71, 46, 0.12);
    --success: #2f8a5a;
    --success-dim: rgba(47, 138, 90, 0.12);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'IBM Plex Mono', 'Share Tech Mono', 'Courier New', monospace;
    --theme-track: -0.01em;
    --theme-weight: 500;
    --theme-backdrop: url('/static/images/themes/clinical/backdrop.svg');
}
/* Mono eyebrows / labels read as instrument readouts. */
body.theme-clinical .screen-eyebrow, body.theme-biolab .screen-eyebrow,
body.theme-clinical .lt-eyebrow,     body.theme-biolab .lt-eyebrow,
body.theme-clinical .info-eyebrow,   body.theme-biolab .info-eyebrow {
    font-family: 'IBM Plex Mono', 'Courier New', monospace;
    font-weight: 400;
    letter-spacing: 0.08em;
    color: var(--accent);
}
body.theme-clinical .placeholder-visual.ph-1, body.theme-biolab .placeholder-visual.ph-1 { background-image: url('/static/images/themes/clinical/scene_1.svg'); }
body.theme-clinical .placeholder-visual.ph-2, body.theme-biolab .placeholder-visual.ph-2 { background-image: url('/static/images/themes/clinical/scene_2.svg'); }
body.theme-clinical .placeholder-visual.ph-3, body.theme-biolab .placeholder-visual.ph-3 { background-image: url('/static/images/themes/clinical/scene_3.svg'); }
body.theme-clinical .placeholder-visual.ph-4, body.theme-biolab .placeholder-visual.ph-4 { background-image: url('/static/images/themes/clinical/scene_4.svg'); }

/* ============================================================
   HIGHER OR LOWER — per-theme stage dressing
   The display screen reads these hooks (display.css defaults keep
   the classless cyber look): --hl-stage (light pooled behind the
   number), --hl-number-font/-ink/-glow, --hl-reveal-ink/-glow,
   --hl-votebar-radius. Voter buttons restyle per world below.
   ============================================================ */

/* TACTICAL — range-board numerals, faint rangefinder rings, hard shadow. */
body.theme-tactical {
    --hl-stage:
        radial-gradient(56vw 40vh at 50% 46%, rgba(169, 180, 102, 0.10), transparent 70%),
        repeating-radial-gradient(circle at 50% 46%, transparent 0 140px, rgba(169, 180, 102, 0.045) 140px 141px);
    --hl-number-font: 'Rajdhani', 'Archivo', system-ui, sans-serif;
    --hl-number-glow: 0 2px 0 rgba(0, 0, 0, 0.45);
    --hl-reveal-glow: 0 2px 0 rgba(0, 0, 0, 0.45);
    --hl-votebar-radius: 3px;
}
body.theme-tactical .hl-number { font-weight: 700; }

/* BOARDROOM — paper spotlight, navy serif numerals, no glow at all. */
body.theme-boardroom, body.theme-office {
    --hl-stage: radial-gradient(58vw 42vh at 50% 46%, #ffffff, transparent 75%);
    --hl-number-font: 'Instrument Serif', 'Playfair Display', Georgia, serif;
    --hl-number-ink: var(--accent);
    --hl-number-glow: none;
    --hl-reveal-glow: none;
    --hl-votebar-radius: 4px;
}
body.theme-boardroom .hl-number, body.theme-office .hl-number { font-weight: 400; letter-spacing: 0; }

/* SIGNAL — amber readout: one soft phosphor halo, nothing stacked. */
body.theme-signal, body.theme-comms {
    --hl-stage: radial-gradient(60vw 44vh at 50% 46%, rgba(240, 168, 58, 0.12), transparent 72%);
    --hl-number-font: 'Share Tech Mono', 'IBM Plex Mono', monospace;
    --hl-number-glow: 0 0 28px rgba(240, 168, 58, 0.45);
    --hl-reveal-glow: 0 0 28px rgba(217, 123, 58, 0.5);
    --hl-votebar-radius: 4px;
}

/* CHANCERY — gilded serif numerals (gradient-clipped gold leaf). */
body.theme-chancery, body.theme-diplomatic {
    --hl-stage: radial-gradient(56vw 40vh at 50% 46%, rgba(201, 164, 79, 0.12), transparent 70%);
    --hl-number-font: 'Playfair Display', Georgia, serif;
    --hl-votebar-radius: 4px;
}
body.theme-chancery .hl-number, body.theme-diplomatic .hl-number {
    background-image: linear-gradient(180deg, #f0d98a 0%, #c9a44f 55%, #8a6c1f 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: none;
    filter: drop-shadow(0 2px 18px rgba(201, 164, 79, 0.3));
}
body.theme-chancery .hl-number-reveal, body.theme-diplomatic .hl-number-reveal {
    background-image: linear-gradient(180deg, #fdf3cf 0%, #f0d98a 45%, #c9a44f 100%);
    filter: drop-shadow(0 2px 26px rgba(240, 217, 138, 0.45));
}

/* INCIDENT — condensed impact numerals, a restrained red bloom. */
body.theme-incident, body.theme-alert {
    --hl-stage: radial-gradient(58vw 42vh at 50% 46%, rgba(232, 87, 76, 0.14), transparent 72%);
    --hl-number-font: 'Anton', 'Archivo', system-ui, sans-serif;
    --hl-number-glow: 0 0 34px rgba(232, 87, 76, 0.4);
    --hl-reveal-glow: 0 0 34px rgba(242, 169, 59, 0.45);
    --hl-votebar-radius: 3px;
}

/* BLUEPRINT — drafting readout: white mono digits on the sheet, hairline bar. */
body.theme-blueprint, body.theme-sketchbook {
    --hl-stage:
        radial-gradient(56vw 40vh at 50% 46%, rgba(242, 246, 251, 0.08), transparent 70%),
        repeating-linear-gradient(90deg, rgba(242, 246, 251, 0.05) 0 1px, transparent 1px 100px),
        repeating-linear-gradient(0deg, rgba(242, 246, 251, 0.05) 0 1px, transparent 1px 100px);
    --hl-number-font: 'IBM Plex Mono', 'Share Tech Mono', monospace;
    --hl-number-ink: #ffffff;
    --hl-number-glow: none;
    --hl-reveal-ink: var(--secondary);
    --hl-reveal-glow: none;
    --hl-votebar-radius: 2px;
}
body.theme-blueprint .hl-number, body.theme-sketchbook .hl-number { font-weight: 500; }
body.theme-blueprint .hl-votebar, body.theme-sketchbook .hl-votebar {
    border: 1px solid rgba(242, 246, 251, 0.55);
}

/* ARENA — the broadcast number stage: spotlight pool + two crossing
   beams, gold-leaf Anton numerals, warm-white reveal, gold-rimmed bar. */
body.theme-arena, body.theme-gameshow {
    --hl-stage:
        radial-gradient(48vw 36vh at 50% 46%, rgba(255, 241, 204, 0.16), transparent 70%),
        conic-gradient(from 148deg at 6% -8%, transparent 0deg, rgba(242, 182, 50, 0.11) 8deg, transparent 17deg),
        conic-gradient(from 195deg at 94% -8%, transparent 0deg, rgba(242, 182, 50, 0.11) 8deg, transparent 17deg),
        linear-gradient(180deg, transparent 84%, rgba(242, 182, 50, 0.05) 100%);
    --hl-number-font: 'Anton', 'Archivo', system-ui, sans-serif;
    --hl-votebar-radius: 6px;
}
body.theme-arena .hl-number, body.theme-gameshow .hl-number {
    background-image: linear-gradient(180deg, #fff1cc 0%, #f2b632 46%, #b9821a 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    text-shadow: none;
    filter: drop-shadow(0 4px 30px rgba(242, 182, 50, 0.35));
    letter-spacing: 0.04em;
}
body.theme-arena .hl-number-reveal, body.theme-gameshow .hl-number-reveal {
    background-image: linear-gradient(180deg, #ffffff 0%, #fff1cc 55%, #f2b632 100%);
    filter: drop-shadow(0 4px 40px rgba(255, 241, 204, 0.5));
}
body.theme-arena .hl-question, body.theme-gameshow .hl-question { color: var(--accent); }
body.theme-arena .hl-votebar, body.theme-gameshow .hl-votebar {
    border: 1px solid rgba(242, 182, 50, 0.45);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6), 0 12px 40px rgba(0, 0, 0, 0.5);
}
/* Voter: HIGHER is the gold key, LOWER the ivory key — both big, both obvious. */
body.theme-arena .hl-voter-btn, body.theme-gameshow .hl-voter-btn {
    border: 2px solid #f2b632;
    border-radius: 12px;
    background: linear-gradient(180deg, #f8c85a, #f2b632 60%, #d99b1e);
    color: #1a1200;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
body.theme-arena .hl-voter-btn.hl-voter-lower, body.theme-gameshow .hl-voter-btn.hl-voter-lower {
    border-color: #e9e5dc;
    background: linear-gradient(180deg, #ffffff, #e9e5dc 60%, #cfc9bc);
    color: #1a1a1a;
}
body.theme-arena .hl-voter-btn.locked, body.theme-gameshow .hl-voter-btn.locked {
    box-shadow: 0 0 0 4px rgba(242, 182, 50, 0.35), 0 0 36px rgba(242, 182, 50, 0.45),
                inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
body.theme-arena .hl-voter-btn.dimmed, body.theme-gameshow .hl-voter-btn.dimmed { opacity: 0.35; }

/* CLINICAL — lab readout: teal mono digits on white, thin bar. */
body.theme-clinical, body.theme-biolab {
    --hl-stage:
        radial-gradient(52vw 40vh at 50% 46%, #ffffff, transparent 72%),
        repeating-radial-gradient(circle at 50% 46%, transparent 0 120px, rgba(15, 124, 114, 0.06) 120px 121px);
    --hl-number-font: 'IBM Plex Mono', 'Share Tech Mono', monospace;
    --hl-number-ink: var(--accent);
    --hl-number-glow: none;
    --hl-reveal-ink: var(--secondary);
    --hl-reveal-glow: none;
    --hl-votebar-radius: 4px;
}
body.theme-clinical .hl-number, body.theme-biolab .hl-number { font-weight: 500; }
body.theme-clinical .hl-voter-btn, body.theme-biolab .hl-voter-btn {
    border: 2px solid var(--line);
    background: var(--surface);
    box-shadow: 0 2px 8px rgba(27, 36, 41, 0.08);
}

/* ---- The lobby's Wi-Fi colours per world (display.css --lobby-*) ----
   Step 1 (join the Wi-Fi) is the venue's Wi-Fi sign: a light card on the
   dark worlds, a dark one on the paper worlds, labelled in a Wi-Fi colour
   deep (or light) enough for it (--lobby-wifi-sign); the top-left corner
   chip is framed in --lobby-wifi. The default teal suits most worlds; these
   take another where teal would read as their own accent. */
body.theme-arena, body.theme-gameshow { --lobby-wifi: #5aa9e6; --lobby-wifi-ink: #06121f; --lobby-wifi-sign: #1f6fb2; }
body.theme-boardroom, body.theme-office,
body.theme-clinical, body.theme-biolab { --lobby-sign-bg: #1d232b; --lobby-sign-ink: #f4f7fb; --lobby-sign-mut: #a9b0ba; }
body.theme-boardroom, body.theme-office { --lobby-wifi: #0f7c72; --lobby-wifi-ink: #fff; --lobby-wifi-sign: #5fd3c3; }
body.theme-clinical, body.theme-biolab { --lobby-wifi: #1f6fb2; --lobby-wifi-ink: #fff; --lobby-wifi-sign: #7db9ee; }
body.theme-blueprint, body.theme-sketchbook { --lobby-wifi: #7fe8d6; --lobby-wifi-ink: #0b2a4a; --lobby-wifi-sign: #0f7c72; }
/* House lights up while the room comes in: ARENA's vignette would shade the
   corners of the light Wi-Fi card, so it waits for the lobby to go. */
body.surface-display.theme-arena::after, body.surface-display.theme-gameshow::after { transition: opacity 0.8s ease; }
body.surface-display.theme-arena:has(#screen-lobby.active)::after,
body.surface-display.theme-gameshow:has(#screen-lobby.active)::after { opacity: 0; }

/* ============================================================
   ABYSS (2026-10-14, HADAL) — teal-black water seven kilometres down,
   one sonar-green accent, practical amber as the second colour, Rajdhani
   caps. Marine snow and sonar rings in the backdrop; the centre stays calm.
   ============================================================ */
body.theme-abyss {
    --bg: #061317;
    --surface: #0c1d22;
    --ink: #dcebe8;
    --mut: #93acaa;
    --faint: #6b8987;
    --line: rgba(220, 235, 232, 0.12);
    --track: #11262c;
    --chip: #11262c;
    --accent: #3fd1a0;
    --accent-ink: #061317;
    --tint: rgba(63, 209, 160, 0.14);
    --choice-a: #3fd1a0;
    --choice-b: #e8a34a;
    --choice-c: #5fe3ff;
    --choice-d: #e86a5f;
    --choice-e: #b9a7ff;
    --choice-f: #a6d36b;
    --choice-g: #f08aa8;
    --choice-h: #d8d8d8;
    --secondary: #e8a34a;
    --secondary-dim: rgba(232, 163, 74, 0.18);
    --danger: #e86a5f;
    --danger-dim: rgba(232, 106, 95, 0.18);
    --success: #3fd1a0;
    --success-dim: rgba(63, 209, 160, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Rajdhani', 'Archivo', system-ui, sans-serif;
    --theme-track: 0.1em;
    --theme-weight: 700;
    --theme-backdrop: url('/static/images/themes/abyss/backdrop.svg');
    --hl-stage: radial-gradient(60vw 44vh at 50% 52%, rgba(63, 209, 160, 0.10), transparent 72%);
    --hl-number-font: 'Rajdhani', 'Archivo', system-ui, sans-serif;
    --hl-number-glow: 0 0 30px rgba(63, 209, 160, 0.4);
    --hl-reveal-glow: 0 0 30px rgba(95, 227, 255, 0.45);
    --hl-votebar-radius: 3px;
}
body.theme-abyss .placeholder-visual.ph-1 { background-image: url('/static/images/themes/abyss/scene_1.svg'); }
body.theme-abyss .placeholder-visual.ph-2 { background-image: url('/static/images/themes/abyss/scene_2.svg'); }
body.theme-abyss .placeholder-visual.ph-3 { background-image: url('/static/images/themes/abyss/scene_3.svg'); }
body.theme-abyss .placeholder-visual.ph-4 { background-image: url('/static/images/themes/abyss/scene_4.svg'); }

/* ============================================================
   GLASSHOUSE (2026-10-18) — the storyboard's look (docs/storyboards/src/
   glasshouse.py): night river ground, glass ink, screen-cyan accent,
   sodium amber outside, red only when something has gone wrong.
   Instrument Serif caps, as the opener's title.
   ============================================================ */
body.theme-glasshouse {
    --bg: #0e1a24;
    --surface: #132029;
    --ink: #e6f0f2;
    --mut: #9fb4ba;
    --faint: #8799a0;
    --line: rgba(159, 195, 201, 0.16);
    --track: #172732;
    --chip: #172732;
    --accent: #39b6d8;
    --accent-ink: #0e1a24;
    --tint: rgba(57, 182, 216, 0.14);
    --choice-a: #39b6d8;
    --choice-b: #f2a33a;
    --choice-c: #7fe0c4;
    --choice-d: #f06a62;
    --choice-e: #b9a7ff;
    --choice-f: #a6d36b;
    --choice-g: #f08aa8;
    --choice-h: #d8d8d8;
    --secondary: #f2a33a;
    --secondary-dim: rgba(242, 163, 58, 0.18);
    --danger: #f06a62;
    --danger-dim: rgba(210, 59, 59, 0.18);
    --success: #39b6d8;
    --success-dim: rgba(57, 182, 216, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Instrument Serif', Georgia, serif;
    --theme-track: 0.06em;
    --theme-weight: 400;
    --theme-backdrop: url('/static/images/themes/glasshouse/backdrop.svg');
    --hl-stage: radial-gradient(60vw 44vh at 50% 52%, rgba(57, 182, 216, 0.10), transparent 72%);
    --hl-number-font: 'Instrument Serif', Georgia, serif;
    --hl-number-glow: 0 0 30px rgba(57, 182, 216, 0.4);
    --hl-reveal-glow: 0 0 30px rgba(242, 163, 58, 0.45);
    --hl-votebar-radius: 2px;
}
body.theme-glasshouse .placeholder-visual.ph-1 { background-image: url('/static/images/themes/glasshouse/scene_1.svg'); }
body.theme-glasshouse .placeholder-visual.ph-2 { background-image: url('/static/images/themes/glasshouse/scene_2.svg'); }
body.theme-glasshouse .placeholder-visual.ph-3 { background-image: url('/static/images/themes/glasshouse/scene_3.svg'); }
body.theme-glasshouse .placeholder-visual.ph-4 { background-image: url('/static/images/themes/glasshouse/scene_4.svg'); }

/* ============================================================
   MEZZANINE (2026-10-19) — FLOOR 13½'s world (docs/storyboards/src/
   floor13.py): the lift car from its back wall. Walnut ground, dial
   cream ink, brass accent, operator maroon rose, the DON'T red only for
   danger. Playfair Display, as the opener's dial.
   ============================================================ */
body.theme-mezzanine {
    --bg: #2c1b10;
    --surface: #3a2416;
    --ink: #efe6d2;
    --mut: #cdb994;
    --faint: #b49c78;
    --line: rgba(200, 160, 70, 0.20);
    --track: #42291a;
    --chip: #42291a;
    --accent: #c8a046;
    --accent-ink: #2c1b10;
    --tint: rgba(200, 160, 70, 0.14);
    --choice-a: #c8a046;
    --choice-b: #e07a8c;
    --choice-c: #8fc7b0;
    --choice-d: #f0d9a8;
    --choice-e: #b9a7ff;
    --choice-f: #a6d36b;
    --choice-g: #7cc4f2;
    --choice-h: #d8d8d8;
    --secondary: #e07a8c;
    --secondary-dim: rgba(123, 30, 44, 0.30);
    --danger: #f47a6e;
    --danger-dim: rgba(212, 38, 44, 0.20);
    --success: #c8a046;
    --success-dim: rgba(200, 160, 70, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Playfair Display', Georgia, serif;
    --theme-track: 0.04em;
    --theme-weight: 700;
    --theme-backdrop: url('/static/images/themes/mezzanine/backdrop.svg');
    --hl-stage: radial-gradient(60vw 44vh at 50% 52%, rgba(242, 196, 109, 0.12), transparent 72%);
    --hl-number-font: 'Playfair Display', Georgia, serif;
    --hl-number-glow: 0 0 30px rgba(242, 196, 109, 0.4);
    --hl-reveal-glow: 0 0 30px rgba(200, 160, 70, 0.45);
    --hl-votebar-radius: 2px;
}
body.theme-mezzanine .placeholder-visual.ph-1 { background-image: url('/static/images/themes/mezzanine/scene_1.svg'); }
body.theme-mezzanine .placeholder-visual.ph-2 { background-image: url('/static/images/themes/mezzanine/scene_2.svg'); }
body.theme-mezzanine .placeholder-visual.ph-3 { background-image: url('/static/images/themes/mezzanine/scene_3.svg'); }
body.theme-mezzanine .placeholder-visual.ph-4 { background-image: url('/static/images/themes/mezzanine/scene_4.svg'); }

/* ============================================================
   AQUARIUM (2026-10-19) — EIGHT's world, from its storyboard (docs/
   storyboards/src/eight.py): a Victorian pier aquarium at night, the
   deep teal of the tanks, glass-glow teal, brass plaques, and Maud's
   warm clay red for danger. Playfair Display, as the opener's title.
   ============================================================ */
body.theme-aquarium {
    --bg: #0b2530;
    --surface: #10303b;
    --ink: #f3ece0;
    --mut: #a9c4c4;
    --faint: #8aa8aa;
    --line: rgba(79, 179, 173, 0.18);
    --track: #143844;
    --chip: #143844;
    --accent: #4fb3ad;
    --accent-ink: #0b2530;
    --tint: rgba(79, 179, 173, 0.14);
    --choice-a: #4fb3ad;
    --choice-b: #e0b062;
    --choice-c: #f2a7b8;
    --choice-d: #f08070;
    --choice-e: #8fd0e8;
    --choice-f: #c9a7e8;
    --choice-g: #b6d97a;
    --choice-h: #d8d2c4;
    --secondary: #e0b062;
    --secondary-dim: rgba(196, 154, 82, 0.18);
    --danger: #e2644f;
    --danger-dim: rgba(194, 86, 61, 0.2);
    --success: #4fb3ad;
    --success-dim: rgba(79, 179, 173, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Playfair Display', Georgia, serif;
    --theme-track: 0.02em;
    --theme-weight: 700;
    --theme-backdrop: url('/static/images/themes/aquarium/backdrop.svg');
    --hl-stage: radial-gradient(60vw 44vh at 50% 52%, rgba(79, 179, 173, 0.12), transparent 72%);
    --hl-number-font: 'Playfair Display', Georgia, serif;
    --hl-number-glow: 0 0 30px rgba(79, 179, 173, 0.4);
    --hl-reveal-glow: 0 0 30px rgba(224, 176, 98, 0.45);
    --hl-votebar-radius: 6px;
}
body.theme-aquarium .placeholder-visual.ph-1 { background-image: url('/static/images/themes/aquarium/scene_1.svg'); }
body.theme-aquarium .placeholder-visual.ph-2 { background-image: url('/static/images/themes/aquarium/scene_2.svg'); }
body.theme-aquarium .placeholder-visual.ph-3 { background-image: url('/static/images/themes/aquarium/scene_3.svg'); }
body.theme-aquarium .placeholder-visual.ph-4 { background-image: url('/static/images/themes/aquarium/scene_4.svg'); }

/* ============================================================
   PREMIERE (2026-10-14) — the storyboard page as a world any scenario
   can pick (docs/storyboards/viewer/style.css, its night): a near-black
   ground, dark cards with a coloured top edge, Big Shoulders Display caps
   for the titles, Courier Prime for the slate's
   labels and the italic lines, Archivo for reading. One violet accent,
   tungsten as the second colour, the storyboard's red for danger. Fact
   panels (the join card, a slide's figures, an escape room's numbers) are
   the clapperboard slate: a 2px ink frame, Courier labels, condensed
   figures. The menus' cards (scenario_cards.css) share the look.
   ============================================================ */
body.theme-premiere {
    --bg: #0a0d10;
    --surface: #11161b;
    --ink: #e4e8ec;
    --mut: #a9b3bd;
    --faint: #808c98;
    --line: rgba(228, 232, 236, 0.12);
    --track: #1a2129;
    --chip: #1a2129;
    --accent: #b9a2ff;
    --accent-ink: #0a0d10;
    --tint: rgba(185, 162, 255, 0.15);
    --choice-a: #b9a2ff;
    --choice-b: #f2c14e;
    --choice-c: #46d0c2;
    --choice-d: #ff6f7d;
    --choice-e: #8ec5ff;
    --choice-f: #b8e06a;
    --choice-g: #f59ad0;
    --choice-h: #d3d9df;
    --secondary: #f2c14e;
    --secondary-dim: rgba(242, 193, 78, 0.18);
    --danger: #ff6f7d;
    --danger-dim: rgba(255, 111, 125, 0.18);
    --success: #64c78d;
    --success-dim: rgba(100, 199, 141, 0.18);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Big Shoulders Display', 'Archivo', system-ui, sans-serif;
    --theme-track: 0.03em;
    --theme-weight: 800;
    --theme-backdrop: url('/static/images/themes/premiere/backdrop.svg');
    --premiere-script: 'Courier Prime', 'Courier New', Courier, monospace;
    --hl-stage:
        radial-gradient(56vw 40vh at 50% 48%, rgba(185, 162, 255, 0.10), transparent 72%),
        conic-gradient(from 160deg at 50% -12%, transparent 0deg, rgba(242, 193, 78, 0.06) 14deg, transparent 40deg);
    --hl-number-font: 'Big Shoulders Display', 'Archivo', system-ui, sans-serif;
    --hl-number-glow: 0 0 30px rgba(185, 162, 255, 0.35);
    --hl-reveal-glow: 0 0 30px rgba(242, 193, 78, 0.4);
    --hl-votebar-radius: 4px;
}
body.theme-premiere .placeholder-visual.ph-1 { background-image: url('/static/images/themes/premiere/scene_1.svg'); }
body.theme-premiere .placeholder-visual.ph-2 { background-image: url('/static/images/themes/premiere/scene_2.svg'); }
body.theme-premiere .placeholder-visual.ph-3 { background-image: url('/static/images/themes/premiere/scene_3.svg'); }
body.theme-premiere .placeholder-visual.ph-4 { background-image: url('/static/images/themes/premiere/scene_4.svg'); }
body.theme-premiere .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(10, 13, 16, 0.95) 30%); }

/* Poster titles: caps, in ink (the storyboard's headings). */
body.theme-premiere .story-title,
body.theme-premiere .lobby-title,
body.theme-premiere .info-title,
body.theme-premiere .ending-title,
body.theme-premiere .banner-title {
    text-transform: uppercase;
}
body.theme-premiere .story-title { color: var(--ink); text-shadow: none; }
body.theme-premiere .hl-number { font-weight: 800; letter-spacing: 0.02em; }
/* The poster face's glyph box is 1.2 em tall (Archivo's 1.09): a line any
   shorter lets the digits' box out of the bottom of the timer's box. */
body.theme-premiere .timer-countdown-display {
    font-family: 'Big Shoulders Display', 'Archivo', system-ui, sans-serif;
    font-weight: 800;
    letter-spacing: 0.02em;
    line-height: 1.2;
    text-shadow: none;
}

/* The screenplay voice: eyebrows and badges as the slate's Courier labels... */
body.theme-premiere .screen-eyebrow,
body.theme-premiere .lt-eyebrow,
body.theme-premiere .info-eyebrow,
body.theme-premiere .escape-eyebrow,
body.theme-premiere .qna-overlay-eyebrow,
body.theme-premiere .quiz-badge,
body.theme-premiere .briefing-badge,
body.theme-premiere .ending-badge,
body.theme-premiere .quiz-voter-badge,
body.theme-premiere .hl-round-badge,
body.theme-premiere .ins-badge {
    font-family: var(--premiere-script);
    font-weight: 700;
    letter-spacing: 0.1em;
}
/* ...and the one-liners in Courier italic in the accent (the storyboard's tagline). */
body.theme-premiere .story-consequence,
body.theme-premiere .results-consequence,
body.theme-premiere .leaderboard-sub,
body.theme-premiere .slide-subtitle {
    font-family: var(--premiere-script);
    font-style: italic;
    color: var(--accent);
    opacity: 1;
}

/* Fact panels as the clapperboard slate. */
body.theme-premiere .lobby-join-section { border: 0.28vh solid var(--ink); border-radius: 0.4vh; }
body.theme-premiere .slide-number { border: 0.2vh solid var(--ink); border-radius: 0.4vh; }
body.theme-premiere .lobby-step-label,
body.theme-premiere .slide-number-label,
body.theme-premiere .escape-stat-label {
    font-family: var(--premiere-script);
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}
body.theme-premiere .lobby-code,
body.theme-premiere .slide-number-value,
body.theme-premiere .escape-stat-value {
    font-family: 'Big Shoulders Display', 'Archivo', system-ui, sans-serif;
    font-weight: 800;
    text-shadow: none;
}
body.theme-premiere .escape-stats {
    border: 0.2vh solid var(--ink);
    border-radius: 0.4vh;
    background: var(--surface);
}

/* Cards on the night: the accent along the top edge, square-ish corners. */
body.theme-premiere .choice-card,
body.theme-premiere .party-card,
body.theme-premiere .priority-card,
body.theme-premiere .inject-card,
body.theme-premiere .spin-card,
body.theme-premiere .ending-team-card,
body.theme-premiere .escape-team-card {
    border-top: 0.3vh solid var(--accent);
    border-radius: 0.6vh;
}

/* ============================================================
   COMMITTEE (2026-10-14, MOONFALL) — the leisure centre's sports hall
   under fluorescent tubes, played completely straight: a pale
   institutional ground, laminated-white cards with the committee's blue
   along the top, Archivo caps for the titles, lanyard red for the
   eyebrows (the CONFIDENTIAL stamp), court green for a right answer.
   The badminton court's lines and the Moon's empty place in the
   backdrop. THE THIRD LIGHT THEME.
   ============================================================ */
body.theme-committee {
    --bg: #eef1ea;
    --surface: #fbfbf7;
    --ink: #1f2a44;
    --mut: #4c566b;
    --faint: #575f71;
    --line: rgba(31, 42, 68, 0.14);
    --track: #e2ddd0;
    --chip: #e7e2d5;
    --accent: #2b44a0;
    --accent-ink: #ffffff;
    --tint: #e2e7f4;
    --choice-a: #2b44a0;
    --choice-b: #9a5a12;
    --choice-c: #2d6a48;
    --choice-d: #b3302b;
    --choice-e: #8e2f74;
    --choice-f: #0e6e7c;
    --choice-g: #5b5f68;
    --choice-h: #6b6a10;
    --secondary: #8a5414;
    --secondary-dim: rgba(138, 84, 20, 0.14);
    --danger: #b3302b;
    --danger-dim: rgba(179, 48, 43, 0.12);
    --success: #2d6a48;
    --success-dim: rgba(45, 106, 72, 0.12);
    --primary: var(--accent);
    --primary-dim: var(--tint);
    --primary-glow: transparent;
    --bg-dark: var(--bg);
    --bg-panel: var(--surface);
    --bg-card: var(--surface);
    --bg-body: var(--bg);
    --bg-sidebar: var(--surface);
    --bg-input: var(--bg);
    --text-primary: var(--ink);
    --text-secondary: var(--mut);
    --text-dim: var(--faint);
    --border-glow: var(--line);
    --border: var(--line);
    --grid-color: transparent;
    --theme-font: 'Archivo', system-ui, sans-serif;
    --theme-track: 0.04em;
    --theme-weight: 700;
    --theme-backdrop: url('/static/images/themes/committee/backdrop.svg');
    --hl-stage:
        radial-gradient(56vw 40vh at 50% 46%, #ffffff, transparent 72%),
        linear-gradient(180deg, transparent 86%, rgba(63, 125, 90, 0.16) 86% calc(86% + 2px), transparent calc(86% + 2px));
    --hl-number-font: 'Archivo', system-ui, sans-serif;
    --hl-number-ink: var(--accent);
    --hl-number-glow: none;
    --hl-reveal-ink: var(--secondary);
    --hl-reveal-glow: none;
    --hl-votebar-radius: 2px;
    --lobby-sign-bg: #1d232b;
    --lobby-sign-ink: #f4f7fb;
    --lobby-sign-mut: #a9b0ba;
    --lobby-wifi: #0f7c72;
    --lobby-wifi-ink: #fff;
    --lobby-wifi-sign: #5fd3c3;
}
body.theme-committee .placeholder-visual.ph-1 { background-image: url('/static/images/themes/committee/scene_1.svg'); }
body.theme-committee .placeholder-visual.ph-2 { background-image: url('/static/images/themes/committee/scene_2.svg'); }
body.theme-committee .placeholder-visual.ph-3 { background-image: url('/static/images/themes/committee/scene_3.svg'); }
body.theme-committee .placeholder-visual.ph-4 { background-image: url('/static/images/themes/committee/scene_4.svg'); }
body.theme-committee .story-container.layout-full .story-text-area { background: linear-gradient(transparent, rgba(238, 241, 234, 0.96) 30%); }

/* Fluorescent light on laminated paper: no glow on the words. */
body.theme-committee .screen > div,
body.theme-committee .info-content,
body.theme-committee .quiz-voter-content {
    text-shadow: none;
}
/* The agenda's titles, in caps. */
body.theme-committee .story-title,
body.theme-committee .lobby-title,
body.theme-committee .info-title,
body.theme-committee .ending-title,
body.theme-committee .banner-title {
    text-transform: uppercase;
}
body.theme-committee .hl-number { font-weight: 700; letter-spacing: 0.01em; }
/* Eyebrows and badges as tracked grotesk caps; the eyebrows in the
   CONFIDENTIAL stamp's red. */
body.theme-committee .screen-eyebrow,
body.theme-committee .lt-eyebrow,
body.theme-committee .info-eyebrow,
body.theme-committee .quiz-badge,
body.theme-committee .briefing-badge,
body.theme-committee .ending-badge {
    font-family: 'Archivo', system-ui, sans-serif;
    font-weight: 700;
    letter-spacing: 0.16em;
}
body.theme-committee .screen-eyebrow,
body.theme-committee .lt-eyebrow,
body.theme-committee .info-eyebrow {
    color: var(--danger);
}
/* Laminated name cards: the committee's blue along the top edge. */
body.theme-committee .choice-card,
body.theme-committee .party-card,
body.theme-committee .priority-card,
body.theme-committee .inject-card,
body.theme-committee .spin-card,
body.theme-committee .ending-team-card,
body.theme-committee .escape-team-card {
    border-top: 0.3vh solid var(--accent);
    border-radius: 0.4vh;
}
