:root {
  /* A dark auditorium: warm near-black, marquee gold, curtain red.
     These are the movie defaults; a variant's theme block in variants.json
     (emitted by variant.php::tl_theme_css) overrides only what differs. */
  --bg: #0d0a0c;
  --surface: #1a1518;
  --surface-2: #241c20;
  --ink: #f7efe3;
  --paper: #f7efe3;
  --muted: #a3928c;
  --line: rgba(247, 239, 227, .14);
  --coral: #e0402e;
  --aqua: #3fb2a6;
  --blue: #5a78ec;
  --yellow: #f0b429;
  --gold-soft: #d9a441;
  --dark: #0d0a0c;
  --felt-deep: #0a0709;
  --green: #35c98a;
  --shadow: 0 30px 80px rgba(0, 0, 0, .55);

  /* The room's plate, the grain over it and the light big type catches.
     The plate is the cosy auditorium from the landing page's hero art —
     curtains with sconces glowing on them, seat backs along the bottom, a
     dark empty middle for the interface — so walking from the landing page
     into the game is walking further into the same cinema. */
  --backdrop: url("/assets/backdrops/auditorium-cosy.webp?v=5");
  /* The seat-back band of the plate, hung under the filmstrip. A variant with
     a different room overrides this alongside --backdrop. */
  --seats-art: url("/assets/backdrops/auditorium-seats.webp?v=5");
  --grain: .05;
  --glow: rgba(240, 180, 41, .18);
  /* How much of the room survives once a film is playing. The cosy plate is
     built with a near-black middle, so the movies room can stay fully lit;
     a variant with a busier plate turns its house lights down from its
     theme block instead of losing the plate. */
  --house-dim: 1;

  /* The set dressing. Every sprocket hole, frame chip and light spill reads
     from these, so a variant swaps the whole film look from its theme block
     without any new CSS. Defaults are the movie chrome. */
  --sprocket: rgba(247, 239, 227, .3);
  --perf-art: repeating-linear-gradient(90deg, var(--sprocket) 0 16px, transparent 16px 36px) center;
  --gap-fill: rgba(240, 180, 41, .07);
  --screen-ring: rgba(240, 180, 41, .16);
  --screen-halo: rgba(240, 180, 41, .1);
  --frame-line: rgba(240, 180, 41, .22);
  --reel-bg: #0e0a0b;

  /* The primary button is a lit shape, so its shades are the theme's own
     rather than tints of one hard-coded red. --coral is the middle stop. */
  --btn-top: #ea5340;
  --btn-base: #b92e1f;
  --btn-top-lit: #f0604c;
  --btn-base-lit: #d63a29;
  --btn-glow: rgba(224, 64, 46, .35);

  /* A light zoom to lose the iframe's own edges. The heavy lifting against
     YouTube's title overlay is done by the masks below, because zooming far
     enough to crop the title would throw away too much picture. */
  --overscan: 1.06;
  /* YouTube's title sits in a band across the top of the player and its share
     row across the bottom. These cover both, whatever state the player is in. */
  --mask-top: 18%;
  --mask-bottom: 16%;
}

* { box-sizing: border-box; }
html, body { min-height: 100%; }
/* The full-bleed reel is 100vw, which on platforms with a permanent scrollbar
   is a hair wider than the writable area; clip rather than grow a sideways
   scroll the page cannot use. */
/* clip stops the full-bleed reel from growing a horizontal scrollbar.
   overflow-y must stay auto: if only x is set to clip, y becomes clip too
   and the filmstrip gets cut off on a short window with no way to scroll. */
/* clip stops the full-bleed reel from growing a horizontal scrollbar. The y
   axis must stay visible: setting it to auto or clip turns the page into its
   own scroll container, which strands the footer and kills scrolling. */
