html { overflow-x: hidden; }
/* Vertically centered — so any line that appears mid-board would shift the
   whole board. Rule: anything that appears mid-board goes in a space that's
   always reserved (e.g. the result bar replaces the 2-line question slot). */
body { display: flex; align-items: center; justify-content: center; padding: 20px; overflow-x: hidden; }
#app { width: 100%; box-sizing: border-box; }
.board { text-align: center; }
/* Screen titles (UP NEXT, SURVEY SAYS!, FAST MONEY…) share the title card's
   heavy caps + hard gold shadow. */
h1 {
  font-size: 64px; font-weight: 900; line-height: 1; margin: 0 0 16px;
  color: var(--gold); text-transform: uppercase; letter-spacing: 0.02em;
  text-shadow: 0 5px 0 var(--gold-strong), 0 10px 24px rgba(0, 0, 0, 0.6);
}
h2 { font-size: 32px; margin: 0 0 18px; }
.matchup { font-size: 26px; color: var(--ink-soft); margin-bottom: 6px; }
.vs { color: var(--gold); font-weight: 700; margin: 0 10px; }
/* Up Next: teams stacked — TEAM / VS / TEAM */
.upnext-round { font-size: 24px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--ink-soft); margin: 0; }
.upnext-teams { font-size: 64px; font-weight: 900; line-height: 1.1; margin: 44px 0 64px; }
.upnext-teams .vs { display: block; margin: 16px 0; font-size: 0.55em; font-weight: 900; }
/* Up Next fills the whole stage: header in the top part, the titled bracket
   in the lower part (space spread evenly instead of bunching in the middle). */
/* Header, call-to-action, bracket as one group centered in the stage; equal
   gaps above and below "PREPARE TO DUEL!" keep it exactly halfway between the
   matchup and the bracket box. Tweak --upnext-gap to tighten/loosen. */
.board.upnext > .board-inner { height: 100%; display: flex; flex-direction: column; justify-content: center; --upnext-gap: 64px; }
/* Bottom gap is a bit bigger: the matchup's line box leaves empty space under
   its text, and the bracket box's edge is solid, so equal numbers LOOK uneven. */
.upnext-cta-zone { display: flex; align-items: center; justify-content: center; margin: var(--upnext-gap) 0 calc(var(--upnext-gap) + 24px); }
.upnext-cta-zone .upnext-cta { animation: cta-beat 1.6s ease-in-out infinite; }
@keyframes cta-beat {
  0%, 60%, 100% { transform: scale(1);    text-shadow: 0 4px 0 rgba(8, 16, 40, 0.9), 0 8px 20px rgba(0, 0, 0, 0.6); }
  15%           { transform: scale(1.07); text-shadow: 0 4px 0 rgba(8, 16, 40, 0.9), 0 0 26px rgba(127, 227, 255, 0.85); }
  30%           { transform: scale(1.02); }
  42%           { transform: scale(1.05); text-shadow: 0 4px 0 rgba(8, 16, 40, 0.9), 0 0 18px rgba(127, 227, 255, 0.6); }
}
.upnext-bracket-title {
  margin: 0 0 10px; font-size: 22px; font-weight: 900; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); text-shadow: 0 3px 0 var(--gold-strong);
}
.upnext-bracket .bracket-team { font-size: 18px; }
.upnext-bracket .bracket-col-header { font-size: 14px; }
.upnext-bracket {
  margin: 0 auto; padding: 16px 28px 12px; max-width: 100%; box-sizing: border-box;
  background: rgba(5, 8, 20, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 16px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}
/* Up Next with the bracket: matchup on one line to leave room for it */
.upnext-teams.one-line { font-size: 56px; margin: 18px 0 0; }
.upnext-teams.one-line > div { display: inline; }
.upnext-teams.one-line .vs { display: inline; margin: 0 22px; font-size: 0.6em; }
.upnext-cta {
  font-size: 52px; font-weight: 900; line-height: 1; text-transform: uppercase; letter-spacing: 0.03em;
  color: #fff;
  text-shadow: 0 4px 0 rgba(8, 16, 40, 0.9), 0 8px 20px rgba(0, 0, 0, 0.6);
}
/* Title screen — placeholder until real graphics */
.title-kicker { font-size: 26px; letter-spacing: 0.3em; text-transform: uppercase; color: var(--ink-soft); }
.title-main {
  font-size: 120px; font-weight: 900; line-height: 0.95; margin: 16px 0 36px;
  color: var(--gold); letter-spacing: 0.02em;
  text-shadow: 0 6px 0 var(--gold-strong), 0 12px 30px rgba(0,0,0,0.6);
}
.strikes { font-size: 22px; letter-spacing: 4px; margin-left: 12px; }
.q { font-size: 30px; font-weight: 700; margin: 10px 0 30px; }
/* Board question: bigger, and always two lines tall so showing it (or a
   long vs short question) never moves the board. */
.board-inner > .q {
  font-size: 38px; line-height: 1.2; margin: 14px 0 22px;
  min-height: 2.4em; display: flex; align-items: center; justify-content: center;
}
.q-hidden { color: var(--ink-soft); font-style: italic; font-weight: 600; }
/* ---------- Strike X (over the board) ----------
   Pops in, holds, fades — total 1.5s (STRIKE_MS in display.js). --t resumes
   it mid-way if the Display re-renders during it. */
.strike-overlay {
  position: absolute; inset: 0; z-index: 10;
  display: flex; align-items: center; justify-content: center; gap: 28px;
  pointer-events: none;
  animation: strike-pop 1.5s ease-out calc(var(--t, 0ms)) both;
}
.strike-x {
  width: 250px; height: 250px;
  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.8)) drop-shadow(0 4px 10px rgba(0, 0, 0, 0.35)) drop-shadow(0 0 14px rgba(224, 38, 31, 0.3));
}
.strike-x svg { width: 100%; height: 100%; display: block; }
@keyframes strike-pop {
  0%   { opacity: 0; transform: scale(0.4); }
  12%  { opacity: 1; transform: scale(1.1); }
  20%  { transform: scale(1); }
  75%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1); }
}

