/* ==========================================================
   GAME NIGHT PM · Tabletop client
   Design system ported from tabletop-ux-v2.html mockups.
   Optimized for TV browsers — large type, high contrast,
   safe-area insets, container-query units for scaling.
   ========================================================== */

:root {
  --void: #0B0B0C;
  --void-2: #18181B;
  --snow: #F5F5F5;
  --acid: #B7FF3C;
  --coral: #FF5A3C;
  --violet: #8B5CF6;
  --gold: #FFC847;
  --blue: #4D7CFF;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  width: 100%;
  height: 100%;
  background: var(--void);
  color: var(--snow);
  font-family: 'Inter', system-ui, sans-serif;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

/* The stage hosts whatever screen is currently mounted. It IS
   the viewport: full-bleed, with a 5% safe-area inset applied
   per-screen so we never render content into TV overscan zones. */
#stage {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  /* Container-query unit anchor — child styles use cqw/cqh. */
  container-type: size;
}

/* Background layer — image or gradient per screen. */
.bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  z-index: 0;
}

/* Brand mark in the lower-right of every in-game screen. */
.brand-mark {
  position: absolute;
  right: 1.4cqw;
  bottom: 1.2cqh;
  height: 3.2cqh;
  min-height: 28px;
  max-height: 64px;
  opacity: 0.55;
  z-index: 5;
  pointer-events: none;
}

/* Stage content sits above the bg. */
.stage-content {
  position: absolute;
  inset: 0;
  padding: 5%;
  z-index: 2;
}

/* ==========================================================
   Pills — round-counter, timer, status pills
   ========================================================== */

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.7cqw;
  padding: 0.6cqh 1.2cqw;
  background: rgba(11, 11, 12, 0.72);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(245, 245, 245, 0.12);
  border-radius: 999px;
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(13px, 1.5cqw, 28px);
  letter-spacing: 0.06em;
  color: var(--snow);
  text-transform: uppercase;
  white-space: nowrap;
}

.pill.acid {
  background: var(--acid);
  color: var(--void);
  border-color: var(--acid);
}

.pill.coral {
  background: var(--coral);
  color: var(--snow);
  border-color: var(--coral);
}

.pill .dot {
  width: 0.7cqw;
  height: 0.7cqw;
  min-width: 8px;
  min-height: 8px;
  background: var(--acid);
  border-radius: 50%;
  display: inline-block;
  flex-shrink: 0;
}

/* ==========================================================
   Topbar — game logo left, optional center, optional right
   ========================================================== */

.topbar {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1cqw;
  margin-bottom: 1.4cqh;
}

.topbar .game-logo {
  height: 6cqh;
  min-height: 48px;
  max-height: 110px;
  object-fit: contain;
}

.topbar .topbar-center {
  display: flex;
  justify-content: center;
}

.topbar .topbar-right {
  display: flex;
  justify-content: flex-end;
  gap: 0.8cqw;
}

/* ==========================================================
   Buttons (used on the join form)
   ========================================================== */

.btn {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(16px, 1.8cqw, 32px);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 1.2cqh 2.4cqw;
  border-radius: 0.9cqw;
  border: none;
  cursor: pointer;
  transition: transform 0.15s ease, filter 0.15s ease;
}

.btn-primary {
  background: var(--acid);
  color: var(--void);
}

.btn-primary:hover { filter: brightness(1.08); }
.btn-primary:active { transform: scale(0.98); }

.btn-primary:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* ==========================================================
   JOIN SCREEN — host enters room code on the TV browser
   ========================================================== */

.join-screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 5%;
  background: radial-gradient(ellipse at top, #1a1a1f 0%, var(--void) 60%);
}

.join-screen .launch-logo {
  height: 18cqh;
  min-height: 100px;
  max-height: 280px;
  margin-bottom: 4cqh;
  filter: drop-shadow(0 12px 40px rgba(183, 255, 60, 0.2));
}