body { overflow-x: clip; overflow-y: visible; }
body {
  margin: 0;
  position: relative;
  color: var(--ink);
  /* Only ever seen if the backdrop plate has not arrived yet, so it is the
     plate's darkest colour rather than anything of its own. */
  background: var(--bg);
  font-family: "DM Sans", ui-sans-serif, system-ui, sans-serif;
  font-size: 17px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* The room.
 *
 * This was drawn in CSS once — curtains from repeating gradients, the projector
 * throw from a conic gradient — and it never stopped looking like gradients.
 * Velvet has weave and depth and light falling unevenly across it, which is a
 * photograph, not four colour stops. So the room is now one rendered plate
 * (tools/generate_game_backdrop.py) and the CSS only has to place it.
 *
 * Fixed rather than scrolling, so the page moves through the room instead of
 * dragging it along. The plate is composed with a dark, empty middle for the
 * interface to sit on, and `cover` keeps that middle centred at any window
 * shape — on a narrow phone the curtains simply crop away, which is what the
 * old breakpoint was doing by hand anyway.
 */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* Anchored to the bottom, not the middle: `cover` on a wide, short window
     crops the plate top and bottom, and the seat backs along its bottom edge
     are the thing that makes the room feel occupied. Losing a little of the
     curtain tops costs nothing. */
  background: var(--backdrop) center bottom / cover no-repeat;
}

/* Projected film always has grain in the light, and the light never sits still. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  opacity: var(--grain);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: flicker 4.5s steps(3, end) infinite;
}
@keyframes flicker {
  0%, 100% { opacity: calc(var(--grain) * .9); }
  33% { opacity: calc(var(--grain) * 1.4); }
  66% { opacity: calc(var(--grain) * .7); }
}
@media (prefers-reduced-motion: reduce) {
  body::after { display: none; }
}

::selection { background: var(--yellow); color: #1b1206; }
:focus-visible { outline: 2px solid var(--yellow); outline-offset: 2px; }
button, input { font: inherit; }
button { cursor: pointer; }
img { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, p { margin-top: 0; }
h1, h2 { font-family: "Space Grotesk", sans-serif; letter-spacing: -.06em; }
/* Big type catches the light coming off the screen. */
h1 { text-shadow: 0 0 60px var(--glow); }

.shell { width: min(calc(100% - 36px), 1120px); margin-inline: auto; }

.screen { display: none; padding-bottom: 60px; }
.screen.is-active { display: block; }
/* The play screen ends in the seat row, which is meant to meet the footer. */
.screen.game { padding-bottom: 0; }

/* Player chip left, the turn question in the middle, end-game right —
   like a title card above the screen. */
.top {
  padding: 16px 0 8px;
  display: grid;
  grid-template-columns: minmax(7rem, 1fr) minmax(0, 3fr) minmax(7rem, 1fr);
  align-items: start;
  gap: 16px;
}
.top-right {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
}
.top .placer {
  width: auto;
  min-width: 0;
  max-width: 44em;
  margin: 0;
  justify-self: center;
  text-align: center;
}
@media (max-width: 720px) {
  /* Who is up and the way out share the first row; the question takes the
     second, so it never pushes End game off its own line. */
  .top {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "who  quit"
      "ask  ask";
    align-items: center;
  }
  .top .turn { grid-area: who; }
  .top .top-right { grid-area: quit; }
  .top .placer { grid-area: ask; justify-self: stretch; }
}

/* The logo lives in assets/game-chrome.css now, so it is the homepage's mark
   rather than a smaller redrawing of it. */

