/* Quiz (Slice 3) — activity styles.
   The leaderboard and podium blocks are copied verbatim from
   reflex.css (the reveal choreography is shared visual language);
   everything else is quiz-specific. */

/* ===================== copied verbatim from reflex.css ===================== */

/* The leaderboard and podium (C7/C8) live in css/base.css — one shared
   implementation for every activity's host screen (Slice 4). The shared
   down-arrow red is the value BOTH activities rendered at runtime (the
   source-level divergence was shadowed — see SLICE4_AUDIT §5.1). */

/* ===================== quiz-specific ===================== */

/* ---------- option letter badges (A-F, the answer identity) ----------
   The letter is the identity; the colour is decoration only — with
   colours suppressed every option is still identifiable by its letter.
   One badge palette, shared by every surface (editor, projector, phone,
   reveal); a future skin overrides these tokens and recolours for free. */

.opt-letter {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: var(--radius-letter);
  font-weight: 900;
  font-size: 0.95rem;
  color: var(--color-on-primary);
}

.opt-letter-a { background: var(--answer-a); }
.opt-letter-b { background: var(--answer-b); }
.opt-letter-c { background: var(--answer-c); }
.opt-letter-d { background: var(--answer-d); }
.opt-letter-e { background: var(--answer-e); }
.opt-letter-f { background: var(--answer-f); }

/* ---------- host: question display ---------- */

.quiz-host {
  width: 100%;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.qh-top {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.qh-qno { font-size: 1.1rem; font-weight: 900; color: var(--color-text); }
.qh-podium-title { font-size: 1.35rem; font-weight: 900; color: var(--color-accent); }
.qh-top-controls { display: flex; gap: 0.6rem; }

.qh-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  overflow: hidden;
}

.qh-timer {
  flex: none;
  font-size: clamp(2.2rem, 9vh, 4.2rem);
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--color-accent);
  line-height: 1;
}

.qh-timer.low { color: var(--color-danger); }

/* (the host total-answered footer was removed by the owner correction
   2026-09-13b: no "N answered" total is shown on the projector) */

.qh-text {
  flex: none;
  font-size: clamp(1.3rem, 4.5vh, 2rem);
  font-weight: 900;
  text-align: center;
  color: var(--color-text);
}

.qh-opts {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  justify-content: center;
}

.qh-opt {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.7rem;
  background: var(--color-surface-control);
  border: var(--border-width-card) solid var(--color-border-row);
  border-radius: var(--radius-tile);
  padding: 0.55rem 0.9rem;
  overflow: hidden;
}

.qh-opt.correct {
  border-color: var(--color-success);
  background: var(--color-success-soft);
}

.qh-opt-text {
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--color-text);
  display: flex;
  justify-content: space-between;
}

/* In-place reveal marks (owner brief 2026-09-21): the card's geometry
   never changes - only its treatment. The correct card keeps full
   strength and gains a tick; every incorrect card darkens and gains a
   cross. */