.join-screen h1 {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(20px, 2.4cqw, 44px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(245, 245, 245, 0.6);
  margin-bottom: 2.8cqh;
}

.code-input-row {
  display: flex;
  gap: 0.8cqw;
  margin-bottom: 3cqh;
}

.code-input {
  width: 5cqw;
  height: 7cqw;
  min-width: 56px;
  min-height: 80px;
  max-width: 110px;
  max-height: 154px;
  border: 2px solid rgba(245, 245, 245, 0.16);
  border-radius: 1cqw;
  background: var(--void-2);
  color: var(--snow);
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(28px, 3.4cqw, 64px);
  text-align: center;
  text-transform: uppercase;
  outline: none;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.code-input:focus {
  border-color: var(--acid);
  background: rgba(183, 255, 60, 0.08);
}

.code-input.filled {
  border-color: rgba(183, 255, 60, 0.4);
}

.join-error {
  color: var(--coral);
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(13px, 1.4cqw, 24px);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-top: 1.2cqh;
  min-height: 1.5cqh;
}

.join-hint {
  color: rgba(245, 245, 245, 0.5);
  font-family: 'Inter', sans-serif;
  font-size: clamp(13px, 1.4cqw, 24px);
  margin-top: 2.4cqh;
  max-width: 480px;
  line-height: 1.5;
}

/* ==========================================================
   LOBBY — game logo top, code centered, status pill, avatars
   ========================================================== */

.lobby {
  position: absolute;
  inset: 0;
  padding: 5%;
  display: flex;
  flex-direction: column;
  gap: 2cqh;
}

.lobby-logo-row {
  display: flex;
  justify-content: center;
  flex-shrink: 0;
}

.lobby-logo {
  max-height: 30cqh;
  max-width: 50%;
  object-fit: contain;
  filter: drop-shadow(0 12px 32px rgba(0, 0, 0, 0.7));
}

.lobby-code-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1cqh;
  flex-shrink: 0;
}

.lobby-code-label {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(11px, 1.2cqw, 22px);
  letter-spacing: 0.18em;
  color: rgba(245, 245, 245, 0.6);
  text-transform: uppercase;
}

.lobby-code-chars {
  display: flex;
  gap: 0.6cqw;
}

.lobby-code-char {
  width: 4cqw;
  height: 5.4cqw;
  min-width: 48px;
  min-height: 64px;
  max-width: 96px;
  max-height: 128px;
  background: var(--acid);
  color: var(--void);
  border-radius: 0.8cqw;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(26px, 3cqw, 56px);
  letter-spacing: -0.02em;
}

.lobby-status-row {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lobby-status-pill {
  font-size: clamp(13px, 1.5cqw, 28px);
}

.lobby-avatar-row {
  display: flex;
  justify-content: center;
  flex-shrink: 0;
}

.lobby-avatars {
  display: flex;
  gap: 1.4cqw;
  flex-wrap: wrap;
  justify-content: center;
}

.av-chip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4cqh;
}

.av-chip img {
  width: 5cqw;
  height: 5cqw;
  min-width: 56px;
  min-height: 56px;
  max-width: 96px;
  max-height: 96px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.5));
}

.av-chip .nick {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(11px, 1.2cqw, 22px);
  letter-spacing: 0.04em;
  color: var(--snow);
  text-transform: uppercase;
}

/* Empty / pending state when room data hasn't loaded yet. */
.loading-screen {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(18px, 2cqw, 36px);
  letter-spacing: 0.2em;
  color: rgba(245, 245, 245, 0.4);
  text-transform: uppercase;
}

.loading-screen::after {
  content: '...';
  display: inline-block;
  margin-left: 0.4em;
  animation: pulse-dots 1.4s infinite;
}

@keyframes pulse-dots {
  0%, 20% { opacity: 0.2; }
  50% { opacity: 1; }
  100% { opacity: 0.2; }
}

/* ==========================================================
   Debug bar — toggled with ?debug=1
   ========================================================== */

#debug-bar {
  position: fixed;
  left: 8px;
  bottom: 8px;
  z-index: 10000;
  background: rgba(0,0,0,0.85);
  color: #B7FF3C;
  font-family: ui-monospace, Menlo, monospace;
  font-size: 11px;
  padding: 6px 10px;
  border-radius: 4px;
  border: 1px solid rgba(183, 255, 60, 0.3);
  max-width: 50vw;
  white-space: pre-wrap;
}

/* ==========================================================
   SUS / DEALBREAKER / SNARK TANK — H2H screens
   Voting, reveal (with author + votes), and standings.
   All screens use the same shell (.sus-screen) so the layout
   stays anchored as the sub-phases swap.
   ========================================================== */

/* Background — moody dark with a subtle radial vignette so the
   answer cards float clearly without competing with imagery. */
.sus-bg {
  background:
    radial-gradient(ellipse at 50% 30%, rgba(139, 92, 246, 0.18) 0%, transparent 55%),
    radial-gradient(ellipse at 50% 110%, rgba(255, 90, 60, 0.12) 0%, transparent 60%),
    var(--void);
}

.sus-screen {
  position: absolute;
  inset: 0;
  padding: 4cqh 4cqw;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: 2cqh;
  z-index: 1;
}

/* Header — small eyebrow tag + big prompt */
.sus-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1cqh;
  text-align: center;
}
.sus-eyebrow {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(10px, 0.9cqw, 16px);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--acid);
  padding: 0.4cqh 1cqw;
  border: 2px solid var(--acid);
  border-radius: 999px;
}
.sus-prompt {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(18px, 2.2cqw, 44px);
  line-height: 1.05;
  color: var(--snow);
  max-width: 70%;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
.sus-standings-title {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(24px, 3cqw, 56px);
  line-height: 1;
  color: var(--snow);
  text-transform: uppercase;
  letter-spacing: -0.02em;
}

/* The two answer cards live in a flexible row that scales down
   on narrower stages without stacking — this is a TV view, we
   never want a vertical stack. */
.sus-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2cqw;
  align-items: stretch;
  padding: 0 6cqw;
  max-width: 84cqw;
  width: 100%;
  justify-self: center;
  align-self: center;
}