.pill {
  padding: 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(247,239,227,.06);
  color: var(--muted);
  font-size: 13px;
  font-weight: 700;
}
.kicker {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 12px;
  color: var(--gold-soft);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.kicker::before { content: ""; width: 22px; height: 3px; border-radius: 10px; background: var(--yellow); box-shadow: 0 0 12px rgba(240,180,41,.7); }

.button {
  min-height: 52px;
  padding: 0 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 0;
  border-radius: 999px;
  font-size: 16px;
  font-weight: 800;
  text-decoration: none;
}
.button:disabled { opacity: .4; cursor: default; }
.button-primary {
  color: #fff;
  background: linear-gradient(180deg, var(--btn-top) 0%, var(--coral) 55%, var(--btn-base) 100%);
  box-shadow: 0 10px 30px var(--btn-glow);
}
.button-primary:hover:not(:disabled) { background: linear-gradient(180deg, var(--btn-top-lit) 0%, var(--btn-base-lit) 100%); }
.button-dark { color: #1b1206; background: var(--paper); }
.button-ghost { border: 1px solid var(--line); background: rgba(247,239,227,.08); color: var(--paper); }
.button-wide { width: 100%; }
.link-button {
  border: 0;
  background: none;
  padding: 0;
  color: var(--muted);
  font-size: 15px;
  font-weight: 700;
  text-decoration: underline;
}

/* ------------------------------------------------------------------ setup */
/* One column down the middle of the room, under the beam.
 *
 * This screen used to run the full 1120px shell with the settings spread across
 * it in three columns, which left the right-hand third of a laptop screen empty
 * and put the curtains behind the headline for want of anywhere else to go.
 * Narrowing it to a single centred column fixes both at once: the composition
 * has a middle to sit in, and the walls get their space back. */
.setup { padding-top: 52px; text-align: center; }
.setup .shell { width: min(calc(100% - 36px), 760px); }
.setup h1 { margin-bottom: 16px; font-size: clamp(38px, 6vw, 62px); line-height: .96; }
.setup .kicker { justify-content: center; }
.lede { max-width: 52ch; margin-inline: auto; color: var(--muted); font-size: 18px; }

/* Label, control, hint — stacked, each one centred under the last. */
.setup-grid {
  margin: 38px 0 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
}
.setup-grid .field { width: 100%; }
.field label { display: block; margin-bottom: 10px; font-size: 14px; font-weight: 800; }
.hint { margin: 8px auto 0; max-width: 46ch; color: var(--muted); font-size: 14px; }

.segmented {
  display: inline-flex;
  flex-wrap: wrap;
  padding: 5px;
  gap: 4px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
}
.segmented button {
  min-width: 56px;
  min-height: 42px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: none;
  font-size: 15px;
  font-weight: 800;
  color: var(--muted);
}
.segmented button.on { background: var(--yellow); color: #1b1206; }

.name-fields {
  margin-top: 24px;
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.name-fields input {
  width: 100%;
  min-height: 54px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
  color: var(--paper);
  font-size: 17px;
}
.setup-actions { margin-top: 34px; display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; }
.setup-actions .button { min-width: 210px; }
.note { margin: 22px auto 0; max-width: 48ch; color: var(--muted); font-size: 14px; }

/* Confirms a choice already made elsewhere rather than asking for it again. */
.mode-chosen {
  margin: 0 0 26px;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 10px;
  color: var(--muted);
  font-size: 15px;
}
.mode-chosen a { color: var(--yellow); text-decoration: underline; text-underline-offset: 3px; }

.host-identity {
  margin: 0;
  min-height: 54px;
  padding: 0 16px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
}
.host-identity b { font-size: 17px; }
.host-identity a { margin-left: auto; color: var(--muted); font-size: 13px; text-decoration: underline; text-underline-offset: 3px; }

/* ------------------------------------------------------------------- game */
/* The room stays lit while a film plays: the sconces, the curtain folds and
   the seat backs are the cosiness of the thing, and the plate's middle is
   near-black so the interface loses nothing to them. Variants with brighter
   plates set --house-dim in their theme block. */
body.playing { background: var(--felt-deep); }
body.playing::before { opacity: var(--house-dim); }
body.playing .pill { background: rgba(247,239,227,.07); border-color: rgba(247,239,227,.14); }

.game-shell {
  min-height: calc(100dvh - var(--chrome-height));
  display: flex;
  flex-direction: column;
}

.turn { display: flex; align-items: center; gap: 12px; }
.turn strong { display: block; font-size: 19px; font-family: "Space Grotesk", sans-serif; letter-spacing: -.03em; }
.turn small { color: rgba(247,239,227,.55); font-weight: 700; }
.turn-dot { width: 16px; height: 16px; border-radius: 50%; background: var(--coral); box-shadow: 0 0 16px currentColor; }

/* One column, like the room in the hero art: the screen hangs big and centred
   between the curtains, and the film strip runs below. */
/* Deliberately not flex: 1. Stretching the stage pushed the filmstrip onto
   the bottom edge of the window, right over the row of seat backs. Sitting at
   its natural height leaves that strip of room on show under the film. */
/* Fills the shell so the seat row at its foot can reach the bottom of the
   window; anything taller than the shell simply overflows and the page
   scrolls, which is why nothing here is allowed to shrink. */
.stage {
  --stage-gap: 14px;
  flex: 1;
  min-height: 0;
  padding: 6px 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--stage-gap);
}

/* The column can stay wide; only the picture shrinks on a short window, so
   the marquee and the replay row line up with it, so the whole block reads as
   one screen rather than a small picture in a wide column. On a short window
   it gives up some width to keep the filmstrip near the fold, but never so
   much that the picture stops being the point. */
.screener {
  width: min(100%, 880px, max(520px, calc((100dvh - 36rem) * 16 / 9)));
  margin-inline: auto;
  flex: 0 1 auto;
}
/* Screen, then the title-bet marquee, then the film strip. Challenge
   buttons (action-row) sit under the strip when a table needs them. */
.stage .screener { order: 1; }
.stage > .marquee { order: 2; }
.stage .reel-wrap { order: 3; }
.stage .action-row { order: 4; }
.stage .table-players { order: 5; }
.stage .house-seats { order: 6; }

/* The row you are sitting in, hung under the film where the hero art has it.
   It is its own strip rather than part of the backdrop plate because `cover`
   crops the plate's own bottom edge away on a wide window and the filmstrip
   covers whatever survives. Purely decorative, hidden from the reader.

   It grows into whatever room is left at the foot of the shell, so the room
   always reaches the footer instead of stopping in a band of black: the strip
   carries a long dark tail below the seats for exactly that, sized `100% auto`
   so the seats stay the same size however tall the element ends up. */
.house-seats {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  flex: 1 0 auto;
  min-height: clamp(44px, 7vh, 84px);
  /* Anchored top: the plush curve of the seat tops is the point of it. */
  background: var(--seats-art) center top / 100% auto no-repeat;
  /* Butted straight against the celluloid, the way the hero art has it. */
  margin-top: calc(-1 * var(--stage-gap));
}

/* The optional side bet, worn like a cinema marquee strip: always there,
   never in the way. Typing is optional; tapping a gap is the only action. */
.marquee {
  width: min(100%, 880px, max(520px, calc((100dvh - 36rem) * 16 / 9)));
  margin-inline: auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 14px;
  border: 1px solid rgba(247, 239, 227, .12);
  background: rgba(11, 7, 9, .72);
}
.marquee[hidden] { display: none; }
.screener .marquee { margin-top: 12px; }
.marquee label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .02em;
  white-space: nowrap;
}
.marquee label span { color: var(--yellow); }
.marquee input {
  flex: 1;
  min-width: 0;
  min-height: 42px;
  padding: 0 12px;
  border-radius: 10px;
  border: 1px solid rgba(247, 239, 227, .16);
  background: rgba(247, 239, 227, .05);
  color: var(--paper);
  font: inherit;
  font-size: 15px;
}
.marquee input::placeholder { color: rgba(247, 239, 227, .35); }
.marquee input:focus-visible { outline: 2px solid var(--yellow); outline-offset: 2px; }
.marquee-hint {
  color: rgba(247, 239, 227, .4);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .04em;
}
@media (max-width: 560px) {
  .marquee { flex-wrap: wrap; }
  .marquee-hint { display: none; }
}

/* --------------------------------------------------------------- screener */
/* The screen in its frame, with a little spill of light around the edges. */
.screener-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: 20px;
  background: #000;
  box-shadow:
    0 0 0 1px var(--screen-ring),
    0 0 70px var(--screen-halo),
    0 34px 80px rgba(0,0,0,.65);
}
.yt-crop {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
/* Scaled up and centred, so the strips where YouTube would place a title or
   controls sit outside the visible frame. */
.yt-crop iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100%;
  height: 100%;
  border: 0;
  transform: translate(-50%, -50%) scale(var(--overscan));
  transform-origin: center;
  pointer-events: none;
}
.screener-mask { position: absolute; left: 0; right: 0; z-index: 2; background: #000; }
.screener-mask.top { top: 0; height: var(--mask-top); }
.screener-mask.bottom { bottom: 0; height: var(--mask-bottom); }
.screener-shield { position: absolute; inset: 0; z-index: 3; background: transparent; }
.screener-veil {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 14px;
  /* Fully opaque on purpose. A paused YouTube frame draws the video title and
     share buttons on top of the picture, so nothing may show through. */
  background: #0b0709;
  color: #fff;
  text-align: center;
  transition: opacity .25s ease;
}
.screener-veil[hidden] { display: none; }
.screener-veil p { margin: 0; font-weight: 800; letter-spacing: .04em; }
.play-fab {
  width: 84px; height: 84px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--coral);
  color: #fff;
  font-size: 30px;
  box-shadow: 0 12px 44px rgba(224,64,46,.5);
}
.screener-bar { margin-top: 14px; display: flex; align-items: center; gap: 14px; }
.screener-bar .button { min-height: 46px; font-size: 15px; }
.clip-progress {
  flex: 1;
  height: 6px;
  border-radius: 999px;
  background: rgba(247,239,227,.14);
  overflow: hidden;
}
.clip-progress span { display: block; width: 0; height: 100%; background: var(--yellow); }

/* --------------------------------------------------------------- timeline */
.placer-title {
  margin: 0 0 4px;
  font-size: clamp(20px, 2.4vw, 28px);
  line-height: 1.15;
}
.placer-sub {
  margin: 0;
  color: rgba(247, 239, 227, .65);
  font-weight: 600;
  font-size: clamp(14px, 1.5vw, 16px);
  line-height: 1.4;
}
.placer.is-idle { opacity: .35; pointer-events: none; }

/* The reel runs the full width of the window, not the width of the shell:
   film is a strip, and a strip with rounded corners and margins is a widget.
   Edge to edge it reads as the projector's film running through the room,
   which is the drawing on the landing page made real. The margin trick pulls
   the element out of its centred column to the viewport edges. */
.reel-wrap {
  grid-column: 1 / -1;
  margin-top: 4px;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  overflow: hidden;
  border-block: 1px solid rgba(247, 239, 227, .1);
  /* Celluloid: a dark strip with a faint sheen down the middle. */
  background:
    linear-gradient(180deg, rgba(247,239,227,.04) 0%, transparent 22%, transparent 78%, rgba(0,0,0,.35) 100%),
    var(--reel-bg);
  box-shadow: 0 18px 50px rgba(0, 0, 0, .45);
}
/* The strip's edge dressing: sprocket holes for film, whatever a variant's
   --perf-art says for anything else. */
.reel-perf {
  height: 22px;
  background: var(--perf-art);
}

.reel {
  display: flex;
  align-items: stretch;
  padding: 18px 24px;
  justify-content: center;
  justify-content: safe center;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(247,239,227,.28) transparent;
}
.reel::-webkit-scrollbar { height: 8px; }
.reel::-webkit-scrollbar-thumb { border-radius: 999px; background: rgba(247,239,227,.22); }

.reel-card {
  flex: 0 0 176px;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid rgba(247,239,227,.14);
  background: rgba(247,239,227,.07);
}
.reel-card.is-new {
  border-color: var(--green);
  box-shadow: 0 0 0 2px rgba(32,203,134,.35);
}
.reel-art { position: relative; aspect-ratio: 16 / 9; background: #000; }
.reel-star {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--yellow);
  color: #1b1206;
  font-size: 13px;
  line-height: 1;
}
.reel-art img { width: 100%; height: 100%; object-fit: cover; }
.reel-year {
  margin: 9px 12px 0;
  font-family: "Space Grotesk", sans-serif;
  font-size: 23px;
  letter-spacing: -.04em;
  color: var(--yellow);
}
.reel-title { margin: 2px 12px 12px; font-size: 15.5px; font-weight: 700; line-height: 1.3; }

.reel-slot {
  /* Wide enough for "Before 1994" to sit on two comfortable lines at the
     label size below; narrower and the year wraps away from its word. */
  flex: 0 0 82px;
  margin: 0 7px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 8px 4px;
  border: 1px dashed rgba(247,239,227,.3);
  border-radius: 12px;
  background: rgba(247,239,227,.04);
  color: rgba(247,239,227,.7);
}
.reel-slot:disabled { opacity: .5; pointer-events: none; }
.reel-slot:disabled.is-picked { opacity: 1; }
.reel-slot:hover, .reel-slot:focus-visible {
  border-style: solid;
  border-color: var(--yellow);
  background: var(--gap-fill);
  color: #fff;
}
.reel-slot.is-picked {
  border-style: solid;
  border-color: var(--yellow);
  background: var(--yellow);
  color: #1b1206;
  box-shadow: 0 0 24px rgba(240,180,41,.4);
}
.reel-slot-plus { font-size: 22px; font-weight: 800; line-height: 1; }
.reel-slot-label { font-size: 14px; font-weight: 800; text-align: center; line-height: 1.3; }

/* ----------------------------------------------------------------- reveal */
.reveal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(5,3,4,.84);
  backdrop-filter: blur(6px);
}
.reveal[hidden] { display: none; }
[hidden] { display: none !important; }
.reveal-card {
  position: relative;
  width: min(100%, 420px);
  padding: 26px 34px;
  border-radius: 20px;
  border: 1px solid var(--frame-line);
  background: linear-gradient(180deg, var(--surface-2) 0%, var(--surface) 60%);
  color: var(--paper);
  text-align: center;
  box-shadow: var(--shadow);
}
/* One frame lifted out of the strip: sprockets down both edges. */
.reveal-card::before, .reveal-card::after {
  content: "";
  position: absolute;
  top: 14px;
  bottom: 14px;
  width: 7px;
  border-radius: 4px;
  background-image: repeating-linear-gradient(180deg, var(--sprocket) 0 11px, transparent 11px 24px);
}
.reveal-card::before { left: 11px; }
.reveal-card::after { right: 11px; }
.reveal-verdict {
  display: inline-block;
  margin-bottom: 16px;
  padding: 7px 16px;
  border-radius: 999px;
  background: var(--green);
  color: #06231a;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: .1em;
  text-transform: uppercase;
  box-shadow: 0 0 26px rgba(53,201,138,.3);
}
.reveal-verdict.is-wrong { background: var(--coral); color: #fff; box-shadow: 0 0 26px rgba(224,64,46,.35); }
.reveal-art { width: 100%; margin-bottom: 18px; border-radius: 14px; }
.reveal-year {
  margin: 0;
  font-family: "Space Grotesk", sans-serif;
  font-size: 54px;
  line-height: 1;
  color: var(--yellow);
  text-shadow: 0 0 34px rgba(240,180,41,.35);
}
.reveal-name { margin: 6px 0 10px; font-size: 27px; }
.reveal-line { margin-bottom: 14px; color: var(--muted); }
.reveal-bonus {
  margin: 0 0 22px;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(240,180,41,.18);
  color: var(--yellow);
  font-size: 14px;
  font-weight: 700;
}
.reveal-bonus.is-miss { background: rgba(247,239,227,.06); color: var(--muted); font-weight: 600; }
.reveal-verdict.is-neutral { background: var(--paper); color: #1b1206; }
.reveal-steal {
  margin: -8px 0 22px;
  padding: 10px 14px;
  border-radius: 12px;
  background: rgba(247,239,227,.06);
  color: var(--muted);
  font-size: 14px;
  font-weight: 700;
}
.reveal-steal.is-win { background: rgba(53,201,138,.2); color: #8ee9c0; }

/* Challenge prompt */
.challenge-list { display: grid; gap: 10px; margin-bottom: 18px; }
.challenge-pick {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface-2);
  color: var(--paper);
  font: inherit;
  text-align: left;
}
.challenge-pick:hover, .challenge-pick:focus-visible {
  border-color: var(--yellow);
  box-shadow: 0 0 0 2px rgba(240,180,41,.2);
}
.challenge-pick b { flex: 1; font-size: 17px; }
.challenge-pick em { font-style: normal; font-weight: 800; color: var(--muted); }
.challenge-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--coral); }

