/* Default palette = the "arcade" theme; themes.css overrides these per
   [data-theme] along with --font and the .grid backdrop. */
:root {
  --neon-cyan:   #00f0ff;
  --neon-pink:   #ff2e88;
  --neon-yellow: #ffd800;
  --neon-green:  #39ff14;
  --neon-purple: #b026ff;
  --neon-red:    #ff3b3b;
  --bg-0:        #0a021a;
  --bg-1:        #14043a;
  --font: 'Press Start 2P', monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }

body {
  font-family: var(--font);
  background: radial-gradient(ellipse at 50% 15%, var(--bg-1) 0%, var(--bg-0) 70%, #000 100%);
  color: #fff;
  min-height: 100vh;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 1.5vh 3vw 3vh;
  position: relative;
  -webkit-font-smoothing: none;
}

/* ---- backdrop ---- */
.grid {
  position: fixed; inset: 0; z-index: 0;
  background-image:
    linear-gradient(rgba(176,38,255,0.20) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0,240,255,0.15) 1px, transparent 1px);
  background-size: 44px 44px;
  transform: perspective(400px) rotateX(60deg);
  transform-origin: 50% 100%;
  mask-image: linear-gradient(to top, #000 0%, transparent 65%);
  -webkit-mask-image: linear-gradient(to top, #000 0%, transparent 65%);
  animation: gridScroll 3s linear infinite;
  opacity: 0.7;
}
@keyframes gridScroll { from { background-position: 0 0; } to { background-position: 0 44px; } }
.scanlines {
  position: fixed; inset: 0; z-index: 50; pointer-events: none;
  background: repeating-linear-gradient(to bottom,
    rgba(0,0,0,0) 0px, rgba(0,0,0,0) 2px,
    rgba(0,0,0,0.18) 3px, rgba(0,0,0,0.18) 4px);
  mix-blend-mode: multiply;
}
.vignette { position: fixed; inset: 0; z-index: 49; pointer-events: none;
  box-shadow: inset 0 0 200px rgba(0,0,0,0.9); }

/* Free-look countdown, top right. Above the scanlines so it stays legible, and
   :empty so it costs nothing at all once a venue has subscribed — no reserved
   space, no stray border, nothing to notice. */
/* Top LEFT, not right: the join QR already owns the right-hand corner, and it
   is the one thing on this screen that must never be obscured — a covered QR
   costs the venue players, a badge two feet away costs nothing. The left
   corner is otherwise empty, so it reads as a matching pair. */
.demobadge {
  /* Above the phase overlays (70–85): this is standing status, not part of any
     one phase, and it was being dimmed out by the lobby and podium cards — the
     screens somebody demoing is most likely to be looking at. */
  position: fixed; top: 14px; left: 16px; z-index: 90;
  font-family: var(--font, "Press Start 2P"), monospace;
  font-size: clamp(0.5rem, 1.15vw, 0.9rem); letter-spacing: 2px;
  color: var(--neon-cyan, #00f0ff);
  background: rgba(10, 2, 26, 0.72);
  border: 2px solid var(--neon-cyan, #00f0ff);
  border-radius: 6px; padding: 8px 12px;
  text-shadow: 0 0 10px rgba(0, 240, 255, 0.8);
  box-shadow: 0 0 18px rgba(0, 240, 255, 0.35);
  pointer-events: none;
}
.demobadge:empty { display: none; }
/* Under two minutes it turns and pulses — the point of the badge is that the
   moment it runs out is not a surprise. */
.demobadge.urgent {
  color: var(--neon-pink, #ff2e88); border-color: var(--neon-pink, #ff2e88);
  text-shadow: 0 0 10px rgba(255, 46, 136, 0.85);
  box-shadow: 0 0 18px rgba(255, 46, 136, 0.4);
  animation: demopulse 1s ease-in-out infinite;
}
@keyframes demopulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
body.lite .demobadge.urgent { animation: none; }

/* ---- lite mode: drop the GPU-heavy effects for weak displays (Smart TVs) ----
   Keeps the neon palette and sharp retro drop-shadows; removes the animated
   perspective grid, scanlines, backdrop blur, glow blurs, and every looping
   animation/transition — the things that saturate a TV's compositor. */
html.lite .grid,
html.lite .scanlines { display: none !important; }
html.lite *,
html.lite *::before,
html.lite *::after {
  animation: none !important;
  transition: none !important;
  text-shadow: none !important;
}
/* :not(.pairing) — the pairing card sets its own opaque background and this
   !important would put the translucency back on exactly the hardware (Pi,
   Smart TV) that runs lite mode. */
html.lite .overlay:not(.pairing) {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
  background: rgba(4,1,15,0.94) !important;
}
html.lite .pairing { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
html.lite .question,
html.lite .timerfill { box-shadow: none !important; }

/* ---- title ---- */
header { z-index: 10; text-align: center; margin: 0.5vh 0 1.5vh; }
.title {
  font-size: clamp(1.4rem, 5.5vw, 4rem);
  letter-spacing: 2px; line-height: 1.15; color: var(--neon-yellow);
  text-shadow: 3px 3px 0 var(--neon-pink), 6px 6px 0 var(--neon-purple), 0 0 18px rgba(255,46,136,0.8);
  animation: titlePulse 1.6s ease-in-out infinite alternate;
}
.title .bot { color: var(--neon-cyan);
  text-shadow: 3px 3px 0 var(--neon-purple), 6px 6px 0 var(--neon-pink), 0 0 18px rgba(0,240,255,0.9); }
@keyframes titlePulse { from { filter: brightness(1); transform: translateY(0); } to { filter: brightness(1.25); transform: translateY(-3px); } }
.subtitle { margin-top: 1vh; font-size: clamp(0.4rem, 1.2vw, 0.75rem); color: var(--neon-green); letter-spacing: 3px; animation: blink 1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* ---- layout ---- */
.wrap {
  z-index: 10; width: min(1180px, 96vw);
  display: grid; grid-template-columns: minmax(0,1fr) 300px; gap: 2vw; align-items: start;
}
@media (max-width: 900px) { .wrap { grid-template-columns: 1fr; } }

.stage { display: flex; flex-direction: column; gap: 2vh; }

.catbar { display: flex; justify-content: space-between; align-items: center; font-size: clamp(0.5rem, 1.4vw, 0.9rem); gap: 1em; }
.category { color: var(--bg-0); background: var(--neon-cyan); padding: 0.7em 1em; border: 3px solid #fff; box-shadow: 4px 4px 0 var(--neon-pink); text-transform: uppercase; }
.qnum { color: var(--neon-purple); white-space: nowrap; }

.question {
  min-height: 5.5em; font-size: clamp(0.72rem, 2.1vw, 1.35rem); line-height: 1.9; color: #fff;
  text-shadow: 0 0 8px rgba(0,240,255,0.5);
  border: 3px solid var(--neon-purple); background: rgba(20,4,58,0.6);
  padding: 1.2em; box-shadow: inset 0 0 30px rgba(176,38,255,0.35);
}
/* Picture questions. Contained, never cropped — a flag cut off at the edge is a
   different flag. The faint frame keeps white-edged flags (Japan, Canada) from
   dissolving into a light theme or blurring into a dark one. */
.qimage { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 0.6vh; }
.qimage img { max-width: min(92vw, 1600px); max-height: 30vh; object-fit: contain;
  outline: 2px solid rgba(255,255,255,0.35); box-shadow: 0 0 24px rgba(0,0,0,0.5); }
/* While the question is read, the picture is the question: the answer tiles
   are hidden anyway, so they give up their space (see showQuestionImage). */
.stage.pic-big .answers { display: none; }
/* With the answers up, the picture sits in the top-left corner beside the
   question instead of on top of it — the same size in a fraction of the
   height, which is what leaves room for it to stay recognisable. */
.stage.pic-small {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "cat cat" "img q" "ans ans" "status status" "bot bot";
  align-items: center;
  column-gap: 2vw;
}
.stage.pic-small .catbar { grid-area: cat; }
.stage.pic-small .qimage { grid-area: img; align-items: flex-start; }
.stage.pic-small .qimage img { max-width: 42vw; }
.stage.pic-small .question { grid-area: q; align-self: center; }
.stage.pic-small .answers { grid-area: ans; }
.stage.pic-small .statusbar { grid-area: status; }
.stage.pic-small .bot-say { grid-area: bot; }
.qimage figcaption { font-size: clamp(0.5rem, 1.3vh, 0.75rem); opacity: 0.55; }
.qimage figcaption:empty { display: none; }
.qimage.hidden { display: none; }
.caret { display: inline-block; width: 0.6em; color: var(--neon-green); animation: blink 0.6s steps(1) infinite; }

.answers { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4vh 1.5vw; }
@media (max-width: 620px) { .answers { grid-template-columns: 1fr; } }

.answer {
  display: flex; align-items: center; gap: 0.8em;
  font-size: clamp(0.58rem, 1.6vw, 1.05rem); line-height: 1.6; text-align: left;
  padding: 1em; border: 3px solid var(--neon-cyan); background: rgba(0,240,255,0.05); color: #cdefff;
  font-family: inherit; cursor: default; width: 100%;
  opacity: 0; transform: translateY(12px);
  transition: opacity 0.25s, transform 0.25s, background 0.15s, color 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.answer.show { opacity: 1; transform: translateY(0); }
.answer .key { color: var(--bg-0); background: var(--neon-yellow); padding: 0.35em 0.6em; flex-shrink: 0; }
.answer.live { cursor: pointer; }
.answer.live:hover { background: rgba(0,240,255,0.18); box-shadow: 0 0 16px rgba(0,240,255,0.5); transform: translateY(-2px); }
.answer.picked { border-color: var(--neon-yellow); background: rgba(255,216,0,0.12); box-shadow: 0 0 20px rgba(255,216,0,0.6); }
.answer.picked .key { background: var(--neon-pink); color: #fff; }
.answer.correct { background: var(--neon-green); color: #04210a; border-color: #fff; box-shadow: 0 0 24px var(--neon-green), 4px 4px 0 var(--neon-purple); animation: flash 0.4s steps(1) 6; }
.answer.correct .key { background: #04210a; color: var(--neon-green); }
.answer.wrongpick { background: rgba(255,59,59,0.2); border-color: var(--neon-red); box-shadow: 0 0 20px rgba(255,59,59,0.6); }
.answer.dim { opacity: 0.28; }
@keyframes flash { 50% { filter: brightness(1.6); } }

/* ---- timer ---- */
.statusbar { display: flex; align-items: center; gap: 1.5vw; }
.timerlabel { font-size: clamp(0.45rem, 1.2vw, 0.85rem); color: var(--neon-yellow); white-space: nowrap; }
.timerbar { flex: 1; height: 22px; border: 3px solid var(--neon-yellow); padding: 3px; background: rgba(0,0,0,0.5); }
.timerfill { height: 100%; width: 100%; background: var(--neon-green); box-shadow: 0 0 12px var(--neon-green); }
.timernum { font-size: clamp(0.8rem, 2.2vw, 1.5rem); color: var(--neon-green); min-width: 2.4em; text-align: right; }
.timernum.warn { color: var(--neon-pink); animation: blink 0.4s steps(1) infinite; }

/* During the reveal the timer is meaningless, so it leaves the flow entirely
   (display:none, not visibility) — that drops the flex gap with it and the
   explanation lands directly under the answers. */
body.revealing > .stage > .statusbar { display: none; }

/* ---- bot speech ---- */
.bot-say {
  min-height: 2.4em; font-size: clamp(0.5rem, 1.4vw, 0.9rem); line-height: 1.7; color: var(--neon-pink);
  border-left: 4px solid var(--neon-pink); padding: 0.8em 1em; background: rgba(255,46,136,0.08);
}
.bot-say b { color: var(--neon-green); }
.bot-say .good { color: var(--neon-green); }
.bot-say .bad { color: var(--neon-red); }
/* the one-line "why" shown next to the revealed answer */
.bot-say .why { color: var(--neon-cyan); }

/* ---- sidebar ---- */
.sidebar { display: flex; flex-direction: column; gap: 2vh; }
.panel { border: 3px solid var(--neon-purple); background: rgba(20,4,58,0.6); box-shadow: inset 0 0 20px rgba(176,38,255,0.25); padding: 1em; }
.panel h2 { font-size: clamp(0.55rem, 1.3vw, 0.85rem); color: var(--neon-yellow); margin-bottom: 0.9em; letter-spacing: 1px; }

/* player HUD */
.hud .handle { color: var(--neon-cyan); font-size: 0.85rem; word-break: break-all; }
.hud .row { display: flex; justify-content: space-between; font-size: 0.6rem; line-height: 2.1; color: #cdefff; }
.hud .row b { color: var(--neon-green); }
.hud .pts { font-size: 1.4rem; color: var(--neon-green); text-shadow: 0 0 10px var(--neon-green); margin: 0.3em 0; }

/* join form */
.join p { font-size: 0.55rem; line-height: 1.9; color: #cdefff; margin-bottom: 1em; }
.join input {
  font-family: inherit; width: 100%; padding: 0.8em; font-size: 0.7rem; color: var(--neon-green);
  background: #04010f; border: 3px solid var(--neon-cyan); margin-bottom: 0.8em; outline: none;
}
.join input:focus { border-color: var(--neon-yellow); box-shadow: 0 0 14px rgba(255,216,0,0.5); }
.btn {
  font-family: inherit; width: 100%; padding: 0.9em; font-size: 0.65rem; cursor: pointer;
  color: var(--bg-0); background: var(--neon-green); border: 3px solid #fff; box-shadow: 4px 4px 0 var(--neon-purple);
  transition: transform 0.08s, box-shadow 0.08s;
}
.btn:hover { filter: brightness(1.1); }
.btn:active { transform: translate(4px,4px); box-shadow: 0 0 0 var(--neon-purple); }
.btn.secondary { background: transparent; color: var(--neon-cyan); border-color: var(--neon-cyan); box-shadow: none; font-size: 0.5rem; padding: 0.6em; margin-top: 0.6em; }
.err { color: var(--neon-red); font-size: 0.5rem; line-height: 1.7; min-height: 1.2em; margin-top: 0.4em; }

/* leaderboard */
.lb { list-style: none; display: flex; flex-direction: column; gap: 0.5em; }
.lb li { display: flex; align-items: center; gap: 0.6em; font-size: 0.55rem; line-height: 1.7; color: #cdefff; }
.lb .n { color: var(--neon-yellow); width: 1.6em; }
.lb .h { flex: 1; color: var(--neon-cyan); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb .p { color: var(--neon-green); }
.lb .me { background: rgba(57,255,20,0.12); outline: 1px solid var(--neon-green); padding: 0.2em 0.3em; }
.lb .empty { color: var(--neon-purple); font-size: 0.5rem; }

.float-pts {
  position: fixed; z-index: 60; font-size: 1.6rem; color: var(--neon-green);
  text-shadow: 0 0 12px var(--neon-green); pointer-events: none;
  animation: floatUp 1.6s ease-out forwards;
}
@keyframes floatUp { 0% { opacity: 0; transform: translateY(0) scale(0.6); } 15% { opacity: 1; } 100% { opacity: 0; transform: translateY(-90px) scale(1.2); } }

/* ---- live scoreboard columns ---- */
.lb li .cc { color: var(--neon-green); }
.lb li .ic { color: var(--neon-red); }
.lb li .p { color: var(--neon-yellow); min-width: 3em; text-align: right; }

/* ---- join card on the display ---- */
.joincard p { font-size: 0.5rem; line-height: 1.9; color: #cdefff; margin-bottom: 0.6em; }
.joincard .tiny { font-size: 0.45rem; color: var(--neon-purple); margin-top: 0.6em; }
.joinbig {
  font-size: clamp(0.6rem, 1.4vw, 0.95rem); color: var(--bg-0); background: var(--neon-green);
  border: 3px solid #fff; box-shadow: 4px 4px 0 var(--neon-pink); padding: 0.7em; text-align: center;
  word-break: break-all;
}

/* ---- get-ready lead-in (before each question) ---- */
.getready {
  position: fixed; inset: 0; z-index: 70; display: flex; align-items: center; justify-content: center;
  /* Opaque, not 92%: this sits between every question, and the last one's
     board showing through put "LOADING…" and the timer bar straight through
     the middle of the text. Done in CSS rather than with the .overlay-up body
     class so there's no second piece of state that could strand the stage
     hidden mid-game. */
  background: radial-gradient(ellipse at 50% 15%, var(--bg-1) 0%, var(--bg-0) 70%, #000 100%);
  padding: 6vw; text-align: center;
}
.getready-count {
  margin-top: 0.5em; font-size: clamp(2.2rem, 9vw, 6rem); color: var(--neon-green);
  text-shadow: 3px 3px 0 var(--neon-purple), 0 0 26px rgba(57,255,20,0.85);
  /* Holds the line open before the first paint, so the text above never
     shifts even for one frame. */
  min-height: 1em; line-height: 1;
}
.getready-card {
  font-size: clamp(1.2rem, 5.5vw, 3.4rem); line-height: 1.6; color: var(--neon-yellow);
  text-shadow: 3px 3px 0 var(--neon-pink), 0 0 22px rgba(255,216,0,0.8);
}
.getready-theme {
  font-size: clamp(0.9rem, 3.4vw, 2rem); color: var(--neon-cyan); letter-spacing: 3px;
  line-height: 1.4; margin-bottom: 0.8em;
  text-shadow: 2px 2px 0 var(--neon-purple), 0 0 18px rgba(0,240,255,0.75);
}
.getready-theme:empty { display: none; }

/* ---- lobby / winner overlay ---- */
.overlay {
  position: fixed; inset: 0; z-index: 80; display: flex; align-items: center; justify-content: center;
  background: rgba(4,1,15,0.86); backdrop-filter: blur(2px); padding: 4vw; text-align: center;
}
.overlay-card { max-width: 780px; max-height: 94vh; overflow: hidden; }
.ov-kicker { font-size: clamp(0.8rem, 2.1vw, 1.4rem); color: var(--neon-pink); letter-spacing: 2px; margin-bottom: 1.2em; }
.ov-title {
  font-size: clamp(1.6rem, 7vw, 4.5rem); color: var(--neon-cyan); line-height: 1.2; word-break: break-word;
  text-shadow: 3px 3px 0 var(--neon-purple), 0 0 22px rgba(0,240,255,0.8);
}
.ov-title.win { color: var(--neon-yellow); text-shadow: 3px 3px 0 var(--neon-pink), 0 0 26px rgba(255,216,0,0.9); animation: titlePulse 1s ease-in-out infinite alternate; }
.ov-count { font-size: clamp(3rem, 12vw, 8rem); color: var(--neon-green); margin: 0.2em 0; text-shadow: 0 0 24px var(--neon-green); }
.ov-score { font-size: clamp(0.9rem, 2.6vw, 1.6rem); color: var(--neon-green); margin: 0.8em 0; }
.ov-sub { font-size: clamp(0.75rem, 1.9vw, 1.2rem); color: #cdefff; line-height: 1.8; margin-top: 0.6em; }
.ov-join { font-size: clamp(0.55rem, 1.6vw, 1rem); color: var(--neon-yellow); margin-top: 1.2em; line-height: 1.8; }
.ov-join b { color: var(--neon-cyan); }
.ov-players, .ov-next { font-size: clamp(0.7rem, 1.7vw, 1.1rem); color: var(--neon-purple); margin-top: 1.2em; }
.ov-qr.small { width: clamp(160px, 18vw, 230px); margin-top: 0.7em; }
.ov-qr {
  width: clamp(150px, 22vw, 250px); height: auto; aspect-ratio: 1; display: block; margin: 1.4em auto 0;
  background: #fff; padding: 10px; border: 5px solid var(--neon-cyan); box-shadow: 6px 6px 0 var(--neon-pink);
  image-rendering: pixelated;
}

/* ---- ranked standings (between rounds) ---- */
.standings {
  list-style: none; margin: 0.7em auto 0; max-width: 46em;
  display: flex; flex-direction: column; gap: 0.3em;
}
.standings li {
  display: flex; align-items: center; gap: 0.8em; text-align: left;
  font-size: clamp(0.7rem, 1.6vw, 1.15rem); line-height: 1.45;
  padding: 0.35em 0.7em; border: 2px solid var(--neon-purple);
  background: rgba(0, 0, 0, 0.25);
}
.standings li.podium { border-color: var(--neon-yellow); }
.standings .rk { width: 1.6em; text-align: right; color: var(--neon-purple); }
.standings .rk.gold { color: #ffd800; }
.standings .rk.silver { color: #cfd8e3; }
.standings .rk.bronze { color: #cd8032; }
.standings .h { flex: 1; color: var(--neon-cyan); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.standings .rec { color: var(--neon-green); font-size: 0.8em; }
.standings .p { color: var(--neon-yellow); min-width: 3.5em; text-align: right; }
.standings .p.neg { color: var(--neon-red); }

/* ---- podium (game over: top three with their venue's titles) ---- */
.podium {
  display: flex; justify-content: center; align-items: flex-end; gap: 1vw;
  margin: 0.8em 0 0.5em; flex-wrap: nowrap;   /* three across, always */
}
.pod {
  flex: 1 1 0; min-width: 0; max-width: 11em;
  padding: 0.7em 0.5em; border: 3px solid var(--neon-purple);
  background: rgba(0, 0, 0, 0.3); text-align: center;
}
.pod.gold   { border-color: #ffd800; transform: scale(1.08); order: 2; z-index: 1; }
.pod.silver { border-color: #cfd8e3; order: 1; }
.pod.bronze { border-color: #cd8032; order: 3; }
.pod-medal {
  font-size: clamp(1.2rem, 4.5vh, 2.4rem); line-height: 1;
  width: 1.8em; height: 1.8em; margin: 0 auto 0.35em;
  display: flex; align-items: center; justify-content: center; border-radius: 50%;
}
.pod.gold .pod-medal   { background: #ffd800; color: #221a00; }
.pod.silver .pod-medal { background: #cfd8e3; color: #1b1f24; }
.pod.bronze .pod-medal { background: #cd8032; color: #241403; }
.pod-title {
  font-size: clamp(0.45rem, 1.5vh, 0.8rem); color: var(--neon-pink);
  letter-spacing: 1px; margin-bottom: 0.45em;
}
.pod-name {
  font-size: clamp(0.7rem, 2.6vh, 1.3rem); color: var(--neon-cyan);
  word-break: break-word; line-height: 1.35;
}
.pod-pts { font-size: clamp(0.5rem, 1.8vh, 0.9rem); color: var(--neon-green); margin-top: 0.35em; }

/* ---- lightning round ---- */
.lightning-intro { background: rgba(20, 2, 30, 0.94); }
.lightning-bolt {
  font-size: clamp(3rem, 16vh, 9rem); line-height: 1;
  color: var(--neon-yellow); text-shadow: 0 0 30px var(--neon-yellow);
  animation: boltPulse 0.5s steps(1) infinite;
}
@keyframes boltPulse { 50% { opacity: 0.45; } }
.lightning-title {
  font-size: clamp(1.6rem, 8vh, 4.5rem); color: var(--neon-yellow); line-height: 1.2;
  letter-spacing: 3px; margin: 0.25em 0 0.4em;
  text-shadow: 4px 4px 0 var(--neon-pink), 0 0 30px rgba(255, 216, 0, 0.9);
}
.lightning-rules {
  font-size: clamp(0.55rem, 2.2vh, 1.1rem); color: #cdefff; line-height: 2;
}
.lightning-rules b { color: var(--neon-green); }

/* the strip under the stage: who took the last lightning question */
#scorebar.flash { display: block !important; }
.lightning-took {
  text-align: center; font-size: clamp(0.7rem, 3vh, 1.6rem); line-height: 1.5;
  color: var(--neon-yellow); padding: 0.4em 0;
}
.lightning-took .who { color: var(--neon-green); }
.lightning-took .nobody { color: var(--neon-purple); }

/* banner in place of the round label while lightning is running */
.qnum .bolt { color: var(--neon-yellow); }

/* ---- promo slide (house specials / sponsor slots) ----
   Full-bleed on a black field so the venue's artwork owns the screen; the
   only chrome is a small corner tag naming the advertiser. */
.promo {
  position: fixed; inset: 0; z-index: 85;
  display: flex; align-items: center; justify-content: center;
  background: #000;
  /* Slides cut in and out hard otherwise, which reads as a glitch on a big
     screen. The promo sits above the get-ready screen it hands over to, so
     fading out cross-dissolves into it. */
  opacity: 0;
  transition: opacity 450ms ease;
}
.promo.on { opacity: 1; }
.promo-img { max-width: 100%; max-height: 100%; object-fit: contain; }
.promo-tag {
  position: absolute; bottom: 3vh; right: 3vw;
  font-size: clamp(0.42rem, 1.3vh, 0.7rem); letter-spacing: 2px;
  color: rgba(255, 255, 255, 0.65); text-transform: uppercase;
  background: rgba(0, 0, 0, 0.45); padding: 0.5em 0.9em; border-radius: 3px;
}
.promo-tag:empty { display: none; }

/* While a full-screen overlay is up, the game board behind it is stale — hide
   the content layers but leave the grid/scanlines/vignette so the theme still
   reads through the overlay's translucency. */
body.overlay-up > .topbar,
body.overlay-up > .stage,
body.overlay-up > .scorebar,
body.overlay-up > .wrap { visibility: hidden; }

/* ---- pairing card (unpaired screen asking to be adopted) ---- */
/* The other overlays sit at 86% over a game in progress, where the board
   behind them is context. This one isn't in a game at all, so the same
   translucency just leaves dead chrome showing through — and the join code
   lands on top of the timer bar. Cover the lot. */
.pairing {
  background: radial-gradient(ellipse at 50% 15%, var(--bg-1) 0%, var(--bg-0) 70%, #000 100%);
  backdrop-filter: none;
}
.pairing .ov-qr { margin-top: 0.6em; }
.pair-code {
  font-size: clamp(2rem, 9vh, 5rem); letter-spacing: 0.18em; color: var(--neon-yellow);
  margin: 0.35em 0 0.2em; word-break: break-all;
}
.pair-steps {
  font-size: clamp(0.5rem, 1.8vh, 0.95rem); line-height: 2; color: #cdefff;
  letter-spacing: 1px;
}
.pair-steps b { color: var(--neon-cyan); }

/* ============ NEW LAYOUT: title centered, QR pinned top-right ============ */
.topbar {
  z-index: 10; width: min(1180px, 96vw); display: flex; align-items: center; justify-content: center;
  margin: 0.5vh 0 1.5vh;
}
.qrbox {
  position: fixed; top: 16px; right: 16px; z-index: 40;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.qrimg {
  width: clamp(74px, 9vw, 128px); height: auto; aspect-ratio: 1; background: #fff; padding: 5px;
  border: 4px solid var(--neon-cyan); box-shadow: 4px 4px 0 var(--neon-pink); image-rendering: pixelated;
}
@media (max-width: 700px) {
  .qrbox { position: static; margin: 0 auto 1vh; } /* stack on narrow screens */
}
.qrlabel { font-size: clamp(0.4rem, 1vw, 0.55rem); color: var(--neon-green); letter-spacing: 1px; }
.qrurl { font-size: 0.42rem; color: var(--neon-cyan); word-break: break-all; max-width: 150px; text-align: center; line-height: 1.5; }
.titleblock { text-align: center; }

/* ============ NEW LAYOUT: stage width + bottom leaderboard ============ */
.stage { width: min(1000px, 94vw); margin: 0 auto; }

.scorebar {
  z-index: 10; width: min(1180px, 96vw); margin: 2.5vh auto 0; border-top: 3px solid var(--neon-purple); padding-top: 1.4vh;
}
.scorebar h2 { font-size: clamp(0.55rem, 1.3vw, 0.85rem); color: var(--neon-yellow); margin-bottom: 1em; letter-spacing: 1px; }
.scorebar h2 .live { color: var(--neon-green); font-size: 0.5rem; margin-left: 0.6em; animation: blink 1s steps(1) infinite; }
.chips { list-style: none; display: flex; flex-wrap: wrap; gap: 0.7em; }
.chips li {
  display: flex; align-items: center; gap: 0.55em; font-size: clamp(0.5rem, 1.1vw, 0.62rem); line-height: 1.6;
  padding: 0.7em 0.9em; border: 2px solid var(--neon-cyan); background: rgba(0,240,255,0.06);
}
.chips li.lead { border-color: var(--neon-yellow); background: rgba(255,216,0,0.1); box-shadow: 0 0 14px rgba(255,216,0,0.5); }
.chips li.empty { border: none; background: none; color: var(--neon-purple); }
.chips .rk { color: var(--neon-yellow); }
/* Podium ranks — plain glyphs + color, since the Pi kiosk has no emoji font. */
.chips .rk.gold { color: #ffd800; text-shadow: 0 0 8px rgba(255, 216, 0, 0.8); }
.chips .rk.silver { color: #cfd8e3; text-shadow: 0 0 8px rgba(207, 216, 227, 0.8); }
.chips .rk.bronze { color: #cd8032; text-shadow: 0 0 8px rgba(205, 128, 50, 0.8); }
.chips .h { color: var(--neon-cyan); max-width: 9em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chips .cc { color: var(--neon-green); }
.chips .ic { color: var(--neon-red); }
.chips .p { color: var(--neon-yellow); min-width: 2.6em; text-align: right; }
.chips .p.neg { color: var(--neon-red); }

/* ============================================================
   FILL THE SCREEN — big-display layout.
   The display (index.html) is meant for a TV / Pi kiosk, so let
   the stage grow to fill the viewport, widen the content, and
   scale the type up. (play.html has its own inline styles and is
   unaffected by anything in this file.)
   ============================================================ */
/* Type is sized by viewport HEIGHT (vh), not width — height is what constrains
   fit, so 1920x1080 and 2560x1080 (ultrawide) render identically instead of the
   text ballooning on wide screens and overflowing into the timer/leaderboard. */
header.topbar { flex: 0 0 auto; margin: 0.4vh 0 1vh; }
.title { font-size: clamp(1.6rem, 5.4vh, 4rem); }

/* stage spans the screen and grows to fill the vertical space; its content is
   vertically centered so the block sits evenly in the available height. */
.stage {
  width: min(1800px, 96vw);
  flex: 1 0 auto;          /* grow to fill, but never shrink below content */
  justify-content: center;
  gap: 1.8vh;
}

/* category tag + round/difficulty/Q stats, centered as one line under the title */
.catbar { font-size: clamp(0.7rem, 2.4vh, 1.3rem); flex: 0 0 auto; justify-content: center; gap: 1.2em; }
.category { border-width: 4px; }
.qnum { text-align: center; }

.question {
  font-size: clamp(1rem, 3.5vh, 2.2rem);
  line-height: 1.55;
  padding: 0.8em 1.1em;
  min-height: 0;
  flex: 0 0 auto;
  max-height: 44vh;
  overflow: auto;
}

/* answer tiles: natural height (no forced stretch — that overlapped the timer) */
.answers { flex: 0 0 auto; gap: 1.6vh 2vw; }
.answer {
  font-size: clamp(0.85rem, 3.1vh, 1.9rem);
  padding: 0.7em 1.1em;
}

/* timer + bot speech scale by height too */
.statusbar { gap: 2vw; flex: 0 0 auto; }
.timerlabel { font-size: clamp(0.7rem, 2.2vh, 1.2rem); }
.timerbar { height: clamp(20px, 2.6vh, 40px); }
.timernum { font-size: clamp(1.1rem, 4vh, 2.4rem); }
.bot-say { font-size: clamp(0.7rem, 2.4vh, 1.3rem); min-height: 0; flex: 0 0 auto; }

/* leaderboard spans the width with larger chips */
.scorebar { width: min(1800px, 96vw); flex: 0 0 auto; margin: 1.2vh auto 0; }
.scorebar h2 { font-size: clamp(0.7rem, 2vh, 1.1rem); margin-bottom: 0.5em; }
.chips li { font-size: clamp(0.55rem, 1.7vh, 0.95rem); padding: 0.6em 0.9em; }
.chips .h { max-width: 14em; }

/* bigger QR so it scans from across the room */
.qrimg { width: clamp(96px, 10vw, 190px); }
