/* ==========================================================================
   HOST / TV SCREEN
   Designed to be read from ~10 feet away. Everything is oversized on purpose.
   ========================================================================== */

/* The palette lives in base.css, which loads first. A second copy here is how
   the TV and the phone drift apart one hex value at a time. */

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

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  overflow: hidden;
}

/* The backdrop lives in host-bg.css, which owns body::before and sits at
   z-index -2, below the drifting blobs at -1. */

#app { height: 100dvh; }

.screen {
  display: none;
  height: 100dvh;
  padding: 3vh 4vw;
  flex-direction: column;
}
.screen.active { display: flex; }

/* Bounded, so a child that wants more room than exists gets clipped to its
   share instead of overflowing across the heading above it. */
#s-vote .center-stack,
#s-question .center-stack {
  min-height: 0;
  overflow: hidden;
}

.center-stack {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2.2vh;
  text-align: center;
}

/* ---- buttons ------------------------------------------------------------ */

/* The hard bottom edge stays on purpose - it is a physical push button, which
   is right for a party game and reads instantly on a phone held by somebody
   who is not concentrating. What changes is that the edge is now a darker
   shade of the button's own colour rather than a hardcoded pink left over
   from the old palette. */
.btn {
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 105%;
  border: none;
  border-radius: var(--r-md);
  cursor: pointer;
  letter-spacing: .02em;
  transition: transform .08s var(--ease), filter .15s var(--ease),
              box-shadow .08s var(--ease);
}
.btn:active { transform: translateY(2px) scale(.99); }
.btn:disabled { opacity: .35; cursor: not-allowed; }

.btn-primary {
  background: linear-gradient(180deg, #ef5a42, var(--danger));
  color: #fff8f4;
  box-shadow: 0 5px 0 #8e2416, 0 14px 30px -8px rgba(226, 69, 47, .5);
}
.btn-primary:hover:not(:disabled) { filter: brightness(1.07); }
.btn-primary:active:not(:disabled) {
  box-shadow: 0 2px 0 #8e2416, 0 8px 18px -8px rgba(226, 69, 47, .45);
}

.btn-ghost {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line);
  font-family: var(--font-ui);
  font-size: 1rem;
  padding: .6rem 1.1rem;
}
.btn-ghost:hover { color: var(--text); border-color: var(--muted); }

.btn-big { font-size: clamp(1.2rem, 2.2vw, 2rem); padding: .8em 2em; }
.next-btn { margin-top: 1vh; }
.skip-btn { position: absolute; bottom: 2vh; right: 3vw; }

/* ---- LOBBY -------------------------------------------------------------- */

.lobby-grid {
  flex: 1;
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 4vw;
  align-items: center;
}

.lobby-left { text-align: left; }

/* Branding, not the message. It used to be the biggest thing on the screen,
   competing with the one piece of information anybody in the room actually
   needs. Now it sits above the join card at a size that says "this is what
   the game is called" and then gets out of the way. */
.logo {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.6vw, 2.6rem);
  font-weight: 900;
  font-stretch: 112%;
  line-height: .9;
  letter-spacing: -.03em;
  margin-bottom: 3.2vh;
  text-align: left;
}
/* Solid, not a gradient.

   A gradient poured through a headline is the single most recognisable
   machine-made flourish there is, and it costs real legibility at ten feet:
   the letters at the pale end thin out against the background while the eye
   is still trying to read the word. The character here comes from the
   letterforms and the size, which is where character is supposed to come
   from. */
.logo span {
  display: block;
  color: var(--danger);
}

.lobby-instructions {
  color: var(--muted);
  font-size: clamp(.9rem, 1.3vw, 1.3rem);
  text-transform: uppercase;
  letter-spacing: .18em;
  margin: 1.2vh 0 .6vh;
}

/* One physical object holding everything a phone needs, rather than six
   loose lines centred under each other. */
.join-card {
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--lift-2);
  padding: clamp(16px, 2.4vw, 34px);
  text-align: left;
}

.join-step {
  font-size: clamp(.7rem, 1.1vw, 1.05rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .26em;
  color: var(--muted);
  margin-bottom: 1.6vh;
}

/* The hero. Character tiles, monospaced by construction because every tile is
   the same width - so the code does not visually jump around between rooms
   the way proportional letterforms would. */
.room-code {
  display: flex;
  gap: clamp(6px, .8vw, 14px);
}
.rc-ch {
  flex: 1 1 0;
  font-family: var(--font-display);
  font-size: clamp(2.6rem, 7.4vw, 7.4rem);
  font-weight: 900;
  font-stretch: 105%;
  line-height: 1.06;
  text-align: center;
  color: var(--text);
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--sink);
  padding: .06em 0 .1em;
}