.sus-card {
  position: relative;
  background: var(--snow);
  color: var(--void);
  border-radius: 0.9cqw;
  padding: 2cqh 1.6cqw;
  display: flex;
  flex-direction: column;
  gap: 1cqh;
  box-shadow: 0 1cqh 2cqh rgba(0, 0, 0, 0.4);
  overflow: hidden;
  transition: transform 0.4s ease, box-shadow 0.4s ease, opacity 0.4s ease;
}

/* Differentiated tinted edge so A and B feel distinct even
   before the vote is revealed. The card body stays neutral so
   answers read clearly. */
.sus-card-a { border-top: 0.5cqh solid var(--blue); }
.sus-card-b { border-top: 0.5cqh solid var(--coral); }

.sus-card-label {
  /* Decorative A/B letters intentionally hidden — kept in markup
     in case we want to reintroduce them as a small badge later. */
  display: none;
}

.sus-card-text {
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  font-size: clamp(14px, 1.7cqw, 34px);
  line-height: 1.2;
  color: var(--void);
  flex: 1;
  display: flex;
  align-items: center;
}

/* Author + vote rows (revealed during reveal stage). Hidden
   structure during voting screen (we don't render them at all
   in the voting-screen markup). */
.sus-card-author {
  display: flex;
  align-items: center;
  gap: 0.8cqw;
  margin-top: auto;
}
.sus-card-author-avatar {
  width: clamp(24px, 2.5cqw, 44px);
  height: clamp(24px, 2.5cqw, 44px);
  border-radius: 50%;
  border: 0.25cqh solid var(--void);
}
.sus-card-author-name {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(10px, 1cqw, 18px);
  letter-spacing: 0.18em;
  color: var(--void);
}

.sus-card-votes {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8cqw;
  padding-top: 0.9cqh;
  border-top: 2px solid rgba(11, 11, 12, 0.12);
}
.sus-vote-count {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(11px, 1.1cqw, 20px);
  letter-spacing: 0.1em;
  color: var(--void);
  text-transform: uppercase;
}
.sus-voter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4cqw;
}
.voter-chip {
  width: clamp(20px, 1.8cqw, 32px);
  height: clamp(20px, 1.8cqw, 32px);
  border-radius: 50%;
  overflow: hidden;
  border: 0.2cqh solid var(--void);
  background: var(--void-2);
}
.voter-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Winner highlight — acid border + outer glow + scale up */
.sus-card-winner {
  outline: 0.5cqh solid var(--acid);
  outline-offset: -0.5cqh;
  box-shadow:
    0 0 0 0.2cqh rgba(183, 255, 60, 0.5),
    0 1cqh 3cqh rgba(183, 255, 60, 0.32),
    0 1cqh 2cqh rgba(0, 0, 0, 0.4);
  transform: translateY(-0.4cqh) scale(1.012);
}
/* Loser fade — keep readable but visually demoted */
.sus-card-loser {
  opacity: 0.6;
}

