/* =========================================================================
   ODD ONE OUT — DESIGN TOKENS
   =========================================================================
   This file is the single source of truth for every visual decision in the
   game. Colors, type, spacing, radius, shadows, animation timing, audio,
   layering — it all lives here as CSS custom properties.

   How it works:
   - Every token is a CSS variable on :root (or scoped to a theme).
   - Game code references these variables via var(--token-name).
   - DaisyUI's theme variables are overridden below so existing Tailwind
     classes like `bg-primary` immediately use our values.
   - Change a value here, see it reflected everywhere on next refresh.
   - NOTHING here affects game logic. Only appearance and feel.

   For designers / Claude Design:
   - Tokens are grouped by purpose: COLORS, TYPE, SPACE, RADIUS, SHADOW,
     MOTION, AUDIO, Z-INDEX, SURFACE.
   - Each token has a plain-English comment for what it's for.
   - Dark-theme-first (luxury aesthetic). A future `data-theme="light"` or
     `data-theme="neon"` could override via the theme-scoping blocks.

   CONTRACT — do not change:
   - Token names (game code references them by these exact names).
   - DaisyUI override mechanism (only the values get changed, not the keys).
   ========================================================================= */

/* -------------------------------------------------------------------------
   COLORS
   -------------------------------------------------------------------------
   Organized by semantic role, not visual appearance. "primary" is the
   brand color; "accent" is the secondary brand; "warning / success / error"
   carry meaning. Surfaces (`base-100`, `base-200`, `base-300`) are the
   background layers — darkest (100) to lightest (300) in a dark theme.
   ------------------------------------------------------------------------- */
:root,
[data-theme="luxury"] {
  /* --- Brand ------------------------------------------------------------ */
  --game-color-primary:       oklch(78% 0.13 70);   /* hot gold — main brand */
  --game-color-primary-fg:    oklch(18% 0.01 70);   /* text ON primary */
  --game-color-secondary:     oklch(46% 0.14 265);  /* deep indigo — accents */
  --game-color-secondary-fg:  oklch(96% 0.01 265);
  --game-color-accent:        oklch(70% 0.18 340);  /* hot pink — celebration */
  --game-color-accent-fg:     oklch(15% 0.01 340);

  /* --- Status ----------------------------------------------------------- */
  --game-color-success:       oklch(72% 0.17 150);  /* caught them */
  --game-color-warning:       oklch(80% 0.18 80);   /* timer running out */
  --game-color-error:         oklch(62% 0.24 25);   /* they got away, emergency */
  --game-color-info:          oklch(72% 0.13 240);  /* neutral info */

  /* --- Surfaces (dark luxury theme) ------------------------------------ */
  --game-color-base-100:      #0a0a0c;              /* app background */
  --game-color-base-200:      #16161a;              /* card background */
  --game-color-base-300:      #22232a;              /* inset / input background */
  --game-color-base-fg:       oklch(95% 0.01 90);   /* body text */
  --game-color-base-fg-muted: oklch(65% 0.01 90);   /* captions, secondary text */

  /* --- Role accents (for badges, rings, player avatars) ---------------- */
  --game-color-role-host:       var(--game-color-primary);
  --game-color-role-odd:        var(--game-color-error);
  --game-color-role-player:     var(--game-color-secondary);
  --game-color-role-spectator:  oklch(50% 0.02 270);
  --game-color-role-clue-agent: oklch(70% 0.15 180);

  /* --- Overlays / scrims ------------------------------------------------ */
  --game-overlay-solid:   #0a0a0c;                  /* blocking overlay, fully opaque */
  --game-overlay-scrim:   rgb(0 0 0 / 0.72);        /* lighter overlay, content behind dimmed */
  --game-overlay-backdrop: rgb(0 0 0 / 0.45);       /* modal backdrop */

  /* --- Glows (used behind avatars, reveal card, etc.) ------------------ */
  --game-glow-primary:  0 0 80px oklch(78% 0.13 70 / 0.45);
  --game-glow-accent:   0 0 80px oklch(70% 0.18 340 / 0.40);
  --game-glow-error:    0 0 80px oklch(62% 0.24 25 / 0.50);
  --game-glow-success:  0 0 80px oklch(72% 0.17 150 / 0.45);
}

/* -------------------------------------------------------------------------
   DAISYUI OVERRIDES  (active as of Pass 11 — 2026-04-21)
   -------------------------------------------------------------------------
   DaisyUI v5 exposes its theme as CSS variables. By overriding these we
   pipe every `bg-primary`, `text-accent`, `btn-warning` class in the
   codebase through OUR tokens above. No JS or HTML changes needed.

   Flipped on in Pass 11 after design passes 1–10 locked in the final
   paper-cutout palette across every scoped stage. Leaving this on means
   new DaisyUI class usage automatically adopts our tokens.
   ------------------------------------------------------------------------- */
[data-theme="luxury"] {
  --color-primary:      var(--game-color-primary);
  --color-primary-content: var(--game-color-primary-fg);
  --color-secondary:    var(--game-color-secondary);
  --color-secondary-content: var(--game-color-secondary-fg);
  --color-accent:       var(--game-color-accent);
  --color-accent-content: var(--game-color-accent-fg);
  --color-success:      var(--game-color-success);
  --color-warning:      var(--game-color-warning);
  --color-error:        var(--game-color-error);
  --color-info:         var(--game-color-info);
  --color-base-100:     var(--game-color-base-100);
  --color-base-200:     var(--game-color-base-200);
  --color-base-300:     var(--game-color-base-300);
  --color-base-content: var(--game-color-base-fg);
}

/* -------------------------------------------------------------------------
   TYPOGRAPHY
   -------------------------------------------------------------------------
   Two families:
   - DISPLAY (Fredoka One): headlines, reveal text, big moments.
   - BODY    (Inter):       everything else.

   Size scale is declarative — "hero / headline / title / body / caption /
   micro". Designers can swap the whole scale by changing the values.
   ------------------------------------------------------------------------- */
:root {
  --font-display: 'Fredoka One', system-ui, sans-serif;
  --font-body:    'Inter', system-ui, sans-serif;
  --font-mono:    ui-monospace, 'SF Mono', Menlo, monospace;

  /* Sizes (clamp so the TV scales gracefully with viewport) */
  --text-hero:     clamp(3rem,  6vw, 6rem);     /* reveal banners, slot machine result */
  --text-headline: clamp(2.25rem, 4vw, 3.75rem); /* screen titles on TV */
  --text-title:    clamp(1.5rem, 2.5vw, 2.25rem); /* screen titles on phone, card headers */
  --text-body:     1rem;
  --text-small:    0.875rem;
  --text-caption:  0.75rem;
  --text-micro:    0.625rem;

  /* Weights */
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  /* Line heights */
  --leading-tight:   1.1;
  --leading-snug:    1.3;
  --leading-normal:  1.5;
  --leading-relaxed: 1.75;

  /* Letter spacing */
  --tracking-tight:  -0.02em;
  --tracking-normal: 0;
  --tracking-wide:   0.05em;
  --tracking-wider:  0.1em;
}

/* -------------------------------------------------------------------------
   SPACING
   -------------------------------------------------------------------------
   Standard 8-point scale. Tailwind's own spacing stays in use (p-4 etc.);
   these are for custom components that want to follow the same rhythm.
   ------------------------------------------------------------------------- */
:root {
  --space-0:  0;
  --space-1:  0.25rem;  /*  4px */
  --space-2:  0.5rem;   /*  8px */
  --space-3:  0.75rem;  /* 12px */
  --space-4:  1rem;     /* 16px */
  --space-5:  1.25rem;  /* 20px */
  --space-6:  1.5rem;   /* 24px */
  --space-8:  2rem;     /* 32px */
  --space-10: 2.5rem;   /* 40px */
  --space-12: 3rem;     /* 48px */
  --space-16: 4rem;     /* 64px */
  --space-24: 6rem;     /* 96px */
}

/* -------------------------------------------------------------------------
   RADIUS
   -------------------------------------------------------------------------
   Corner roundness scale. `radius-pill` is for fully-rounded buttons;
   `radius-full` is for circles (avatars).
   ------------------------------------------------------------------------- */
:root {
  --radius-sm:   0.375rem;   /*  6px — tight inputs */
  --radius-md:   0.625rem;   /* 10px — standard buttons */
  --radius-lg:   1rem;       /* 16px — cards */
  --radius-xl:   1.5rem;     /* 24px — big cards, reveal panels */
  --radius-pill: 9999px;
  --radius-full: 9999px;
}

/* -------------------------------------------------------------------------
   SHADOWS & ELEVATION
   -------------------------------------------------------------------------
   Four levels plus glow variants. "Elevation" is the standard material-
   style depth cues; "glow" is the dramatic colored halo for reveals and
   celebrations — signature luxury/Jackbox feel.
   ------------------------------------------------------------------------- */
:root {
  --elevation-sm:  0 1px 2px rgb(0 0 0 / 0.35);
  --elevation-md:  0 4px 12px rgb(0 0 0 / 0.40);
  --elevation-lg:  0 10px 30px rgb(0 0 0 / 0.55);
  --elevation-xl:  0 20px 60px rgb(0 0 0 / 0.65);

  --glow-primary:  var(--game-glow-primary);
  --glow-accent:   var(--game-glow-accent);
  --glow-error:    var(--game-glow-error);
  --glow-success:  var(--game-glow-success);

  /* Rings — used on avatars, selected cards */
  --ring-width-sm: 2px;
  --ring-width-md: 4px;
  --ring-width-lg: 8px;
}

/* -------------------------------------------------------------------------
   MOTION (DURATIONS + EASINGS)
   -------------------------------------------------------------------------
   Every animation in the game pulls its duration and easing from here.
   This is how a designer re-tunes "feel" without touching code:
   - Make everything faster: reduce all durations.
   - Make reveals more dramatic: stretch `--dur-reveal-step`.
   - Softer UI: swap `--ease-snap` for `--ease-out`.
   ------------------------------------------------------------------------- */
:root {
  /* Durations */
  --dur-instant:     0ms;
  --dur-quick:       120ms;  /* button press feedback */
  --dur-fast:        240ms;  /* hover, small transitions */
  --dur-normal:      400ms;  /* screen fades, card appearances */
  --dur-slow:        800ms;  /* dramatic reveals */
  --dur-dramatic:    1500ms; /* slot machine stops, reveal banner */
  --dur-epic:        3000ms; /* full-screen celebrations */

  /* Animation stage times — used by reveal timeline */
  --dur-reveal-step:        700ms;
  --dur-testimonial-inter:  1500ms; /* pause between testimonial videos */
  --dur-slot-stop:          2500ms; /* slot machine settles */
  --dur-countdown-tick:     1000ms;

  /* Easings (pure CSS cubic-beziers; GSAP code uses named aliases) */
  --ease-linear:   linear;
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);         /* smooth stop */
  --ease-in:       cubic-bezier(0.7, 0, 0.84, 0);         /* slow start */
  --ease-in-out:   cubic-bezier(0.87, 0, 0.13, 1);        /* dramatic */
  --ease-snap:     cubic-bezier(0.22, 1, 0.36, 1);        /* quick punchy UI */
  --ease-bounce:   cubic-bezier(0.68, -0.55, 0.265, 1.55);/* playful overshoot */
  --ease-elastic:  cubic-bezier(0.68, -0.6, 0.32, 1.6);   /* rubber band */
}

/* -------------------------------------------------------------------------
   AUDIO (CONCEPTUAL — informs AudioManager if we wire it up)
   -------------------------------------------------------------------------
   We have sound files in /client/assets/sounds/. If a designer wants to
   re-balance audio globally, these variables act as the dial. Currently
   informational — AudioManager would need to read these to actually use
   them.
   ------------------------------------------------------------------------- */
:root {
  --audio-volume-default: 0.8;   /* 0 to 1 */
  --audio-volume-duck:    0.3;   /* when video is playing */
  --audio-fade-in:        200ms;
  --audio-fade-out:       400ms;
}

/* -------------------------------------------------------------------------
   Z-INDEX LAYERING
   -------------------------------------------------------------------------
   Every overlay / modal / floating element picks from this scale. Higher
   number wins. Keeping them declarative prevents arbitrary z-index wars.
   ------------------------------------------------------------------------- */
:root {
  --z-base:           1;
  --z-sticky:         20;
  --z-dropdown:       30;
  --z-overlay-scrim:  40;
  --z-modal:          50;
  --z-slot-machine:   60;   /* host reveal takes over everything */
  --z-between-countdown: 70; /* countdown wins over slot machine */
  --z-toast:          80;
  --z-debug:          9999;
}

/* -------------------------------------------------------------------------
   SURFACE RECIPES
   -------------------------------------------------------------------------
   Pre-mixed backgrounds for commonly-styled surfaces. Reusing these keeps
   cards/modals/reveals visually consistent.
   ------------------------------------------------------------------------- */
:root {
  --surface-card:       var(--game-color-base-200);
  --surface-card-hover: color-mix(in oklab, var(--game-color-base-200) 85%, var(--game-color-primary));
  --surface-inset:      var(--game-color-base-300);
  --surface-overlay:    var(--game-overlay-solid);
  --surface-badge:      color-mix(in oklab, var(--game-color-base-300) 80%, transparent);
}

/* -------------------------------------------------------------------------
   GAME-SPECIFIC SEMANTIC UTILITY CLASSES
   -------------------------------------------------------------------------
   Thin utility classes that make intent readable in HTML. These are NOT
   required — existing Tailwind classes still work — but as screens get
   cleaned up, replacing `class="bg-primary/20 text-primary font-display"`
   with `class="badge-host"` makes the HTML self-documenting and gives a
   designer ONE selector to restyle.

   Rule of thumb: add a semantic class here when the same visual treatment
   appears in 3+ places.
   ------------------------------------------------------------------------- */
.surface-overlay-solid {
  background: var(--surface-overlay);
}

.surface-overlay-scrim {
  background: var(--game-overlay-scrim);
}

.surface-overlay-backdrop {
  background: var(--game-overlay-backdrop);
}

.glow-primary   { box-shadow: var(--glow-primary); }
.glow-accent    { box-shadow: var(--glow-accent); }
.glow-error     { box-shadow: var(--glow-error); }
.glow-success   { box-shadow: var(--glow-success); }

/* Role accents — wrap an avatar / card to signal a player's role. */
.role-host      { --role-accent: var(--game-color-role-host); }
.role-odd       { --role-accent: var(--game-color-role-odd); }
.role-player    { --role-accent: var(--game-color-role-player); }
.role-spectator { --role-accent: var(--game-color-role-spectator); }
.role-clue      { --role-accent: var(--game-color-role-clue-agent); }

.role-ring {
  box-shadow: 0 0 0 var(--ring-width-md) var(--role-accent, var(--game-color-primary));
}

/* -------------------------------------------------------------------------
   MOTION UTILITIES
   -------------------------------------------------------------------------
   Drop these on any element to get tuned, consistent motion. They pair
   CSS `transition-duration` + `transition-timing-function` with our token
   values, so the "feel" stays coherent across the whole game.
   ------------------------------------------------------------------------- */
.motion-quick   { transition: all var(--dur-quick) var(--ease-snap); }
.motion-fast    { transition: all var(--dur-fast) var(--ease-out); }
.motion-normal  { transition: all var(--dur-normal) var(--ease-in-out); }
.motion-slow    { transition: all var(--dur-slow) var(--ease-in-out); }

.motion-bounce  { transition: transform var(--dur-fast) var(--ease-bounce); }
.motion-snap    { transition: transform var(--dur-quick) var(--ease-snap); }

/* Keyframe library — callable from either CSS `animation:` or JS. */
@keyframes pulse-glow {
  0%, 100% { filter: drop-shadow(0 0 0 transparent); }
  50%      { filter: drop-shadow(var(--glow-primary)); }
}

@keyframes tv-attention-pulse {
  0%, 100% { opacity: 0.9; transform: scale(1); }
  50%      { opacity: 1;   transform: scale(1.03); }
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-6px); }
  75%      { transform: translateX(6px); }
}