.qh-mark {
  display: none;
  margin-left: auto;
  padding-left: 0.6rem;
  font-weight: 900;
  font-size: 1.5em;
  line-height: 1;
}
.qh-opt.correct .qh-mark { display: block; color: #FFFFFF; }
/* Owner correction 2026-09-23 (M1): the cross is the non-colour "wrong"
   signal and must read from across a room - dark ink on a lightly muted
   card, never a faint white glyph on a darkened one. */
.qh-opt.incorrect .qh-mark { display: block; color: #20242C; }
.qh-revealed .qh-opt.correct { box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.55); }
.qh-revealed .qh-opt.incorrect { filter: saturate(0.35) brightness(0.92); opacity: 0.92; }

.qh-ready {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 900;
  color: var(--color-text);
  background: var(--color-scrim-ink);
  border-radius: var(--radius-button);
  z-index: 5;
}

/* The shared bomb countdown plays over the question-read screen: the
   same overlay moment reflex-host has, with the question dimmed behind
   the 3-2-1 (kb-* styles live in css/base.css). */
.qh-bombbox {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: var(--color-scrim-ink);
  border-radius: var(--radius-button);
  z-index: 5;
}

@keyframes qh-cd-pop {
  from { transform: scale(1.4); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* W5: TIME'S UP replaces the 0.0 in the timer slot itself. */
.qh-timer.timesup {
  font-size: clamp(1.8rem, 6vh, 3rem);
  color: var(--color-danger);
  white-space: nowrap;
}

/* ---------- screen 1: the countdown (owner fix) ----------
   The announce is the shared bomb's own moment — the question and the
   answers appear only AFTER the countdown, never behind it. */

/* ---------- player: nothing before GO (owner fix) ----------
   During the countdown the phone shows only the announce overlays: the
   question text and the answer tiles stay hidden until the GO flash,
   even when the visibility toggles would otherwise show them. */
.qz-stage.pre-go .qz-text,
.qz-stage.pre-go .qz-options { display: none; }

/* ---------- the in-place answer distribution chart ----------
   The space between the question and the answer cards (owner brief
   2026-09-21): one column per answer with the player count, the exact
   percentage of submitted answers, the bar in the answer's own colour,
   the A-F letter, and the tick on the correct bar. Hidden until the
   authoritative reveal; the card geometry is untouched. */

.qh-chart-space {
  position: relative;
  align-self: stretch;   /* the stage centres its children; the reserve spans the width */
  flex: 1 1 auto;
  min-height: 0;
}

.qh-chart {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: none;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(8px, 1vw, 18px);
}

.qh-chart.qh-chart-live { display: flex; }

.qh-chart::after {
  /* the baseline the bars stand on (the prototype's rule) */
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--qh-bar-letter-h, 34px);
  height: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.88);
}

.qh-bar-col {
  position: relative;
  z-index: 1;
  height: 100%;
  flex: 1 1 0;
  max-width: 8.2vw;
  display: grid;
  grid-template-rows: auto 1fr auto;
  align-items: end;
}

.qh-bar-stat {
  align-self: end;
  padding-bottom: 0.5rem;
  color: #FFFFFF;
  text-align: center;
  font-weight: 900;
  font-size: clamp(13px, 1.05vw, 20px);
  line-height: 1.08;
  text-shadow: 0 2px 0 rgba(103, 40, 24, 0.35);
  white-space: nowrap;
}

.qh-bar-stat strong { display: block; margin-top: 0.18rem; font-size: 1.32em; }

.qh-bar-track {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.qh-bar-fill {
  width: 100%;
  min-height: 10px;
  border: 2px solid rgba(255, 255, 255, 0.82);
  border-bottom: 0;
  border-radius: 6px 6px 0 0;
  background: var(--qh-bar-color, #FFF7ED);
}

.qh-bar-col.correct .qh-bar-fill { box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.6); }

.qh-bar-tick {
  position: absolute;
  left: 50%;
  bottom: 6px;
  transform: translateX(-50%);
  color: #FFFFFF;
  font-weight: 900;
  font-size: clamp(22px, 2.6vw, 52px);
  line-height: 1;
  text-shadow: 0 2px 0 rgba(32, 36, 44, 0.4);
}

.qh-bar-letter {
  align-self: end;
  color: #FFFFFF;
  text-align: center;
  font-weight: 900;
  font-size: clamp(16px, 1.6vw, 30px);
  line-height: 1;
}

/* The quiz's scoreboard shell (.qh-lb, .qh-lb-title, .qh-instruction,
   .qh-lb-rows, .qh-lb-empty) lives in css/base.css with the rest of the
   shared leaderboard rules (Slice 4) — one copy, used by every
   activity's host screen. */

/* ---------- host: setup / authoring ---------- */

.qz-setup {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.qs-title { margin: 0; font-size: 1.4rem; font-weight: 900; color: var(--color-accent); }

.qs-list { display: flex; flex-direction: column; gap: 0.75rem; }

.qs-row {
  background: var(--color-surface);
  border: var(--border-width-card) solid var(--color-border);
  border-radius: var(--radius-button);
  padding: 0.8rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.qs-head { display: flex; align-items: center; gap: 0.5rem; }
.qs-label { font-weight: 900; color: var(--color-accent); flex: 1; }

.qs-btn {
  border: none;
  background: var(--color-surface-track);
  color: var(--color-text);
  width: 1.8rem;
  height: 1.8rem;
  border-radius: var(--radius-letter);
  font-weight: 900;
  cursor: pointer;
}

.qs-btn:hover { background: var(--color-surface-ctrl-hover); }

.qs-text {
  font-size: 1.05rem;
  font-weight: 700;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-tile-small);
  border: var(--border-width-card) solid var(--color-border-input);
  background: var(--color-surface-control);
  color: var(--color-text);
  width: 100%;
}

.qs-opts { display: flex; flex-direction: column; gap: 0.4rem; }

.qs-opt {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.qs-opt input[type="checkbox"] { width: 1.3rem; height: 1.3rem; accent-color: var(--color-success); flex: none; }

/* Owner amendment: soft character limits. Each field carries a remaining
   counter at its upper-right and an error line beneath; typing and paste
   are never shortened or blocked. */
.qs-text-field,
.qs-opt-field {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.qs-count {
  display: block;
  text-align: right;
  font-size: 0.72rem;
  font-weight: 800;
  line-height: 1.35;
  color: var(--color-text-quiet);
  font-variant-numeric: tabular-nums;
}

.qs-count.qs-count-over { color: var(--color-danger); }

.qs-field-error {
  display: block;
  text-align: right;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1.35;
  color: var(--color-danger);
}

.qs-field-error.hidden { display: none; }

.qs-text[aria-invalid="true"],
.qs-opt-text[aria-invalid="true"] { border-color: var(--color-danger); }

.qs-opt-text {
  flex: 1;
  font-size: 0.95rem;
  padding: 0.45rem 0.6rem;
  border-radius: var(--radius-input);
  border: var(--border-width-card) solid var(--color-border-muted);
  background: var(--color-surface-control);
  color: var(--color-text);
}

.qs-addopt { align-self: flex-start; }

/* Per-question warnings appear AT the question (owner fix): a quiet red
   line inside the card, never the bottom strip. */
.qs-row-error {
  margin: 0;
  color: var(--color-danger-soft);
  font-size: 0.85rem;
  font-weight: 700;
  min-height: 1.2em;
}

/* Persistent validation problems (character limits) for the
   question; the row itself gets a red edge until they are fixed. */
.qs-row-problems {
  margin: 0;
  color: var(--color-danger);
  font-size: 0.82rem;
  font-weight: 800;
}

.qs-row-problems.hidden { display: none; }

.qs-row.qs-row-invalid { border-color: var(--color-danger); }

/* The quiz's own player-screen settings (owner change): a card at the
   bottom of the editor, after the add-question buttons. Saved with the
   quiz — every quiz can carry its own values. */
.qs-visibility {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  background: var(--color-surface);
  border: var(--border-width-card) solid var(--color-border);
  border-radius: var(--radius-button);
  padding: 0.9rem 1rem;
}

.qs-visibility-title {
  font-size: 1.05rem;
  font-weight: 900;
  color: var(--color-text);
}

.qs-visibility-sub {
  font-size: 0.85rem;
  color: var(--color-text-quiet);
  margin-top: -0.35rem;
}

/* W4: Time limit and Points are each a labelled, full-width control with
   room around it — never cramped inline fields. */
.qs-foot {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--color-text-soft);
}

.qs-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  width: 100%;
}

.qs-field-label {
  font-size: 0.85rem;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-quiet);
}

.qs-field select {
  width: 100%;
  font-size: 1rem;
  padding: 0.55rem 0.6rem;
  border-radius: var(--radius-tile-small);
  border: var(--border-width-card) solid var(--color-border-muted);
  background: var(--color-surface-control);
  color: var(--color-text);
  min-height: 2.9rem;
}

.qs-field select option { color: var(--color-on-primary); }

.qs-field .qs-applyall { align-self: flex-start; }

.qs-actions { display: flex; gap: 0.6rem; flex-wrap: wrap; }

.qs-error { margin: 0; color: var(--color-danger-soft); font-weight: 600; min-height: 1.4em; }

.qs-hint {
  margin: 0;
  font-size: 0.9rem;
  color: var(--color-text-quiet);
}

/* ---------- player ---------- */

.quiz-player {
  width: 100%;
  max-width: 24rem;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.qz-top { display: flex; align-items: center; justify-content: space-between; }
.qz-question-no { font-weight: 900; color: var(--color-text); }
.qz-timer { font-size: 1.6rem; font-weight: 900; font-variant-numeric: tabular-nums; color: var(--color-accent); }
.qz-timer.low { color: var(--color-danger); }

.qz-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.qz-text {
  font-size: 1.35rem;
  font-weight: 900;
  color: var(--color-text);
  text-align: center;
}

.qz-options { display: flex; flex-direction: column; gap: 0.6rem; }

.qz-option {
  font-size: 1.15rem;
  font-weight: 800;
  padding: 0.8rem 1rem;
  border: var(--border-width-input) solid var(--color-border-strong);
  border-radius: var(--radius-button);
  background: var(--color-surface-input);
  color: var(--color-text);
  cursor: pointer;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  transition: transform 0.06s ease, background 0.12s ease, border-color 0.12s ease;
}

.qz-option-text { flex: 1; }

.qz-option:active { transform: scale(0.98); }

.qz-option.selected {
  border-color: var(--color-focus);
  background: var(--color-selection-soft);
}

.qz-option:disabled { cursor: default; }

.qz-ready {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  font-weight: 900;
  color: var(--color-text);
  background: var(--color-scrim-ink-soft);
  border-radius: var(--radius-button);
  z-index: 5;
}

.qz-countdown {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-scrim-ink-soft);
  border-radius: var(--radius-button);
  z-index: 5;
}

.qz-countdown b {
  font-size: 6rem;
  font-weight: 900;
  color: var(--color-accent);
  animation: qh-cd-pop 0.9s ease both;
}

.qz-go {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 4rem;
  font-weight: 900;
  color: var(--color-accent);
  z-index: 6;
  animation: qh-cd-pop 0.7s ease both;
  pointer-events: none;
}

/* Owner correction 2026-09-22: the legacy phone countdown/GO animations
   are part of the complete Quiz flow and must honour reduced motion. The
   reduced state is the FINAL visible composition, not a shorter pop. */
@media (prefers-reduced-motion: reduce) {
  .qz-countdown b,
  .qz-go { animation: none; }
}

.qz-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  /* Owner correction 2026-09-22: the result message must be readable.
     The old 60% scrim let the question and answer cards compete with
     "Correct!", the selected answer, points and the waiting line. The
     deep ink scrim is the approved gameplay value (same family as the
     Reflex result overlay); the approved phone layout is untouched. */
  background: var(--color-scrim-stage-deep);
  border-radius: var(--radius-button);
  z-index: 5;
  text-align: center;
}

.qz-big { font-size: 1.7rem; font-weight: 900; color: var(--color-text); }
.qz-big.gold { color: var(--medal-gold); }
.qz-big.correct { color: var(--color-success); }
.qz-big.wrong { color: var(--color-danger); }
.qz-answer-text { font-size: 1.05rem; font-weight: 700; color: var(--color-text); overflow-wrap: anywhere; }
.qz-time { font-size: 1.3rem; font-weight: 900; color: var(--color-text); font-variant-numeric: tabular-nums; }
.qz-sub { font-size: 1rem; color: var(--color-text-muted); }

/* =====================================================================
   APPROVED PHONE REVEAL + FINAL (owner correction 2026-09-23, B1).
   The reveal and the final are their OWN full-screen coral compositions
   (answer reveal option B player column; Leaderboard main player
   column). The dead question/answer grid is hidden - never a dark box
   laid over a ghosted question, never a selection mark or points.
   ===================================================================== */
body.game-shell-live.game-shell-player .qz-stage.qz-result-mode .qz-top,
body.game-shell-live.game-shell-player .qz-stage.qz-result-mode .qz-text,
body.game-shell-live.game-shell-player .qz-stage.qz-result-mode .qz-options,
body.game-shell-live.game-shell-player .qz-stage.qz-result-mode .qz-pending { display: none; }
body.game-shell-live.game-shell-player .qz-stage.qz-result-mode .qz-overlay {
  background: transparent;
  gap: clamp(10px, 2vh, 16px);
}
body.game-shell-live.game-shell-player .qz-result-icon {
  width: clamp(84px, 26vw, 108px);
  height: clamp(84px, 26vw, 108px);
  border-radius: 50%;
  background: #FFF7ED;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(2.4rem, 9vw, 3.2rem);
  font-weight: 900;
  line-height: 1;
  box-shadow: 0 10px 24px rgba(140, 28, 8, 0.3);
}
body.game-shell-live.game-shell-player .qz-result-icon.correct { color: #3E9B47; }
body.game-shell-live.game-shell-player .qz-result-icon.wrong { color: #E5432A; }
body.game-shell-live.game-shell-player .qz-big.correct,
body.game-shell-live.game-shell-player .qz-big.wrong {
  color: #FFFFFF;
  font-size: clamp(1.9rem, 7.4vw, 2.4rem);
}
body.game-shell-live.game-shell-player .qz-correct-pill {
  background: #FFD43B;
  color: #20242C;
  font-weight: 800;
  font-size: clamp(0.95rem, 4vw, 1.1rem);
  padding: 0.5rem 1.1rem;
  border-radius: 999px;
  max-width: 100%;
  overflow-wrap: anywhere;
}
body.game-shell-live.game-shell-player .qz-big-screen {
  color: #FFFFFF;
  font-weight: 800;
  font-size: clamp(1rem, 4.4vw, 1.2rem);
}
body.game-shell-live.game-shell-player .qz-stage.qz-result-mode .qz-sub { color: rgba(255, 255, 255, 0.85); }
/* (the rank/points classes were removed with the owner correction
   2026-09-23: the player completion is receipt-only.) */
body.game-shell-live.game-shell-player .qz-final-line {
  color: #FFFFFF;
  font-weight: 700;
  font-size: clamp(1rem, 4.4vw, 1.2rem);
}

/* =====================================================================
   Batch 8 — QUIZ GAMEPLAY: CLASSIC GAME GRID (activity-owned).
   Host + player active-question presentation inside the frozen Batch 7
   coral shell. These rules are QUIZ-specific; the shared shell stylesheet
   never names .qh-* / .qz-*. body.game-shell-live is only a context.
   ===================================================================== */

/* Batch 8 correction: the timer and Next form ONE band placed below the
   genuine logo (12px clear of it), and the activity content starts below
   that band so the timer/Next can never intersect the question or grid.
   The logo itself is untouched - only its exposed geometry is used. */
body.game-shell-live.game-shell-host {
  --gs-band-top: calc(var(--gs-logo-bottom) + 12px);
  --gs-timer-top: var(--gs-band-top);
  --gs-action-top: var(--gs-band-top);
  --gs-content-top: calc(var(--gs-band-top) + clamp(52px, 8vh, 96px) + 8px);
}

/* Owner amendment 2026-09-11: the active question lives in the shell's
   aligned timer | question | Next row. The content region starts below the
   COMPLETE row (the shell measures it into --gs-band-h), so a two-line
   question pushes the answer area down instead of overlapping it. */
body.game-shell-live.game-shell-host .gs-root.gs-band-live {
  --gs-content-top: calc(var(--gs-band-top) + var(--gs-band-h, clamp(52px, 8vh, 96px)) + 8px);
}

/* ---------- HOST: hero fills the shell content region ---------- */
body.game-shell-live.game-shell-host .quiz-host {
  width: 100%;
  height: 100%;
  gap: clamp(0.6rem, 1.6vh, 1.2rem);
}

/* The primary progression button lives in the shell's action slot; this
   top bar carries only activity-owned SECONDARY controls (Back / Podium /
   Session summary), aligned left so it never collides with the primary. */
body.game-shell-live.game-shell-host .quiz-host .qh-top {
  justify-content: flex-start;
  gap: 0.6rem;
}
body.game-shell-live.game-shell-host .quiz-host .qh-qno { display: none; }
body.game-shell-live.game-shell-host .quiz-host .qh-top-controls { flex-wrap: wrap; }

body.game-shell-live.game-shell-host .quiz-host .qh-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(0.9rem, 2.4vh, 2rem);
}

/* the question is the hero (real saved text, capped at 120 chars, wraps).
   Owner amendment 2026-09-11: on the ACTIVE host screen the question sits
   in the shell's aligned timer | question | Next row, so the same type
   rules must match it inside .gs-band-center as well as the in-stage
   fallback (shell absent / non-band screens). */
body.game-shell-live.game-shell-host .quiz-host .qh-text,
body.game-shell-live.game-shell-host .gs-band-center > .qh-text {
  flex: none;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2rem, 5.4vh, 3.6rem);
  line-height: 1.08;
  color: #FFFFFF;
  text-align: center;
  max-width: min(76vw, 1180px);
  text-wrap: balance;
  overflow-wrap: anywhere;
  text-shadow: 0 3px 0 rgba(150, 32, 8, 0.28);
}
/* inside the row the question can only use the centre cell */
body.game-shell-live.game-shell-host .gs-band-center > .qh-text { max-width: 100%; }
body.game-shell-live.game-shell-host .quiz-host .qh-text.qh-q-long,
body.game-shell-live.game-shell-host .gs-band-center > .qh-text.qh-q-long { font-size: clamp(1.7rem, 4.4vh, 2.9rem); }
body.game-shell-live.game-shell-host .quiz-host .qh-text.qh-q-xl,
body.game-shell-live.game-shell-host .gs-band-center > .qh-text.qh-q-xl { font-size: clamp(1.4rem, 3.6vh, 2.3rem); }

/* the answer grid is the dominant element; 2-6 answers by option count.
   Owner correction 2026-09-13b: the stage has THREE deliberate regions -
   the header lives in the shell band, the MIDDLE is reserved for the reveal
   chart (`#qh-chart-space`, empty and coral during the question), and the
   answer cards are locked to the bottom. Card geometry depends on the option
   count and the viewport only - never on answer length - so every card in a
   question is identical and the eventual reveal never moves them. ALWAYS two
   columns, row-major: 3 = 4 minus D and 5 = 6 minus F with the final odd
   card in the LEFT column (never centred/stretched) and the empty slot left
   as background. */
body.game-shell-live.game-shell-host .quiz-host .qh-stage {
  --qh-chart-min: clamp(216px, 30vh, 340px);
}
/* the active question stage keeps a 4px bottom inset so the last card's
   complete border box sits clear of the clip edge (owner correction b19) */
body.game-shell-live.game-shell-host .quiz-host .qh-stage.qh-stage-chart { padding-bottom: 4px; }
body.game-shell-live.game-shell-host .quiz-host .qh-chart-space {
  position: relative;
  align-self: stretch;   /* the stage centres its children; the reserve spans the width */
  flex: 1 1 auto;
  min-height: var(--qh-chart-min);
}
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) {
  flex: 0 0 auto;
  /* owner correction b22: the grid fills the bounded centred content column
     (the panel-equivalent); the freed side space is viewport margin + the
     approved confetti. Column gap = the reference's 1.18% of the column;
     the row gap stays vh-based because it is vertical budget. */
  width: 100%;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: var(--qh-card-h);
  column-gap: clamp(10px, calc(var(--qz-content-w) * 0.0118), 22px);
  row-gap: clamp(8px, 1.2vh, 16px);
}
/* locked card heights per option count and viewport (2 larger, 3 = 4, 5 = 6).
   Owner correction b19: the rows follow the selected mockup's reference
   proportions (5/6 rows ~ reference-scaled height) so the reserved chart
   middle is prominent; the vertical padding was tightened as a spacing
   adjustment so the floor-safe text still fits the shorter rows. */