.join-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.6vw;
  margin-top: 2.2vh;
}
.join-where { min-width: 0; }
.jw-label {
  display: block;
  font-size: clamp(.65rem, .95vw, .95rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .26em;
  color: var(--muted);
  margin-bottom: .5vh;
}
/* A URL is an address, not an accent. Colouring it made it compete with the
   code for the same job. */
.join-url {
  font-size: clamp(1rem, 2vw, 2rem);
  font-weight: 700;
  color: var(--text);
  word-break: break-all;
  line-height: 1.1;
}

.qr-wrap {
  flex: none;
  display: block;
  padding: 8px;
  background: #fff;
  border-radius: var(--r-md);
  box-shadow: var(--lift-1);
}
.qr-wrap img { display: block; width: clamp(84px, 9vw, 132px); height: auto; }
.qr-hint { color: var(--muted); font-size: .9rem; margin-top: .8vh; }

.lobby-right { display: flex; flex-direction: column; height: 84vh; }

.players-title {
  font-size: clamp(1rem, 1.6vw, 1.5rem);
  letter-spacing: .2em;
  color: var(--muted);
  margin-bottom: 1.5vh;
}
.players-title .count { color: var(--text); }

.player-list {
  list-style: none;
  flex: 1;
  overflow-y: auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .8vh 1vw;
  align-content: start;
}
.player-list li {
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid transparent;
  border-radius: var(--r-md);
  box-shadow: var(--lift-1);
  padding: .7em 1em;
  font-size: clamp(.9rem, 1.5vw, 1.5rem);
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: .5em;
  animation: pop .25s ease;
}
.player-list li.host { border-left-color: var(--prize); }
.player-list li.away { opacity: .4; }
.player-list .crown { font-size: .85em; }

@keyframes pop {
  from { transform: scale(.85); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.lobby-controls {
  display: flex;
  gap: 1vw;
  align-items: center;
  margin-top: 2vh;
}
.rounds-label {
  color: var(--muted);
  font-size: .8rem;
  letter-spacing: .15em;
  display: flex;
  flex-direction: column;
  gap: .4em;
}
.rounds-label select {
  background: var(--surface);
  color: var(--text);
  border: 2px solid var(--line);
  border-radius: 8px;
  padding: .6em .8em;
  font-size: 1.1rem;
  font-weight: 700;
  font-family: inherit;
}
.lobby-controls .btn-primary { flex: 1; }

.debug-bar { display: flex; gap: .6vw; margin-top: 1.2vh; opacity: .5; }
.debug-bar .btn { font-size: .8rem; padding: .5em .9em; }

/* ---- ROUND INTRO -------------------------------------------------------- */

/* A label and a live counter were the same component. They are not the same
   thing, and making them identical is part of what flattens a screen out.

   This one is a label: quiet, square-ish, flat. It names the round, it is not
   a control, and it does not change while you are looking at it. */
.round-pill {
  display: inline-block;
  background: var(--line-soft);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: .45em 1em;
  font-family: var(--font-display);
  font-size: clamp(.7rem, 1.05vw, 1rem);
  font-weight: 700;
  letter-spacing: .22em;
  color: var(--muted);
}

/* The title card. Set in the display face at its widest and heaviest, because
   this is the one screen with nothing else on it to compete - and narrowed by
   JS when the round name is a long one, so "NEVER HAVE I EVER" stays the same
   height as "TRIVIA" instead of shrinking to fit. */
.round-title {
  font-family: var(--font-display);
  font-size: clamp(3rem, 11vw, 11rem);
  font-weight: 900;
  font-stretch: var(--title-width, 105%);
  letter-spacing: -.03em;
  line-height: .92;
  color: var(--text);
  text-transform: uppercase;
  /* One line, always. Wrapping is what a title card must not do: the break
     lands in a different place for every round name, so the screen jumps
     around between rounds instead of holding still. Held to one line, the
     width axis has something to solve against - see fitTitle(). */
  white-space: nowrap;
  animation: slam .4s cubic-bezier(.2,1.4,.4,1);
}
@keyframes slam {
  from { transform: scale(1.4); opacity: 0; }
  to   { transform: scale(1); opacity: 1; }
}

.round-sub { color: var(--muted); font-size: clamp(1rem, 2vw, 1.8rem); }

.bonus-banner {
  background: linear-gradient(90deg, rgba(208, 154, 60,.16), rgba(226, 69, 47,.16));
  border: 2px solid var(--gold);
  border-radius: 14px;
  padding: 1em 2em;
  font-size: clamp(1rem, 2vw, 1.9rem);
  font-weight: 800;
  color: var(--gold);
  animation: glow 2s ease-in-out infinite;
}
.bonus-banner:empty { display: none; }
@keyframes glow {
  0%,100% { box-shadow: 0 0 0 rgba(208, 154, 60,0); }
  50%     { box-shadow: 0 0 40px rgba(208, 154, 60,.35); }
}

.effects-row { display: flex; gap: 1vw; flex-wrap: wrap; justify-content: center; }
.effect-chip {
  background: rgba(61, 138, 144,.15);
  border: 2px solid var(--purple);
  color: var(--purple);
  border-radius: 999px;
  padding: .45em 1.1em;
  font-size: clamp(.8rem, 1.2vw, 1.1rem);
  font-weight: 800;
}

/* ---- QUESTION ----------------------------------------------------------- */

#s-question { position: relative; }

/* END GAME is fixed in this corner, so the row reserves space for it rather
   than letting the answered count slide underneath it. */
.q-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1vw;
  padding-right: clamp(90px, 9vw, 150px);
}
/* And this one is a readout: recessed into the panel, because the number
   inside it changes while the room watches it. */
.answered-pill {
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  box-shadow: var(--sink);
  padding: .45em 1.2em;
  font-size: clamp(.75rem, 1.1vw, 1.05rem);
  font-weight: 800;
  color: var(--muted);
}

/* A track cut into the page, with the fill sitting in it. */
.timer-bar {
  height: 8px;
  background: var(--sunken);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-pill);
  overflow: hidden;
  margin: 2vh 0;
  box-shadow: var(--sink);
}
.timer-bar.wide { width: 60vw; }
/* Solid, and it changes colour by MEANING rather than by position.

   It used to be a green-gold-pink gradient painted across the whole track, so
   the bar was already showing you red while there were twenty seconds left -
   the colour described where you were on the bar, not how much time you had.
   Now it is one colour that turns when the time actually gets short, which is
   the only thing the colour was ever meant to tell you. */
.timer-fill {
  height: 100%;
  width: 100%;
  background: var(--focus);
  transition: width .2s linear, background-color .4s var(--ease);
}
.timer-bar.low .timer-fill  { background: var(--prize); }
.timer-bar.out .timer-fill  { background: var(--danger); }

.q-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4vh;
}