@keyframes slide-up-fade {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.anim-pulse-glow         { animation: pulse-glow var(--dur-epic) var(--ease-in-out) infinite; }
.anim-attention-pulse    { animation: tv-attention-pulse var(--dur-dramatic) var(--ease-in-out) infinite; }
.anim-shake              { animation: shake var(--dur-fast) var(--ease-out); }
.anim-slide-up-fade      { animation: slide-up-fade var(--dur-normal) var(--ease-out) both; }
.anim-fade-in            { animation: fade-in var(--dur-normal) var(--ease-out) both; }


/* =========================================================================
   LOBBY / SKETCH THEME (cartoon / warm / paper-cutout) — shared primitives scoped to :is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"])
   =========================================================================
   Adapted from Claude Design's "Sketch Lobby" direction (April 2026).
   These rules apply inside any container whose `data-stage` starts with
   `lobby` or `phone-` (lobby, phone-entry, phone-role-reveal,
   phone-round-active, phone-host-checklist, phone-gather, phone-voting,
   phone-spectator, phone-overlay). The rest of the game keeps the
   luxury-dark palette. When design lands on the global redesign, these
   can be promoted to :root.

   Lobby-decorative primitives (.wordmark, .room-ticket,
   .player-paper-card, .ready-counter, brick-wall background,
   #player-list hide) stay scoped to :is([data-stage^="lobby"],
   [data-stage="phone-entry"]) — they're specific to the pre-round
   screens.

   Contract:
   - No element IDs or data-slot names change.
   - Purely additive visual layer. Pre-existing Tailwind/DaisyUI classes on
     the lobby elements still resolve normally; these just override look.
   ========================================================================= */

:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) {
  /* Ink / line system */
  --lobby-ink:           #1A1613;
  --lobby-ink-soft:      #3A2E24;

  /* Paper / surface cream */
  --lobby-paper:         #F4E9CE;
  --lobby-paper-warm:    #FDF4DE;
  --lobby-paper-inset:   #F6E8C6;

  /* Accents */
  --lobby-mango:         #FFC878;
  --lobby-coral:         #E86B6B;
  --lobby-teal:          #4FB3B3;  /* CTA */
  --lobby-teal-dark:     #338B8B;
  --lobby-green:         #8FCF82;  /* ready / success */

  /* Typography family defaults */
  font-family: 'Nunito', var(--font-body);

  /* Hard-edged cartoon shadow recipes */
  --lobby-shadow-md:   0 4px 0 0 var(--lobby-ink), 0 8px 16px rgb(26 22 19 / 0.18);
  --lobby-shadow-lg:   0 6px 0 0 var(--lobby-ink), 0 12px 24px rgb(26 22 19 / 0.22);
  --lobby-shadow-xl:   0 8px 0 0 var(--lobby-ink), 0 16px 32px rgb(26 22 19 / 0.26);

  --lobby-border-md:   3px solid var(--lobby-ink);
  --lobby-border-lg:   4px solid var(--lobby-ink);
}