body.game-shell-live.game-shell-host .quiz-host #qh-opts[data-n="2"] { --qh-card-h: clamp(160px, 20.5vh, 280px); }
body.game-shell-live.game-shell-host .quiz-host #qh-opts[data-n="3"],
body.game-shell-live.game-shell-host .quiz-host #qh-opts[data-n="4"] { --qh-card-h: clamp(104px, 13.5vh, 170px); }
body.game-shell-live.game-shell-host .quiz-host #qh-opts[data-n="5"],
body.game-shell-live.game-shell-host .quiz-host #qh-opts[data-n="6"] { --qh-card-h: clamp(81.8px, 11vh, 130px); }

body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt {
  display: flex;
  align-items: center;
  gap: clamp(0.8rem, 1.6vw, 1.6rem);
  /* owner correction b19: tightened vertical padding (spacing adjustment)
     keeps the floor-safe text inside the reference-scaled rows */
  padding: clamp(10px, 1.5vh, 24px) clamp(18px, 2.2vw, 40px);
  border: 4px solid #FFF7ED;
  border-radius: clamp(14px, 1.6vw, 22px);
  box-shadow: 0 6px 0 rgba(32, 36, 44, 0.32);
  color: #FFFFFF;
  font-weight: 800;
  cursor: default;
  overflow: hidden;
}
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-letter {
  flex: none;
  font-size: clamp(2rem, 4.8vh, 3.4rem);
  font-weight: 900;
  line-height: 1;
  min-width: 1.15em;
  text-align: center;
  /* inherit the CARD's colour (C/D are Dark Ink) */
  color: inherit;
}
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt-text {
  flex: 1;
  display: block;
  /* Owner amendment 2026-09-11: a deliberate STARTING scale by option
     count (2 largest, 3-4 slightly smaller, 5-6 slightly smaller again),
     responsive to the viewport. The uniform fit steps every answer in a
     question down together only when the text needs it; the min() values
     are PROVISIONAL responsive floors pending the owner's visual sign-off
     (samples in Screenshots/Quiz-Character-Limits/projector/). */
  font-size: clamp(1.3rem, 2.6vw, 2.1rem);
  font-weight: 800;
  /* 1.32 keeps the glyph box inside the text box for the approved Nunito
     Sans metrics (smaller line-heights leave a 2px scrollHeight overflow) */
  line-height: 1.32;
  overflow-wrap: anywhere;
  /* inherit the CARD's colour - never a fixed white that would defeat
     the Dark Ink cards (C yellow, D cream) */
  color: inherit;
}
body.game-shell-live.game-shell-host .quiz-host .qh-opts-2:not(.qh-opts-reveal) .qh-opt-text { font-size: clamp(22px, 2.9vw, 46px); }
body.game-shell-live.game-shell-host .quiz-host .qh-opts-3:not(.qh-opts-reveal) .qh-opt-text { font-size: clamp(21px, 2.6vw, 42px); }
body.game-shell-live.game-shell-host .quiz-host .qh-opts-4:not(.qh-opts-reveal) .qh-opt-text { font-size: clamp(20px, 2.4vw, 38px); }
body.game-shell-live.game-shell-host .quiz-host .qh-opts-5:not(.qh-opts-reveal) .qh-opt-text { font-size: clamp(19px, 2.2vw, 34px); }
body.game-shell-live.game-shell-host .quiz-host .qh-opts-6:not(.qh-opts-reveal) .qh-opt-text { font-size: clamp(18px, 2.1vw, 32px); }
/* owner close-out: the Quiz Next keeps its approved Sunshine Yellow surface
   and Dark Ink label when disabled — no colour-distorting filter, no
   opacity drift. The shell moves the button into its action slot, so this
   override deliberately does NOT live under .quiz-host. Quiz scope only:
   the shared shell rule and the frozen lobby are untouched. */
/* Owner brief 2026-09-21: the projector Next is a NORMAL yellow KaBoomz
   button - no thick white outline, no drop shadow (the prototype's
   treatment). The shell's white 4px rim and layered shadow are released
   for the quiz Next only; geometry (slot width/height) is untouched. */