/* ----------------------------------------------------------------- finish */
.finish h1 { font-size: clamp(40px, 7vw, 68px); margin-bottom: 24px; }
.finish-board { display: grid; gap: 12px; margin-bottom: 8px; }
.finish-row {
  padding: 18px 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--surface);
}
.finish-row.is-winner {
  border-color: var(--yellow);
  background: linear-gradient(180deg, rgba(240,180,41,.14), var(--surface));
  box-shadow: 0 0 0 1px rgba(240,180,41,.3), 0 0 40px rgba(240,180,41,.15);
}
.finish-row b { font-size: 19px; }
.finish-row span { color: var(--muted); font-weight: 700; }

/* The signup offer on the finish screen. Given the marquee treatment because
   this is the one moment a guest has a concrete reason to want an account —
   they are looking at a result they would rather keep. */
.finish-signup {
  margin: 22px 0 6px;
  padding: 26px 24px;
  border-radius: 20px;
  border: 1px solid rgba(240,180,41,.34);
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(240,180,41,.16), transparent 62%),
    var(--surface);
  box-shadow: 0 0 44px rgba(240,180,41,.12);
  text-align: center;
}
.finish-signup h2 {
  margin: 0 0 8px;
  font-size: clamp(21px, 3.4vw, 27px);
  letter-spacing: -.01em;
}
.finish-signup p {
  margin: 0 auto 18px;
  max-width: 46ch;
  color: var(--muted);
}
.finish-signup .setup-actions { justify-content: center; }