/* ---- INK-STROKED DISPLAY TYPE ----
   The signature chunky outlined cream display used for the wordmark, big
   headings, and button labels. */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ink-stroke {
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 3px var(--lobby-ink);
  paint-order: stroke fill;
  text-shadow:
    4px 4px 0 rgba(26, 22, 19, 0.18),
    0 5px 0 var(--lobby-ink);
  letter-spacing: 0.01em;
  line-height: 0.95;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ink-stroke-sm {
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2px var(--lobby-ink);
  paint-order: stroke fill;
  text-shadow: 0 3px 0 var(--lobby-ink);
  letter-spacing: 0.01em;
  line-height: 0.95;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ink-stroke-dark {
  color: var(--lobby-ink);
  -webkit-text-stroke: 1px var(--lobby-ink);
  paint-order: stroke fill;
  letter-spacing: 0.02em;
  line-height: 1;
  font-family: 'Fredoka One', cursive;
}

/* ---- PAPER CUTOUT CARD ----
   Cream fill + thick ink border + hard ink drop shadow. */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .paper {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 24px;
  box-shadow: var(--lobby-shadow-lg);
  position: relative;
  color: var(--lobby-ink);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .paper-sm {
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 16px;
  box-shadow: var(--lobby-shadow-md);
  position: relative;
  color: var(--lobby-ink);
}

/* ---- CHUNKY 3D BUTTON (TEAL CTA) ----
   Use as: <button class="btn-chunky">READY UP</button>
   Variants: .btn-chunky--ready (green when already readied).
   The :not(.hidden) is load-bearing: Tailwind's `.hidden` utility
   (display: none) loses the specificity fight against this compound
   selector, so buttons like #btn-start-game stayed visible on every
   phone. Surfaced by the Playwright suite. */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky:not(.hidden) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2px var(--lobby-ink);
  paint-order: stroke fill;
  background: var(--lobby-teal);
  border: var(--lobby-border-lg);
  border-radius: 9999px;
  padding: 1rem 2rem;
  font-size: clamp(1.5rem, 3vw, 2rem);
  letter-spacing: 0.02em;
  box-shadow:
    0 8px 0 0 var(--lobby-ink),
    0 14px 24px rgb(26 22 19 / 0.25);
  cursor: pointer;
  transition: transform 120ms var(--ease-snap),
              box-shadow 120ms var(--ease-snap);
  user-select: none;
  text-transform: uppercase;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky:hover {
  transform: translateY(-2px);
  box-shadow:
    0 10px 0 0 var(--lobby-ink),
    0 18px 30px rgb(26 22 19 / 0.30);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky:active,
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky.is-pressed {
  transform: translateY(6px);
  box-shadow:
    0 2px 0 0 var(--lobby-ink),
    0 4px 8px rgb(26 22 19 / 0.20);
}
/* Variant selectors compound `.btn-chunky.btn-chunky--ready` so they
   match the `(0,3,0)` specificity of `.btn-chunky:not(.hidden)` above.
   Without the extra class, the teal rule out-specs the variant and
   every --ready / --amber button stayed teal when visible (hidden
   ones showed the variant color only because the `:not(.hidden)` rule
   didn't match them). Caught during Pass 2 while wiring the green
   NOTIFY PLAYERS button. */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky.btn-chunky--ready:not(.hidden) {
  background: var(--lobby-green);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky.btn-chunky--amber:not(.hidden) {
  background: var(--lobby-mango);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky[disabled],
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky.is-disabled {
  opacity: 0.65;
  cursor: not-allowed;
  transform: none;
}

/* ---- MARQUEE WORDMARK ("ODD ONE OUT") ----
   Simplified marquee: amber panel with bulbs along edges + chunky outlined
   letters inside. No per-letter tiles (that's a v2 upgrade). */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .wordmark {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 1rem 2.5rem;
  background: linear-gradient(180deg, #D89A48 0%, #B57628 55%, #8F5615 100%);
  border: 3px solid var(--lobby-ink);
  border-radius: 1.5rem;
  box-shadow:
    0 6px 0 0 rgba(26, 22, 19, 0.35),
    0 12px 24px rgb(26 22 19 / 0.25);
  font-family: 'Fredoka One', cursive;
  white-space: nowrap;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .wordmark__text {
  position: relative;
  z-index: 2;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2.5px var(--lobby-ink);
  paint-order: stroke fill;
  letter-spacing: 0.04em;
  text-shadow:
    3px 3px 0 rgba(26, 22, 19, 0.22),
    0 4px 0 var(--lobby-ink);
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .wordmark::before,
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .wordmark::after {
  content: "";
  position: absolute;
  left: 8px; right: 8px;
  height: 10px;
  background-image: radial-gradient(circle at 50% 50%,
    #FFF4C7 0%, #FFD96B 35%, #C98A1A 75%, transparent 80%);
  background-size: 20px 10px;
  background-repeat: repeat-x;
  background-position: center;
  pointer-events: none;
  z-index: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .wordmark::before { top: -5px; }
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .wordmark::after  { bottom: -5px; }

/* ---- PAPER SIGN (used for "Waiting for players...") ---- */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .paper-sign {
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 12px;
  padding: 0.75rem 1.5rem;
  box-shadow: var(--lobby-shadow-md);
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-ink);
  -webkit-text-stroke: 0.75px var(--lobby-ink);
  transform: rotate(-1.5deg);
  display: inline-block;
  letter-spacing: 0.02em;
}

/* ---- ROOM-CODE TICKET (two halves: URL + code) ---- */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket {
  display: inline-flex;
  align-items: stretch;
  transform: rotate(-1deg);
  filter:
    drop-shadow(0 6px 0 rgba(26, 22, 19, 0.35))
    drop-shadow(0 14px 24px rgb(0 0 0 / 0.35));
  font-family: 'Fredoka One', cursive;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket__label {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-right: none;
  border-radius: 14px 0 0 14px;
  padding: 0.6rem 1.25rem 0.6rem 1.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket__label-sub {
  font-family: 'Nunito', sans-serif;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.25em;
  color: #5C4B3A;
  text-transform: uppercase;
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket__url {
  margin-top: 0.25rem;
  font-size: 1.5rem;
  color: var(--lobby-ink);
  -webkit-text-stroke: 1px var(--lobby-ink);
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket__code {
  background: var(--lobby-mango);
  border: var(--lobby-border-lg);
  border-radius: 0 14px 14px 0;
  padding: 0.5rem 1.75rem 0.5rem 1.25rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket__code-sub {
  font-family: 'Nunito', sans-serif;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.3em;
  color: var(--lobby-ink);
  text-transform: uppercase;
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket__code-value {
  margin-top: 0.125rem;
  font-size: 2.75rem;
  color: var(--lobby-ink);
  -webkit-text-stroke: 1.5px var(--lobby-ink);
  letter-spacing: 0.14em;
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .room-ticket__tape {
  position: absolute;
  top: -10px;
  right: 10px;
  width: 48px;
  height: 16px;
  background: var(--lobby-green);
  border: 2px solid var(--lobby-ink);
  transform: rotate(8deg);
}

/* ---- PLAYER PAPER CARD (used in TV 4x2 grid + phone featured card) ---- */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 20px;
  box-shadow: var(--lobby-shadow-lg);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 10px 12px 12px;
  position: relative;
  color: var(--lobby-ink);
  transition: opacity 160ms ease;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card--me {
  border-width: 5px;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card--unready {
  opacity: 0.88;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card__photo {
  width: 110px;
  height: 110px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--lobby-paper-inset);
  border: var(--lobby-border-md);
  display: flex;
  align-items: center;
  justify-content: center;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card__name {
  margin-top: 6px;
  font-family: 'Fredoka One', cursive;
  font-size: 1.25rem;
  color: var(--lobby-ink);
  letter-spacing: 0.03em;
  -webkit-text-stroke: 1px var(--lobby-ink);
  text-transform: uppercase;
  line-height: 1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card__sub {
  font-family: 'Nunito', sans-serif;
  font-size: 0.625rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(26, 22, 19, 0.55);
  margin-top: 2px;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card__ready-badge {
  position: absolute;
  top: -14px;
  right: -14px;
  padding: 4px 10px;
  background: var(--lobby-green);
  border: 3px solid var(--lobby-ink);
  border-radius: 10px;
  font-family: 'Fredoka One', cursive;
  font-size: 0.875rem;
  transform: rotate(6deg);
  box-shadow: 0 3px 0 0 rgba(26, 22, 19, 0.35);
  color: var(--lobby-ink);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card--empty {
  background: rgba(244, 233, 206, 0.35);
  border: 3px dashed rgba(26, 22, 19, 0.4);
  border-radius: 20px;
  box-shadow: none;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 196px;
  font-family: 'Fredoka One', cursive;
  font-size: 1.25rem;
  color: rgba(26, 22, 19, 0.5);
  letter-spacing: 0.1em;
}

/* ---- FEATURED (BIG) PLAYER CARD — phone self-card ---- */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card--featured {
  padding: 22px 20px;
  border-radius: 24px;
  width: 100%;
  max-width: 320px;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card--featured .player-paper-card__photo {
  width: 210px;
  height: 210px;
  border-radius: 18px;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .player-paper-card--featured .player-paper-card__name {
  margin-top: 10px;
  font-size: 3rem;
  -webkit-text-stroke: 2px var(--lobby-ink);
}

/* ---- READY COUNTER (tally + notches) — phone bottom ---- */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__card {
  position: relative;
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 14px;
  padding: 10px 28px 12px;
  box-shadow: 0 5px 0 0 rgba(26, 22, 19, 0.4), 0 10px 18px rgb(26 22 19 / 0.22);
  transform: rotate(-1.2deg);
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: 'Fredoka One', cursive;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__num {
  font-size: 4rem;
  color: var(--lobby-ink);
  -webkit-text-stroke: 2px var(--lobby-ink);
  letter-spacing: 0.02em;
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__denom {
  font-size: 2.375rem;
  color: rgba(26, 22, 19, 0.55);
  letter-spacing: 0.04em;
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__label {
  margin-left: 10px;
  font-size: 1.375rem;
  color: var(--lobby-ink);
  letter-spacing: 0.12em;
  -webkit-text-stroke: 0.75px var(--lobby-ink);
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__tape {
  position: absolute;
  top: -10px;
  left: 18px;
  width: 54px;
  height: 16px;
  background: var(--lobby-green);
  border: 2px solid var(--lobby-ink);
  transform: rotate(-6deg);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__notches {
  display: flex;
  gap: 5px;
  padding: 0 4px;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__notch {
  width: 14px;
  height: 18px;
  border: 1.5px solid var(--lobby-ink);
  border-radius: 2px;
  background: transparent;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .ready-counter__notch.is-filled {
  background: var(--lobby-green);
  box-shadow: inset 0 -3px 0 rgba(26, 22, 19, 0.18);
}

/* ---- LOBBY STAGE CONTAINERS ----
   Brick-wall backgrounds + neutralize default light-on-dark Tailwind
   colors on the text INSIDE the lobby so everything reads as near-black
   ink on cream paper. */
:is([data-stage^="lobby"], [data-stage="phone-entry"]) {
  background-image: url("/assets/images/brick-phone.webp");
  background-size: cover;
  background-position: center;
  color: var(--lobby-ink);
}
:is([data-stage^="lobby"], [data-stage="phone-entry"])[data-stage-variant="tv"] {
  background-image: url("/assets/images/brick-tv.webp");
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) p,
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) span,
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) h1,
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) h2,
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) h3 {
  color: var(--lobby-ink);
}

/* ---- SPECIAL: hide player-list grid in the lobby (phone) ----
   The legacy `#player-list` grid holds player DATA that other screens
   query (voting, DMs, etc.), so we can't delete it. But we don't want
   to render it on the lobby — the new design uses a featured self-card
   and a ready-counter tally instead. Keep the element in the DOM,
   hidden from view. */
:is([data-stage^="lobby"], [data-stage="phone-entry"]) #player-list {
  display: none !important;
}

/* =========================================================================
   ENTRY FLOW — character picker + name-character stages
   =========================================================================
   The three entry stages (lobby-entry, lobby-pick-character,
   lobby-name-character) share the lobby aesthetic via the `lobby-` prefix.
   This block adds the picker-specific chrome (the 20-tile grid) and some
   entry-screen layout fixes.
   ========================================================================= */

/* Make the entry + pick/name containers scroll when content overflows
   (20 tiles are tall on a short phone). */
[data-stage="phone-entry"][data-slot="pick-character"],
[data-stage="phone-entry"][data-slot="name-character"] {
  padding-bottom: 8px;
}

/* Character tile — one per archetype in the picker grid.
   Paper-cutout card with emoji + label. Selected state gets an ink ring. */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .character-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 10px 6px;
  background: var(--lobby-paper);
  border: 3px solid var(--lobby-ink);
  border-radius: 14px;
  box-shadow: 0 4px 0 0 var(--lobby-ink);
  color: var(--lobby-ink);
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  text-align: center;
  min-height: 88px;
  cursor: pointer;
  transition: transform 0.08s ease, box-shadow 0.08s ease;
  transform: rotate(-0.5deg);
  -webkit-tap-highlight-color: transparent;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .character-tile:nth-child(even) {
  transform: rotate(0.6deg);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .character-tile:hover {
  transform: translateY(-2px) rotate(0deg);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .character-tile:active {
  transform: translateY(2px) rotate(0deg);
  box-shadow: 0 2px 0 0 var(--lobby-ink);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .character-tile--selected {
  background: var(--lobby-mango);
  border-width: 4px;
  transform: translateY(-2px) rotate(-1.2deg);
  box-shadow: 0 6px 0 0 var(--lobby-ink), 0 10px 18px rgb(26 22 19 / 0.28);
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .character-tile__emoji {
  font-size: 2.25rem;
  line-height: 1;
}
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .character-tile__label {
  font-size: 0.75rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* =========================================================================
   PASS 1 — PHONE ENTRY PRIMITIVES
   =========================================================================
   Paper-ticket text input. Used on every pre-lobby phone input
   (#input-room-code, #input-character-name, #input-player-name). Replaces
   the earlier id-targeted rules with a reusable class so every future
   entry-flow input inherits the same treatment.
   ========================================================================= */

[data-stage="phone-entry"] .input-paper-ticket {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 20px;
  box-shadow: 0 5px 0 0 var(--lobby-ink), 0 10px 20px rgb(26 22 19 / 0.22);
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-ink);
  text-align: center;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.9rem 1.5rem;
  font-size: clamp(1.5rem, 4.5vw, 2.5rem);
  width: 100%;
  max-width: 22rem;
}
[data-stage="phone-entry"] .input-paper-ticket:focus {
  outline: none;
  background: var(--lobby-paper-warm);
  box-shadow:
    0 5px 0 0 var(--lobby-ink),
    0 10px 20px rgb(26 22 19 / 0.22),
    0 0 0 3px var(--lobby-teal) inset;
}
/* Room-code input uses a monospace face for the 4-char code so the tile
   reads like a ticket stub. */
[data-stage="phone-entry"] #input-room-code.input-paper-ticket {
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: 0.3em;
}

/* ---- Tailwind `.hidden` override — keep display:none winning ----
   Scoped rules like `.paper-chip { display: inline-flex }` and the
   stage-level `[data-stage="phone-role-reveal"] { display: flex }`
   blocks below match Tailwind's `.hidden { display: none }` on
   specificity but come later in the cascade, so without help they
   would out-paint the hide. Pin `.hidden` to wins both INSIDE a
   phone-* stage (children) and ON the stage element itself. */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]).hidden,
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .hidden {
  display: none !important;
}

/* =========================================================================
   PASS 2 — PHONE IN-ROUND STAGES
   =========================================================================
   Three stages covered here:
   - [data-stage="phone-role-reveal"] — dramatic "YOU ARE THE ODD ONE OUT"
     vs. "YOU ARE A PLAYER" moment. Two variant cards + corner stamp for
     the OOO task.
   - [data-stage="phone-round-active"] — mid-round HUD with timer ticket
     up top, optional task paper, big chunky SUS button.
   - [data-stage="phone-host-checklist"] — clipboard-style pre-round
     setup: pick a task, set a timer, notify.

   The shared primitives (.paper, .paper-sm, .btn-chunky, .ink-stroke,
   .ink-stroke-sm, .paper-sign, .character-tile, lobby ink / paper
   variables) are inherited via the `[data-stage^="phone-"]` broaden
   earlier in this file.
   ========================================================================= */

/* ---- Shared corner stamp ("YOUR JOB", "CAUGHT!", etc.) ----
   Rotated paper-tag treatment reused across stages. Same transform idiom
   as .paper-sign, slightly tighter padding so it reads like a sticker. */
:is([data-stage^="phone-"]) .stamp {
  display: inline-block;
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 10px;
  padding: 0.35rem 0.85rem;
  box-shadow: 0 3px 0 0 var(--lobby-ink), 0 6px 12px rgb(26 22 19 / 0.20);
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-ink);
  -webkit-text-stroke: 0.5px var(--lobby-ink);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transform: rotate(-4deg);
}
:is([data-stage^="phone-"]) .stamp--ooo {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 1px var(--lobby-ink);
}
:is([data-stage^="phone-"]) .stamp--mango {
  background: var(--lobby-mango);
}

/* =========================================================================
   STAGE: phone-role-reveal
   ========================================================================= */

[data-stage="phone-role-reveal"] {
  background:
    radial-gradient(ellipse at top, #3A1414 0%, #2A0E0E 55%, #140606 100%);
  min-height: 100vh;
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
}
[data-stage="phone-role-reveal"][data-variant="player"] {
  background:
    radial-gradient(ellipse at top, #1B3A1F 0%, #112A14 55%, #061408 100%);
}

/* Reveal card shared shape — a big rotated paper hero. */
:is([data-stage="phone-role-reveal"]) .reveal-card {
  position: relative;
  width: 100%;
  max-width: 340px;
  border-radius: 28px;
  border: 5px solid var(--lobby-ink);
  padding: 2.25rem 1.5rem;
  text-align: center;
  box-shadow:
    0 10px 0 0 var(--lobby-ink),
    0 24px 36px rgb(0 0 0 / 0.55);
  animation: reveal-pop var(--dur-dramatic) var(--ease-bounce) both;
}

/* OOO variant — blood-red paper with heavy shake on entry. */
:is([data-stage="phone-role-reveal"]) .reveal-card-ooo {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  animation: reveal-pop var(--dur-dramatic) var(--ease-bounce) both,
             shake var(--dur-slow) var(--ease-out) var(--dur-dramatic) 1;
}
:is([data-stage="phone-role-reveal"]) .reveal-card-ooo .reveal-card__title {
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 3px var(--lobby-ink);
  paint-order: stroke fill;
  text-shadow: 0 5px 0 var(--lobby-ink), 4px 4px 0 rgba(0,0,0,0.35);
  font-size: clamp(2.5rem, 9vw, 3.75rem);
  letter-spacing: 0.02em;
  line-height: 0.9;
  margin: 0;
}
:is([data-stage="phone-role-reveal"]) .reveal-card-ooo .reveal-card__sub {
  margin-top: 1rem;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.95rem;
  color: var(--lobby-paper-warm);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Player variant — green paper, softer entry. */
:is([data-stage="phone-role-reveal"]) .reveal-card-player {
  background: var(--lobby-green);
  color: var(--lobby-ink);
}
:is([data-stage="phone-role-reveal"]) .reveal-card-player .reveal-card__title {
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2.5px var(--lobby-ink);
  paint-order: stroke fill;
  text-shadow: 0 4px 0 var(--lobby-ink);
  font-size: clamp(2.25rem, 8vw, 3.25rem);
  line-height: 0.95;
  letter-spacing: 0.02em;
  margin: 0;
}
:is([data-stage="phone-role-reveal"]) .reveal-card-player .reveal-card__sub {
  margin-top: 1rem;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.95rem;
  color: var(--lobby-ink);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Corner stamp floating off the top-right of the reveal card — used for
   the OOO's "YOUR JOB" task tag. */
:is([data-stage="phone-role-reveal"]) .reveal-card__stamp {
  position: absolute;
  top: -18px;
  right: -14px;
  max-width: 70%;
  font-size: 0.8rem;
}
:is([data-stage="phone-role-reveal"]) .reveal-card__stamp-label {
  display: block;
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  opacity: 0.8;
  margin-bottom: 2px;
}
:is([data-stage="phone-role-reveal"]) .reveal-card__stamp-value {
  display: block;
  font-size: 0.95rem;
  line-height: 1.1;
  text-transform: none;
  letter-spacing: 0.02em;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
}

@keyframes reveal-pop {
  0%   { opacity: 0; transform: scale(0.8) rotate(-4deg); }
  60%  { opacity: 1; transform: scale(1.03) rotate(1deg); }
  100% { opacity: 1; transform: scale(1) rotate(-1deg); }
}

/* =========================================================================
   STAGE: phone-round-active
   ========================================================================= */

[data-stage="phone-round-active"] {
  background:
    linear-gradient(180deg, #231C15 0%, #16110C 100%);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Timer ticket — monospace digits on cream paper, pinned at the top. */
:is([data-stage="phone-round-active"]) .timer-paper {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-lg);
  border-radius: 16px;
  padding: 0.6rem 1.25rem;
  box-shadow: 0 5px 0 0 var(--lobby-ink), 0 10px 18px rgb(0 0 0 / 0.35);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--lobby-ink);
  letter-spacing: 0.06em;
  line-height: 1;
  transform: rotate(-1deg);
}
:is([data-stage="phone-round-active"]) .timer-paper__label {
  font-family: 'Nunito', sans-serif;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.65;
  margin-right: 0.25rem;
}
:is([data-stage="phone-round-active"]) .timer-paper__digits {
  font-size: 2rem;
  letter-spacing: 0.08em;
}

/* Timer urgency — pure-CSS variants picked up when phone.js (or a
   future pass) toggles `.text-warning` / `.text-error` on the timer
   wrapper. Base state stays cream. */
:is([data-stage="phone-round-active"]) .timer-paper.text-warning,
:is([data-stage="phone-round-active"]) .timer-paper:has(.text-warning) {
  background: var(--lobby-mango);
}
:is([data-stage="phone-round-active"]) .timer-paper.text-error,
:is([data-stage="phone-round-active"]) .timer-paper:has(.text-error) {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  animation: pulse-glow var(--dur-dramatic) var(--ease-in-out) infinite;
}

/* Top strip containing timer + utility chips. Translucent inset, scrolls
   with content. */
:is([data-stage="phone-round-active"]) .round-top-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1rem 0.5rem;
}
:is([data-stage="phone-round-active"]) .round-top-strip__chips {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* Small paper chip for the connection pill + role pip + secondary
   actions in the top strip. Reuses the .paper-sign idiom but sized for
   a row of chips instead of a standalone sign. */
:is([data-stage^="phone-"]) .paper-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--lobby-paper);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 9999px;
  padding: 0.25rem 0.75rem;
  box-shadow: 0 3px 0 0 var(--lobby-ink);
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--lobby-ink);
}
:is([data-stage^="phone-"]) .paper-chip--mango  { background: var(--lobby-mango); }
:is([data-stage^="phone-"]) .paper-chip--coral  { background: var(--lobby-coral); color: var(--lobby-paper-warm); -webkit-text-stroke: 0.5px var(--lobby-ink); }
:is([data-stage^="phone-"]) .paper-chip--teal   { background: var(--lobby-teal); color: var(--lobby-paper-warm); -webkit-text-stroke: 0.5px var(--lobby-ink); }
:is([data-stage^="phone-"]) .paper-chip--green  { background: var(--lobby-green); }

/* Task card — paper wrap around #my-task-display for host/OOO. */
:is([data-stage="phone-round-active"]) .task-paper {
  margin: 0.75rem 1rem 1.25rem;
  padding: 1.25rem;
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 22px;
  box-shadow: var(--lobby-shadow-lg);
  color: var(--lobby-ink);
  position: relative;
}
:is([data-stage="phone-round-active"]) .task-paper__label {
  display: inline-block;
  font-family: 'Nunito', sans-serif;
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--lobby-ink);
  opacity: 0.6;
  margin-bottom: 0.35rem;
}
:is([data-stage="phone-round-active"]) .task-paper__text {
  font-family: 'Fredoka One', cursive;
  font-size: 1.35rem;
  line-height: 1.2;
  color: var(--lobby-ink);
  letter-spacing: 0.01em;
}

/* SUS button — bigger, thumbable, coral by default. Composes with
   .btn-chunky so the chunky press animation applies. Selector needs to
   match `.btn-chunky:not(.hidden)`'s (0,3,0) specificity plus one more
   class to win the background assignment. */
:is([data-stage^="lobby"], [data-stage^="phone-"], [data-stage^="ipad-"], [data-stage="tv-entry"], [data-stage="tv-round-active"], [data-stage="tv-gather"], [data-stage="tv-emergency"], [data-stage="tv-reveal"], [data-stage="tv-testimonials"], [data-stage="tv-between-rounds"]) .btn-chunky.sus-button-chunky:not(.hidden) {
  background: var(--lobby-coral);
  font-size: clamp(1.75rem, 5vw, 2.25rem);
  padding: 1.25rem 2.5rem;
  letter-spacing: 0.08em;
  min-width: 16rem;
}

/* Main action column in round-active — centers the SUS button + any
   secondary action buttons so the thumb reaches them. */
:is([data-stage="phone-round-active"]) .round-action-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 1rem;
}

/* Footer bar — connection + role chips aligned at the bottom. */
:is([data-stage="phone-round-active"]) .round-footer-bar {
  margin-top: auto;
  padding: 0.75rem 1rem 1rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* =========================================================================
   STAGE: phone-host-checklist
   ========================================================================= */

[data-stage="phone-host-checklist"] {
  background:
    linear-gradient(180deg, #E6D5A8 0%, #C4B287 100%);
  min-height: 100vh;
  padding: 1.25rem 1rem 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
}
:is([data-stage="phone-host-checklist"]) .checklist-clipboard {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
:is([data-stage="phone-host-checklist"]) .checklist-heading {
  text-align: center;
  font-size: clamp(1.75rem, 5.5vw, 2.25rem);
  margin: 0.5rem 0 0.25rem;
}
:is([data-stage="phone-host-checklist"]) .checklist-subhead {
  text-align: center;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  color: var(--lobby-ink);
  opacity: 0.75;
  margin-bottom: 0.5rem;
}
:is([data-stage="phone-host-checklist"]) .checklist-card {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 20px;
  box-shadow: var(--lobby-shadow-lg);
  padding: 1rem 1.15rem 1.15rem;
  color: var(--lobby-ink);
}
:is([data-stage="phone-host-checklist"]) .checklist-card__step {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: 'Fredoka One', cursive;
  font-size: 0.95rem;
  color: var(--lobby-ink);
  margin-bottom: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
:is([data-stage="phone-host-checklist"]) .checklist-card__check {
  width: 1.65rem;
  height: 1.65rem;
  border: 2.5px solid var(--lobby-ink);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--lobby-paper-inset);
  font-size: 0.9rem;
  line-height: 1;
}
:is([data-stage="phone-host-checklist"]) .checklist-card__check.is-complete,
:is([data-stage="phone-host-checklist"]) .checklist-card__check.bg-success {
  background: var(--lobby-green);
  color: var(--lobby-ink);
}

/* Task-option buttons (injected by renderChecklistTasks) use the shared
   .character-tile class — redeclare the layout defaults so the text
   reads LEFT-ALIGNED rather than centered like the archetype grid. */
:is([data-stage="phone-host-checklist"]) #checklist-task-options .character-tile {
  flex-direction: row;
  align-items: flex-start;
  justify-content: flex-start;
  text-align: left;
  min-height: auto;
  padding: 0.6rem 0.8rem;
  gap: 0.5rem;
  font-size: 0.8rem;
  line-height: 1.2;
  transform: rotate(-0.4deg);
  text-transform: none;
  letter-spacing: 0.01em;
}
:is([data-stage="phone-host-checklist"]) #checklist-task-options .character-tile:nth-child(even) {
  transform: rotate(0.5deg);
}

/* Shuffle + custom-task utility buttons live inside the task-picker
   card. Keep their Tailwind look; only soften to ink palette. */
:is([data-stage="phone-host-checklist"]) #checklist-task-options button:not(.character-tile),
:is([data-stage="phone-host-checklist"]) #checklist-task-options textarea {
  background: var(--lobby-paper-inset);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 14px;
  color: var(--lobby-ink);
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  padding: 0.55rem 0.8rem;
  box-shadow: 0 3px 0 0 var(--lobby-ink);
  margin-top: 0.4rem;
  width: 100%;
  text-align: center;
  cursor: pointer;
}
:is([data-stage="phone-host-checklist"]) #checklist-task-options textarea {
  text-align: left;
  resize: vertical;
}
:is([data-stage="phone-host-checklist"]) #checklist-task-options .divider {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  color: var(--lobby-ink);
  opacity: 0.55;
  margin: 0.5rem 0 0.35rem;
}

/* Timer picker chips — Tailwind .btn .btn-outline picks up a paper
   treatment; selected preset flashes amber. */
:is([data-stage="phone-host-checklist"]) .checklist-timer-preset {
  background: var(--lobby-paper-inset);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 12px;
  color: var(--lobby-ink);
  font-family: 'Fredoka One', cursive;
  font-size: 0.95rem;
  padding: 0.45rem 0.2rem;
  box-shadow: 0 3px 0 0 var(--lobby-ink);
  letter-spacing: 0.03em;
  transition: transform 80ms var(--ease-snap), box-shadow 80ms var(--ease-snap);
}
:is([data-stage="phone-host-checklist"]) .checklist-timer-preset:hover {
  transform: translateY(-2px);
  box-shadow: 0 5px 0 0 var(--lobby-ink);
}
:is([data-stage="phone-host-checklist"]) .checklist-timer-preset.is-selected {
  background: var(--lobby-mango);
  transform: translateY(1px);
  box-shadow: 0 2px 0 0 var(--lobby-ink);
}
:is([data-stage="phone-host-checklist"]) #checklist-custom-mins {
  background: var(--lobby-paper-inset);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 12px;
  color: var(--lobby-ink);
  font-family: 'JetBrains Mono', monospace;
  padding: 0.4rem 0.6rem;
}
:is([data-stage="phone-host-checklist"]) #btn-checklist-custom-timer {
  background: var(--lobby-teal);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 1px var(--lobby-ink);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 12px;
  font-family: 'Fredoka One', cursive;
  padding: 0.4rem 0.9rem;
  box-shadow: 0 3px 0 0 var(--lobby-ink);
  letter-spacing: 0.05em;
}

/* Selected-state panels — inline success indicator. */
:is([data-stage="phone-host-checklist"]) #checklist-task-selected,
:is([data-stage="phone-host-checklist"]) #checklist-timer-selected {
  background: var(--lobby-green);
  border: 3px solid var(--lobby-ink);
  border-radius: 14px;
  padding: 0.75rem 0.9rem;
  color: var(--lobby-ink);
  margin-top: 0.75rem;
  box-shadow: 0 3px 0 0 var(--lobby-ink);
}
:is([data-stage="phone-host-checklist"]) #checklist-task-selected p,
:is([data-stage="phone-host-checklist"]) #checklist-timer-selected p {
  color: var(--lobby-ink);
}
:is([data-stage="phone-host-checklist"]) #btn-checklist-change-task,
:is([data-stage="phone-host-checklist"]) #btn-checklist-change-timer {
  background: transparent;
  border: none;
  color: var(--lobby-ink);
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: underline;
  padding: 0.35rem 0;
  margin-top: 0.2rem;
  cursor: pointer;
}

/* Notify-players CTA container pins to the bottom of the clipboard. */
:is([data-stage="phone-host-checklist"]) .checklist-notify-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
}
:is([data-stage="phone-host-checklist"]) .checklist-notify-wrap .btn-chunky {
  width: 100%;
  max-width: 22rem;
}
:is([data-stage="phone-host-checklist"]) .checklist-notify-hint {
  font-family: 'Nunito', sans-serif;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--lobby-ink);
  opacity: 0.6;
  text-align: center;
  text-transform: uppercase;
}

/* =========================================================================
   PASS 3 — PHONE GATHER / VOTING / WATCH-TV / SPECTATOR / BETWEEN-ROUNDS
   =========================================================================
   Six screens that all show a grid of players + a single primary CTA.
   Unified behind the same brick-wall background + paper-cutout grid
   pattern. Stages covered:
   - [data-stage="phone-gather"][data-slot="normal"]   — "head to the TV"
   - [data-stage="phone-gather"][data-slot="emergency"] — coral CTA variant
   - [data-stage="phone-voting"]                        — suspect picker grid
   - [data-stage="phone-watch-tv"]                      — passive "watch"
   - [data-stage="phone-spectator"]                     — spectator seat
   - [data-stage="phone-between-rounds"]                — ready-up + start-next

   Primitives inherited via the broader [data-stage^="phone-"] scope:
   .paper, .paper-sm, .paper-sign, .btn-chunky (+ --amber / --ready),
   .ink-stroke, .ink-stroke-sm, .paper-chip, .character-tile (+ --selected),
   .stamp. New primitives added below.
   ========================================================================= */

/* ---- Shared: brick-wall background on all six stage containers.
   Same image the lobby + phone-entry uses, so the tonal handoff from
   lobby → round-active (dark) → gather (bricks again) feels intentional
   rather than jarring. */
[data-stage="phone-gather"],
[data-stage="phone-voting"],
[data-stage="phone-watch-tv"],
[data-stage="phone-spectator"],
[data-stage="phone-between-rounds"] {
  background:
    url('/assets/images/brick-phone.webp') center / cover no-repeat,
    var(--lobby-ink);
  min-height: 100vh;
  color: var(--lobby-ink);
}

/* ---- PAPER TILE (small grid cell) ----
   Used in gather + vote grids. Fits 3-4 across on a 390px phone with
   1rem gutters. Composable with <button> (voting) or <div> (gather). */
:is([data-stage^="phone-"]) .paper-tile-sm {
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 14px;
  box-shadow: 0 4px 0 0 var(--lobby-ink);
  padding: 10px 6px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--lobby-ink);
  position: relative;
  min-height: 116px;
  font-family: 'Nunito', sans-serif;
  transform: rotate(-0.6deg);
  transition: transform 120ms var(--ease-snap), box-shadow 120ms var(--ease-snap);
  cursor: default;
  text-align: center;
  -webkit-tap-highlight-color: transparent;
  appearance: none;
  -webkit-appearance: none;
  font: inherit;
}
:is([data-stage^="phone-"]) .paper-tile-sm:nth-child(even) {
  transform: rotate(0.7deg);
}
:is([data-stage^="phone-"]) button.paper-tile-sm {
  cursor: pointer;
}
:is([data-stage^="phone-"]) button.paper-tile-sm:hover {
  transform: translateY(-2px) rotate(0deg);
  box-shadow: 0 6px 0 0 var(--lobby-ink), 0 9px 14px rgb(26 22 19 / 0.22);
}
:is([data-stage^="phone-"]) button.paper-tile-sm:active {
  transform: translateY(2px) rotate(0deg);
  box-shadow: 0 2px 0 0 var(--lobby-ink);
}
:is([data-stage^="phone-"]) .paper-tile-sm__avatar {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  overflow: hidden;
  background: var(--lobby-paper-inset);
  border: 2.5px solid var(--lobby-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}
:is([data-stage^="phone-"]) .paper-tile-sm__avatar img,
:is([data-stage^="phone-"]) .paper-tile-sm__avatar video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
:is([data-stage^="phone-"]) .paper-tile-sm__name {
  font-family: 'Fredoka One', cursive;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  line-height: 1;
  color: var(--lobby-ink);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
}
:is([data-stage^="phone-"]) .paper-tile-sm__status {
  font-family: 'Nunito', sans-serif;
  font-size: 0.55rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(26, 22, 19, 0.5);
  line-height: 1;
}

/* ---- GATHER "HERE" STAMP + gathered-card green fill ---- */
:is([data-stage^="phone-"]) .paper-tile-sm.gather-status--here {
  background: var(--lobby-green);
  transform: rotate(-1.4deg);
  box-shadow: 0 5px 0 0 var(--lobby-ink), 0 9px 14px rgb(26 22 19 / 0.25);
}
:is([data-stage^="phone-"]) .paper-tile-sm.gather-status--here .paper-tile-sm__status {
  color: rgba(26, 22, 19, 0.85);
}
:is([data-stage^="phone-"]) .stamp-here {
  position: absolute;
  top: -12px;
  right: -8px;
  padding: 3px 10px;
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 9999px;
  font-family: 'Fredoka One', cursive;
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  transform: rotate(11deg);
  -webkit-text-stroke: 0.6px var(--lobby-ink);
  box-shadow: 0 2px 0 0 var(--lobby-ink);
  white-space: nowrap;
}

/* =========================================================================
   STAGE: phone-gather (normal + emergency)
   ========================================================================= */

[data-stage="phone-gather"] {
  padding: 1.75rem 1rem 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
}
:is([data-stage="phone-gather"]) .gather-headline {
  text-align: center;
  font-size: clamp(2rem, 7vw, 2.75rem);
  margin: 0.25rem 0 0;
}
:is([data-stage="phone-gather"]) .gather-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px 10px;
  width: 100%;
  max-width: 24rem;
}
:is([data-stage="phone-gather"]) .gather-caller-card {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 18px;
  box-shadow: var(--lobby-shadow-md);
  padding: 0.75rem 1rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  transform: rotate(-1.4deg);
  max-width: 22rem;
  width: 100%;
}
:is([data-stage="phone-gather"]) .gather-caller-card__photo {
  width: 58px;
  height: 58px;
  border-radius: 12px;
  overflow: hidden;
  border: 2.5px solid var(--lobby-ink);
  background: var(--lobby-paper-inset);
  flex-shrink: 0;
}
:is([data-stage="phone-gather"]) .gather-caller-card__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
:is([data-stage="phone-gather"]) .gather-caller-card__label {
  font-family: 'Nunito', sans-serif;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(26, 22, 19, 0.55);
  line-height: 1;
}
:is([data-stage="phone-gather"]) .gather-caller-card__name {
  font-family: 'Fredoka One', cursive;
  font-size: 1.15rem;
  line-height: 1.05;
  letter-spacing: 0.02em;
  color: var(--lobby-ink);
}

/* Emergency variant — coral CTA override. The gather CTA buttons
   (#btn-normal-at-tv / #btn-at-tv) share the chunky primitive; the
   emergency slot swaps the teal fill for coral. */
[data-stage="phone-gather"][data-slot="emergency"] .btn-chunky:not(.btn-chunky--amber):not(.btn-chunky--ready):not(.hidden) {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2px var(--lobby-ink);
}
[data-stage="phone-gather"][data-slot="emergency"] .gather-headline {
  color: var(--lobby-coral);
  -webkit-text-stroke: 3px var(--lobby-ink);
}

/* =========================================================================
   STAGE: phone-voting
   ========================================================================= */

[data-stage="phone-voting"] {
  padding: 1.75rem 1rem 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
}
:is([data-stage="phone-voting"]) .vote-headline {
  text-align: center;
  font-size: clamp(1.75rem, 6vw, 2.25rem);
  margin: 0.25rem 0 0;
}
:is([data-stage="phone-voting"]) .vote-sub {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lobby-paper-warm);
  opacity: 0.85;
  margin: 0;
  text-align: center;
}
:is([data-stage="phone-voting"]) .vote-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 12px;
  width: 100%;
  max-width: 24rem;
}
/* Voting tile "selected" treatment composes with .character-tile--selected
   (amber fill + ink ring). The compound selector matches the base
   .paper-tile-sm specificity + a second class so the amber override lands. */
:is([data-stage="phone-voting"]) button.paper-tile-sm.character-tile--selected {
  background: var(--lobby-mango);
  border-width: 4px;
  transform: translateY(-2px) rotate(-1deg);
  box-shadow: 0 6px 0 0 var(--lobby-ink), 0 10px 18px rgb(26 22 19 / 0.28);
}
:is([data-stage="phone-voting"]) button.paper-tile-sm.is-locked {
  opacity: 0.45;
  pointer-events: none;
}

/* =========================================================================
   STAGE: phone-watch-tv
   ========================================================================= */

[data-stage="phone-watch-tv"] {
  padding: 2rem 1.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  text-align: center;
}
:is([data-stage="phone-watch-tv"]) .watch-headline {
  font-size: clamp(2.25rem, 8vw, 3.25rem);
  line-height: 0.9;
  animation: watch-wobble var(--dur-epic) var(--ease-in-out) infinite;
}
:is([data-stage="phone-watch-tv"]) .watch-sub {
  font-size: 0.9rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
@keyframes watch-wobble {
  0%, 100% { transform: rotate(-1.5deg); }
  50%      { transform: rotate(1.5deg); }
}

/* =========================================================================
   STAGE: phone-spectator
   ========================================================================= */

[data-stage="phone-spectator"] {
  padding: 2rem 1.25rem 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 1rem;
  text-align: center;
}
:is([data-stage="phone-spectator"]) .spectator-headline {
  font-size: clamp(2.25rem, 7vw, 3rem);
  margin: 0.25rem 0 0;
}
:is([data-stage="phone-spectator"]) .spectator-note {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--lobby-paper-warm);
  opacity: 0.9;
  margin: 0;
}
:is([data-stage="phone-spectator"]) #spectator-timer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 14px;
  padding: 0.6rem 1.25rem;
  box-shadow: var(--lobby-shadow-md);
  transform: rotate(-1deg);
  color: var(--lobby-ink);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.08em;
}
:is([data-stage="phone-spectator"]) #spectator-timer p {
  font-family: 'Nunito', sans-serif;
  font-size: 0.55rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--lobby-ink);
  opacity: 0.65;
  margin: 0;
}
:is([data-stage="phone-spectator"]) #spectator-timer-display {
  font-size: 2rem;
  line-height: 1;
  color: var(--lobby-ink);
}
:is([data-stage="phone-spectator"]) #spectator-soundboard {
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 18px;
  padding: 1rem;
  box-shadow: var(--lobby-shadow-md);
  width: 100%;
  max-width: 22rem;
}
:is([data-stage="phone-spectator"]) #spectator-soundboard p {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--lobby-ink);
  opacity: 0.7;
  margin: 0 0 0.5rem;
  text-align: center;
}

/* =========================================================================
   STAGE: phone-between-rounds
   ========================================================================= */

[data-stage="phone-between-rounds"] {
  padding: 1.75rem 1rem 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
}
:is([data-stage="phone-between-rounds"]) .between-headline {
  text-align: center;
  font-size: clamp(2rem, 7vw, 2.75rem);
  margin: 0.25rem 0 0.25rem;
}
:is([data-stage="phone-between-rounds"]) .between-sub {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.75rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--lobby-paper-warm);
  opacity: 0.85;
  text-align: center;
  margin: 0;
}
:is([data-stage="phone-between-rounds"]) #between-ready-list {
  width: 100%;
  max-width: 22rem;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
}
/* Paper row for each player in the ready list. Rendered by
   renderBetweenRoundsReadyList with class="between-ready-row paper-sm". */
:is([data-stage="phone-between-rounds"]) .between-ready-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 0.75rem;
  border-radius: 14px;
  color: var(--lobby-ink);
}
:is([data-stage="phone-between-rounds"]) .between-ready-row--ready {
  background: var(--lobby-green);
}
:is([data-stage="phone-between-rounds"]) .between-ready-row__avatar {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--lobby-paper-inset);
  border: 2.5px solid var(--lobby-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 1.6rem;
  line-height: 1;
}
:is([data-stage="phone-between-rounds"]) .between-ready-row__avatar img,
:is([data-stage="phone-between-rounds"]) .between-ready-row__avatar video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
:is([data-stage="phone-between-rounds"]) .between-ready-row__name {
  flex: 1;
  font-family: 'Fredoka One', cursive;
  font-size: 0.95rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--lobby-ink);
  line-height: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
:is([data-stage="phone-between-rounds"]) .between-ready-row__status {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(26, 22, 19, 0.55);
}
:is([data-stage="phone-between-rounds"]) .between-ready-row--ready .between-ready-row__status {
  color: var(--lobby-ink);
  opacity: 0.85;
}
:is([data-stage="phone-between-rounds"]) .between-action-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  max-width: 22rem;
}
:is([data-stage="phone-between-rounds"]) .between-action-column .btn-chunky {
  width: 100%;
}

/* =========================================================================
   PASS 4: phone-overlay (soundboard + spectator-soundboard + toast)
   =========================================================================
   Three overlay surfaces that float on top of the round during the
   testimonials reel: the creator/player soundboard bottom-sheet, the
   spectator's inline soundboard panel, and the transient notification
   toast. Shared paper aesthetic — scoped so the existing DaisyUI chrome
   on unredesigned screens keeps its dark-luxury look.

   Contract:
   - `#phone-soundboard-overlay` + `#spectator-soundboard` carry
     `data-stage="phone-overlay"` + `data-slot="soundboard"` /
     `data-slot="spectator-soundboard"`.
   - `#notification-area` carries `data-stage="phone-overlay"` +
     `data-slot="toast"`.
   - `.soundboard-tile` is the per-emoji button (emitted by
     populatePhoneSoundboardGrid + populateSpectatorSoundboardGrid).
   - `.toast-paper` wraps each showNotification alert.
   ========================================================================= */

/* Bottom-sheet layout for the creator/player overlay. The existing
   Tailwind `fixed inset-0 flex items-center justify-center` centres the
   sheet in the viewport; we pin it to the bottom with padding instead so
   the TV reel stays readable above it. Backdrop gets a 40% ink scrim. */
#phone-soundboard-overlay[data-slot="soundboard"] {
  justify-content: flex-end;
  padding: 0;
  background: rgba(26, 22, 19, 0.4);
}

/* Paper sheet treatment — the spec's prescribed CSS. Applied to the
   overlay root for the soundboard and the spectator panel. ID-scoped
   selector tacks onto the attribute combo so specificity beats the
   existing `:is([data-stage="phone-spectator"]) #spectator-soundboard`
   rule (1,1,0) — the attribute-only form (0,2,0) loses that fight. */
[data-stage="phone-overlay"][data-slot="soundboard"],
[data-stage="phone-overlay"][data-slot="spectator-soundboard"],
#phone-soundboard-overlay[data-slot="soundboard"] > div,
#spectator-soundboard[data-slot="spectator-soundboard"] {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 32px 32px 0 0;
  box-shadow: var(--lobby-shadow-xl);
  color: var(--lobby-ink);
  padding: 1rem 1rem 2rem;
}

/* Bottom-sheet sits full-width on the phone; spectator panel stays
   width-constrained (it's inline inside the spectator screen). */
#phone-soundboard-overlay[data-slot="soundboard"] > div {
  max-width: none;
  width: 100%;
}

/* Skip-button strip at the top of the sheet — shrinks the default
   .btn-chunky (padding 1rem 2rem, clamp(1.5rem,...,2rem) font) into a
   pill that fits above the 3×3 emoji grid. Scoped to the overlay so it
   doesn't shrink the main round-active CTAs. */
[data-stage="phone-overlay"] .btn-chunky:not(.hidden) {
  padding: 0.45rem 1.1rem;
  font-size: 0.95rem;
  border-width: 3px;
  box-shadow:
    0 4px 0 0 var(--lobby-ink),
    0 8px 14px rgb(26 22 19 / 0.22);
}

/* "Now Playing" header strip inside the sheet — the inline Tailwind
   `text-sm text-base-content/50` looked right on dark-luxury but reads
   washed-out on cream paper. Pull it back into the lobby ink palette. */
[data-stage="phone-overlay"][data-slot="soundboard"] > div > p,
[data-stage="phone-overlay"] #phone-soundboard-now-name {
  color: var(--lobby-ink);
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
}
[data-stage="phone-overlay"][data-slot="soundboard"] > div > p {
  opacity: 0.65;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  font-size: 0.7rem;
  margin-bottom: 0.35rem;
}
[data-stage="phone-overlay"] #phone-soundboard-now-photo {
  border: 2.5px solid var(--lobby-ink);
  background: var(--lobby-paper-warm);
}