body.game-shell-live .gs-root .gs-action > #qh-next {
  background: #FFD43B;
  color: #20242C;
  border: 0;
  box-shadow: none;
}
body.game-shell-live .gs-root .gs-action > #qh-next:disabled {
  filter: none;
  opacity: 1;
  box-shadow: none;
}
/* owner close-out: real host Quiz Next busy state (the only Next that sends
   a request). Label keeps its box (transparent), one centred spinner,
   solid yellow surface, geometry stable. */
body.game-shell-live .gs-root .gs-action > #qh-next { position: relative; }
body.game-shell-live .gs-root .gs-action > #qh-next.loading { color: transparent !important; }
body.game-shell-live .gs-root .gs-action > #qh-next.loading::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 22px; height: 22px;
  margin: -11px 0 0 -11px;
  border-radius: 50%;
  border: 3px solid rgba(32, 36, 44, 0.25);
  border-top-color: #20242C;
  animation: qh-next-spin 0.8s linear infinite;
}
@keyframes qh-next-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  body.game-shell-live .gs-root .gs-action > #qh-next.loading::after { animation: none; }
}
/* owner final order 2026-09-12b: same A-F order as the player (A green,
   B blue, C yellow, D cream, E purple, F pink); scoped Quiz answer-palette
   trial; all six host cards carry Dark Ink text/labels. */
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt:nth-child(1) { background: #7ED957; color: #20242C; }
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt:nth-child(2) { background: #21C4F3; color: #20242C; }
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt:nth-child(3) { background: #FFD43B; color: #20242C; }
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt:nth-child(4) { background: #FFF7ED; color: #20242C; }
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt:nth-child(5) { background: #A78BFA; color: #20242C; }
body.game-shell-live.game-shell-host .quiz-host .qh-opts:not(.qh-opts-reveal) .qh-opt:nth-child(6) { background: #F472B6; color: #20242C; }

/* length classes no longer size the answer text: the answer grid is
   count-specific and the uniform font fit in quiz-host.js steps every
   answer in a question down together when needed (never below the
   projector readability floor). Cards never clip and the host never
   scrolls. */

/* (the host total-answered footer was removed by the owner correction
   2026-09-13b: no "N answered" total is shown on the projector) */

/* Answers are never hidden during gameplay (owner decision 2026-09-11).
   Admission is counts-only (owner decision 2026-09-17); the runtime keeps
   the uniform fit at the readability floor and never hides an answer. */

/* Owner handoff 2026-09-13: the old narrow-viewport two-column fallback for
   5/6 options was deleted with the legacy grids - the active grid is ALWAYS
   two columns now, on every supported host size. */

/* ---------- HOST timer: cream surface, clock, seconds, s suffix ---------- */
body.game-shell-live.game-shell-host .gs-timer > #qh-timer {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-size: clamp(1.6rem, 3.4vh, 2.4rem);
  min-height: clamp(52px, 8vh, 96px);
  box-sizing: border-box;
}
body.game-shell-live.game-shell-host .gs-timer > #qh-timer .qh-clock { width: 1em; height: 1em; flex: none; color: #FF6B4A; }
body.game-shell-live.game-shell-host .gs-timer > #qh-timer .qh-timer-num { font-weight: 900; font-variant-numeric: tabular-nums; }
body.game-shell-live.game-shell-host .gs-timer > #qh-timer .qh-timer-s { font-size: 0.55em; font-weight: 800; }
body.game-shell-live.game-shell-host .gs-timer > #qh-timer.low { color: #E5432A; }
body.game-shell-live.game-shell-host .gs-timer > #qh-timer.low .qh-clock { color: #E5432A; }
body.game-shell-live.game-shell-host .gs-timer > #qh-timer.timesup { color: #E5432A; }

/* ---------- HOST final results (top-10 composition) ----------
   Owner correction 2026-09-21: the default Final Results screen shows
   places 1-3 as the large centred podium and places 4-10 in the shared
   leaderboard rows directly below, all inside one projector viewport.
   The title reads from the back of a venue. */
body.game-shell-live.game-shell-host .quiz-host .qh-podium-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.6rem, 3.6vh, 3rem);
  color: #FFFFFF;
  text-shadow: 0 3px 0 rgba(150, 32, 8, 0.28);
}
body.game-shell-live.game-shell-host .quiz-host .qh-final-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 1.6vh, 20px);
  width: 100%;
}
/* Owner correction 2026-09-22: the Final Results composition starts a
   small responsive gap below the visible logo (no empty band). The host
   content top normally reserves the band row; the podium screen has no
   band, so it reuses that space for the podium and leaderboard. */
body.game-shell-live.game-shell-host .gs-content:has(.qh-final-stage) {
  --gs-content-top: calc(var(--gs-logo-bottom) + clamp(12px, 1.6vh, 20px));
}
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium {
  flex: none;
  width: min(100%, 1080px);
  height: clamp(150px, 26vh, 300px);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(14px, 1.6vw, 34px);
}
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium .podium-slot {
  flex: 0 1 clamp(130px, 21vw, 320px);
  max-width: 320px;
  padding: clamp(10px, 1.6vh, 22px) clamp(8px, 1vw, 18px) 0;
}
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium .podium-slot.first { height: clamp(150px, 26vh, 300px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium .podium-slot.second { height: clamp(120px, 19.5vh, 225px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium .podium-slot.third { height: clamp(100px, 15vh, 175px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium .ps-place { font-size: clamp(13px, 1.1vw, 22px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium .ps-name { font-size: clamp(16px, 1.5vw, 30px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-podium .ps-time { font-size: clamp(14px, 1.25vw, 26px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-rows {
  flex: none;
  width: min(100%, 1080px);
  display: flex;
  flex-direction: column;
  gap: clamp(3px, 0.7vh, 9px);
}
body.game-shell-live.game-shell-host .quiz-host .qh-final-rows .rh-lb-row {
  flex: 0 0 auto;
  height: clamp(26px, 4.2vh, 54px);
  padding: 0 clamp(10px, 1.1vw, 20px);
}
body.game-shell-live.game-shell-host .quiz-host .qh-final-rows .rh-lb-row .lb-rank { font-size: clamp(15px, 1.25vw, 26px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-rows .rh-lb-row .lb-name { font-size: clamp(15px, 1.35vw, 28px); }
body.game-shell-live.game-shell-host .quiz-host .qh-final-rows .rh-lb-row .lb-time { font-size: clamp(15px, 1.25vw, 26px); }
/* three or fewer players: the podium is the whole screen (no empty rail) */
body.game-shell-live.game-shell-host .quiz-host .qh-final-stage.qh-final-nolist .qh-final-podium { height: auto; }
body.game-shell-live.game-shell-host .quiz-host .qh-final-empty {
  flex: none;
  color: #FFFFFF;
  font-weight: 800;
  font-size: clamp(16px, 1.6vw, 28px);
  text-shadow: 0 2px 0 rgba(150, 32, 8, 0.3);
}

/* ---------- HOST in-place reveal ----------
   The reveal happens on the SAME screen: the cards keep their locked
   geometry (only treatment + mark change) and the chart lives in the
   reserved middle. Projector-scale type for the counts/percentages. */
body.game-shell-live.game-shell-host .quiz-host .qh-revealed .qh-opt .qh-mark {
  font-size: clamp(26px, 2.6vw, 52px);
}
body.game-shell-live.game-shell-host .quiz-host .qh-bar-stat {
  font-size: clamp(15px, 1.25vw, 26px);
}
body.game-shell-live.game-shell-host .quiz-host .qh-bar-letter {
  font-size: clamp(18px, 1.8vw, 36px);
}
body.game-shell-live.game-shell-host .quiz-host .qh-timesup {
  display: inline-block;
  font-size: clamp(1.6rem, 4.2vh, 2.6rem);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* =====================================================================
   PLAYER active Quiz (same coral shell; no timer, count, score or rank)
   ===================================================================== */

/* Fill the shell content region EXACTLY (bounded height) so the stage can
   scroll internally; centred, capped to a readable width. */
body.game-shell-live.game-shell-player .quiz-player {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(92vw, 520px);
  max-width: none;
  margin: 0;
}

/* the question number row and the hidden timer never show on the phone */
body.game-shell-live.game-shell-player .qz-top { display: none; }
body.game-shell-live.game-shell-player .qz-timer { display: none; }

/* the content region (question + answers) is the scroll container: the
   logo and the Leave control stay fixed, and a long question + answers
   scroll as one reachable region. */
body.game-shell-live.game-shell-player .qz-stage {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(0.7rem, 1.6vh, 1.1rem);
  /* no-scroll requirement: the stage never scrolls and never clips the
     approved maximum content (see the compact phone rules below) */
  overflow: hidden;
  overflow: clip;
  overflow-clip-margin: 6px;
  /* overflow: clip + overflow-clip-margin adds paint clearance for the
     final card's border, rounded corners, focus outline and press
     transform WITHOUT changing usable geometry (the answers area is
     unchanged, so the fit profiles stay valid). Browsers without
     overflow: clip keep the overflow: hidden fallback above. */
  position: relative;
  -webkit-overflow-scrolling: touch;
  /* size container: the Screen 09 confirmation composes against the ACTUAL
     answer area (below the shell chrome), not the raw viewport */
  container-type: size;
  container-name: qzstage;
}

/* pre-go: the question and answers stay hidden until GO (owner fix). This
   is redeclared with the shell player context so the player grid rules
   cannot out-specify the base hiding. */
body.game-shell-live.game-shell-player .qz-stage.pre-go .qz-text,
body.game-shell-live.game-shell-player .qz-stage.pre-go .qz-options { display: none; }

body.game-shell-live.game-shell-player .qz-text {
  flex: none;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.3rem, 5.4vw, 1.8rem);
  /* Owner close-out 2026-09-16 (question readability): the runtime question
     fit reads this as the PREFERRED size and steps down only while the
     layout would otherwise be invalid - never by character-count tier. The
     length tiers below stay as the initial/no-JS fallback. */
  --qz-q-max: clamp(1.3rem, 5.4vw, 1.8rem);
  
  line-height: 1.12;
  color: #FFFFFF;
  text-align: center;
  overflow-wrap: anywhere;
  text-shadow: 0 2px 0 rgba(150, 32, 8, 0.26);
}
/* controlled scale for long questions (300 chars supported) */
body.game-shell-live.game-shell-player .qz-text.qz-q-long { font-size: clamp(1.1rem, 4.4vw, 1.5rem); }
body.game-shell-live.game-shell-player .qz-text.qz-q-xl { font-size: clamp(1rem, 3.9vw, 1.3rem); }

/* phone: one vertical stack; the cards FILL the remaining answer area in
   equal rows, so their dimensions come from the option count and the real
   viewport - never from the answer text. The uniform font fit in
   quiz-player.js steps the text down together when needed. */
body.game-shell-live.game-shell-player .qz-options {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-auto-rows: 1fr;               /* equal heights within the question */
  align-content: stretch;
  gap: clamp(0.55rem, 1.3vh, 0.85rem);
}
/* count-aware minimum card sizes (a lower floor, never a content size) */
body.game-shell-live.game-shell-player #qz-options[data-n="2"] .qz-option { min-height: clamp(64px, 12.5vh, 112px); padding-block: clamp(1rem, 2.2vh, 1.5rem); }
body.game-shell-live.game-shell-player #qz-options[data-n="3"] .qz-option { min-height: clamp(60px, 10.5vh, 96px); }
body.game-shell-live.game-shell-player #qz-options[data-n="4"] .qz-option { min-height: clamp(60px, 11vh, 100px); padding-block: clamp(0.9rem, 2vh, 1.35rem); }
body.game-shell-live.game-shell-player #qz-options[data-n="5"] .qz-option { min-height: clamp(48px, 7vh, 74px); }
body.game-shell-live.game-shell-player #qz-options[data-n="6"] .qz-option { min-height: clamp(44px, 6.2vh, 66px); }

body.game-shell-live.game-shell-player .qz-option {
  display: flex;
  align-items: center;
  font-family: var(--font-body);
  gap: clamp(0.7rem, 3vw, 1rem);
  min-height: 56px;
  padding: 0.85rem clamp(0.9rem, 3.4vw, 1.2rem);
  border: 3px solid #FFF7ED;
  border-radius: 16px;
  color: #20242C;
  font-weight: 800;
  text-align: left;
  cursor: pointer;
  transition: transform 0.06s ease, filter 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}
/* owner final order 2026-09-12b: A green, B blue, C yellow, D cream,
   E purple, F pink. SCOPED Quiz answer-palette trial (explicit exception to
   the no-purple rule, these exact proposed answer colours and their intended
   uses only). All six carry Dark Ink text and A-F labels. */
body.game-shell-live.game-shell-player .qz-option:nth-child(1) { background: #7ED957; }
body.game-shell-live.game-shell-player .qz-option:nth-child(2) { background: #21C4F3; }
body.game-shell-live.game-shell-player .qz-option:nth-child(3) { background: #FFD43B; }
body.game-shell-live.game-shell-player .qz-option:nth-child(4) { background: #FFF7ED; }
body.game-shell-live.game-shell-player .qz-option:nth-child(5) { background: #A78BFA; }
body.game-shell-live.game-shell-player .qz-option:nth-child(6) { background: #F472B6; }

body.game-shell-live.game-shell-player .qz-letter {
  flex: none;
  min-width: 1.3em;
  font-size: clamp(1.3rem, 5vw, 1.8rem);
  font-weight: 900;
  line-height: 1;
  text-align: center;
}
body.game-shell-live.game-shell-player .qz-option-text {
  flex: 1;
  font-size: clamp(1.05rem, 3.8vw, 1.3rem);
  font-weight: 800;
  /* 1.32 keeps the glyph box inside the text box for Nunito Sans */
  line-height: 1.32;
  overflow-wrap: anywhere;
}
/* Owner correction 2026-09-18: only whitespace-free phone answers use
   mid-run breaks. Sentences, questions, host and two-column player retain
   their existing wrapping; typography and allocation are unchanged. */
@media (max-width: 639px) {
  body.game-shell-live.game-shell-player .qz-option-text.qz-unbroken {
    word-break: break-all;
  }
}
/* Owner amendment 2026-09-11: a deliberate per-count STARTING scale on the
   phone (2 largest, 3-4 slightly smaller, 5-6 slightly smaller again),
   responsive to the viewport. The uniform fit steps every answer in a
   question down together only when the text needs it; 16px is the approved
   phone readability floor and the runtime never goes below it. */
body.game-shell-live.game-shell-player #qz-options[data-n="2"] .qz-option-text { font-size: clamp(18px, 5.4vw, 28px); }
body.game-shell-live.game-shell-player #qz-options[data-n="3"] .qz-option-text { font-size: clamp(17px, 5.0vw, 26px); }
body.game-shell-live.game-shell-player #qz-options[data-n="4"] .qz-option-text { font-size: clamp(16.5px, 4.7vw, 24px); }
body.game-shell-live.game-shell-player #qz-options[data-n="5"] .qz-option-text { font-size: clamp(16.2px, 4.4vw, 22px); }
body.game-shell-live.game-shell-player #qz-options[data-n="6"] .qz-option-text { font-size: clamp(16px, 4.2vw, 21px); }
body.game-shell-live.game-shell-player .qz-check {
  flex: none;
  width: 1.6rem;
  height: 1.6rem;
  border-radius: 50%;
  background: #FFFFFF;
  color: #20242C;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 900;
  font-size: 1.05rem;
  line-height: 1;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.12s ease, transform 0.12s ease;
}
/* Dark Ink checkmarks on the existing white badges for ALL six options
   (owner final 2026-09-12); badge shape, rim and timing unchanged. */
body.game-shell-live.game-shell-player .qz-option:hover { filter: brightness(1.06); }
body.game-shell-live.game-shell-player .qz-option:focus-visible { outline: 3px solid #FFD43B; outline-offset: 2px; }
body.game-shell-live.game-shell-player .qz-option:active { transform: translateY(1px) scale(0.99); }
/* selected: a stronger cream rim + check, never colour alone, no jump */
body.game-shell-live.game-shell-player .qz-option.selected { outline: 4px solid #FFF7ED; outline-offset: -4px; }
body.game-shell-live.game-shell-player .qz-option.selected .qz-check { opacity: 1; transform: scale(1); }
body.game-shell-live.game-shell-player .qz-option:disabled { cursor: default; }
body.game-shell-live.game-shell-player .qz-option:disabled:not(.selected) { opacity: 0.55; }

/* Screen 09 (Hybrid C) status band — owner fix 2026-09-12c: the pending and
   rejection messages get a RESERVED band below the answer grid. The band
   keeps its height in every state (visibility, never display), so entering
   or leaving pending never moves or resizes a card, and the message can
   never cover the question, answers, labels, checkmarks, focus rings or
   Leave. The mobile allocation reserves the same 32px band inside the
   measured lower gap. */
body.game-shell-live.game-shell-player .qz-pending {
  flex: none;
  position: static;
  margin: 0 auto;
  width: fit-content;
  max-width: min(92%, 420px);
  min-height: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.75rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  color: #FFFFFF;
  font-size: 14px;
  line-height: 1.2;
  font-weight: 700;
  text-align: center;
  overflow-wrap: anywhere;
}
/* the reserved band never collapses: hidden = invisible but still holding
   its height (base .hidden is display:none !important) */
body.game-shell-live.game-shell-player .qz-pending.hidden { display: flex !important; visibility: hidden; }
/* definitive rejection: honest, friendly, never an acceptance. 13px and the
   tighter leading keep the two-line copy fully inside the 32px reserved
   band at 320px wide (the glyph boxes, not just the line boxes). */
body.game-shell-live.game-shell-player .qz-pending.qz-bad {
  background: rgba(32, 36, 44, 0.72);
  color: #FFF7ED;
  font-weight: 800;
  font-size: 13px;
  line-height: 1.1;
  border-radius: 14px;
}

/* Answers are never hidden during gameplay (owner decision 2026-09-11).
   Admission is counts-only (owner decision 2026-09-17); the runtime keeps
   the uniform fit at the readability floor and never hides an answer. */

/* Screen 09 (Option C, owner correction 2026-09-24) - confirmation stage.
   The question, counter and grid hide; the shell's coral and confetti stay
   behind the neutral party-popper receipt. No medallion, no divider: the
   popper sits plainly on the coral, exactly the approved treatment. The
   genuine shell logo is never hidden for this state. The composition is
   container-driven so every line fits without scrolling at 320x568,
   360x640 and 390x844; reduced motion presents the same final layout
   immediately (no entrance animation). */
body.game-shell-live.game-shell-player .qz-stage.qz-confirmed .qz-top,
body.game-shell-live.game-shell-player .qz-stage.qz-confirmed .qz-text,
body.game-shell-live.game-shell-player .qz-stage.qz-confirmed .qz-options,
body.game-shell-live.game-shell-player .qz-stage.qz-confirmed .qz-pending { display: none; }

body.game-shell-live.game-shell-player .qz-confirm {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* safe centering: auto margins centre when it fits, collapse to the top
     (scrollable below) only when content genuinely needs more room */
  justify-content: flex-start;
  gap: clamp(0.5rem, 3vh, 1.8rem);
  padding: clamp(0.2rem, 1vh, 0.6rem) 0;
  text-align: center;
  min-height: 0;
}
body.game-shell-live.game-shell-player .qz-confirm > .qz-confirm-badge { margin-top: auto; }
body.game-shell-live.game-shell-player .qz-confirm > .qz-confirm-wait { margin-bottom: auto; }
body.game-shell-live.game-shell-player .qz-confirm:focus { outline: none; }

/* the neutral party-popper receipt (Option C): the icon alone on the
   coral shell - never a cream medallion, never a correctness circle */
body.game-shell-live.game-shell-player .qz-confirm-badge {
  width: min(30vw, 14vh, 144px);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: qz-confirm-pop 0.28s ease both;
}
body.game-shell-live.game-shell-player .qz-confirm-badge svg { width: 100%; height: auto; display: block; }

/* the confetti burst (owner correction 2026-09-24): one outward spread
   per piece, 340ms with a slight overshoot, never looping. The base
   transform IS the final position, so reduced motion (animation: none)
   renders the completed static burst immediately with no layout shift. */
body.game-shell-live.game-shell-player .qz-popper-bit {
  transform-box: fill-box;
  transform-origin: center;
  transform: translate(var(--tx, 0px), var(--ty, 0px)) rotate(var(--rot, 0deg));
  animation: qz-bit-burst 0.34s cubic-bezier(0.2, 1.5, 0.45, 1) both;
  animation-delay: var(--bd, 0ms);
}
@keyframes qz-bit-burst {
  0% { transform: translate(0px, 0px) rotate(var(--rot, 0deg)) scale(0.2); opacity: 0; }
  65% { opacity: 1; }
  100% { transform: translate(var(--tx, 0px), var(--ty, 0px)) rotate(var(--rot, 0deg)) scale(1); opacity: 1; }
}

body.game-shell-live.game-shell-player .qz-confirm-title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: min(13vw, 8.6vh, 52px);
  line-height: 1.06;
  color: #FFFFFF;
  text-shadow: 0 3px 0 rgba(150, 32, 8, 0.24);
  overflow-wrap: anywhere;
}
body.game-shell-live.game-shell-player .qz-confirm-look {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: min(7.8vw, 5.6vh, 2rem);
  line-height: 1.18;
  color: #FFFFFF;
  text-shadow: 0 2px 0 rgba(150, 32, 8, 0.22);
  overflow-wrap: anywhere;
}
body.game-shell-live.game-shell-player .qz-confirm-wait {
  margin: 0;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: min(6.4vw, 4.8vh, 1.6rem);
  line-height: 1.25;
  color: #FFFFFF;
  opacity: 0.97;
  text-shadow: 0 2px 0 rgba(150, 32, 8, 0.18);
  overflow-wrap: anywhere;
}

/* container-queried composition (Chromium/Safari 16+); the vw/vh values
   above stay as the fallback */
@supports (width: 1cqw) {
  body.game-shell-live.game-shell-player .qz-confirm { gap: clamp(0.5rem, 3.4cqh, 1.8rem); padding: clamp(0.2rem, 0.9cqh, 0.6rem) 0; }
  body.game-shell-live.game-shell-player .qz-confirm-badge { width: min(30cqw, 15cqh, 144px); }
  body.game-shell-live.game-shell-player .qz-confirm-title { font-size: min(13cqw, 8.6cqh, 52px); }
  body.game-shell-live.game-shell-player .qz-confirm-look { font-size: min(7.8cqw, 5.6cqh, 2rem); }
  body.game-shell-live.game-shell-player .qz-confirm-wait { font-size: min(6.4cqw, 4.8cqh, 1.6rem); }
}

/* compact phones: tighten every gap and size so the receipt AND the
   complete Leave game control stay on screen at 320x568 / 360x640 */
@media (max-height: 700px) {
  body.game-shell-live.game-shell-player .qz-confirm { gap: 0.55rem; padding: 0; }
  body.game-shell-live.game-shell-player .qz-confirm-badge { width: min(28vw, 12.5vh, 104px); }
  body.game-shell-live.game-shell-player .qz-confirm-title { font-size: min(10.5vw, 6.6vh, 34px); }
  body.game-shell-live.game-shell-player .qz-confirm-look { font-size: min(6.6vw, 4.8vh, 1.4rem); }
  body.game-shell-live.game-shell-player .qz-confirm-wait { font-size: min(5.8vw, 4.2vh, 1.2rem); }
}

/* =====================================================================
   Owner authorization 2026-09-11 - Quiz gameplay logo reduction.
   The genuine artwork is untouched (same asset, same aspect ratio, same
   recognizability); only the RENDERED size and the reserved header shrink
   during Quiz gameplay, freeing height for the question and answers.
   Scoped to the quiz gameplay classes so the frozen lobby, Reflex
   gameplay, reveal/scoreboard/podium and every other screen keep the
   original composition. The content region follows the logo through
   --gs-logo-bottom, so the recovered space is real, not decorative.

   CORRECTION (owner review 2026-09-11): the player shell's .gs-logo rule
   hard-codes its own width/top, so overriding only the variables moved the
   content up while the artwork stayed large (overlap). This rule sets the
   ACTUAL rendered logo to the same values the reserved header uses, and
   the real-element geometry is asserted by the logo-geometry harness. */
body.game-shell-live.qz-player-live {
  --gs-logo-top: clamp(8px, 1.4vh, 18px);
  --gs-logo-width: clamp(88px, 26vw, 132px);
}
body.game-shell-live.qz-player-live.game-shell-player .gs-logo {
  top: calc(env(safe-area-inset-top) + var(--gs-logo-top));
  width: var(--gs-logo-width);
  max-height: none;
}
body.game-shell-live.qz-player-live.game-shell-player .gs-content {
  top: calc(env(safe-area-inset-top) + var(--gs-logo-bottom) + var(--gs-content-gap, clamp(8px, 1.6vh, 16px)));
}
/* Owner mobile spacing rebalance (2026-09-15): the standard-phone content
   reserve held ~45px more than the Leave control needs; while the answer
   grid is on screen the reserve keeps the Leave's COMPLETE 44px interactive
   target clear with a 14px gap, and the freed space moves into the
   question-to-option-A gap (a real layout allocation: the answer group sits
   lower while the card heights, the 32px status band and the Leave are
   untouched). The predicate is the answering state itself, so the pre-go
   countdown, the reveal/timesup/complete overlays and the Screen 09
   confirmation keep their exact previous stage box and composition.
   Fallback: without :has() support the rules drop as a whole and the
   compact allocation stays - never a half-applied allocation.
   UPDATE (owner consolidated 2026-09-16): the 40:60 rule now also applies
   to the question-toggled-off layout (anchored to the visible logo art) and
   to the compact phone; the runtime pass in quiz-player.js allocates the
   final margin, and the compact header below tightens so even the maximum
   content (320x568, 120cp question, 6x40 answers) reaches 40:60. */
@media (min-width: 481px), (min-height: 721px) {
  body.game-shell-live.qz-player-live.game-shell-player
    .gs-content:has(.qz-stage:not(.pre-go):not(.qz-confirmed) #qz-overlay.hidden) {
    bottom: calc(env(safe-area-inset-bottom) + 70px);
  }
  body.game-shell-live.qz-player-live.game-shell-player
    .gs-content:has(.qz-stage:not(.pre-go):not(.qz-confirmed) #qz-overlay.hidden) #qz-options {
    margin-top: calc(clamp(72px, 12vh, 104px) - 70px);
  }
}
@media (max-width: 480px) and (max-height: 720px) {
  body.game-shell-live.qz-player-live {
    --gs-logo-top: clamp(3px, 0.7vh, 8px);
    --gs-logo-width: clamp(58px, 20.5vw, 86px);
    /* Owner consolidated 2026-09-16: the compact-only header reduction that
       makes 40:60 reachable for the maximum-content case (it frees ~8.7px
       above the question; measured - the genuine artwork, its aspect ratio
       and recognisability are preserved). Disclosed with the spacing
       evidence in Screenshots/Player-Spacing-Rebalance/README.md. */
    --gs-content-gap: clamp(4px, 1vh, 12px);
  }
}
@media (max-width: 480px) and (max-height: 720px) {
  /* Owner-authorised scoped correction (2026-09-18h/i): compact QUIZ
     ANSWERING only. The reserved 32px status band ends exactly at the Leave
     control's top edge (no overlap; Leave does not move), which certifies the
     approved maximum-budget content at 320x568 and grows every answer card.
     The :has() predicate matches the answering state including selected,
     pending and rejected (the overlay stays hidden); pre-go (pre-go class),
     confirmation (qz-confirmed), reveal (overlay not hidden) and every
     non-quiz compact screen keep the shared 60px default from
     game-shell.css. This rule is more specific than the base rule and only
     matches while a quiz answer stage is on screen. */
  body.game-shell-live.qz-player-live.game-shell-player
    .gs-content:has(.qz-stage:not(.pre-go):not(.qz-confirmed) #qz-overlay.hidden) {
    bottom: calc(env(safe-area-inset-bottom) + 56px);
  }
}
/* ============================================================
   Owner fidelity pass b21 (after the b20 review). Measured against the
   selected mockup's LEFT (during-question) panel, 1014x627 (a 16:10 frame):
     logo art        109x79 at (22,18)  = 10.75% w, top 2.87%
     progress chip   166x36 centered, top 4.8%
     utilities       two 42px circles, top 3.8%, right 2.5%
     band row        timer 119x54 at (33,104) = 11.74% w, top 16.6%
                     Next 125x57 at (866,93) = 12.33% w
                     question ink 648x40 centred, cap height 31, 1 line
     open middle     question bottom -> grid top
     grid            95.66% w, side margins ~2.1-2.3%, row gap ~8px
   The browser viewports are 16:9 / 4:3, so the header is allocated in
   COLUMNS (logo above the timer; the band row positioned independently)
   and the logo width auto-fits the vertical room above the band with its
   genuine aspect - it is never stretched and never pushes the band down.
   ============================================================ */
body.game-shell-live.game-shell-host.qz-host-live {
  /* Owner brief 2026-09-21 (approved prototype): use nearly the full
     projector width with compact outer margins - the reference's answer
     area spans ~95% of the frame. The b22 bounded column (155vh) is
     widened to 168vh with a tight side margin; the coral stays
     full-screen and the freed side space carries the approved confetti.
     Every element below is sized or anchored from this column. */
  --qz-content-w: min(168vh, calc(100vw - 2 * clamp(14px, 2vw, 40px)));
  --qz-side: calc((100vw - var(--qz-content-w)) / 2);
  /* the two band slots (reference 11.74% / 12.33% of the panel). The Next
     slot is the wider one, so the centre cell carries a compensation margin
     (below) equal to the difference: the question otherwise sits ~5px left
     of screen centre at 1920 (b22 review). */
  --qz-timer-slot: clamp(100px, calc(var(--qz-content-w) * 0.1174), 220px);
  --qz-next-slot: clamp(104px, calc(var(--qz-content-w) * 0.1233), 230px);
  --gs-logo-top: clamp(14px, 2.7vh, 32px);
  /* the band row has its own top (16.4vh = the reference's 16.6% at the
     16:10 board scale); it is NOT tied to the logo bottom, so a larger
     logo never moves the question/Next/chart */
  --gs-band-top: clamp(108px, 16.4vh, 182px);
}
/* the shell content region and the band row both BECOME the centred content
   column; the question and progress stay screen-centred: the centre cell
   cancels the timer/Next slot difference (Next is the wider slot), so its
   centre lands on the column = screen centre */
body.game-shell-live.game-shell-host.qz-host-live .gs-content {
  left: 50%; right: auto;
  width: var(--qz-content-w);
  transform: translateX(-50%);
}
/* logo: reference width relative to the column (10.75%), auto-fit to the
   vertical room above the band (never overlaps the timer) */
body.game-shell-live.game-shell-host.qz-host-live .gs-logo {
  left: var(--qz-side);
  width: min(calc(var(--qz-content-w) * 0.1075), calc((var(--gs-band-top) - var(--gs-logo-top) - 1.2vh) / var(--gs-logo-aspect)));
  max-height: none;
}
body.game-shell-live.game-shell-host.qz-host-live .gs-band {
  left: 50%; right: auto;
  width: var(--qz-content-w);
  transform: translateX(-50%);
  gap: clamp(12px, calc(var(--qz-content-w) * 0.016), 30px);
}
/* the question wraps INSIDE the centre cell: the cell takes exactly the
   leftover row space (flex-basis 0) and the question fills it, so a long
   question can never push the timer or Next out */
body.game-shell-live.game-shell-host.qz-host-live .gs-band-center { flex: 1 1 0%; min-width: 0; margin-left: calc(var(--qz-next-slot) - var(--qz-timer-slot)); }
body.game-shell-live.game-shell-host.qz-host-live .gs-band-center > .qh-text { width: 100%; max-width: 100%; flex: 1 1 auto; min-width: 0; }
/* the question keeps the reference's 63.9%-of-panel occupied width for
   ordinary short questions - measured against the CONTENT column, which is
   the panel-equivalent; longer content steps down (mid/long/xl) and the
   runtime question fitter guarantees the line count */
body.game-shell-live.game-shell-host.qz-host-live .gs-band-center > .qh-text:not(.qh-q-mid):not(.qh-q-long):not(.qh-q-xl) { font-size: clamp(34px, calc(var(--qz-content-w) * 0.0403), 88px); }
body.game-shell-live.game-shell-host.qz-host-live .gs-band-center > .qh-text.qh-q-mid { font-size: clamp(28px, 4.7vh, 56px); }
body.game-shell-live.game-shell-host.qz-host-live .gs-meta {
  top: clamp(24px, 4.8vh, 56px);
  /* the reference chip is 16.37% of the panel; it stays screen-centred */
  width: calc(var(--qz-content-w) * 0.1637);
  box-sizing: border-box;
  text-align: center;
  padding: 10px clamp(14px, calc(var(--qz-content-w) * 0.016), 30px);
  font-size: clamp(16px, calc(var(--qz-content-w) * 0.0165), 30px);
}
body.game-shell-live.game-shell-host.qz-host-live .gs-utilities {
  top: clamp(20px, 3.8vh, 44px);
  right: var(--qz-side);
}
/* the shell slots carry their own min-widths; the reference measured sizes
   are relative to the panel = the content column */
body.game-shell-live.game-shell-host.qz-host-live .gs-timer { min-width: var(--qz-timer-slot); }
body.game-shell-live.game-shell-host.qz-host-live .gs-action { min-width: 0; }
body.game-shell-live.game-shell-host.qz-host-live .gs-util { width: clamp(38px, calc(var(--qz-content-w) * 0.0414), 78px); height: clamp(38px, calc(var(--qz-content-w) * 0.0414), 78px); }
body.game-shell-live.game-shell-host.qz-host-live .gs-util .gs-ic { width: 52%; height: 52%; }
body.game-shell-live.game-shell-host.qz-host-live .gs-timer > #qh-timer {
  padding: 0 0.1em;
  gap: 0.2em;
  /* the pill is SLOT-width at every viewport (the reference's 11.74%) and
     must NOT move when the countdown shows 100-120 (three digits). The
     numeral area is RESERVED at 3 tabular digits (min-width: 3ch below), so
     the icon/number/unit layout is identical from 120 to 0; the tighter
     internal padding/gap and the font cap (slot / 4.05 = the measured
     3.671em content + margin) keep the content inside the slot at 1024x768,
     where the uncapped content previously overran it (b22 review). */
  font-size: min(clamp(1.7rem, 3.9vh, 2.9rem), calc(var(--qz-timer-slot) / 4.05));
  min-height: clamp(52px, 8.6vh, 100px);
  width: 100%;
  justify-content: center;
}
body.game-shell-live.game-shell-host.qz-host-live .gs-timer > #qh-timer .qh-timer-num {
  display: inline-block;
  min-width: 3ch;
  text-align: center;
}
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-action > #qh-next { min-width: var(--qz-next-slot); }
/* b22: the reference's "Next ->" arrow (decorative, hidden from the
   accessible name via aria-hidden). Button geometry is unchanged - the
   arrow lives inside the existing measured min-width. The markup already
   carries the label space, so the arrow adds NO margin: any extra
   margin/width pushed the natural content past the min-width at 1024x768
   and 1280x720 and widened the rendered button (b22 review). During the
   loading state the label turns transparent and the arrow hides with it. */
.qh-next-arrow { font-weight: inherit; }
#qh-next.loading .qh-next-arrow { visibility: hidden; }

/* b22: with the composition bounded to the centred content column, the
   approved sparse confetti lives in the added coral side margins (the
   reference scattering is 4 pieces left / 5 right beside the open middle).
   Every piece is ANCHORED to the content edge (6px outside it; the 45deg
   rotated diamonds need more than 3px so their rotated bounding box stays
   outside - b22 review), so it can never overlap the content, the chart
   area (including the baseline), the cards or the controls at any viewport.
   Deterministic fixed positions; quiz-host live only. The shell's auto-hide
   stays the backstop. */
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti > span { opacity: 1; }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti .c-dot { width: clamp(8px, calc(var(--qz-content-w) * 0.011), 19px); height: clamp(8px, calc(var(--qz-content-w) * 0.011), 19px); }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti .c-rect { width: clamp(12px, calc(var(--qz-content-w) * 0.019), 32px); height: clamp(7px, calc(var(--qz-content-w) * 0.0095), 16px); }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti .c-diamond { width: clamp(9px, calc(var(--qz-content-w) * 0.0125), 21px); height: clamp(9px, calc(var(--qz-content-w) * 0.0125), 21px); }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti .c-bar { width: clamp(14px, calc(var(--qz-content-w) * 0.02), 34px); height: clamp(3px, calc(var(--qz-content-w) * 0.0045), 8px); }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti .c-star { width: clamp(10px, calc(var(--qz-content-w) * 0.0145), 24px); height: clamp(10px, calc(var(--qz-content-w) * 0.0145), 24px); }
/* left margin: each piece's right edge sits 6px left of the content column */
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(1) { left: auto; right: calc(100vw - var(--qz-side) + 6px); top: 34%; bottom: auto; background: #FFD43B; }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(2) { left: auto; right: calc(100vw - var(--qz-side) + 6px); top: 42%; bottom: auto; background: #FFF7ED; transform: rotate(-14deg); }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(3) { left: auto; right: calc(100vw - var(--qz-side) + 6px); top: 47%; bottom: auto; background: #21C4F3; }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(4) { left: auto; right: calc(100vw - var(--qz-side) + 6px); top: 55%; bottom: auto; background: #7ED957; }
/* right margin: each piece's left edge sits 6px right of the content column */
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(5) { right: auto; left: calc(100vw - var(--qz-side) + 6px); top: 33%; bottom: auto; background: #FFF7ED; }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(6) { right: auto; left: calc(100vw - var(--qz-side) + 6px); top: 39%; bottom: auto; background: #21C4F3; }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(7) { right: auto; left: calc(100vw - var(--qz-side) + 6px); top: 46%; bottom: auto; background: #7ED957; }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(8) { right: auto; left: calc(100vw - var(--qz-side) + 6px); top: 51%; bottom: auto; background: #FFD43B; transform: rotate(12deg); }
body.game-shell-live.game-shell-host.qz-host-live .gs-root .gs-confetti span:nth-child(9) { right: auto; left: calc(100vw - var(--qz-side) + 6px); top: 57%; bottom: auto; background: #21C4F3; }

/* module-level polite announcer (visually hidden everywhere, shell or not) */
.qz-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

@keyframes qz-confirm-pop {
  0% { transform: scale(0.72); }
  70% { transform: scale(1.04); }
  100% { transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  body.game-shell-live.game-shell-player .qz-check { transition: none; }
  body.game-shell-live.game-shell-player .qz-confirm-badge { animation: none; }
  body.game-shell-live.game-shell-player .qz-popper-bit { animation: none; }
}

/* owner adjustment 2026-09-11: richer decorative confetti on the Quiz
   player screen (about 1.5-2x the previous visible pieces), spread across
   the top, side edges and lower background. Behind the interface, inert to
   pointer input, hidden from assistive tech, static under reduced motion.
   Quiz-player scope only: the host, the frozen lobby and other player
   screens are untouched. */
body.game-shell-live.game-shell-player .qz-confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
body.game-shell-live.game-shell-player .qz-confetti span { position: absolute; display: block; width: 7px; height: 7px; border-radius: 2px; opacity: 0.9; }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(3n) { border-radius: 50%; width: 5px; height: 5px; }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(4n) { width: 10px; height: 5px; }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(1) { left: 4%; top: 3%; background: #7ED957; transform: rotate(18deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(2) { left: 15%; top: 7%; background: #FFD43B; transform: rotate(-24deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(3) { left: 28%; top: 2%; background: #21C4F3; transform: rotate(41deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(4) { left: 44%; top: 5%; background: #FF922B; transform: rotate(-12deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(5) { left: 61%; top: 3%; background: #FF6B4A; transform: rotate(27deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(6) { left: 78%; top: 6%; background: #7ED957; transform: rotate(-33deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(7) { left: 92%; top: 2%; background: #FFF7ED; transform: rotate(14deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(8) { left: 2%; top: 24%; background: #21C4F3; transform: rotate(-19deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(9) { left: 96%; top: 28%; background: #FFD43B; transform: rotate(38deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(10) { left: 3%; top: 46%; background: #FF922B; transform: rotate(11deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(11) { left: 95%; top: 51%; background: #7ED957; transform: rotate(-27deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(12) { left: 1%; top: 68%; background: #FFF7ED; transform: rotate(29deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(13) { left: 97%; top: 72%; background: #FF6B4A; transform: rotate(-16deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(14) { left: 8%; top: 88%; background: #21C4F3; transform: rotate(23deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(15) { left: 22%; top: 94%; background: #FFD43B; transform: rotate(-36deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(16) { left: 38%; top: 91%; background: #7ED957; transform: rotate(17deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(17) { left: 55%; top: 95%; background: #FF922B; transform: rotate(-21deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(18) { left: 71%; top: 92%; background: #FF6B4A; transform: rotate(34deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(19) { left: 84%; top: 88%; background: #21C4F3; transform: rotate(-9deg); }
body.game-shell-live.game-shell-player .qz-confetti span:nth-child(20) { left: 92%; top: 96%; background: #FFF7ED; transform: rotate(26deg); }
/* the activity content stacks above the decoration */
body.game-shell-live.game-shell-player .quiz-player > .qz-top,
body.game-shell-live.game-shell-player .quiz-player > .qz-stage { position: relative; z-index: 1; }

/* tablet / desktop: two equal columns, cards fill their rows; an
   incomplete final row (3 or 5 options) centres at the same card width
   and height, so every card in a question has identical dimensions.
   Card size comes from the count and the viewport, never the text. */
@media (min-width: 640px) {
  body.game-shell-live.game-shell-player .qz-options {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    align-content: stretch;
    gap: clamp(0.7rem, 1.6vh, 1.1rem);
  }
  body.game-shell-live.game-shell-player #qz-options[data-n="3"] .qz-option:nth-child(3),
  body.game-shell-live.game-shell-player #qz-options[data-n="5"] .qz-option:nth-child(5) {
    grid-column: 1 / -1;
    justify-self: center;
    width: calc(50% - clamp(0.7rem, 1.6vh, 1.1rem) / 2);
  }
}

/* tablet/laptop player: the phone column widens so the 2-column grid grows
   sideways instead of taller; a maximum-content answer pair stays two short
   rows and the no-scroll stage never overflows */
@media (min-width: 700px) {
  body.game-shell-live.game-shell-player .gs-content > .quiz-player { width: min(92vw, 1040px); }
}

/* compact phone: the no-scroll layout for the approved text caps. Cards
   stay content-sized and equal within a question; the question/answer type
   never drops below 1rem on a phone; every card contains its text. */
@media (max-width: 639px) {
  body.game-shell-live.game-shell-player .qz-stage { gap: 0.3rem; }
  body.game-shell-live.game-shell-player .qz-text { font-size: clamp(1.2rem, 5vw, 1.5rem); --qz-q-max: clamp(1.2rem, 5vw, 1.5rem); }
  body.game-shell-live.game-shell-player .qz-text.qz-q-long { font-size: clamp(1.05rem, 4.2vw, 1.25rem); }
  body.game-shell-live.game-shell-player .qz-text.qz-q-xl { font-size: clamp(1rem, 3.9vw, 1.1rem); }
  body.game-shell-live.game-shell-player .qz-options { gap: 0.4rem; }
  /* the count-aware card rules use an id selector; the compact padding must
     match it to win, keeping the block padding small on every option count */
  body.game-shell-live.game-shell-player #qz-options[data-n="2"] .qz-option,
  body.game-shell-live.game-shell-player #qz-options[data-n="3"] .qz-option,
  body.game-shell-live.game-shell-player #qz-options[data-n="4"] .qz-option,
  body.game-shell-live.game-shell-player #qz-options[data-n="5"] .qz-option,
  body.game-shell-live.game-shell-player #qz-options[data-n="6"] .qz-option {
    padding-block: 0.24rem;
    padding-inline: 0.5rem;
  }
  body.game-shell-live.game-shell-player .qz-option { gap: 0.45rem; border-width: 2px; }
  body.game-shell-live.game-shell-player .qz-letter { min-width: 1em; font-size: clamp(1rem, 4.2vw, 1.35rem); }
  body.game-shell-live.game-shell-player .qz-check { width: 1.25rem; height: 1.25rem; font-size: 0.9rem; }
}

/* compact-HEIGHT phones: the owner-approved card styling is untouched; only
   the two gaps tighten so the reserved 32px status band fits while every
   accepted maximum (6x40, 5x40, 4x60, 3x40, 2x60) still renders at the 16px
   floor. These are the geometry values the mobile allocation and the
   reference fixtures use (32px band / 2.4px stage gap / 2px card gap);
   measured by devtools/android-test/probe-status-combos.mjs.
   Owner close-out 2026-09-16: the answer grid gap tightened 4px -> 2px here
   after probe-clearance measured the effect at the compact maximum (320x568,
   120cp question, six 40cp answers): the interior character-metric clearance
   to the card's inner border edge rises 1.31px -> 2.14px, the cards grow
   50.83px -> 52.48px, and the question keeps its space-driven size (16.7px)
   with the 40:60 ratio intact. Still a deliberate, visibly separated gap;
   disclosed with the spacing evidence. */
@media (max-width: 639px) and (max-height: 640px) {
  body.game-shell-live.game-shell-player .qz-stage { gap: 2.4px; }
  body.game-shell-live.game-shell-player .qz-options { gap: 2px; }
}

/* Owner correction 2026-09-21: the compact phone must safely contain the
   full 75-unit answers at the 16px floor. The runtime adds
   .qz-answers-tight ONLY when the approved 40:60 allocation and the grown
   six-row region still cannot hold the text; it tightens the card's
   internal block padding and the answer leading just enough, and is
   removed again whenever the approved allocation holds. The font size is
   never changed here (16px floor), no card is hidden and no text is
   clipped. */
body.game-shell-live.game-shell-player #qz-options.qz-answers-tight .qz-option {
  padding-block: 1px;
}
body.game-shell-live.game-shell-player #qz-options.qz-answers-tight .qz-option-text {
  line-height: 1.08;
}