/* Status bar ("Table 2 WINS!", "takes this board!", Fast Money win) — takes
   over the question line's spot (.q always reserves 2 lines, so no shifting). */
.board-status {
  display: inline-block;
  padding: 10px 30px;
  line-height: 1;
  /* Trim the line box to the capital letters so top/bottom padding look even. */
  text-box: trim-both cap alphabetic;
  border-radius: 5px;
  background: rgba(7, 10, 20, 0.88);
  box-shadow: 0 0 0 2px rgba(217, 162, 51, 0.5), 0 8px 24px rgba(0, 0, 0, 0.6);
  font-size: 40px; font-weight: 900; font-style: normal; color: var(--gold); text-transform: uppercase;
  text-shadow: 0 3px 0 rgba(8, 16, 40, 0.85);
}
/* Board header: quiet context line, then the big "who's up" headline */
.board-kicker {
  font-size: 16px; font-weight: 700; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0 0 6px;
}
.board-kicker .vs { margin: 0 6px; }
.board-headline {
  font-size: 34px; font-weight: 900; line-height: 1.1; text-transform: uppercase; color: #fff;
  text-shadow: 0 4px 0 rgba(8, 16, 40, 0.9), 0 8px 20px rgba(0, 0, 0, 0.6);
}
.board-headline .headline-key { color: var(--gold); }

/* ---------- Score box (below the answer board) ----------
   Big number in a blue dot-textured panel with a grey bezel. Duel: the
   playing team's score. Final: center = board pot, sides = team totals. */