/* Per-emoji reaction button. Replaces the legacy
   `btn btn-ghost btn-lg text-2xl` DaisyUI triplet. */
[data-stage="phone-overlay"] .soundboard-tile {
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 20px;
  box-shadow: var(--lobby-shadow-md);
  width: 100%;
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.25rem;
  cursor: pointer;
  transition: transform 120ms var(--ease-snap);
  color: var(--lobby-ink);
}
[data-stage="phone-overlay"] .soundboard-tile:hover,
[data-stage="phone-overlay"] .soundboard-tile:active {
  transform: translateY(-2px);
  background: var(--lobby-mango);
}

/* Spectator soundboard header — the `<p>Soundboard</p>` inside
   #spectator-soundboard. Pass 3's existing rule scoped to
   `phone-spectator` already styles it; we re-assert color here so the
   `data-slot="spectator-soundboard"` panel block doesn't break that
   text when it takes over the paper background. */
#spectator-soundboard[data-slot="spectator-soundboard"] > p {
  color: var(--lobby-ink);
  text-align: center;
  opacity: 0.7;
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  margin: 0 0 0.5rem;
}

/* Toast container — `#notification-area` stays where it is (Tailwind
   `fixed top-2 left-2 right-2 z-50`); we only style descendants. */
[data-stage="phone-overlay"][data-slot="toast"] {
  z-index: var(--z-toast);
}
[data-stage="phone-overlay"] .toast-paper {
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 14px;
  box-shadow: var(--lobby-shadow-md);
  padding: 0.5rem 1rem;
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-ink);
  animation: slide-up-fade var(--dur-fast) var(--ease-out) both;
  margin-bottom: 0.5rem;
  letter-spacing: 0.01em;
}