.question-text {
  font-size: clamp(1.6rem, 4.4vw, 4.4rem);
  font-weight: 800;
  text-align: center;
  line-height: 1.15;
  max-width: 85%;
}

.options {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.6vh 2vw;
  width: 82%;
}
.options.two-up { grid-template-columns: 1fr 1fr; width: 70%; }

.option {
  background: var(--surface);
  border: 3px solid var(--line);
  border-radius: 22px;
  padding: 1em 1.2em;
  font-size: clamp(1rem, 2.2vw, 2.1rem);
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: .8em;
  transition: border-color .3s var(--ease), background-color .3s var(--ease), transform .3s var(--ease), opacity .3s var(--ease);
}
.option .letter {
  width: 1.7em; height: 1.7em;
  flex: none;
  display: grid; place-items: center;
  background: var(--line);
  border-radius: 8px;
  font-weight: 900;
  font-size: .8em;
}
.option.correct {
  border-color: var(--green);
  background: rgba(79, 157, 107,.14);
  transform: scale(1.03);
}
.option.correct .letter { background: var(--green); color: #06301f; }
.option.wrong { opacity: .35; }
.option .tally {
  margin-left: auto;
  font-size: .75em;
  color: var(--muted);
  font-weight: 800;
}

/* tap race */
.tap-stage {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  background: var(--bg);
}
.tap-word {
  font-size: clamp(4rem, 18vw, 18rem);
  font-weight: 900;
  letter-spacing: -.03em;
  color: var(--muted);
}
.tap-stage.go { background: var(--green); }
.tap-stage.go .tap-word { color: #05291a; animation: slam .15s ease; }

/* ---- REVEAL ------------------------------------------------------------- */

.reveal-head { text-align: center; margin-bottom: 2vh; }
/* The verdict, and the whole reason the screen exists - so it leads. It used
   to be the smallest thing on the reveal, set in a green gradient that also
   said "correct", which is wrong for a line like "Fitz got away with it". */
.reveal-answer {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 5vw, 5rem);
  font-weight: 900;
  font-stretch: 95%;
  letter-spacing: -.03em;
  line-height: 1;
  color: var(--text);
}
.reveal-answer:empty { display: none; }
.winner-line {
  font-size: clamp(1rem, 1.8vw, 1.7rem);
  color: var(--gold);
  font-weight: 700;
  margin-top: .6vh;
}

.reveal-body { flex: 1; display: flex; flex-direction: column; align-items: center; min-height: 0; }

/* A section marker, not a headline. Rules either side make it read as a
   divider between "what happened" and "what it costs you" - previously it
   was a second gradient shout competing with the verdict above it. */
.punish-title {
  font-family: var(--font-display);
  font-size: clamp(.85rem, 1.5vw, 1.5rem);
  font-weight: 700;
  letter-spacing: .28em;
  color: var(--danger);
  margin-bottom: 1.6vh;
  display: flex;
  align-items: center;
  gap: 1.2em;
  justify-content: center;
  white-space: nowrap;
}
.punish-title::before,
.punish-title::after {
  content: "";
  height: 2px;
  flex: 1 1 0;
  max-width: 22vw;
  background: linear-gradient(90deg, transparent, var(--danger-dim));
}
.punish-title::after { background: linear-gradient(270deg, transparent, var(--danger-dim)); }

.punish-list {
  list-style: none;
  width: 72%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 1vh;
}
.punish-list li {
  display: flex;
  align-items: center;
  gap: 1em;
  background: var(--surface);
  border-left: 8px solid var(--pink);
  border-radius: 14px;
  padding: .8em 1.2em;
  font-size: clamp(1rem, 1.9vw, 1.8rem);
  animation: slidein .3s ease backwards;
}
.punish-list li:nth-child(1) { animation-delay: .05s; }
.punish-list li:nth-child(2) { animation-delay: .12s; }
.punish-list li:nth-child(3) { animation-delay: .19s; }
.punish-list li:nth-child(4) { animation-delay: .26s; }
.punish-list li:nth-child(5) { animation-delay: .33s; }
@keyframes slidein {
  from { transform: translateX(-24px); opacity: 0; }
  to   { transform: none; opacity: 1; }
}
.punish-list .pname { font-weight: 800; }
.punish-list .preason { color: var(--muted); font-size: .75em; margin-left: auto; }
.punish-list .psips {
  background: var(--pink);
  color: #fff;
  border-radius: 999px;
  padding: .25em .9em;
  font-weight: 900;
  font-size: .85em;
  white-space: nowrap;
}
.punish-list li.shielded { border-left-color: var(--blue); }
.punish-list li.shielded .psips { background: var(--blue); }
.punish-list li.chug { border-left-color: var(--gold); }
.punish-list li.chug .psips { background: var(--gold); color: #3a2c00; }
.punish-list li.none { border-left-color: var(--line); color: var(--muted); justify-content: center; }

.award-banner {
  text-align: center;
  background: rgba(208, 154, 60,.12);
  border: 2px solid var(--gold);
  border-radius: 14px;
  padding: .9em 1.6em;
  font-size: clamp(1rem, 1.8vw, 1.7rem);
  font-weight: 800;
  color: var(--gold);
  margin: 2vh auto 0;
  max-width: 70%;
}

/* ---- CARD WINDOW / RESOLVE ---------------------------------------------- */

.cards-title {
  font-size: clamp(2rem, 5.5vw, 5rem);
  font-weight: 900;
  color: var(--purple);
}
.cards-sub { color: var(--muted); font-size: clamp(1rem, 1.8vw, 1.6rem); }

.played-list { list-style: none; display: flex; flex-wrap: wrap; gap: 1vw; justify-content: center; }
.played-list li {
  background: var(--surface);
  border: 2px solid var(--purple);
  border-radius: 14px;
  padding: .6em 1.2em;
  font-size: clamp(.9rem, 1.5vw, 1.4rem);
  font-weight: 700;
  animation: pop .25s ease;
}

.bonus-shout {
  font-size: clamp(2.5rem, 8vw, 8rem);
  font-weight: 900;
  color: var(--gold);
  letter-spacing: .04em;
  animation: slam .35s cubic-bezier(.2,1.4,.4,1);
  text-shadow: 0 0 60px rgba(208, 154, 60,.4);
}
.card-counter { color: var(--muted); letter-spacing: .2em; font-size: .95rem; font-weight: 800; }

.big-card {
  background: linear-gradient(160deg, #2a1f3d, var(--surface));
  border: 3px solid var(--purple);
  border-radius: 22px;
  padding: 1.6em 2.4em;
  box-shadow: 0 0 60px rgba(61, 138, 144,.25);
  animation: pop .3s ease;
}
.big-card-icon { font-size: clamp(2.5rem, 6vw, 5rem); }
.big-card-name {
  font-size: clamp(1.4rem, 3vw, 2.8rem);
  font-weight: 900;
  color: var(--purple);
  margin-top: .2em;
}
.big-card-desc { color: var(--muted); font-size: clamp(.9rem, 1.5vw, 1.4rem); margin-top: .3em; }

.card-story {
  font-size: clamp(1.1rem, 2.4vw, 2.2rem);
  font-weight: 700;
}
.card-story b { color: var(--gold); }

/* ---- SCORES ------------------------------------------------------------- */

.score-columns { display: grid; grid-template-columns: 1fr 1fr; gap: 4vw; width: 78%; }
.score-col h3 {
  color: var(--muted);
  letter-spacing: .2em;
  font-size: clamp(.8rem, 1.2vw, 1.1rem);
  margin-bottom: 1.4vh;
}
.score-list { list-style: none; display: flex; flex-direction: column; gap: .8vh; }
.score-list li {
  display: flex;
  align-items: center;
  gap: .8em;
  background: var(--surface);
  border-radius: 14px;
  padding: .7em 1.1em;
  font-size: clamp(.95rem, 1.7vw, 1.6rem);
  font-weight: 700;
}
.score-list li:first-child { border: 2px solid var(--gold); }
.score-list .rank { color: var(--muted); font-weight: 900; width: 1.6em; }
.score-list .val { margin-left: auto; color: var(--gold); font-weight: 900; }

/* ---- misc --------------------------------------------------------------- */

.conn-warn {
  position: fixed;
  top: 1vh; left: 50%;
  transform: translateX(-50%);
  background: var(--pink);
  color: #fff;
  padding: .5em 1.4em;
  border-radius: 999px;
  font-weight: 800;
  z-index: 50;
}

/* Narrow screens (previewing the host view on a laptop or in a small pane) */
@media (max-width: 900px) {
  .lobby-grid { grid-template-columns: 1fr; gap: 2vh; }
  .lobby-right { height: auto; }
  .player-list { grid-template-columns: 1fr; }
  .options { grid-template-columns: 1fr; width: 92%; }
  .score-columns { grid-template-columns: 1fr; gap: 2vh; }
  .punish-list { width: 94%; }
}

/* --------------------------------------------------------------------------
   Applied from the Web Interface Guidelines audit.
   -------------------------------------------------------------------------- */

/* Numbers that tick in place must not jitter as digit widths change. The tap
   counter updates several times a second; the countdown every second. */
.answered-pill, .score-list .val, .timer-tag, .round-pill,
.tug-count, .tc-score, .final-stat span, .card-counter,
.quip-results .qv, .tally-list b, .cr-guess b {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Stop single words dropping to their own line in big display type.

   .round-title is deliberately NOT in this list. `white-space` and `text-wrap`
   are two shorthands over the same `text-wrap-mode` longhand, so this rule -
   which sits after .round-title in the file - was quietly resetting that
   title's `nowrap` back to `wrap`, and the one-line fit measured against a
   title that had already wrapped. Balancing is for text that wraps; a title
   held to one line has nothing to balance. */
.question-text, .q-prompt, .reveal-answer,
.cards-title, .challenge-text, .ad-tag, .big-status, .verdict-text {
  text-wrap: balance;
}

/* Surfaces catch a light from above rather than sitting flat on the page.
   One inset hairline; no extra DOM. */
.player-list li, .vote-card, .team-card, .roster, .big-card, .option,
.punish-list li, .answer, .card, .tool-btn, .round-pill, .answered-pill,
.effect-chip, .bet-chip, .typing-list li, .clue, .dare-box, .final-stat {
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}