.score-row { display: flex; justify-content: center; align-items: flex-start; gap: 40px; margin: 36px 0 0; }
.score-center { display: flex; flex-direction: column; align-items: center; gap: 20px; }
/* Strike count under the score box: empty slots fill with the strike X */
.strike-slots { display: flex; gap: 12px; }
.strike-slot { width: 40px; height: 40px; border: 3px solid rgba(224, 38, 31, 0.35); border-radius: 8px; box-sizing: border-box; }
.strike-slot.filled { border: none; }
.strike-slot.unused { border-color: rgba(139, 147, 168, 0.25); background: rgba(139, 147, 168, 0.08); }
.strike-slot svg { width: 100%; height: 100%; display: block; }
.score-box {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 150px; height: 84px; padding: 0 24px;
  font-size: 58px; font-weight: 900; line-height: 1; color: #fff;
  text-shadow: 0 4px 0 rgba(8, 16, 40, 0.85), 0 8px 16px rgba(0, 0, 0, 0.5);
  background:
    radial-gradient(circle, rgba(255, 255, 255, 0.10) 0 3px, transparent 4px) 0 0 / 16px 16px,
    linear-gradient(180deg, #3f6fd1 0%, #2a55b5 55%, #1f4596 100%);
  border: 6px solid #6b7488;
  border-radius: 12px;
  box-shadow: inset 0 0 18px rgba(0, 0, 0, 0.45), 0 0 0 2px #2a3044, 0 8px 20px rgba(0, 0, 0, 0.5);
}
/* Final: labeled boxes — fixed-width columns + one-line labels keep all three
   boxes the same size with tops/bottoms lined up. */
.team-score { width: 220px; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.team-score .strike-slots { margin-top: 12px; } /* 8px gap + 12 = same 20px drop as the duel box */
.team-score .score-box { width: 170px; min-width: 0; }
.team-score-name {
  height: 24px; font-size: 20px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}

/* ---------- Fast Money board ----------
   Same gold frame as the answer board; black answer/points boxes with thin
   blue edges that fill in with white text. */
/* Bright blue frame -> dark band -> recessed blue panel with a vignette,
   so the board looks set into the wall. */
.fm-board {
  max-width: min(1000px, 100%);
  margin: 0 auto;
  padding: 28px 32px 18px;
  background: radial-gradient(ellipse 80% 70% at 50% 40%, #1447c9 0%, #0d339a 55%, #081f63 100%);
  border: 5px solid #3a8dff;
  border-radius: 22px;
  box-shadow:
    0 0 0 2px #1d4fa8,
    0 0 28px rgba(58, 141, 255, 0.4),
    inset 0 0 0 9px #050814,
    inset 0 0 0 11px rgba(58, 141, 255, 0.35),
    inset 0 0 50px 12px rgba(0, 0, 0, 0.55);
}
.fm-halves { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
.fm-player {
  height: 26px; margin-bottom: 8px;
  font-size: 18px; font-weight: 700; letter-spacing: 0.15em; text-transform: uppercase; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Points boxes are square: width = row height (62px). The sweeping red block
   (.fm-ans::after) uses the same width. */
.fm-rows { display: grid; grid-template-columns: minmax(0, 1fr) 62px; gap: 10px; }
.fm-ans, .fm-pts {
  height: 62px; box-sizing: border-box;
  display: flex; align-items: center;
  background: #000;
  border: 2px solid #3f6fd1;
  border-radius: 4px;
  font-size: 30px; font-weight: 900; text-transform: uppercase; color: #fff;
  text-shadow: 0 3px 0 rgba(8, 16, 40, 0.85);
}
.fm-ans { justify-content: flex-start; padding: 0 16px; min-width: 0; }
.fm-ans > span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fm-pts { justify-content: center; }
/* Red block: a 44px square that sits INSIDE the blue-edged points box.
   Used by the block sweeping across the answer box and the one waiting in
   the points box (.pending) until the score is revealed. */
.fm-pts.pending::before, .fm-ans.just-revealed::after {
  content: '';
  width: 44px; height: 44px; box-sizing: border-box;
  border: 2px solid #5C0503; border-radius: 4px;
  background: linear-gradient(180deg, #FF5A4E 0%, #E3211A 45%, #9E0B08 100%);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.3), inset 0 -2px 0 rgba(0, 0, 0, 0.3);
}
/* P2 repeat: red X in the points box */
.fm-x { width: 46px; height: 46px; }
.fm-x svg { width: 100%; height: 100%; display: block; }

/* Answer reveal: the red square sweeps left -> right (0.6s) across the answer
   box, uncovering the text behind it, and lands centered in the points box.
   Positions are relative to the answer box's padding box: the points box's
   outer edge is at 100% + 2px border + 10px gap = 100% + 12px, and the
   44px square is centered in the 62px box (+9px) -> 100% + 21px.
   Score reveal: no animation — the red square simply becomes the number. */
@keyframes wipe-lr {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes fm-sweep {
  from { left: 7px; }
  to   { left: calc(100% + 21px); }
}
@keyframes fm-sweep-visible { from, to { opacity: 1; } }
@keyframes fm-arrive { from { opacity: 0; } to { opacity: 1; } }
.fm-ans { position: relative; }
.fm-ans.just-revealed { z-index: 2; }
.fm-ans.just-revealed::after {
  position: absolute; top: 50%; margin-top: -22px;
  left: calc(100% + 21px);
  opacity: 0; /* hidden once landed — the points box's own square takes over */
  animation: fm-sweep 0.6s ease-in-out calc(var(--t, 0ms)) backwards,
             fm-sweep-visible 0.6s linear calc(var(--t, 0ms)) backwards;
}
.fm-ans.just-revealed > span { animation: wipe-lr 0.6s ease-in-out calc(var(--t, 0ms)) both; }
/* "Remind everyone" reveal of P1's column: plain left->right wipe, all at once. */
.fm-ans.remind-reveal > span, .fm-pts.remind-reveal > span { animation: wipe-lr 0.5s ease-out calc(var(--t, 0ms)) both; }
/* Waiting square blinks slowly like a cursor until the score is revealed. */
@keyframes fm-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.fm-pts.pending::before { animation: fm-blink 1.4s ease-in-out infinite; }
.fm-pts.pending.arriving::before {
  animation: fm-arrive 0.01s linear calc(var(--t, 0ms) + 0.6s) both,
             fm-blink 1.4s ease-in-out calc(var(--t, 0ms) + 0.6s) infinite;
}
.fm-ans > span, .fm-pts > span { display: inline-block; }
.fm-total-row { height: 62px; margin-top: 14px; display: flex; justify-content: flex-end; }
.fm-total {
  display: inline-flex; align-items: center; gap: 20px;
  padding: 0 16px 0 20px;
  background: #000; border: 2px solid #3f6fd1; border-radius: 4px;
  color: #fff; font-weight: 900; text-shadow: 0 3px 0 rgba(8, 16, 40, 0.85);
}
.fm-total-label { font-size: 24px; letter-spacing: 0.04em; }
.fm-total-num { font-size: 40px; min-width: 2em; text-align: right; }
.fm-total.fm-time-low .fm-total-num { color: #FF5A4E; }
/* Target hit: TOTAL box glows gold */
@keyframes fm-win-glow { 0%, 100% { box-shadow: 0 0 10px rgba(217, 162, 51, 0.5); } 50% { box-shadow: 0 0 28px rgba(242, 185, 74, 0.95); } }
.fm-total.fm-total-win { border-color: var(--gold); animation: fm-win-glow 1.2s ease-in-out infinite; }
.fm-total.fm-total-win .fm-total-num { color: #FFE08A; }
/* Inset look: dark top/right edges, the blue edge only on bottom/left. */
.fm-ans, .fm-pts, .fm-total { border-top-color: #06112e; border-right-color: #06112e; }

/* ---------- Crowd standings (Display) ----------
   Same blue inset panel as the Fast Money board; every cell its own black
   inset box (dark top/right edge, blue bottom/left). Host keeps the plain table. */
.board .crowd-standings {
  max-width: min(900px, 100%); margin: 0 auto; padding: 24px 30px 20px;
  background: radial-gradient(ellipse 80% 70% at 50% 40%, #1447c9 0%, #0d339a 55%, #081f63 100%);
  border: 5px solid #3a8dff; border-radius: 22px;
  box-shadow:
    0 0 0 2px #1d4fa8,
    0 0 28px rgba(58, 141, 255, 0.4),
    inset 0 0 0 9px #050814,
    inset 0 0 0 11px rgba(58, 141, 255, 0.35),
    inset 0 0 50px 12px rgba(0, 0, 0, 0.55);
}
.board .crowd-standings h3 { display: none; }
/* Game Over "WINNER!": pops in big, then a white shine sweeps across the gold
   letters on a loop while the glow pulses (think the show's $20,000 graphic).
   Gold is a gradient clipped to the text, so the glow uses drop-shadow. */
.winner-title {
  display: inline-block;
  font-size: 120px; font-weight: 900; line-height: 1; letter-spacing: 0.03em;
  background: linear-gradient(100deg, #D9A233 0%, #F2C14E 38%, #FFF6D6 48%, #F2C14E 58%, #D9A233 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  filter: drop-shadow(0 6px 0 #8a5a12) drop-shadow(0 0 18px rgba(242, 185, 74, 0.55));
  animation:
    winner-pop 0.9s cubic-bezier(0.2, 1.4, 0.4, 1) both,
    winner-shine 2.6s linear 0.9s infinite,
    winner-glow 1.6s ease-in-out 0.9s infinite;
}
@keyframes winner-pop {
  0%   { transform: scale(0.2); opacity: 0; }
  60%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); }
}
@keyframes winner-shine {
  from { background-position: 120% 0; }
  to   { background-position: -120% 0; }
}
@keyframes winner-glow {
  0%, 100% { filter: drop-shadow(0 6px 0 #8a5a12) drop-shadow(0 0 14px rgba(242, 185, 74, 0.45)); }
  50%      { filter: drop-shadow(0 6px 0 #8a5a12) drop-shadow(0 0 34px rgba(255, 224, 138, 0.95)); }
}

/* Game Over: the #1 crowd row (only that one, even on a tie) gets a
   subtle version of the WINNER! treatment — gold edges that gently pulse and
   a slow shine across the table name. */
.standings-final .cs-leader td {
  border-color: var(--gold); border-top-color: var(--gold-strong); border-right-color: var(--gold-strong);
  animation: leader-glow 1.8s ease-in-out infinite;
}
.standings-final .cs-leader .cs-table .team-label {
  background: linear-gradient(100deg, #FFE08A 0%, #FFE08A 40%, #FFFFFF 50%, #FFE08A 60%, #FFE08A 100%);
  background-size: 250% 100%;
  -webkit-background-clip: text; background-clip: text;
  color: transparent; text-shadow: none;
  animation: winner-shine 3.2s linear infinite;
}
@keyframes leader-glow {
  0%, 100% { box-shadow: 0 0 6px rgba(217, 162, 51, 0.35); }
  50%      { box-shadow: 0 0 16px rgba(242, 185, 74, 0.8); }
}

/* Label above the standings on screens where the title is about something else (Game Over) */
.standings-label {
  margin: 26px 0 12px; font-size: 26px; font-weight: 900; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--gold); text-shadow: 0 3px 0 var(--gold-strong), 0 6px 14px rgba(0, 0, 0, 0.5);
}
.board .crowd-standings table { border-collapse: separate; border-spacing: 10px 10px; font-size: 30px; margin: -10px; width: calc(100% + 20px); }
.board .crowd-standings th {
  border: none; padding: 0 6px; font-size: 15px; white-space: nowrap;
  letter-spacing: 0.15em; color: rgba(255, 255, 255, 0.7);
}
.board .crowd-standings td {
  height: 62px; padding: 0 16px; box-sizing: border-box;
  background: #000; color: #fff; font-weight: 900; text-transform: uppercase;
  border: 2px solid #3f6fd1; border-top-color: #06112e; border-right-color: #06112e; border-radius: 4px;
  text-shadow: 0 3px 0 rgba(8, 16, 40, 0.85);
}
.board .crowd-standings .cs-rank { width: 62px; padding: 0; text-align: center; color: var(--gold); }
.board .crowd-standings .cs-round { width: 110px; text-align: center; color: var(--good); }
.board .crowd-standings .cs-total { width: 100px; text-align: center; color: #FFE08A; }
.board .crowd-standings th.cs-round, .board .crowd-standings th.cs-total { text-align: center; }

/* ---------- Fast Money win: stage lights pulse ----------
   Six sparse layers of bright dots EXACTLY on the backdrop's dot grid (same
   7px radius), each with its own period/offset and blink timing, so the
   pulsing reads as random. Alignment rule: a layer's tile is (P x gap) by
   (Q x row) with the dot at the tile centre, positioned "left 50% bottom
   k*row" like the backdrop — P can be anything (50% centring keeps columns
   aligned) but Q MUST be odd, or the dot lands half a row off. */
/* Selector must out-rank `#app > .board > *` (position: relative on panel children). */
#app > .board > .win-twinkle { position: absolute; inset: 0 0 14px 0; z-index: 1; pointer-events: none; }
.win-twinkle i {
  position: absolute; inset: 0;
  background: radial-gradient(circle, #F2FCFF 0 3px, #8FE6FF 5px, #3FB6FF var(--dot-r), rgba(63, 182, 255, 0.35) calc(var(--dot-r) + 2px), transparent calc(var(--dot-r) + 5px));
  animation: win-twinkle var(--d) ease-in-out var(--delay) infinite both;
  opacity: 0;
}
.win-twinkle i:nth-child(1) { background-size: calc(3 * var(--dot-gap)) calc(5 * var(--dot-row)); background-position: left calc(50% + 1 * var(--dot-gap)) bottom calc(1 * var(--dot-row)); --d: 1.3s; --delay: 0s; }
.win-twinkle i:nth-child(2) { background-size: calc(5 * var(--dot-gap)) calc(3 * var(--dot-row)); background-position: left calc(50% + 3 * var(--dot-gap)) bottom calc(2 * var(--dot-row)); --d: 1.7s; --delay: -0.4s; }
.win-twinkle i:nth-child(3) { background-size: calc(7 * var(--dot-gap)) calc(5 * var(--dot-row)); background-position: left calc(50% + 2 * var(--dot-gap)) bottom 0; --d: 1.1s; --delay: -0.7s; }
.win-twinkle i:nth-child(4) { background-size: calc(4 * var(--dot-gap)) calc(7 * var(--dot-row)); background-position: left calc(50% + 0 * var(--dot-gap)) bottom calc(3 * var(--dot-row)); --d: 1.9s; --delay: -1.1s; }
.win-twinkle i:nth-child(5) { background-size: calc(6 * var(--dot-gap)) calc(3 * var(--dot-row)); background-position: left calc(50% + 5 * var(--dot-gap)) bottom calc(1 * var(--dot-row)); --d: 1.5s; --delay: -0.2s; }
.win-twinkle i:nth-child(6) { background-size: calc(5 * var(--dot-gap)) calc(7 * var(--dot-row)); background-position: left calc(50% + 1 * var(--dot-gap)) bottom calc(4 * var(--dot-row)); --d: 1.2s; --delay: -0.9s; }
@keyframes win-twinkle { 0%, 100% { opacity: 0; } 45%, 55% { opacity: 1; } }

/* ---------- Answer board ----------
   Borrowed ideas (framed board, numbered slots, reveal), our own palette.
   Always 8 slots (1-4 left, 5-8 right); slots past the question's answer
   count are blank bars — so every board is the same size and never shifts. */
.tiles {
  display: grid;
  grid-auto-flow: column;
  grid-template-rows: repeat(4, 1fr);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  margin: 0 auto 30px;
  max-width: min(1000px, 100%);
  padding: 18px;
  background: #070a14;
  border: 5px solid var(--gold);
  border-radius: 22px;
  box-shadow:
    0 0 0 2px var(--gold-strong),
    0 0 28px rgba(217, 162, 51, 0.35),
    inset 0 0 24px rgba(0, 0, 0, 0.8);
}
.tile {
  position: relative;
  height: 74px;
  min-width: 0;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid #7f9cc9;
  border-radius: 6px;
  background: linear-gradient(180deg, #3f6fd1 0%, #2a55b5 48%, #1f4596 52%, #2a55b5 100%);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.25), inset 0 -2px 0 rgba(0, 0, 0, 0.3);
  /* Same heavy caps + hard drop shadow as the title screen */
  font-weight: 900;
  color: #fff;
  text-shadow: 0 3px 0 rgba(8, 16, 40, 0.85), 0 6px 12px rgba(0, 0, 0, 0.5);
}
.tile.empty { background: linear-gradient(180deg, #1c2f5c, #152449); border-color: #3a4f78; }
/* Hidden answer: slot number in a navy oval */
.tile-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 68px; height: 46px;
  border-radius: 50%;
  background: radial-gradient(ellipse at 50% 35%, #2b3f7a, #0d1735 70%);
  border: 2px solid #a9c2ee;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
  font-size: 30px;
}
/* Revealed: answer left, points in their own box right */
.tile.revealed { justify-content: space-between; background: linear-gradient(180deg, #2a55b5, #1a3c86); }
.tile-text {
  flex: 1; min-width: 0; padding: 0 16px; text-align: left;
  font-size: 28px; text-transform: uppercase; letter-spacing: 0.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile-pts {
  flex: none; align-self: stretch; width: 84px;
  display: flex; align-items: center; justify-content: center;
  border-left: 2px solid #7f9cc9;
  background: linear-gradient(180deg, #3f6fd1, #2a55b5);
  font-size: 34px;
}
/* Reveal: top-to-bottom wipe, answer and points together.
   Only on the tile/row that was just revealed (display.js trackReveal). */
@keyframes reveal-wipe {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}
.tile.just-revealed > * { animation: reveal-wipe 0.5s ease-out calc(var(--t, 0ms)) both; }
.fm-table tr.just-revealed td:nth-child(n+2) { animation: reveal-wipe 0.5s ease-out calc(var(--t, 0ms)) both; }
/* 3D flip (TILE_REVEAL = 'flip' in display.js): the outer tile becomes a
   see-through stage; the two faces carry the tile look. Card turns on its
   horizontal axis — numbered front away, answer back toward the room. */
.tile.flip { perspective: 700px; background: none; border-color: transparent; box-shadow: none; }
.flip-card {
  position: absolute; inset: -2px;
  transform-style: preserve-3d;
  animation: tile-flip 0.6s ease-in-out calc(var(--t, 0ms)) both;
}
.face {
  position: absolute; inset: 0;
  display: flex; align-items: center;
  border: 2px solid #7f9cc9; border-radius: 6px;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.25), inset 0 -2px 0 rgba(0, 0, 0, 0.3);
}
.face-front { justify-content: center; background: linear-gradient(180deg, #3f6fd1 0%, #2a55b5 48%, #1f4596 52%, #2a55b5 100%); }
.face-back  { justify-content: space-between; background: linear-gradient(180deg, #2a55b5, #1a3c86); transform: rotateX(180deg); }
@keyframes tile-flip {
  from { transform: rotateX(0deg); }
  to   { transform: rotateX(-180deg); }
}
/* --t is a negative delay set by display.js when a re-render lands mid-wipe,
   so the new element resumes the wipe where the old one was. */
/* Flipped after the board ended — not earned, so dimmed. */
.tile.revealed.unclaimed { filter: saturate(0.4) brightness(0.75); }
.scorebar {
  display: flex;
  justify-content: center;
  gap: 50px;
  font-size: 28px;
  font-weight: 700;
  color: var(--gold);
}
.fm-list { max-width: 900px; margin: 0 auto; text-align: left; }
.fm-row {
  display: flex;
  justify-content: space-between;
  font-size: 24px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.fm-cell { margin-left: 24px; }
.fm-cell:first-child { margin-left: 0; }
.fm-table { max-width: 700px; margin: 20px auto 0; font-size: 26px; }
.fm-table th { font-size: 15px; padding: 10px 14px; }
.fm-table td { padding: 16px 14px; }
.fm-table td:first-child { width: 44px; }
.fm-table td:last-child { width: 130px; }


/* ---------- Stage backdrop (board panel only, not the bracket) ----------
   Pure CSS stand-in for real artwork: navy spotlight + vignette, and blue
   "stage light" dots along the bottom, brighter toward the floor. Upper rows
   are sparse so columns have uneven heights (a skyline) — built from layers
   with different periods (3, 5, 7 columns) and offsets, so the pattern only
   repeats every ~100 columns and reads as random. Each higher row's dots are
   a subset of the row below, so no dot ever floats over a gap.
   Swap for an image later if wanted. */
#app > .board {
  --dot-gap: 44px;   /* horizontal spacing */
  --dot-row: 28px;   /* vertical spacing */
  --dot-r: 7px;      /* dot radius */
  /* ONE fixed size on every screen — the panel never grows or shrinks.
     Content is centered inside; fitBoard() (display.js) zooms the content
     down if a screen is taller than this (e.g. a long Crowd Round reveal). */
  /* Sized to (nearly) fill a 1920x1080 projector with a small margin; on
     bigger monitors it stays this size, centered. */
  --stage-w: min(1880px, calc(100vw - 40px));
  --stage-h: min(1040px, calc(100vh - 40px));
  width: var(--stage-w);
  max-width: none;
  height: var(--stage-h);
  display: flex;
  flex-direction: column;
  justify-content: center;
  position: relative;
  overflow: hidden;
  border-radius: 18px;
  padding: 32px 40px 40px; /* bottom used to reserve a pinned status bar; it now lives in the question slot */
  background:
    radial-gradient(ellipse 55% 65% at 50% 30%, rgba(60, 150, 255, 0.12), transparent 70%),
    radial-gradient(ellipse 90% 90% at 50% 30%, #1c2b52 0%, #131c38 50%, #0a0e1a 100%);
  box-shadow: inset 0 0 140px rgba(0, 0, 0, 0.65), 0 10px 40px rgba(0, 0, 0, 0.4);
}
#app > .board > * { position: relative; z-index: 1; }
#app > .board::after {
  content: '';
  position: absolute;
  inset: 0 0 14px 0; /* whole panel; dots measured up from the floor */
  pointer-events: none;
  /* Positions use "left X bottom Y" so rows count up from the floor no matter
     how tall the board is. The answer frame is opaque, so dots only show
     around it. The mask fades everything out toward the top. */
  background:
    /* floor: every column, brightest */
    radial-gradient(circle, #3FB6FF 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left 50% bottom 0 / var(--dot-gap) var(--dot-row) repeat-x,
    /* row 2 accents: every 5th, bright cyan (before its base so it paints on top) */
    radial-gradient(circle, #7FE3FF 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 2 * var(--dot-gap)) bottom calc(1 * var(--dot-row)) / calc(5 * var(--dot-gap)) var(--dot-row) repeat-x,
    /* rows 2-4: every column */
    radial-gradient(circle, rgba(40, 125, 235, 0.7) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left 50% bottom calc(1 * var(--dot-row)) / var(--dot-gap) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.55) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left 50% bottom calc(2 * var(--dot-row)) / var(--dot-gap) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left 50% bottom calc(3 * var(--dot-row)) / var(--dot-gap) var(--dot-row) repeat-x,
    /* skyline above: sparse brighter columns (period 3/5/7), each row a subset of the one below */
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 1 * var(--dot-gap)) bottom calc(4 * var(--dot-row)) / calc(3 * var(--dot-gap)) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 4 * var(--dot-gap)) bottom calc(4 * var(--dot-row)) / calc(5 * var(--dot-gap)) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 2 * var(--dot-gap)) bottom calc(4 * var(--dot-row)) / calc(7 * var(--dot-gap)) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 4 * var(--dot-gap)) bottom calc(5 * var(--dot-row)) / calc(5 * var(--dot-gap)) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 2 * var(--dot-gap)) bottom calc(5 * var(--dot-row)) / calc(7 * var(--dot-gap)) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 2 * var(--dot-gap)) bottom calc(6 * var(--dot-row)) / calc(7 * var(--dot-gap)) var(--dot-row) repeat-x,
    radial-gradient(circle, rgba(40, 125, 235, 0.45) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left calc(50% + 2 * var(--dot-gap)) bottom calc(7 * var(--dot-row)) / calc(7 * var(--dot-gap)) var(--dot-row) repeat-x,
    /* faint field filling the whole panel — fades out going up via the mask */
    radial-gradient(circle, rgba(40, 125, 235, 0.35) 0 var(--dot-r), transparent calc(var(--dot-r) + 1px)) left 50% bottom 0 / var(--dot-gap) var(--dot-row) repeat;
  -webkit-mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0.55) 30%, rgba(0, 0, 0, 0.12) 75%, transparent 100%);
          mask-image: linear-gradient(to top, #000 0%, rgba(0, 0, 0, 0.55) 30%, rgba(0, 0, 0, 0.12) 75%, transparent 100%);
}