/* =========================================================================
   PASS 5: TV ENTRY (#tv-screen-join)
   =========================================================================
   Brings the Sketch-Lobby cartoon look to the TV's "Start Game / Join
   Existing" landing screen — the first thing players see when they
   power on the TV. Earlier this screen was raw DaisyUI dark luxury on
   black; now it shares the brick-wall + paper-cutout vocabulary with
   the lobby.

   Inheritance: the shared lobby/phone scope at the top of this file
   (variables, .paper, .btn-chunky, .wordmark, .ink-stroke, .paper-sign,
   .input-paper-ticket, etc.) was broadened in this pass to include
   `[data-stage="tv-entry"]`. So any primitive used on a phone-entry
   ticket / lobby card already works inside #tv-screen-join. This block
   only adds the layout chrome the TV size needs.

   Sister stage `[data-stage="tv-host-selection"]` (the legacy
   #tv-screen-hostsetup div) was REMOVED from tv.html in this pass
   after a usage check (no `showScreen('hostsetup')` call exists; dead
   since the Session 8 refactor). No CSS for it lands here — the DOM
   is gone, so a redesign would have nothing to paint.
   ========================================================================= */

[data-stage="tv-entry"] {
  background:
    url('/assets/images/brick-tv.webp') center / cover no-repeat,
    var(--lobby-ink);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* `safe center` keeps the column centered when it fits, but falls back
     to top-anchored when content overflows (form expanded + error pill
     visible). Without `safe`, the flex container clips the top + bottom
     symmetrically and the error pill ends up below the viewport. */
  justify-content: safe center;
  padding: 2rem;
  gap: 2rem;
}

/* Wordmark sized up for TV viewing distance — about 1.5× the lobby
   marquee. The base .wordmark rule (~2.5rem padding-x) already wraps
   the text in the cream display style; this just amps the size. */
[data-stage="tv-entry"] .wordmark {
  padding: 1.25rem 3rem;
}
[data-stage="tv-entry"] .wordmark__text {
  font-size: clamp(3rem, 7vw, 7rem);
}

/* Paper card holding the explainer line. Wider + roomier than a phone
   paper card. */
[data-stage="tv-entry"] .paper {
  padding: 2rem 3rem;
  max-width: 48rem;
  text-align: center;
}
[data-stage="tv-entry"] .paper p {
  color: var(--lobby-ink);
  font-family: 'Nunito', sans-serif;
  font-size: clamp(1.25rem, 2vw, 1.75rem);
  font-weight: 700;
  line-height: 1.3;
  margin: 0;
}

/* CTA row — two chunky pills side by side. */
[data-stage="tv-entry"] .tv-entry-cta-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem;
}

/* Bump the chunky button size up for TV. The base rule clamps to
   ~1.5–2rem; on a 1080p TV that reads small. */
[data-stage="tv-entry"] .btn-chunky:not(.hidden) {
  font-size: clamp(1.75rem, 2.5vw, 2.25rem);
  padding: 1.25rem 2.75rem;
  border-width: 5px;
  box-shadow:
    0 8px 0 0 var(--lobby-ink),
    0 14px 22px rgb(26 22 19 / 0.28);
}

/* Join-code sub-form — a paper-ticket holding the input + connect
   button. Stays hidden until #btn-tv-join-toggle reveals it. */
[data-stage="tv-entry"] #tv-join-form {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 24px;
  box-shadow: var(--lobby-shadow-lg);
  padding: 1.5rem 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  max-width: 26rem;
  width: 100%;
}

/* Make the join-code input read like a ticket stub (matches the phone
   room-code input). */
[data-stage="tv-entry"] #tv-room-code.input-paper-ticket,
[data-stage="tv-entry"] #tv-room-code {
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 18px;
  box-shadow: 0 4px 0 0 var(--lobby-ink), 0 8px 14px rgb(26 22 19 / 0.18);
  font-family: 'JetBrains Mono', monospace;
  color: var(--lobby-ink);
  font-size: clamp(2rem, 4vw, 3rem);
  letter-spacing: 0.3em;
  text-align: center;
  text-transform: uppercase;
  padding: 0.75rem 1.5rem;
  width: 100%;
  max-width: 18rem;
}
[data-stage="tv-entry"] #tv-room-code:focus {
  outline: none;
  background: var(--lobby-paper);
  box-shadow:
    0 4px 0 0 var(--lobby-ink),
    0 8px 14px rgb(26 22 19 / 0.18),
    0 0 0 3px var(--lobby-teal) inset;
}

/* Error pill — coral .paper-sign treatment so a bad room code reads
   loud without breaking the paper-cutout aesthetic. */
[data-stage="tv-entry"] #tv-join-error.paper-sign {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 1px var(--lobby-ink);
  font-size: clamp(1.25rem, 2vw, 1.6rem);
}

/* =========================================================================
   PASS 6: TV ROUND-ACTIVE + GATHER
   =========================================================================
   The two highest-airtime in-game TV screens. Pass 6 trades the dark
   DaisyUI grid for a brick-wall backdrop with paper-cutout player
   tiles, a chunky timer ticket up top, a coral-on-cream sus bar at
   the bottom of every tile, an amber HOST stamp on the host card,
   and a green AT TV stamp on gathered cards.

   Inheritance: the shared lobby/phone scope at the top of this file
   was broadened in this pass to include `[data-stage="tv-round-active"]`
   and `[data-stage="tv-gather"]`, so every primitive already
   established (`.paper`, `.paper-sm`, `.paper-sign`, `.ink-stroke`,
   `.ink-stroke-sm`, `.btn-chunky`, lobby variables) is reachable here.
   This block adds only the round/gather-specific chrome (timer
   ticket, big tile, stamp variants, chunky sus bar, the brick-wall
   backdrop on the two stages).
   ========================================================================= */

/* Stage containers — brick-wall + ink color baseline. */
[data-stage="tv-round-active"],
[data-stage="tv-gather"] {
  background:
    url('/assets/images/brick-tv.webp') center / cover no-repeat,
    var(--lobby-ink);
  min-height: 100vh;
  color: var(--lobby-ink);
}

/* ---------- Round-active layout ---------- */

[data-stage="tv-round-active"] {
  display: flex;
  flex-direction: column;
  padding: 1.5rem 2rem 2rem;
  gap: 1.25rem;
}

/* Top header strip — round pip on the left, timer ticket centered,
   host name on the right. */
[data-stage="tv-round-active"] .round-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
[data-stage="tv-round-active"] .round-header__left,
[data-stage="tv-round-active"] .round-header__right {
  flex: 0 0 auto;
  min-width: 12rem;
}
[data-stage="tv-round-active"] .round-header__right {
  text-align: right;
}

/* Round-number pip — coral .paper-sign reuse but a touch bigger. */
[data-stage="tv-round-active"] .round-pip.paper-sign {
  font-size: clamp(1.4rem, 2vw, 2rem);
  padding: 0.6rem 1.4rem;
  background: var(--lobby-mango);
  letter-spacing: 0.06em;
}

/* Host label — small paper-sign tag on the right. */
[data-stage="tv-round-active"] .host-tag {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.25rem;
}
[data-stage="tv-round-active"] .host-tag__label {
  font-family: 'Nunito', sans-serif;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--lobby-paper-warm);
  opacity: 0.8;
}
[data-stage="tv-round-active"] .host-tag__name {
  font-family: 'Fredoka One', cursive;
  font-size: clamp(1.2rem, 1.8vw, 1.75rem);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 1px var(--lobby-ink);
  paint-order: stroke fill;
  letter-spacing: 0.02em;
}

/* Timer ticket — paper plaque with mono numerals. */
[data-stage="tv-round-active"] .timer-paper,
[data-stage="tv-gather"] .timer-paper {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 18px;
  padding: 0.5rem 1.75rem 0.75rem;
  box-shadow: var(--lobby-shadow-md);
  position: relative;
  transform: rotate(-1deg);
  min-width: 14rem;
}
[data-stage="tv-round-active"] .timer-paper__label,
[data-stage="tv-gather"] .timer-paper__label {
  font-family: 'Nunito', sans-serif;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--lobby-ink);
  opacity: 0.65;
  line-height: 1;
}
[data-stage="tv-round-active"] .timer-paper__value,
[data-stage="tv-gather"] .timer-paper__value {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  font-size: clamp(2.5rem, 4.5vw, 4rem);
  letter-spacing: 0.04em;
  line-height: 1.1;
  color: var(--lobby-ink);
}
/* When the round JS adds .text-warning (default), the timer reads
   amber on cream; when it swaps to .text-error (last 5 minutes), it
   flips to coral. The Tailwind classes still match — we override
   the color so they read correctly on the paper background. */
[data-stage="tv-round-active"] .timer-paper__value.text-warning,
[data-stage="tv-gather"] .timer-paper__value.text-warning {
  color: var(--lobby-mango);
  -webkit-text-stroke: 1px var(--lobby-ink);
  paint-order: stroke fill;
}
[data-stage="tv-round-active"] .timer-paper__value.text-error,
[data-stage="tv-gather"] .timer-paper__value.text-error {
  color: var(--lobby-coral);
  -webkit-text-stroke: 1px var(--lobby-ink);
  paint-order: stroke fill;
}

/* Round body — left = player grid, right = leaderboard panel. */
[data-stage="tv-round-active"] .round-body {
  flex: 1;
  display: flex;
  gap: 1.5rem;
  min-height: 0;
}
[data-stage="tv-round-active"] .round-body__grid {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
[data-stage="tv-round-active"] #tv-player-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.25rem;
}
@media (max-width: 1280px) {
  [data-stage="tv-round-active"] #tv-player-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Leaderboard sidebar — paper card. */
[data-stage="tv-round-active"] .round-body__leaderboard {
  width: 22rem;
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 24px;
  box-shadow: var(--lobby-shadow-lg);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  transform: rotate(0.6deg);
}
[data-stage="tv-round-active"] .round-body__leaderboard h3 {
  font-family: 'Fredoka One', cursive;
  font-size: 1.5rem;
  margin: 0 0 0.25rem;
  color: var(--lobby-ink);
  -webkit-text-stroke: 0.5px var(--lobby-ink);
  text-align: center;
}
[data-stage="tv-round-active"] #tv-leaderboard {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* ---------- Player tile (used by renderPlayerGrid) ---------- */

:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .paper-tile-lg {
  position: relative;
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 22px;
  box-shadow: var(--lobby-shadow-lg);
  padding: 1rem 0.75rem 0.85rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  color: var(--lobby-ink);
  transform: rotate(-0.6deg);
}
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .paper-tile-lg:nth-child(even) {
  transform: rotate(0.7deg);
}
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .paper-tile-lg--host {
  background: var(--lobby-mango);
}
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .paper-tile-lg--disconnected {
  opacity: 0.45;
  filter: grayscale(0.4);
}
/* Gather: dim non-gathered cards so the AT TV ones pop. */
[data-stage="tv-gather"] .paper-tile-lg--waiting {
  opacity: 0.55;
}

/* Avatar slot — fixed square so the image / video / emoji centers. */
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .paper-tile-lg__avatar {
  width: 7.5rem;
  height: 7.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 16px;
  overflow: hidden;
}
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .paper-tile-lg__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

/* Name strip. */
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .paper-tile-lg__name {
  font-size: clamp(1rem, 1.25vw, 1.4rem);
  text-align: center;
  line-height: 1.05;
  letter-spacing: 0.02em;
  margin: 0;
}

/* Stamp variants — extends the existing .stamp idiom (rotated paper
   tag in the corner). Anchor to the top-right of the tile. */
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .stamp-host,
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .stamp-at-tv {
  position: absolute;
  top: -10px;
  right: -8px;
  font-family: 'Fredoka One', cursive;
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.7rem;
  border: 2.5px solid var(--lobby-ink);
  border-radius: 999px;
  box-shadow: 0 3px 0 0 var(--lobby-ink);
  -webkit-text-stroke: 0.5px var(--lobby-ink);
  paint-order: stroke fill;
  transform: rotate(8deg);
  z-index: 2;
  white-space: nowrap;
}
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .stamp-host {
  background: var(--lobby-mango);
  color: var(--lobby-ink);
}
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .stamp-at-tv {
  background: var(--lobby-green);
  color: var(--lobby-ink);
}

/* "waiting…" mini-tag for the gather screen — pinned to the bottom
   so it doesn't compete with the AT TV stamp visually. */
[data-stage="tv-gather"] .paper-tile-lg__waiting {
  font-family: 'Nunito', sans-serif;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(26, 22, 19, 0.55);
  margin-top: -0.25rem;
}

/* ---------- Suspicion bar (replaces the legacy .sus-bar) ---------- */

:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .sus-bar-chunky {
  position: relative;
  width: 100%;
  height: 14px;
  background: var(--lobby-paper-warm);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 999px;
  overflow: hidden;
  box-shadow: 0 2px 0 0 var(--lobby-ink);
}
:is([data-stage="tv-round-active"], [data-stage="tv-gather"]) .sus-bar-chunky__fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--lobby-mango), var(--lobby-coral));
  /* Width is set inline by renderPlayerGrid; the legacy CSS transition
     stays in tv.html (.sus-bar { transition: width 0.8s }) — we keep
     the new fill responding to the same `style="width: N%"` attribute. */
  transition: width 0.8s ease-in-out;
}

/* ---------- Spectator strip (round screen footer) ---------- */

[data-stage="tv-round-active"] #tv-round-spectators {
  margin-top: 0.5rem;
}
[data-stage="tv-round-active"] #tv-round-spectators p {
  font-family: 'Nunito', sans-serif;
  font-size: 0.75rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--lobby-paper-warm);
  opacity: 0.8;
  margin-bottom: 0.4rem;
}
[data-stage="tv-round-active"] .spectator-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: var(--lobby-paper);
  border: 2px solid var(--lobby-ink);
  border-radius: 999px;
  padding: 0.25rem 0.7rem;
  font-family: 'Nunito', sans-serif;
  font-size: 0.85rem;
  font-weight: 800;
  color: var(--lobby-ink);
}
[data-stage="tv-round-active"] .spectator-chip__avatar {
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  background: var(--lobby-paper-warm);
  border: 1.5px solid var(--lobby-ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  line-height: 1;
}

/* ---------- Leaderboard rows (used by renderLeaderboard) ---------- */
/* The existing renderLeaderboard helper is NOT touched in Pass 6 (it
   renders into #tv-leaderboard which we re-skin via descendant
   selectors). Keep its emoji-bg-flex layout and override colors so
   it reads on the paper sidebar. */
[data-stage="tv-round-active"] #tv-leaderboard > div {
  background: var(--lobby-paper-warm);
  border: 2px solid var(--lobby-ink);
  border-radius: 12px;
  padding: 0.5rem 0.75rem;
  color: var(--lobby-ink);
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
[data-stage="tv-round-active"] #tv-leaderboard span,
[data-stage="tv-round-active"] #tv-leaderboard .text-warning,
[data-stage="tv-round-active"] #tv-leaderboard .font-display {
  color: var(--lobby-ink);
}
[data-stage="tv-round-active"] #tv-leaderboard .avatar > div {
  background: var(--lobby-paper);
  border: 1.5px solid var(--lobby-ink);
}

/* ---------- Gather screen ---------- */

[data-stage="tv-gather"] {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: safe center;
  padding: 2rem;
  gap: 1.75rem;
}
[data-stage="tv-gather"] .gather-headline {
  font-size: clamp(3rem, 6vw, 5.5rem);
  text-align: center;
  margin: 0;
  letter-spacing: 0.04em;
}
[data-stage="tv-gather"] .gather-counter.paper-sign {
  background: var(--lobby-mango);
  font-size: clamp(1.4rem, 2vw, 1.75rem);
  padding: 0.5rem 1.25rem;
}
[data-stage="tv-gather"] #tv-gather-players {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 13rem));
  gap: 1.25rem;
  justify-content: center;
  max-width: 80rem;
  width: 100%;
}

/* =========================================================================
   DESIGN PASS 7 — TV Emergency screen
   =========================================================================
   `data-stage="tv-emergency"` is the 3-second heart-stopping beat between
   all-players-gathered-for-emergency and the emergency reveal fires.
   Coral + ink warning-tape backdrop, huge pulsing caller card, rotated
   "EMERGENCY" stamp. All primitives inherit from the shared
   :is([data-stage^="lobby"], …, [data-stage="tv-emergency"], [data-stage="tv-reveal"]) list above.
   ========================================================================= */

[data-stage="tv-emergency"] {
  min-height: 100vh;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.5rem;
  padding: 2rem;
  position: relative;
  overflow: hidden;
  background:
    repeating-linear-gradient(
      45deg,
      var(--lobby-coral) 0,
      var(--lobby-coral) 80px,
      var(--lobby-ink) 80px,
      var(--lobby-ink) 160px
    );
  background-size: 226px 226px; /* sqrt(160^2 + 160^2) so 45deg scroll tiles */
  animation: emergency-stripes-scroll 6s linear infinite;
}