/* Footer — vote progress (during voting) or hint (during reveal) */
.sus-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1cqh;
  text-align: center;
}
.sus-hint {
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: clamp(14px, 1.4cqw, 26px);
  color: rgba(245, 245, 245, 0.55);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Voting progress dots + label */
.vote-progress {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8cqh;
}
.vote-dots {
  display: flex;
  gap: 0.8cqw;
}
.vote-dot {
  width: clamp(14px, 1.4cqw, 26px);
  height: clamp(14px, 1.4cqw, 26px);
  border-radius: 50%;
  border: 0.25cqh solid var(--snow);
  background: transparent;
  transition: background 0.3s ease, transform 0.3s ease;
}
.vote-dot.filled {
  background: var(--acid);
  border-color: var(--acid);
  transform: scale(1.1);
}
.vote-progress-label {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(14px, 1.4cqw, 26px);
  letter-spacing: 0.18em;
  color: var(--snow);
  text-transform: uppercase;
}

/* ==========================================================
   STANDINGS — list view shown as the second sub-stage of
   h2hReveal. Compact for up to 10 players on a TV.
   ========================================================== */
.standings-list {
  display: flex;
  flex-direction: column;
  gap: 1cqh;
  padding: 0 6cqw;
  overflow: hidden;
  align-self: center;
  width: 100%;
  max-width: 88cqw;
}
.standings-row {
  display: grid;
  grid-template-columns: clamp(40px, 4cqw, 80px) clamp(48px, 5cqw, 96px) 1fr auto auto;
  align-items: center;
  gap: 1.4cqw;
  padding: 1.4cqh 2cqw;
  background: var(--void-2);
  border-radius: 1cqw;
  border-left: 0.5cqh solid transparent;
  transition: transform 0.4s ease, background 0.4s ease, border-left-color 0.4s ease;
}
.standings-row-just-scored {
  background: rgba(183, 255, 60, 0.12);
  border-left-color: var(--acid);
  transform: translateX(0.5cqw);
  animation: scoredPulse 0.6s ease-out;
}
@keyframes scoredPulse {
  0%   { transform: translateX(-1cqw) scale(0.98); }
  60%  { transform: translateX(0.8cqw) scale(1.01); }
  100% { transform: translateX(0.5cqw) scale(1); }
}
.standings-rank {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(20px, 2.4cqw, 48px);
  color: var(--snow);
  opacity: 0.5;
  text-align: center;
}
.standings-avatar {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  object-fit: cover;
  border: 0.3cqh solid var(--void);
}
.standings-name {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(18px, 2cqw, 40px);
  letter-spacing: 0.12em;
  color: var(--snow);
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.standings-delta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.2cqh;
  min-width: 5cqw;
}
.delta-num {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(14px, 1.5cqw, 28px);
  color: var(--acid);
  letter-spacing: 0.04em;
  animation: deltaIn 0.35s ease-out;
}
.delta-bonus {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(9px, 0.85cqw, 14px);
  letter-spacing: 0.18em;
  color: var(--gold);
  background: rgba(255, 200, 71, 0.15);
  padding: 0.2cqh 0.6cqw;
  border-radius: 0.25cqw;
  text-transform: uppercase;
  animation: deltaIn 0.35s ease-out 0.1s both;
}
@keyframes deltaIn {
  from { opacity: 0; transform: translateY(0.4cqh); }
  to   { opacity: 1; transform: translateY(0); }
}
.standings-score {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(22px, 2.6cqw, 56px);
  color: var(--snow);
  letter-spacing: -0.02em;
  text-align: right;
  min-width: 6cqw;
}

/* ==========================================================
   PERSISTENT CORNER OVERLAY — room code + leave button
   These elements live OUTSIDE #stage so they survive every
   `stage.innerHTML = ...` rewrite. Position is fixed to the
   viewport corners; sizing is fluid via clamp() so it's legible
   on phones-as-TVs and unobtrusive on actual 4K displays.
   ========================================================== */

.corner-room-code {
  position: fixed;
  top: max(2.4vh, env(safe-area-inset-top, 0));
  left: max(2.4vw, env(safe-area-inset-left, 0));
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.55em 0.9em;
  background: rgba(11, 11, 12, 0.62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1.5px solid rgba(245, 245, 245, 0.18);
  border-radius: 0.6em;
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(14px, 1.1vw, 20px);
  color: var(--snow);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  pointer-events: none; /* purely informational */
}

.corner-code-label {
  font-size: 0.62em;
  color: rgba(245, 245, 245, 0.55);
  letter-spacing: 0.32em;
  margin-right: 0.25em;
}

.corner-code-char {
  display: inline-block;
  min-width: 0.85em;
  text-align: center;
  color: var(--snow);
}

.corner-leave-btn {
  position: fixed;
  top: max(2.4vh, env(safe-area-inset-top, 0));
  right: max(2.4vw, env(safe-area-inset-right, 0));
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 0.45em;
  padding: 0.55em 0.9em;
  background: rgba(11, 11, 12, 0.62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1.5px solid rgba(245, 245, 245, 0.18);
  border-radius: 0.6em;
  color: var(--snow);
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(13px, 1cqw, 18px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}
.corner-leave-btn:hover {
  background: rgba(255, 90, 60, 0.22);
  border-color: var(--coral);
}
.corner-leave-btn:active {
  transform: scale(0.96);
}
.corner-leave-btn svg {
  width: 1.05em;
  height: 1.05em;
  flex: 0 0 auto;
}
.corner-leave-btn[hidden],
.corner-room-code[hidden] {
  display: none !important;
}

/* ==========================================================
   GAME OVER MODAL
   Full-screen dim with a centered card that auto-dismisses
   after ~3s. The progress bar fills over that window so the
   countdown is visible without numerals.
   ========================================================== */

.game-over-modal {
  position: absolute;
  inset: 0;
  background: rgba(11, 11, 12, 0.78);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
  animation: gameOverFadeIn 0.3s ease-out;
}
@keyframes gameOverFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.game-over-card {
  background: var(--void-2);
  border: 2px solid var(--coral);
  border-radius: 1.4cqw;
  padding: 4cqh 5cqw;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2cqh;
  box-shadow: 0 2cqh 5cqh rgba(0, 0, 0, 0.55);
  max-width: 70%;
  animation: gameOverCardIn 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes gameOverCardIn {
  from { transform: translateY(2cqh) scale(0.92); opacity: 0; }
  to   { transform: translateY(0)    scale(1);    opacity: 1; }
}

.game-over-eyebrow {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(36px, 5cqw, 96px);
  line-height: 1;
  color: var(--coral);
  text-transform: uppercase;
  letter-spacing: -0.02em;
}
.game-over-body {
  font-family: 'Inter', sans-serif;
  font-weight: 700;
  font-size: clamp(16px, 1.7cqw, 30px);
  color: var(--snow);
  letter-spacing: 0.05em;
}

.game-over-progress {
  width: 26cqw;
  max-width: 60%;
  height: 0.6cqh;
  background: rgba(245, 245, 245, 0.16);
  border-radius: 999px;
  overflow: hidden;
}
.game-over-progress-bar {
  height: 100%;
  width: 0;
  background: var(--coral);
  border-radius: inherit;
  animation: gameOverFill 3s linear forwards;
}
@keyframes gameOverFill {
  from { width: 0; }
  to   { width: 100%; }
}

/* ==========================================================
   DAMN LIKELY — TV screens
   Uses the same .sus-screen/.sus-cards shell as Dealbreaker
   (so layout stays consistent), with a distinct background
   gradient and a centered "OR" divider between the two
   prompts to read clearly as a binary choice.
   ========================================================== */

.damn-bg {
  background:
    radial-gradient(ellipse at 50% 0%, rgba(77, 124, 255, 0.20) 0%, transparent 55%),
    radial-gradient(ellipse at 50% 100%, rgba(183, 255, 60, 0.10) 0%, transparent 60%),
    var(--void);
}

.damn-prefix {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(14px, 1.4cqw, 24px);
  letter-spacing: 0.16em;
  color: rgba(245, 245, 245, 0.62);
  text-transform: uppercase;
  margin-top: 0.4cqh;
}

/* Damn Likely cards live in a 3-column grid (card, OR, card) so
   the divider sits centered between them at any viewport. */
.damn-cards {
  grid-template-columns: 1fr auto 1fr;
  gap: 1.6cqw;
}

.damn-card {
  /* Damn Likely cards have only the prompt + (during reveal) the
     vote tally — no author row. Slightly more vertical breathing
     room and centered text for the binary choice feel. */
  justify-content: center;
}
.damn-card-text {
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  font-size: clamp(16px, 1.9cqw, 38px);
  line-height: 1.18;
  color: var(--void);
  text-align: center;
  letter-spacing: -0.01em;
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.damn-vs {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(20px, 2.4cqw, 48px);
  letter-spacing: 0.18em;
  color: var(--snow);
  align-self: center;
  text-transform: uppercase;
  /* Subtle background ring so OR floats over the gradient */
  padding: 0.8cqh 1.4cqw;
  border-radius: 999px;
  border: 2px solid rgba(245, 245, 245, 0.22);
  background: rgba(11, 11, 12, 0.55);
}
.damn-vs-faded {
  opacity: 0.45;
  border-color: rgba(245, 245, 245, 0.12);
}

/* ==========================================================
   LEAST LIKELY — TV screens
   Different shape: single prompt card, no head-to-head.
   The TV shows the prompt big and points players at their
   phones for the actual voting/reveal. Background uses warm
   coral tones to differentiate from Damn Likely's blue/green.
   ========================================================== */

.least-bg {
  background:
    radial-gradient(ellipse at 50% 0%, rgba(255, 90, 60, 0.18) 0%, transparent 55%),
    radial-gradient(ellipse at 50% 100%, rgba(255, 200, 71, 0.10) 0%, transparent 60%),
    var(--void);
}

.least-prompt-card {
  align-self: center;
  justify-self: center;
  width: min(72cqw, 1100px);
  background: var(--snow);
  color: var(--void);
  border-radius: 1cqw;
  padding: 5cqh 4cqw;
  display: flex;
  flex-direction: column;
  gap: 2cqh;
  align-items: center;
  text-align: center;
  border-top: 0.5cqh solid var(--coral);
  box-shadow: 0 1.2cqh 3cqh rgba(0, 0, 0, 0.5);
}
.least-prompt-card-revealed {
  outline: 0.5cqh solid var(--coral);
  outline-offset: -0.5cqh;
  box-shadow:
    0 0 0 0.2cqh rgba(255, 90, 60, 0.4),
    0 1.2cqh 3cqh rgba(255, 90, 60, 0.32);
}

.least-prefix {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(13px, 1.3cqw, 22px);
  letter-spacing: 0.16em;
  color: var(--coral);
  text-transform: uppercase;
}

.least-prompt-text {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(28px, 3.2cqw, 64px);
  line-height: 1.1;
  color: var(--void);
  letter-spacing: -0.01em;
}

/* Final-standings winner row gets a slightly stronger highlight
   than the per-round just-scored row (used by Damn Likely). */
.standings-row-winner {
  background: rgba(183, 255, 60, 0.18);
  border-left-color: var(--acid);
}

/* ==========================================================
   LEAST LIKELY — reveal additions (verdict + per-player bars)
   ========================================================== */

.least-reveal-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2cqh;
  align-self: center;
  width: 100%;
}

/* Compact prompt card for the reveal — narrower than the prompt
   phase since we share vertical space with the verdict + bars. */
.least-reveal-body .least-prompt-card {
  width: min(56cqw, 900px);
  padding: 2.4cqh 3cqw;
  gap: 1cqh;
}
.least-reveal-body .least-prompt-text {
  font-size: clamp(22px, 2.4cqw, 44px);
}

/* Verdict block — tie card OR winner row */
.least-verdict {
  font-family: 'Archivo Black', sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  display: flex;
  align-items: center;
  gap: 1.5cqw;
  padding: 1.6cqh 3cqw;
  border-radius: 0.9cqw;
  box-shadow: 0 1cqh 2cqh rgba(0, 0, 0, 0.4);
  animation: verdictPop 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes verdictPop {
  from { opacity: 0; transform: translateY(0.8cqh) scale(0.92); }
  to   { opacity: 1; transform: translateY(0)    scale(1);    }
}

.least-verdict-tie {
  background: var(--coral);
  color: var(--snow);
  font-size: clamp(28px, 3.2cqw, 64px);
  letter-spacing: 0.04em;
  padding: 2cqh 4cqw;
}

.least-verdict-winner {
  background: var(--coral);
  color: var(--snow);
}
.least-verdict-avatar {
  width: clamp(48px, 5cqw, 92px);
  height: clamp(48px, 5cqw, 92px);
  border-radius: 50%;
  border: 0.4cqh solid var(--snow);
  object-fit: cover;
}
.least-verdict-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.2cqh;
}
.least-verdict-name {
  font-size: clamp(24px, 2.8cqw, 56px);
  line-height: 1;
  letter-spacing: -0.01em;
}
.least-verdict-label {
  font-family: 'Inter', sans-serif;
  font-weight: 700;
  font-size: clamp(12px, 1.2cqw, 22px);
  letter-spacing: 0.18em;
  opacity: 0.82;
  text-transform: uppercase;
}

/* Per-player vote breakdown bars — mirrors the phone UI but
   horizontal full-width across the bottom of the reveal screen.
   Grid: avatar | name | bar track | percentage. */
.least-bars {
  display: flex;
  flex-direction: column;
  gap: 0.9cqh;
  width: min(64cqw, 1000px);
  padding: 0;
}
.least-bar-row {
  display: grid;
  grid-template-columns: clamp(32px, 3cqw, 56px) clamp(80px, 8cqw, 160px) 1fr clamp(40px, 4cqw, 72px);
  align-items: center;
  gap: 1.2cqw;
  padding: 0.8cqh 1.4cqw;
  background: var(--void-2);
  border-radius: 0.6cqw;
  border-left: 0.4cqh solid transparent;
  transition: background 0.3s ease, border-left-color 0.3s ease;
}
.least-bar-row-leader {
  background: rgba(255, 90, 60, 0.16);
  border-left-color: var(--coral);
}
.least-bar-avatar {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  object-fit: cover;
  border: 0.25cqh solid var(--void);
}
.least-bar-name {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(14px, 1.5cqw, 28px);
  letter-spacing: 0.12em;
  color: var(--snow);
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.least-bar-track {
  height: clamp(10px, 1.2cqh, 22px);
  background: rgba(245, 245, 245, 0.10);
  border-radius: 999px;
  overflow: hidden;
  position: relative;
}
.least-bar-fill {
  height: 100%;
  background: var(--acid);
  border-radius: inherit;
  transition: width 0.5s cubic-bezier(0.2, 0.9, 0.3, 1);
}
.least-bar-row-leader .least-bar-fill {
  background: var(--coral);
}
.least-bar-pct {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(13px, 1.4cqw, 26px);
  color: var(--snow);
  letter-spacing: 0.02em;
  text-align: right;
}

/* ==========================================================
   DAMN LIKELY — reveal: cards + standings layout
   ========================================================== */

/* Cards + standings are wrapped together in .damn-reveal-body
   so they can be vertically centered as a single unit inside
   the .sus-screen body row. The wrapper is a flex column with
   justify-content: center to push the cards+standings block
   to the vertical middle of the available space. Without this
   wrapper, the two children sit at the top of the grid row
   with all the dead vertical space below them. The "I'm damn
   likely to..." prefix lives inside the wrapper too so it
   sits just above the cards rather than floating up near the
   eyebrow at the top of the screen.

   .damn-voting-body uses the same pattern for parity: the
   voting screen would otherwise show the prefix pinned to the
   top header while the cards sit in the middle, then the
   reveal screen would show the prefix down above the cards,
   making the prefix appear to "jump" between phases. With both
   wrappers, the prefix travels with the cards in both phases. */
.damn-reveal-body,
.damn-voting-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 0;  /* allow shrinking inside grid 1fr row */
  width: 100%;
}
/* Use explicit margins between the wrapper's children so the
   prefix sits well away from the cards (~2 lines of its own
   font) while the standings get a slightly wider break from
   the cards below. A uniform `gap` on the wrapper made the
   prefix feel disconnected. Using `em` ties the gap to the
   prefix's own font size so it scales correctly at any
   viewport. */
.damn-reveal-body > .damn-prefix,
.damn-voting-body > .damn-prefix {
  margin: 0 0 2.4em 0;
}
.damn-reveal-body > .standings-list {
  margin-top: 3cqh;
}

/* Compact card sizing so cards + standings both fit on screen.
   The voting phase keeps its larger card; only the reveal goes
   compact to leave vertical room for the standings list below.
   Switched from grid to flex layout: `flex: 1 1 0` on each card
   forces both to grow equally from a 0 basis regardless of their
   text content, which the previous `minmax(0, 1fr)` grid rule
   wasn't reliably doing. */
.damn-cards-compact {
  width: min(70cqw, 1100px);
  display: flex;
  flex-direction: row;
  align-items: stretch;
  justify-content: center;
  gap: 2cqw;
  justify-self: center;  /* horizontal centering in the .sus-screen grid row */
  margin-left: auto;
  margin-right: auto;
  padding: 0;            /* override inherited .sus-cards padding */
  max-width: none;       /* override inherited .sus-cards max-width */
  grid-template-columns: none;  /* drop the inherited grid columns */
}
.damn-cards-compact .damn-card {
  flex: 1 1 0;            /* equal growth from 0 — guaranteed equal widths */
  min-width: 0;           /* allow shrinking */
  padding: 2cqh 2.4cqw;
  min-height: 0;
}
.damn-cards-compact .damn-vs {
  flex: 0 0 auto;         /* "OR" sits at its content width */
  align-self: center;
}
/* Smaller, more conservative font on the compact card. The previous
   clamp(20, 2.3cqw, 42) was actually larger than the voting card's
   clamp(16, 1.9cqw, 38), which made reveal text wrap harder than
   voting text. With smaller text, both cards wrap consistently. */
.damn-cards-compact .damn-card-text {
  font-size: clamp(16px, 1.7cqw, 32px);
  line-height: 1.15;
}
.damn-cards-compact .sus-vote-count {
  font-size: clamp(13px, 1.4cqw, 24px);
}

/* Shrink + center the standings list. Sits directly under the
   cards on the reveal screen — narrow enough to feel grouped
   with them rather than spanning the full stage. The rows
   themselves get a tighter padding for the same reason. */
/* Shrink + center the standings list. Sits directly under the
   cards on the reveal screen — narrow enough to feel grouped
   with them rather than spanning the full stage. The rows
   themselves get a tighter padding for the same reason.
   Positioning (vertical + horizontal centering) is handled by
   the .damn-reveal-body flex wrapper, so this rule just sets
   the box's intrinsic size. */
.damn-standings {
  width: min(55cqw, 860px);
  max-width: 90cqw;
  padding: 0;
  overflow-y: auto;
}
.damn-standings .standings-row {
  padding: 0.9cqh 1.4cqw;
  gap: 1cqw;
  grid-template-columns: clamp(28px, 2.6cqw, 56px) clamp(36px, 3.6cqw, 72px) 1fr auto auto;
}
.damn-standings .standings-rank {
  font-size: clamp(16px, 1.8cqw, 36px);
}
.damn-standings .standings-name {
  font-size: clamp(16px, 1.8cqw, 32px);
}
.damn-standings .standings-score {
  font-size: clamp(18px, 2cqw, 38px);
  min-width: clamp(40px, 4cqw, 80px);
  text-align: center;
}

/* Streak-bonus pill — orange/coral to stand apart from the
   regular acid-green delta number. Communicates "you're on fire". */
.standings-row .delta-bonus {
  display: inline-block;
  margin-left: 0.6cqw;
  padding: 0.15cqh 0.6cqw;
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(10px, 0.85cqw, 16px);
  letter-spacing: 0.08em;
  color: var(--snow);
  background: var(--coral);
  border-radius: 4px;
  vertical-align: middle;
}

/* ==========================================================
   SUS / SNARK TANK / DEALBREAKER — final results
   ==========================================================
   The final-results screen shows the leaderboard standings
   revealed bottom-up, optionally followed by a "Final Deal"
   champion card. Cascade is driven from JS by removing the
   *-pending classes via setTimeout; CSS provides the
   transition that animates from hidden → visible. */

.sus-finals-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3cqh;
  min-height: 0;
  width: 100%;
}

.sus-finals-list {
  width: min(60cqw, 900px);
  max-width: 92cqw;
  margin-left: auto;
  margin-right: auto;
  padding: 0;
}
/* Final standings rows are slightly bigger than the H2H scoring
   rows since this is the climax of the game — the user wants the
   names readable from across the room. */
.sus-finals-list .standings-row {
  padding: 1.4cqh 1.8cqw;
  gap: 1.4cqw;
  grid-template-columns: clamp(36px, 3.4cqw, 72px) clamp(48px, 4.6cqw, 92px) 1fr auto;
  transition: opacity 0.45s ease, transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.sus-finals-list .standings-rank   { font-size: clamp(20px, 2.2cqw, 42px); }
.sus-finals-list .standings-name   { font-size: clamp(20px, 2.4cqw, 44px); }
.sus-finals-list .standings-score  {
  font-size: clamp(24px, 2.8cqw, 52px);
  min-width: clamp(60px, 5cqw, 100px);
  text-align: center;
}

/* Pre-reveal state for cascade. JS removes this class on a
   stagger to animate each row in from below. */
.standings-row-pending {
  opacity: 0;
  transform: translateY(20px);
}

/* Final Deal champion card — author + their winning answer. */
.sus-final-deal {
  width: min(60cqw, 900px);
  max-width: 92cqw;
  margin-left: auto;
  margin-right: auto;
  background: rgba(24, 24, 27, 0.85);
  border: 1px solid rgba(255, 90, 60, 0.35);
  border-radius: 18px;
  padding: 2.2cqh 2cqw;
  transition: opacity 0.6s ease;
}
.sus-final-deal-pending {
  opacity: 0;
}
.sus-final-deal-label {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(13px, 1.3cqw, 22px);
  letter-spacing: 0.18em;
  color: var(--coral);
  margin-bottom: 1.2cqh;
}
.sus-final-deal-body {
  display: flex;
  align-items: center;
  gap: 1.8cqw;
}
.sus-final-deal-avatar {
  width: clamp(56px, 5.2cqw, 104px);
  height: clamp(56px, 5.2cqw, 104px);
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
}
.sus-final-deal-text {
  display: flex;
  flex-direction: column;
  gap: 0.6cqh;
  min-width: 0;
  flex: 1 1 auto;
}
.sus-final-deal-author {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(18px, 2cqw, 38px);
  color: var(--snow);
}
.sus-final-deal-answer {
  font-family: 'Inter', sans-serif;
  font-weight: 700;
  font-size: clamp(15px, 1.5cqw, 28px);
  line-height: 1.25;
  color: rgba(245, 245, 245, 0.85);
  /* Allow up to 3 lines, then ellipsis to keep the card a sane height. */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ==========================================================
   SUS / SNARK TANK — first roundIntro splash
   Shown at the very start of a game (round 0, no scores yet).
   "Get ready · ACT 1" with the player roster as chips below.
   ========================================================== */
.sus-first-intro-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.4cqh;
  min-height: 0;
  width: 100%;
}
.sus-first-intro-tagline {
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  letter-spacing: 0.06em;
  font-size: clamp(20px, 2cqw, 40px);
  color: rgba(245, 245, 245, 0.62);
  text-transform: uppercase;
}
.sus-first-intro-act {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(60px, 7.5cqw, 160px);
  letter-spacing: 0.06em;
  color: var(--acid);
  text-transform: uppercase;
  line-height: 1;
}
.sus-first-intro-players {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.4cqw;
  width: min(80cqw, 1300px);
  margin-top: 1.6cqh;
}
.sus-first-intro-players .lobby-avatar-chip {
  display: flex;
  align-items: center;
  gap: 0.8cqw;
  padding: 0.8cqh 1.4cqw;
  background: rgba(24, 24, 27, 0.7);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 999px;
}
.sus-first-intro-players .lobby-avatar-chip img {
  width: clamp(36px, 3cqw, 56px);
  height: clamp(36px, 3cqw, 56px);
  border-radius: 50%;
  object-fit: cover;
}
.sus-first-intro-players .lobby-avatar-chip span {
  font-family: 'Archivo Black', sans-serif;
  font-size: clamp(14px, 1.4cqw, 24px);
  letter-spacing: 0.06em;
  color: var(--snow);
}

/* ==========================================================
   SUS / SNARK TANK — voting + reveal body wrappers
   ==========================================================
   Mirrors the Damn Likely pattern: the prompt was previously in
   .sus-header at the top of the screen, leaving a big gap before
   the cards. Moving it into a flex-column body wrapper next to
   the cards keeps them visually grouped — prompt sits ~2 lines
   above the cards, both vertically centered in the 1fr middle
   row of the .sus-screen grid. */
.sus-voting-body,
.sus-reveal-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 0;
  width: 100%;
}
/* ~2 lines of breathing room between the prompt and the cards.
   `em` ties to the prompt's own font size so the gap scales
   correctly at any viewport. */
.sus-voting-body > .sus-prompt,
.sus-reveal-body > .sus-prompt {
  margin: 0 0 2.4em 0;
  text-align: center;
}

/* ==========================================================
   Corner mute button — sits left of the leave button. Same
   visual language as .corner-leave-btn but icon-only (no label).
   When muted, gets a slash overlay via .muted class.
   ========================================================== */
.corner-mute-btn {
  position: fixed;
  top: max(2.4vh, env(safe-area-inset-top, 0));
  /* Stick to the right edge, but offset left by roughly the
     width of the leave button so we don't overlap. Tuned visually
     against the leave button at clamp(13px, 1cqw, 18px) base. */
  right: calc(max(2.4vw, env(safe-area-inset-right, 0)) + 7.5em);
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.55em 0.7em;
  background: rgba(11, 11, 12, 0.62);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1.5px solid rgba(245, 245, 245, 0.18);
  border-radius: 0.6em;
  color: var(--snow);
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}
.corner-mute-btn:hover {
  background: rgba(183, 255, 60, 0.18);
  border-color: var(--acid);
}
.corner-mute-btn:active {
  transform: scale(0.94);
}
.corner-mute-btn.muted {
  color: rgba(245, 245, 245, 0.55);
}
.corner-mute-btn.muted:hover {
  border-color: rgba(245, 245, 245, 0.4);
  background: rgba(11, 11, 12, 0.82);
}
.corner-mute-btn svg {
  width: 1.35em;
  height: 1.35em;
  flex: 0 0 auto;
}
.corner-mute-btn[hidden] {
  display: none !important;
}