/* ----------------------------------------------------------------- tables */
.form-error {
  padding: 12px 16px;
  border-radius: 14px;
  border: 1px solid rgba(224,64,46,.4);
  background: rgba(224,64,46,.14);
  color: #ff9b8b;
  font-weight: 700;
}
.join-form { max-width: 420px; margin-inline: auto; }
.text-input {
  width: 100%;
  min-height: 54px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
  color: var(--paper);
  font: inherit;
  font-size: 17px;
}
.open-tables-title { margin: 40px 0 6px; font-size: 24px; }
.open-table-row { max-width: 560px; margin-inline: auto; text-align: left; }
.open-table-row b { flex: none; }
.open-table-row em { flex: 1; }
.table-join-btn { text-decoration: none; padding: 8px 16px; min-height: 0; }
.join-form .field { margin-bottom: 16px; }
.join-form label { display: block; margin-bottom: 8px; font-weight: 800; font-size: 14px; }
.join-form input {
  width: 100%;
  min-height: 54px;
  padding: 0 16px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--surface);
  color: var(--paper);
  font: inherit;
  font-size: 17px;
}
.text-input::placeholder, .join-form input::placeholder { color: rgba(247,239,227,.35); }
.text-input:focus-visible, .join-form input:focus-visible, .name-fields input:focus-visible {
  outline: 2px solid var(--yellow);
  outline-offset: 2px;
}