@keyframes emergency-stripes-scroll {
  from { background-position:   0   0; }
  to   { background-position: 226px 0; }
}

/* Decorative inner frame so the hot backdrop never spills through whitespace.
   pointer-events: none ensures no click is swallowed (animation is CSS-only
   anyway, but belt-and-braces per the session brief). */
[data-stage="tv-emergency"]::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse at center,
    transparent 40%,
    rgba(26, 22, 19, 0.25) 100%
  );
  pointer-events: none;
  z-index: 0;
}

[data-stage="tv-emergency"] > * {
  position: relative;
  z-index: 1;
}

/* Big ink-stroke headline at the top of the viewport. */
[data-stage="tv-emergency"] .emergency-headline {
  font-size: clamp(4rem, 8vw, 7rem);
  letter-spacing: 0.04em;
  margin: 0;
  text-align: center;
  animation: emergency-flicker var(--dur-dramatic) var(--ease-in-out) infinite;
}

@keyframes emergency-flicker {
  0%, 100% { opacity: 1; }
  48%      { opacity: 1; }
  50%      { opacity: 0.65; }
  52%      { opacity: 1; }
}

/* "called by" sublabel — sits between headline and caller card. */
[data-stage="tv-emergency"] .emergency-subheadline {
  font-family: var(--font-display, 'Fredoka One', cursive);
  font-size: clamp(1.5rem, 2.2vw, 2rem);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2px var(--lobby-ink);
  text-shadow: 0 3px 0 var(--lobby-ink);
  margin: 0;
  letter-spacing: 0.08em;
}

/* The caller card — red paper tile, pulsing, with a rotated EMERGENCY stamp. */
[data-stage="tv-emergency"] .emergency-card {
  background: var(--lobby-coral);
  border: var(--lobby-border-lg);
  border-radius: 32px;
  box-shadow: var(--lobby-shadow-xl);
  padding: 2.5rem 4rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  animation: emergency-heartbeat var(--dur-dramatic) ease-in-out infinite;
  position: relative;
  max-width: 640px;
}

@keyframes emergency-heartbeat {
  0%, 100% { transform: scale(1)    rotate(-1deg); }
  30%      { transform: scale(1.07) rotate(-1deg); }
  40%      { transform: scale(1.03) rotate(-1deg); }
  55%      { transform: scale(1.05) rotate(-1deg); }
  70%      { transform: scale(1.00) rotate(-1deg); }
}

/* The caller's avatar slot — cream disk on coral paper. */
[data-stage="tv-emergency"] .emergency-card__avatar {
  width: 15rem;
  height: 15rem;
  border-radius: 999px;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-lg);
  box-shadow: var(--lobby-shadow-md);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-size: 8rem;
  line-height: 1;
}

[data-stage="tv-emergency"] .emergency-card__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 999px;
}

[data-stage="tv-emergency"] .emergency-card__avatar img[src=""] {
  display: none;
}

[data-stage="tv-emergency"] .emergency-card__name {
  font-size: clamp(2.2rem, 4vw, 3.25rem);
  text-align: center;
  margin: 0;
}

/* Bottom directive — "Gather at the TV!" CTA. */
[data-stage="tv-emergency"] .emergency-directive {
  font-family: var(--font-display, 'Fredoka One', cursive);
  font-size: clamp(1.4rem, 2vw, 1.9rem);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 1.5px var(--lobby-ink);
  text-shadow: 0 2px 0 var(--lobby-ink);
  letter-spacing: 0.06em;
  margin: 0;
}

/* Rotated stamp in the top-right corner of the caller card. */
[data-stage="tv-emergency"] .stamp-emergency {
  position: absolute;
  top: -1.25rem;
  right: -1.5rem;
  background: var(--lobby-ink);
  color: var(--lobby-coral);
  -webkit-text-stroke: 0;
  text-shadow: none;
  border: 3px solid var(--lobby-paper-warm);
  border-radius: 12px;
  padding: 0.5rem 1.5rem;
  transform: rotate(-8deg);
  font-family: var(--font-display, 'Fredoka One', cursive);
  font-size: clamp(1.4rem, 1.8vw, 1.75rem);
  letter-spacing: 0.12em;
  box-shadow: 0 4px 0 0 rgba(26, 22, 19, 0.6);
  z-index: 2;
}

/* =========================================================================
   DESIGN PASS 8 — TV Reveal screen (THE BIG ONE)
   =========================================================================
   `data-stage="tv-reveal"` is the emotional peak of every round. The
   existing GSAP timeline (`runRevealSequence`, `runEmergencyRevealSequence`)
   is NOT touched by this pass — timings/easing/ordering unchanged. This
   block skins the elements the timeline animates: the backdrop, title,
   ink divider, intro, OOO reveal card, CAUGHT/GOT AWAY banner, task
   card, scores list, and vote cards (normal) / caller card (emergency).
   All primitives (.paper, .paper-sm, .ink-stroke, .paper-sign) inherit
   from the shared :is(…, [data-stage="tv-reveal"]) list above.
   ========================================================================= */

/* ---------- Stage scaffold ---------- */

[data-stage="tv-reveal"] {
  min-height: 100vh;
  width: 100%;
  padding: 1.25rem 2rem 1.5rem;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse 120% 90% at 50% 50%,
      var(--lobby-paper-warm) 0%,
      var(--lobby-paper) 55%,
      #E4D3A8 100%);
  color: var(--lobby-ink);
}

/* Darkening overlay. runRevealSequence fades #tv-reveal-bg from
   opacity:0 → 0.7. We give it an ink radial so the fade reads as a
   cinematic dim on the paper stage (ink at low alpha feels like spot
   lights coming down) rather than a flat black veil. */
[data-stage="tv-reveal"] #tv-reveal-bg {
  background: radial-gradient(ellipse 85% 75% at 50% 45%,
    rgba(26, 22, 19, 0.0) 0%,
    rgba(26, 22, 19, 0.35) 55%,
    rgba(26, 22, 19, 0.65) 100%);
  pointer-events: none;
}

[data-stage="tv-reveal"] .reveal-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  max-width: 1400px;
  margin: 0 auto;
}

/* ---------- Title (e.g. "THE ODD ONE OUT WAS…" / "EMERGENCY VOTE") ---------- */

[data-stage="tv-reveal"] .reveal-title {
  font-size: clamp(2.75rem, 5vw, 4.5rem);
  margin: 0;
  text-align: center;
  letter-spacing: 0.04em;
}

/* ---------- Vote cards row (normal reveal only) ---------- */

[data-stage="tv-reveal"] .reveal-votes-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  width: 100%;
  max-width: 72rem;
}

/* `.vote-card` is a paper-sm preset: voter avatar up top, voter name,
   a "voted for" paper-sign, and the target name in green (correct) or
   coral (wrong). Slight alternating rotation for life. */
[data-stage="tv-reveal"] .vote-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.65rem 1rem 0.85rem;
  min-width: 8rem;
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 16px;
  box-shadow: var(--lobby-shadow-md);
  color: var(--lobby-ink);
  position: relative;
}
[data-stage="tv-reveal"] .vote-card:nth-child(odd)  { transform: rotate(-1.5deg); }
[data-stage="tv-reveal"] .vote-card:nth-child(even) { transform: rotate( 1.5deg); }

[data-stage="tv-reveal"] .vote-card__avatar {
  width: 4rem;
  height: 4rem;
  border-radius: 999px;
  background: var(--lobby-paper-warm);
  border: 2.5px solid var(--lobby-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
[data-stage="tv-reveal"] .vote-card__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

[data-stage="tv-reveal"] .vote-card__name {
  font-size: 0.95rem;
  margin: 0;
  line-height: 1.05;
  text-align: center;
}

[data-stage="tv-reveal"] .vote-card__label {
  font-size: 0.8rem;
  padding: 0.2rem 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transform: rotate(-2deg);
}

[data-stage="tv-reveal"] .vote-card__target {
  font-family: 'Fredoka One', cursive;
  font-size: 1.1rem;
  padding: 0.2rem 0.7rem;
  border-radius: 999px;
  letter-spacing: 0.04em;
  border: 2px solid var(--lobby-ink);
}
[data-stage="tv-reveal"] .vote-card__target--correct {
  background: var(--lobby-green);
  color: var(--lobby-ink);
}
[data-stage="tv-reveal"] .vote-card__target--wrong {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 0.75px var(--lobby-ink);
}

/* ---------- Ink divider (thick scribble) ---------- */

/* Solid wavy ink bar — stands in for a hand-drawn SVG scribble and needs
   no external assets. Sized wide, short, with a slight tilt. */
[data-stage="tv-reveal"] #tv-reveal-divider {
  width: min(60%, 40rem);
  height: 10px;
  background: var(--lobby-ink);
  border-radius: 999px;
  transform: rotate(-1deg);
  box-shadow: 0 4px 0 0 rgba(26, 22, 19, 0.25);
  margin: 0.5rem 0 0.25rem;
  /* The .divider class Tailwind attaches has its own styles; we override
     the layout/size to read as ink stroke. */
  display: block;
}

/* Hide the two divider pseudo-children Tailwind's DaisyUI .divider
   utility injects (they were empty in the old design but can show
   hairlines on some Tailwind versions). */
[data-stage="tv-reveal"] #tv-reveal-divider::before,
[data-stage="tv-reveal"] #tv-reveal-divider::after {
  display: none;
}

/* ---------- Intro ("The Odd One Out was…") ---------- */

[data-stage="tv-reveal"] .reveal-intro {
  font-size: clamp(1.2rem, 1.6vw, 1.5rem);
  font-style: italic;
  margin: 0;
  text-align: center;
  letter-spacing: 0.03em;
}

/* ---------- OOO reveal card (huge paper + avatar + name + stamp) ---------- */

[data-stage="tv-reveal"] .reveal-ooo-card {
  padding: 1.25rem 2.25rem 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  max-width: 24rem;
  position: relative;
  /* The GSAP tween sets inline transform: scale(0.3) → scale(1). Keep
     rotation out of inline transform so we don't fight the tween; the
     alternating rotation idiom used on paper-sm is off for this card. */
}

[data-stage="tv-reveal"] .reveal-ooo-avatar {
  width: 13rem;
  height: 13rem;
  max-width: 80vw;
  border-radius: 999px;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-lg);
  box-shadow: var(--lobby-shadow-md);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-size: 8rem;
  line-height: 1;
}
[data-stage="tv-reveal"] .reveal-ooo-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 999px;
}
[data-stage="tv-reveal"] .reveal-ooo-avatar img[src=""] {
  display: none;
}
[data-stage="tv-reveal"] .reveal-ooo-avatar > * {
  max-width: 100%;
  max-height: 100%;
}

[data-stage="tv-reveal"] .reveal-ooo-name {
  font-size: clamp(2rem, 3.5vw, 3rem);
  margin: 0;
  text-align: center;
  letter-spacing: 0.02em;
}

/* ---------- Stamp family (rotated corner paper tags) ----------
   Follows the .stamp-host / .stamp-at-tv / .stamp-emergency idiom
   from Passes 6 + 7. Shared base + per-variant color. */
[data-stage="tv-reveal"] .stamp-ooo,
[data-stage="tv-reveal"] .stamp-task-done,
[data-stage="tv-reveal"] .stamp-task-fail {
  position: absolute;
  font-family: 'Fredoka One', cursive;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.3rem 0.9rem;
  border: 3px solid var(--lobby-ink);
  border-radius: 14px;
  box-shadow: 0 4px 0 0 rgba(26, 22, 19, 0.7);
  -webkit-text-stroke: 0.5px var(--lobby-ink);
  paint-order: stroke fill;
  white-space: nowrap;
  z-index: 2;
}

/* OOO stamp: coral paper, anchored top-right of the reveal card, bigger
   + more assertively rotated than the other stamps. */
[data-stage="tv-reveal"] .stamp-ooo {
  top: -1rem;
  right: -1.25rem;
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  font-size: clamp(1.1rem, 1.5vw, 1.4rem);
  padding: 0.5rem 1.25rem;
  transform: rotate(-10deg);
}

/* Task stamps: green (done) / coral (fail). Anchored top-right of the
   task card. */
[data-stage="tv-reveal"] .stamp-task-done {
  top: -0.85rem;
  right: -0.9rem;
  background: var(--lobby-green);
  color: var(--lobby-ink);
  font-size: clamp(0.95rem, 1.3vw, 1.15rem);
  transform: rotate(8deg);
}
[data-stage="tv-reveal"] .stamp-task-fail {
  top: -0.85rem;
  right: -0.9rem;
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  font-size: clamp(0.95rem, 1.3vw, 1.15rem);
  transform: rotate(-6deg);
}

/* ---------- CAUGHT / GOT AWAY banner ---------- */

[data-stage="tv-reveal"] .reveal-caught {
  font-size: clamp(2.4rem, 4vw, 3.75rem);
  margin: 0;
  text-align: center;
  letter-spacing: 0.06em;
}
/* GSAP tween scales this element from 2 → 1 on reveal. Keep transform
   untouched here; color via modifier classes. */
[data-stage="tv-reveal"] .reveal-caught--correct {
  color: var(--lobby-green);
  -webkit-text-stroke: 3px var(--lobby-ink);
  text-shadow: 0 5px 0 var(--lobby-ink);
}
[data-stage="tv-reveal"] .reveal-caught--wrong {
  color: var(--lobby-coral);
  -webkit-text-stroke: 3px var(--lobby-ink);
  text-shadow: 0 5px 0 var(--lobby-ink);
}

/* ---------- Task card ---------- */

[data-stage="tv-reveal"] .reveal-task-card {
  padding: 1rem 1.75rem 1.25rem;
  width: 100%;
  max-width: 40rem;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

[data-stage="tv-reveal"] .reveal-task-label {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(26, 22, 19, 0.55);
  font-size: 0.95rem;
  margin: 0;
}

[data-stage="tv-reveal"] .reveal-task-text {
  font-size: clamp(1.15rem, 1.8vw, 1.65rem);
  margin: 0;
  line-height: 1.15;
  letter-spacing: 0.01em;
  color: var(--lobby-ink);
  -webkit-text-stroke: 0;
  text-shadow: none;
}

[data-stage="tv-reveal"] .reveal-task-status {
  font-family: 'Fredoka One', cursive;
  font-size: 1.2rem;
  margin-top: 0.25rem;
  padding: 0.2rem 0.6rem;
  display: inline-block;
  border-radius: 999px;
  letter-spacing: 0.05em;
  align-self: flex-start;
}
[data-stage="tv-reveal"] .reveal-task-status--done {
  background: rgba(143, 207, 130, 0.35);
  color: #2E5D29;
}
[data-stage="tv-reveal"] .reveal-task-status--fail {
  background: rgba(232, 107, 107, 0.3);
  color: #7A2A2A;
}

/* ---------- Scores card + rows ---------- */

[data-stage="tv-reveal"] .reveal-scores-card {
  padding: 0.85rem 1.5rem 1.1rem;
  width: 100%;
  max-width: 40rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}

[data-stage="tv-reveal"] .reveal-scores-title {
  font-size: clamp(1.1rem, 1.6vw, 1.4rem);
  text-align: center;
  margin: 0;
  letter-spacing: 0.04em;
}

[data-stage="tv-reveal"] .reveal-scores-list {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

/* One paper-sm row per player: avatar — name — round delta — session total. */
[data-stage="tv-reveal"] .scorelist-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 0.6rem;
  padding: 0.35rem 0.85rem;
  background: var(--lobby-paper-warm);
  border: 2.5px solid var(--lobby-ink);
  border-radius: 14px;
  box-shadow: 0 3px 0 0 var(--lobby-ink);
}
[data-stage="tv-reveal"] .scorelist-row:nth-child(odd)  { transform: rotate(-0.4deg); }
[data-stage="tv-reveal"] .scorelist-row:nth-child(even) { transform: rotate( 0.4deg); }

[data-stage="tv-reveal"] .scorelist-row__avatar {
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 999px;
  background: var(--lobby-paper);
  border: 2px solid var(--lobby-ink);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}
[data-stage="tv-reveal"] .scorelist-row__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

[data-stage="tv-reveal"] .scorelist-row__name {
  font-size: 1rem;
  margin: 0;
  line-height: 1;
  color: var(--lobby-ink);
  -webkit-text-stroke: 0;
  text-shadow: none;
  letter-spacing: 0.01em;
  font-weight: 800;
  font-family: 'Fredoka One', cursive;
}

[data-stage="tv-reveal"] .scorelist-row__delta {
  font-family: 'Fredoka One', cursive;
  font-size: 1.2rem;
  padding: 0.1rem 0.7rem;
  border-radius: 999px;
  letter-spacing: 0.02em;
  min-width: 2.8rem;
  text-align: center;
}
[data-stage="tv-reveal"] .scorelist-row__delta--up {
  background: var(--lobby-green);
  color: var(--lobby-ink);
}
[data-stage="tv-reveal"] .scorelist-row__delta--down {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 0.75px var(--lobby-ink);
}
[data-stage="tv-reveal"] .scorelist-row__delta--zero {
  background: var(--lobby-paper);
  color: rgba(26, 22, 19, 0.55);
}

[data-stage="tv-reveal"] .scorelist-row__total {
  font-family: 'Fredoka One', cursive;
  font-size: 0.95rem;
  padding: 0.2rem 0.6rem;
  background: var(--lobby-paper);
  border: 2px solid var(--lobby-ink);
  border-radius: 999px;
  letter-spacing: 0.04em;
  color: var(--lobby-ink);
  white-space: nowrap;
}

/* ---------- Emergency caller card (emergency reveal only) ----------
   runEmergencyRevealSequence builds one big .paper card into
   #tv-reveal-votes showing the caller → target accusation. Same
   cartoon vocabulary as the rest of the reveal. */

[data-stage="tv-reveal"] .reveal-caller-card {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1.25rem;
  padding: 1.75rem 2.25rem 2rem;
  max-width: 46rem;
  width: 100%;
  position: relative;
  background: var(--lobby-coral);
  border: var(--lobby-border-lg);
  border-radius: 24px;
  box-shadow: var(--lobby-shadow-xl);
  color: var(--lobby-paper-warm);
}

[data-stage="tv-reveal"] .reveal-caller-card__side {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}

[data-stage="tv-reveal"] .reveal-caller-card__avatar {
  width: 8rem;
  height: 8rem;
  border-radius: 999px;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  box-shadow: var(--lobby-shadow-md);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  font-size: 4.5rem;
  line-height: 1;
  color: var(--lobby-ink);
}
[data-stage="tv-reveal"] .reveal-caller-card__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

[data-stage="tv-reveal"] .reveal-caller-card__name {
  font-size: clamp(1.4rem, 2vw, 1.8rem);
  margin: 0;
  text-align: center;
}

[data-stage="tv-reveal"] .reveal-caller-card__label {
  font-size: clamp(0.9rem, 1.1vw, 1rem);
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.9;
  margin: 0;
}

[data-stage="tv-reveal"] .reveal-caller-card__accused {
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  padding: 0.5rem 1.25rem;
  align-self: center;
  transform: rotate(-4deg);
  background: var(--lobby-paper);
  color: var(--lobby-ink);
  border-radius: 999px;
  border: 3px solid var(--lobby-ink);
  box-shadow: 0 3px 0 0 var(--lobby-ink);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-family: 'Fredoka One', cursive;
}

/* Responsive collapse — stack caller / accused / target vertically on
   narrower screens (e.g. iPad-width TV). */
@media (max-width: 900px) {
  [data-stage="tv-reveal"] .reveal-caller-card {
    grid-template-columns: 1fr;
  }
  [data-stage="tv-reveal"] .reveal-caller-card__accused {
    justify-self: center;
  }
}

/* =========================================================================
   PASS 9 — TV testimonials + between-rounds
   =========================================================================
   Shared vocabulary with the rest of the sketch/paper theme: brick-tv
   backdrop, paper + paper-sm cards, ink-stroke headings, paper-sign
   rotated tags. Scoped to [data-stage="tv-testimonials"] and
   [data-stage="tv-between-rounds"]. Ready-notch is a local primitive
   specific to this stage; .leaderboard-row is the named row element the
   session brief calls for (a sibling of Pass 8's .scorelist-row — same
   grid idea, more vertical room because between-rounds gives it the
   whole card). */

/* ---------- tv-screen-testimonials ---------------------------------- */

[data-stage="tv-testimonials"] {
  position: relative;
  background: url('/assets/images/brick-tv.webp') center / cover no-repeat var(--lobby-ink);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  padding: 2.5rem 2rem;
  overflow: hidden;
  color: var(--lobby-ink);
}

/* Paper frame around the <video> — cream border + ink outline + shadow. */
[data-stage="tv-testimonials"] .reel-frame {
  position: relative;
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 32px;
  box-shadow: var(--lobby-shadow-xl);
  padding: 1.25rem;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 72vw;
}

[data-stage="tv-testimonials"] #tv-testimonial-video {
  border-radius: 18px;
  width: 52vw;
  max-width: 960px;
  aspect-ratio: 16 / 9;
  background: #111;
  display: block;
  object-fit: contain;
  border: 3px solid var(--lobby-ink);
}

/* Header row — badge + speaker attribution */
[data-stage="tv-testimonials"] .reel-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}

[data-stage="tv-testimonials"] #tv-testimonial-badge {
  font-size: clamp(2.2rem, 4vw, 3.8rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  line-height: 1;
  position: static;
  margin: 0;
}

[data-stage="tv-testimonials"] .reel-speaker {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  padding: 0.6rem 1.2rem;
  transform: rotate(-2.5deg);
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 18px;
  box-shadow: var(--lobby-shadow-md);
  color: var(--lobby-ink);
}

[data-stage="tv-testimonials"] .reel-speaker__photo {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 999px;
  border: 3px solid var(--lobby-ink);
  object-fit: cover;
  background: var(--lobby-paper);
  flex-shrink: 0;
}

[data-stage="tv-testimonials"] .reel-speaker__name {
  font-family: 'Fredoka One', cursive;
  font-size: 1.6rem;
  line-height: 1;
  margin: 0;
  color: var(--lobby-ink);
}

/* Footer row — coral accusation pill */
[data-stage="tv-testimonials"] .reel-footer {
  display: flex;
  justify-content: center;
}

[data-stage="tv-testimonials"] .reel-accusation {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2px var(--lobby-ink);
  padding: 0.55rem 1.4rem;
  font-size: clamp(1.2rem, 1.8vw, 1.7rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transform: rotate(1.8deg);
  border: var(--lobby-border-md);
  border-radius: 999px;
  box-shadow: var(--lobby-shadow-md);
  font-family: 'Fredoka One', cursive;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  line-height: 1;
}

[data-stage="tv-testimonials"] .reel-accusation strong {
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 2px var(--lobby-ink);
  font-weight: inherit;
}

/* Counter — top-right corner sign */
[data-stage="tv-testimonials"] #tv-testimonial-counter {
  position: absolute;
  top: 1.5rem;
  right: 1.5rem;
  font-family: 'Fredoka One', cursive;
  font-size: 1.2rem;
  padding: 0.5rem 1rem;
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 14px;
  box-shadow: var(--lobby-shadow-md);
  transform: rotate(3deg);
  color: var(--lobby-ink);
  letter-spacing: 0.04em;
}

/* ---------- tv-screen-between --------------------------------------- */

[data-stage="tv-between-rounds"] {
  position: relative;
  background: url('/assets/images/brick-tv.webp') center / cover no-repeat var(--lobby-ink);
  min-height: 100vh;
  padding: 3rem 4rem 4rem;
  color: var(--lobby-ink);
}

[data-stage="tv-between-rounds"] .between-header {
  text-align: center;
  margin: 0 0 2rem;
}

[data-stage="tv-between-rounds"] .between-title {
  font-size: clamp(2.8rem, 5.5vw, 4.8rem);
  text-transform: uppercase;
  margin: 0;
  letter-spacing: 0.05em;
  line-height: 1.05;
}

[data-stage="tv-between-rounds"] .between-subtitle {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 1.1rem;
  color: var(--lobby-paper-warm);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.85;
  margin: 0.75rem 0 0;
}

[data-stage="tv-between-rounds"] .between-grid {
  display: grid;
  grid-template-columns: minmax(0, 2.4fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
  max-width: 1400px;
  margin: 0 auto;
}

@media (max-width: 1200px) {
  [data-stage="tv-between-rounds"] .between-grid {
    grid-template-columns: 1fr;
  }
}

[data-stage="tv-between-rounds"] .leaderboard-card {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 28px;
  box-shadow: var(--lobby-shadow-xl);
  padding: 1.75rem 2rem 2rem;
}

[data-stage="tv-between-rounds"] .leaderboard-card__title {
  text-align: center;
  margin: 0 0 1.25rem;
  font-size: clamp(1.7rem, 2.6vw, 2.1rem);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

[data-stage="tv-between-rounds"] .leaderboard-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 1rem;
  padding: 0.7rem 1.2rem;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 16px;
  box-shadow: var(--lobby-shadow-md);
  margin-bottom: 0.75rem;
  color: var(--lobby-ink);
}

[data-stage="tv-between-rounds"] .leaderboard-row:last-child {
  margin-bottom: 0;
}

[data-stage="tv-between-rounds"] .leaderboard-row:nth-child(odd) {
  transform: rotate(-0.4deg);
}

[data-stage="tv-between-rounds"] .leaderboard-row:nth-child(even) {
  transform: rotate(0.4deg);
}

[data-stage="tv-between-rounds"] .leaderboard-row--top {
  background: var(--lobby-mango);
  border-width: 4px;
}

[data-stage="tv-between-rounds"] .leaderboard-row__rank {
  font-size: clamp(1.8rem, 2.4vw, 2.2rem);
  width: 2.75rem;
  text-align: center;
  line-height: 1;
  margin: 0;
}

[data-stage="tv-between-rounds"] .leaderboard-row__avatar {
  width: 4rem;
  height: 4rem;
  border-radius: 999px;
  border: 3px solid var(--lobby-ink);
  background: var(--lobby-paper);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}

[data-stage="tv-between-rounds"] .leaderboard-row__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

[data-stage="tv-between-rounds"] .leaderboard-row__name {
  font-size: clamp(1.4rem, 2vw, 1.75rem);
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-ink);
  line-height: 1;
  margin: 0;
}

[data-stage="tv-between-rounds"] .leaderboard-row__score {
  font-size: clamp(2rem, 2.8vw, 2.6rem);
  padding: 0 0.35rem;
  letter-spacing: 0.02em;
  line-height: 1;
  margin: 0;
}

/* Ready-up side card */
[data-stage="tv-between-rounds"] .ready-card {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 28px;
  box-shadow: var(--lobby-shadow-xl);
  padding: 1.5rem 1.25rem 1.75rem;
  text-align: center;
}

[data-stage="tv-between-rounds"] .ready-card__title {
  margin: 0 0 1rem;
  font-size: clamp(1.4rem, 2vw, 1.7rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

[data-stage="tv-between-rounds"] .ready-card__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
}

[data-stage="tv-between-rounds"] .ready-notch {
  width: 6.75rem;
  padding: 0.55rem 0.3rem 0.7rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 16px;
  box-shadow: var(--lobby-shadow-md);
  transition: transform 0.25s ease, background 0.25s ease;
  color: var(--lobby-ink);
}

[data-stage="tv-between-rounds"] .ready-notch:nth-child(odd) {
  transform: rotate(-1.5deg);
}

[data-stage="tv-between-rounds"] .ready-notch:nth-child(even) {
  transform: rotate(1.5deg);
}

[data-stage="tv-between-rounds"] .ready-notch--ready {
  background: var(--lobby-teal);
  color: var(--lobby-paper-warm);
}

[data-stage="tv-between-rounds"] .ready-notch__avatar {
  width: 3rem;
  height: 3rem;
  border-radius: 999px;
  border: 2.5px solid var(--lobby-ink);
  background: var(--lobby-paper);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}

[data-stage="tv-between-rounds"] .ready-notch__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

[data-stage="tv-between-rounds"] .ready-notch__name {
  font-family: 'Fredoka One', cursive;
  font-size: 0.85rem;
  line-height: 1;
  color: var(--lobby-ink);
  margin: 0;
}

[data-stage="tv-between-rounds"] .ready-notch--ready .ready-notch__name {
  color: var(--lobby-paper-warm);
}

[data-stage="tv-between-rounds"] .ready-notch__status {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--lobby-ink-soft);
  line-height: 1;
  margin: 0;
}

[data-stage="tv-between-rounds"] .ready-notch--ready .ready-notch__status {
  color: var(--lobby-paper-warm);
}

/* Countdown overlay — full-screen scrim with huge paper card. */
[data-stage="tv-between-rounds"] #tv-between-countdown {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--game-overlay-scrim);
  z-index: var(--z-between-countdown);
  padding: 2rem;
}

[data-stage="tv-between-rounds"] #tv-between-countdown.hidden {
  display: none;
}

[data-stage="tv-between-rounds"] #tv-between-countdown > .paper {
  max-width: 36rem;
  padding: 2rem 4rem 3rem;
  text-align: center;
  transform: rotate(-1.2deg);
}

[data-stage="tv-between-rounds"] .countdown-label {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 1.15rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--lobby-ink-soft);
  margin: 0 0 1.25rem;
}

[data-stage="tv-between-rounds"] .countdown-number {
  font-size: clamp(6rem, 14vw, 12rem);
  line-height: 1;
  margin: 0;
}

[data-stage="tv-between-rounds"] .countdown-hint {
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: 0.95rem;
  color: var(--lobby-ink-soft);
  margin: 1.25rem 0 0;
}

[data-stage="tv-between-rounds"] .countdown-hint strong {
  color: var(--lobby-coral);
  font-weight: 800;
}

/* =========================================================================
   DESIGN PASS 10 — iPad (all 7 screens)
   =========================================================================
   The iPad sits on the coffee table as the shared "emergency button" device.
   Every screen here reuses the lobby/phone/TV sketch vocabulary (brick
   backdrop, cream paper, ink-stroke display, chunky 3D buttons) so it feels
   like the same arcade machine. The iconic moment is the huge heartbeat-
   pulsing red button — own primitive (`.ipad-emergency-button`) with an
   amber bulb ring around it.

   No game logic changes — the click handler on `#btn-emergency` at
   `ipad.js:105` continues to fire; this is purely visual.

   Primitives reused (already scoped via the shared `:is(...)` list):
   `.paper`, `.paper-sm`, `.paper-sign`, `.btn-chunky`, `.btn-chunky--amber`,
   `.ink-stroke`, `.ink-stroke-sm`, `.character-tile`, `.stamp-emergency`
   (new ipad-scoped copy), `.timer-paper` (new ipad-scoped copy).
   ========================================================================= */

/* ---- Shared ipad scaffold ----
   Brick backdrop + fill the viewport. Every ipad-* stage inherits these. */
[data-stage^="ipad-"] {
  min-height: 100vh;
  width: 100%;
  background-image: url("/assets/images/brick-tv.webp");
  background-size: cover;
  background-position: center;
  color: var(--lobby-ink);
  font-family: 'Nunito', var(--font-body);
  padding: 2rem 2.5rem 2.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.75rem;
  box-sizing: border-box;
  position: relative;
}

/* Neutralize DaisyUI/Tailwind helpers that bleed through on iPad buttons
   (e.g., the legacy `.btn`/`.btn-lg` on #btn-ipad-join) so the chunky
   CTA variant lands crisp. Scoped so nothing outside ipad stages is
   affected. */
[data-stage^="ipad-"] .btn,
[data-stage^="ipad-"] .btn-lg,
[data-stage^="ipad-"] .btn-primary,
[data-stage^="ipad-"] .btn-ghost {
  background: transparent;
  border: none;
  box-shadow: none;
  min-height: 0;
  height: auto;
}
[data-stage^="ipad-"] .btn-chunky.btn-chunky.btn-chunky:not(.hidden) {
  /* Re-assert chunky styling against any .btn utility. */
  background: var(--lobby-teal);
}
[data-stage^="ipad-"] .btn-chunky.btn-chunky--amber.btn-chunky--amber:not(.hidden) {
  background: var(--lobby-mango);
}

/* ---- IPAD-ENTRY (screen-join) ---- */
[data-stage="ipad-entry"] .wordmark {
  padding: 1.25rem 3rem;
  font-size: clamp(2.25rem, 4.5vw, 3.25rem);
}

[data-stage="ipad-entry"] .ipad-entry-card {
  background: var(--lobby-paper);
  border: var(--lobby-border-lg);
  border-radius: 28px;
  box-shadow: var(--lobby-shadow-xl);
  padding: 2.5rem 3rem 2.75rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  max-width: 32rem;
  width: 100%;
  transform: rotate(-0.8deg);
}

[data-stage="ipad-entry"] .ipad-entry-subtitle {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-size: 0.95rem;
  color: var(--lobby-ink-soft);
  margin: 0;
}

/* iPad-sized room-code ticket — bigger than the phone-entry variant. */
[data-stage="ipad-entry"] #ipad-room-code.input-paper-ticket {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-lg);
  border-radius: 22px;
  padding: 1.1rem 1.25rem;
  font-size: clamp(1.75rem, 4.5vw, 2.5rem);
  letter-spacing: 0.2em;
  color: var(--lobby-ink);
  -webkit-text-stroke: 1px var(--lobby-ink);
  text-align: center;
  box-shadow:
    0 6px 0 0 var(--lobby-ink),
    0 12px 22px rgb(26 22 19 / 0.25);
  width: 100%;
  max-width: 22rem;
  text-transform: uppercase;
  outline: none;
}
[data-stage="ipad-entry"] #ipad-room-code.input-paper-ticket::placeholder {
  color: rgba(26, 22, 19, 0.35);
  letter-spacing: 0.12em;
}
[data-stage="ipad-entry"] #ipad-room-code.input-paper-ticket:focus {
  background: #FFF7E1;
  box-shadow:
    0 6px 0 0 var(--lobby-ink),
    0 12px 22px rgb(26 22 19 / 0.25),
    0 0 0 3px var(--lobby-teal) inset;
}