.lobby-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  margin-top: 28px;
}
/* The code as a lit marquee board, bulbs and all. */
.join-code {
  position: relative;
  font-family: "Space Grotesk", sans-serif;
  font-size: 60px;
  letter-spacing: .16em;
  text-indent: .16em;
  padding: 26px 26px;
  border-radius: 18px;
  border: 1px solid rgba(240,180,41,.35);
  background: linear-gradient(180deg, #241b1c 0%, #16100f 100%);
  color: var(--yellow);
  text-align: center;
  text-shadow: 0 0 28px rgba(240,180,41,.45);
  box-shadow: inset 0 0 40px rgba(240,180,41,.08), 0 20px 50px rgba(0,0,0,.45);
}
.join-code::before, .join-code::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  height: 6px;
  background-image: radial-gradient(circle, rgba(240,180,41,.85) 40%, transparent 45%);
  background-size: 18px 6px;
  background-repeat: repeat-x;
}
.join-code::before { top: 9px; }
.join-code::after { bottom: 9px; }

.qr-box { margin-top: 14px; }
.qr-box img { border-radius: 14px; border: 1px solid var(--line); background: #fff; }

.lobby-seats { display: grid; gap: 10px; margin-bottom: 14px; }
.seat-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--surface);
}
.seat-chip b { flex: 1; }
.seat-chip em { font-style: normal; font-weight: 700; color: var(--muted); font-size: 13px; }
.seat-chip.is-empty { color: var(--muted); border-style: dashed; background: transparent; justify-content: center; }
.seat-dot { width: 12px; height: 12px; border-radius: 50%; flex: none; }

/* In-game seat strip (dark background) */
.table-players {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.table-players .seat-chip {
  background: rgba(247,239,227,.06);
  border-color: rgba(247,239,227,.13);
  color: var(--paper);
  padding: 9px 14px;
}
.table-players .seat-chip em { color: rgba(247,239,227,.55); }
.table-players .seat-chip.is-active {
  border-color: var(--yellow);
  box-shadow: 0 0 0 1px rgba(240,180,41,.5), 0 0 26px rgba(240,180,41,.2);
}
.table-players .seat-chip.is-away { opacity: .45; }

.board-note {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  padding: 34px;
  border-radius: 18px;
  border: 1px solid rgba(247,239,227,.11);
  background: rgba(247,239,227,.04);
}
.board-note h2 { margin: 0; font-size: 26px; }
.board-note p { margin: 0; color: rgba(247,239,227,.6); }

.paused-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 12px;
  margin-bottom: 18px;
  padding: 12px 18px;
  border-radius: 12px;
  border: 1px solid rgba(240,180,41,.38);
  background: rgba(240,180,41,.1);
  color: var(--paper);
}
.paused-bar strong { color: var(--yellow); }
.paused-bar span { color: rgba(247,239,227,.65); font-size: 14px; }
.button-small { padding: 8px 16px; min-height: 0; font-size: 14px; }
body.is-paused .reel-card, body.is-paused .screener-frame { opacity: .55; }