[data-stage="ipad-entry"] #btn-ipad-join.btn-chunky {
  font-size: clamp(1.5rem, 3vw, 2.2rem);
  padding: 1.1rem 2.5rem;
}

[data-stage="ipad-entry"] #ipad-join-error.paper-sign {
  background: var(--lobby-coral);
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 1.25px var(--lobby-ink);
  letter-spacing: 0.06em;
  transform: rotate(-2deg);
}

/* ---- IPAD-WAITING ---- */
[data-stage="ipad-waiting"] .ipad-waiting-title {
  text-align: center;
  max-width: 72rem;
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  margin: 0;
}

[data-stage="ipad-waiting"] p.ipad-waiting-subtitle {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 0.5px var(--lobby-ink);
  text-shadow: 0 2px 0 var(--lobby-ink);
  margin: 0;
}

[data-stage="ipad-waiting"] .ipad-waiting-room-sign {
  display: inline-flex;
  align-items: baseline;
  gap: 0.75rem;
  font-size: 1.4rem;
  padding: 0.9rem 1.75rem;
}

[data-stage="ipad-waiting"] .ipad-waiting-room-sign strong {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.3em;
  font-size: 2rem;
  color: var(--lobby-ink);
  -webkit-text-stroke: 1.25px var(--lobby-ink);
}

/* The horizontal sofa-strip of mini player tiles. */
[data-stage="ipad-waiting"] .ipad-waiting-sofa {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: center;
  gap: 1rem;
  max-width: 80rem;
  padding: 0.5rem 0.25rem;
}

[data-stage="ipad-waiting"] .paper-tile-sm {
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-md);
  border-radius: 16px;
  box-shadow: var(--lobby-shadow-md);
  padding: 0.6rem 0.7rem 0.7rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  min-width: 6.5rem;
  transition: transform 200ms ease, opacity 200ms ease;
}

[data-stage="ipad-waiting"] .paper-tile-sm:nth-child(odd)  { transform: rotate(-1.5deg); }
[data-stage="ipad-waiting"] .paper-tile-sm:nth-child(even) { transform: rotate( 1.5deg); }

[data-stage="ipad-waiting"] .paper-tile-sm.opacity-40 {
  opacity: 0.45;
}

[data-stage="ipad-waiting"] .paper-tile-sm__avatar {
  width: 4rem;
  height: 4rem;
  border-radius: 999px;
  border: 2.5px solid var(--lobby-ink);
  background: var(--lobby-paper);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}

[data-stage="ipad-waiting"] .paper-tile-sm__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

[data-stage="ipad-waiting"] .paper-tile-sm__name {
  font-family: 'Fredoka One', cursive;
  font-size: 0.95rem;
  color: var(--lobby-ink);
  line-height: 1;
  letter-spacing: 0.02em;
  max-width: 8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- IPAD-EMERGENCY-BUTTON (THE ICONIC MOMENT) ----
   Full viewport, center: a massive circular red button on cream brick
   with an amber bulb ring around the perimeter. */
[data-stage="ipad-emergency-button"] {
  padding: 1.25rem 2rem 2rem;
  gap: 1.25rem;
}

/* Top strip with the timer ticket — echoes phone-round-active. */
[data-stage="ipad-emergency-button"] .ipad-emergency-timer-row {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}

[data-stage="ipad-emergency-button"] .timer-paper {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-lg);
  border-radius: 18px;
  padding: 0.7rem 1.4rem;
  box-shadow: 0 6px 0 0 var(--lobby-ink), 0 12px 20px rgb(0 0 0 / 0.35);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--lobby-ink);
  letter-spacing: 0.08em;
  line-height: 1;
  transform: rotate(-1deg);
}

[data-stage="ipad-emergency-button"] .timer-paper__label {
  font-family: 'Nunito', sans-serif;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.65;
}

[data-stage="ipad-emergency-button"] #ipad-timer {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: clamp(2rem, 5vmin, 2.75rem);
  letter-spacing: 0.08em;
  line-height: 1;
}

/* Amber-bulb ring wrapper. Two thin gradient rings make the "bulbs"
   without per-LED markup — same trick as .wordmark::before/::after. */
[data-stage="ipad-emergency-button"] .ipad-emergency-ring {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  margin: 0.5rem 0;
}

[data-stage="ipad-emergency-button"] .ipad-emergency-ring::before {
  content: "";
  position: absolute;
  inset: -28px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 0,   #FFF4C7 0 6px, #FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 100% 50%,#FFF4C7 0 6px, #FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 50% 100%,#FFF4C7 0 6px, #FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 0 50%,   #FFF4C7 0 6px, #FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 85.4% 14.6%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 14.6% 14.6%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 85.4% 85.4%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 14.6% 85.4%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 67.3% 3.3%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 32.7% 3.3%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 96.7% 32.7%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 96.7% 67.3%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 67.3% 96.7%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 32.7% 96.7%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 3.3% 32.7%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px),
    radial-gradient(circle at 3.3% 67.3%,#FFF4C7 0 6px,#FFD96B 6px 10px, transparent 11px);
  background-repeat: no-repeat;
  filter: drop-shadow(0 2px 0 var(--lobby-ink));
  pointer-events: none;
  animation: ipad-bulbs-shimmer 1.8s var(--ease-in-out) infinite;
}

@keyframes ipad-bulbs-shimmer {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.65; }
}

/* The big red button itself — custom primitive, 2× the lobby's
   .btn-chunky scale, heartbeat-pulsing, radial-gradient face. */
[data-stage="ipad-emergency-button"] .ipad-emergency-button {
  width: min(60vmin, 520px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%,
    #FF8A8A 0%, var(--lobby-coral) 55%, #A83838 100%);
  border: 8px solid var(--lobby-ink);
  box-shadow:
    0 14px 0 0 var(--lobby-ink),
    0 0 60px rgba(232, 107, 107, 0.55),
    inset 0 -10px 0 rgba(0,0,0,0.30),
    inset 0 18px 28px rgba(255, 255, 255, 0.22);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 4px var(--lobby-ink);
  paint-order: stroke fill;
  text-shadow: 0 6px 0 var(--lobby-ink);
  font-size: clamp(3rem, 9vmin, 7rem);
  letter-spacing: 0.06em;
  line-height: 0.9;
  text-align: center;
  cursor: pointer;
  animation: ipad-emergency-heartbeat var(--dur-dramatic) var(--ease-in-out) infinite;
  transition: transform 120ms var(--ease-snap),
              box-shadow 120ms var(--ease-snap);
  user-select: none;
  position: relative;
  z-index: 1;
}

[data-stage="ipad-emergency-button"] .ipad-emergency-button:hover {
  transform: translateY(-3px);
  box-shadow:
    0 17px 0 0 var(--lobby-ink),
    0 0 80px rgba(232, 107, 107, 0.7),
    inset 0 -10px 0 rgba(0,0,0,0.30),
    inset 0 18px 28px rgba(255, 255, 255, 0.22);
}

[data-stage="ipad-emergency-button"] .ipad-emergency-button:active {
  transform: translateY(8px) scale(0.98);
  box-shadow:
    0 6px 0 0 var(--lobby-ink),
    0 0 120px rgba(232, 107, 107, 0.8),
    inset 0 -8px 0 rgba(0,0,0,0.30);
}

@keyframes ipad-emergency-heartbeat {
  0%, 100% { transform: scale(1); }
  30%      { transform: scale(1.05); }
  40%      { transform: scale(1.02); }
  55%      { transform: scale(1.04); }
  70%      { transform: scale(1.00); }
}

/* Instructions below the button — rotated paper sign. */
[data-stage="ipad-emergency-button"] .ipad-emergency-hint.paper-sign {
  font-size: 1.25rem;
  letter-spacing: 0.04em;
  padding: 0.8rem 1.5rem;
}

/* ---- IPAD-SELECT-CALLER / IPAD-SELECT-TARGET ---- */
[data-stage="ipad-select-caller"],
[data-stage="ipad-select-target"] {
  padding: 2rem 3rem 2.5rem;
  gap: 1.5rem;
}

[data-stage="ipad-select-caller"] .ipad-select-title,
[data-stage="ipad-select-target"] .ipad-select-title {
  text-align: center;
  font-size: clamp(2.2rem, 4.5vw, 3.25rem);
  margin: 0;
}

[data-stage="ipad-select-caller"] p.ipad-select-subtitle,
[data-stage="ipad-select-target"] p.ipad-select-subtitle {
  font-family: 'Nunito', sans-serif;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-size: 0.95rem;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 0.5px var(--lobby-ink);
  text-shadow: 0 2px 0 var(--lobby-ink);
  margin: 0;
}

[data-stage="ipad-select-caller"] #caller-grid,
[data-stage="ipad-select-target"] #target-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1.25rem;
  width: 100%;
  max-width: 60rem;
  margin: 0;
}

/* Each caller/target card — paper-sm tile + big avatar + ink-stroke name.
   ipad.js creates a plain `<div>` wrapper inside #caller-grid / #target-grid
   and fills it via renderAvatarCard(); the `> div` descendant selector
   styles that wrapper without needing to change the JS className. */
[data-stage="ipad-select-caller"] #caller-grid > div,
[data-stage="ipad-select-target"] #target-grid > div {
  background: var(--lobby-paper-warm);
  border: var(--lobby-border-lg);
  border-radius: 20px;
  box-shadow: var(--lobby-shadow-lg);
  padding: 1rem 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  cursor: pointer;
  transition: transform 150ms var(--ease-snap),
              box-shadow 150ms var(--ease-snap);
  user-select: none;
}

[data-stage="ipad-select-caller"] #caller-grid > div:nth-child(odd)  { transform: rotate(-1.25deg); }
[data-stage="ipad-select-caller"] #caller-grid > div:nth-child(even) { transform: rotate( 1.25deg); }
[data-stage="ipad-select-target"] #target-grid > div:nth-child(odd)  { transform: rotate(-1.25deg); }
[data-stage="ipad-select-target"] #target-grid > div:nth-child(even) { transform: rotate( 1.25deg); }

[data-stage="ipad-select-caller"] #caller-grid > div:hover,
[data-stage="ipad-select-target"] #target-grid > div:hover {
  transform: translateY(-4px) rotate(0deg);
  box-shadow:
    0 10px 0 0 var(--lobby-ink),
    0 18px 28px rgb(26 22 19 / 0.28);
}

[data-stage="ipad-select-caller"] #caller-grid > div:active,
[data-stage="ipad-select-target"] #target-grid > div:active {
  transform: translateY(4px) rotate(0deg);
  box-shadow: 0 2px 0 0 var(--lobby-ink);
}

[data-stage="ipad-select-caller"] .ipad-char-tile__avatar,
[data-stage="ipad-select-target"] .ipad-char-tile__avatar {
  width: 9rem;
  height: 9rem;
  border-radius: 999px;
  border: 3px solid var(--lobby-ink);
  background: var(--lobby-paper);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

[data-stage="ipad-select-caller"] .ipad-char-tile__avatar > *,
[data-stage="ipad-select-target"] .ipad-char-tile__avatar > * {
  max-width: 100%;
  max-height: 100%;
}

/* Target variant — coral warning ring around the avatar. */
[data-stage="ipad-select-target"] .ipad-char-tile__avatar {
  border-color: var(--lobby-coral);
  box-shadow:
    inset 0 0 0 4px var(--lobby-paper-warm),
    inset 0 0 0 8px var(--lobby-coral),
    0 4px 0 0 var(--lobby-ink);
}

[data-stage="ipad-select-caller"] .ipad-char-tile__name,
[data-stage="ipad-select-target"] .ipad-char-tile__name {
  font-family: 'Fredoka One', cursive;
  font-size: 1.35rem;
  color: var(--lobby-ink);
  -webkit-text-stroke: 0.75px var(--lobby-ink);
  letter-spacing: 0.02em;
  text-align: center;
  line-height: 1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin: 0;
}

/* BACK CTA — anchor to bottom-right on iPad. */
[data-stage="ipad-select-caller"] .ipad-cancel-row,
[data-stage="ipad-select-target"] .ipad-cancel-row {
  position: absolute;
  right: 2.5rem;
  bottom: 2rem;
}

/* ---- IPAD-BANNED ---- */
[data-stage="ipad-banned"] {
  background-color: #5A1F1F;
  background-image:
    linear-gradient(rgba(90, 31, 31, 0.75), rgba(40, 13, 13, 0.9)),
    url("/assets/images/brick-tv.webp");
  padding: 3rem;
  gap: 1.5rem;
}

[data-stage="ipad-banned"] .ipad-banned-card.paper {
  max-width: 44rem;
  padding: 2.25rem 3rem 2.5rem;
  text-align: center;
  transform: rotate(-1deg);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  border-color: var(--lobby-ink);
  background: var(--lobby-paper-warm);
}

[data-stage="ipad-banned"] .ipad-banned-card .ink-stroke {
  font-size: clamp(2.1rem, 5vw, 3rem);
  color: var(--lobby-coral);
  -webkit-text-stroke: 3px var(--lobby-ink);
  margin: 0;
}

[data-stage="ipad-banned"] .ipad-banned-card p {
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-ink);
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  letter-spacing: 0.02em;
  line-height: 1.2;
  margin: 0;
}

[data-stage="ipad-banned"] .ipad-banned-stamp.stamp-emergency {
  position: static;
  transform: rotate(-6deg);
  background: var(--lobby-ink);
  color: var(--lobby-coral);
  -webkit-text-stroke: 0;
  border: 3px solid var(--lobby-paper-warm);
  border-radius: 10px;
  padding: 0.35rem 1rem;
  font-family: 'Fredoka One', cursive;
  font-size: 1.15rem;
  letter-spacing: 0.2em;
  box-shadow: 0 4px 0 0 rgba(26, 22, 19, 0.5);
}

[data-stage="ipad-banned"] .ipad-banned-timer.timer-paper {
  display: inline-flex;
  align-items: baseline;
  gap: 0.75rem;
  background: var(--lobby-paper);
  border: var(--lobby-border-md);
  border-radius: 14px;
  padding: 0.6rem 1.3rem;
  box-shadow: var(--lobby-shadow-md);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--lobby-ink);
  letter-spacing: 0.08em;
}

[data-stage="ipad-banned"] .ipad-banned-timer__label {
  font-family: 'Nunito', sans-serif;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.6;
}

[data-stage="ipad-banned"] #ipad-timer-banned {
  font-size: 1.6rem;
}

/* ---- IPAD-EMERGENCY-CALLED ---- */
[data-stage="ipad-emergency-called"] {
  padding: 3rem;
  gap: 1.25rem;
}

[data-stage="ipad-emergency-called"] .ipad-called-card.paper {
  position: relative;
  background: var(--lobby-mango);
  border-color: var(--lobby-ink);
  border-radius: 32px;
  padding: 2.5rem 3.5rem 2.75rem;
  max-width: 48rem;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.25rem;
  transform: rotate(-1.2deg);
  animation: ipad-called-bounce 2400ms var(--ease-in-out) infinite;
}

@keyframes ipad-called-bounce {
  0%, 100% { transform: rotate(-1.2deg) translateY(0); }
  50%      { transform: rotate(-0.6deg) translateY(-6px); }
}

[data-stage="ipad-emergency-called"] .ipad-called-card .ink-stroke {
  font-size: clamp(2.4rem, 6vw, 4rem);
  color: var(--lobby-coral);
  -webkit-text-stroke: 3px var(--lobby-ink);
  margin: 0;
}

[data-stage="ipad-emergency-called"] .ipad-called-card .stamp-emergency {
  position: absolute;
  top: -1.25rem;
  right: -1.5rem;
  background: var(--lobby-ink);
  color: var(--lobby-coral);
  -webkit-text-stroke: 0;
  border: 3px solid var(--lobby-paper-warm);
  border-radius: 12px;
  padding: 0.5rem 1.3rem;
  transform: rotate(-8deg);
  font-family: 'Fredoka One', cursive;
  font-size: 1.4rem;
  letter-spacing: 0.14em;
  box-shadow: 0 4px 0 0 rgba(26, 22, 19, 0.6);
  z-index: 2;
}

[data-stage="ipad-emergency-called"] .ipad-called-card p {
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-ink);
  font-size: clamp(1.25rem, 2.5vw, 1.75rem);
  letter-spacing: 0.03em;
  margin: 0;
}

[data-stage="ipad-emergency-called"] p.ipad-called-directive {
  font-family: 'Fredoka One', cursive;
  color: var(--lobby-paper-warm);
  -webkit-text-stroke: 1.5px var(--lobby-ink);
  text-shadow: 0 3px 0 var(--lobby-ink);
  font-size: clamp(1.4rem, 3vw, 2rem);
  letter-spacing: 0.06em;
  margin: 0;
}

/* -------------------------------------------------------------------------
   PASS 11 — UTILITY CLASSES (for ex-inline styles)
   -------------------------------------------------------------------------
   Added in Pass 11 so HTML templates don't carry hardcoded colors.
   Each class routes through a token so a single edit in this file
   repaints every user of the class.
   ------------------------------------------------------------------------- */
.bg-overlay-solid { background: var(--game-overlay-solid); }

/* -------------------------------------------------------------------------
   END OF TOKENS
   ========================================================================= */