.action-row {
  width: min(100%, 440px);
  margin: 0 auto;
  display: grid;
  gap: 10px;
}
.action-row:empty { display: none; }
.action-note { margin: 4px 0 0; color: rgba(247,239,227,.55); font-weight: 600; font-size: 14px; }
.reel-owner {
  margin: 10px 16px 0;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--gold-soft);
}

@media (max-width: 900px) {
  .lobby-cols { grid-template-columns: 1fr; }
}

/* A short window trims the dressing around the picture rather than the picture
   itself, so the seat row under the film stays in view on a laptop. These live
   at the end of the file on purpose: the rules they narrow are declared above,
   and at equal specificity the last one wins. */
@media (max-height: 900px) {
  .stage { --stage-gap: 10px; }
  .top { padding: 8px 0 4px; gap: 10px; }
  .placer-title { font-size: clamp(18px, 2.2vw, 24px); }
  .placer-sub { font-size: 14px; }
  .screen:not(.game) { padding-bottom: 24px; }
  .marquee { margin-top: 8px; padding: 8px 12px; }
  .marquee input { min-height: 38px; }
  .screener-bar { margin-top: 10px; }
  .screener-bar .button { min-height: 40px; }
  .reel-perf { height: 16px; }
  .reel { padding: 12px 24px; }
  .reel-card { flex-basis: 152px; }
  .reel-year { margin-top: 4px; font-size: 19px; }
  .reel-title { margin-bottom: 6px; font-size: 14px; }
  .reel-slot { min-height: 96px; }
}
@media (max-height: 700px) {
  .play-fab { width: 64px; height: 64px; font-size: 24px; }
  .house-seats { min-height: 38px; }
}
