/* Question block, score pod, and the board itself.
   The board dominates: it gets the largest type, the chunkiest borders and
   the only 3D transform on the page. */

.question-block {
  text-align: center;
  padding: var(--gap-lg) 0 var(--gap);
}

.asked-line {
  font-size: clamp(11px, 2.6vw, 13px);
  letter-spacing: 0.28em;
  color: var(--green);
  text-shadow: var(--glow-green);
  margin: 0 0 var(--gap-sm);
}

.question-text {
  font-family: var(--font-display);
  font-size: clamp(20px, 5.2vw, 34px);
  line-height: 1.18;
  letter-spacing: 0.01em;
  margin: 0;
  color: var(--ink);
  text-wrap: balance;
}

/* --- Score pod --------------------------------------------------------- */

.score-pod {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin: var(--gap) auto var(--gap-lg);
  padding: 10px 34px;
  width: fit-content;
  background: linear-gradient(180deg, #0a0f24 0%, #05070f 100%);
  border: var(--border-chunky) solid var(--gold-deep);
  border-radius: 6px;
  box-shadow: var(--glow-gold), inset 0 0 22px rgba(255, 181, 46, 0.12);
}

.score-pod__label {
  font-size: 10px;
  letter-spacing: 0.34em;
  color: var(--gold-deep);
  text-transform: uppercase;
}

.score-pod__value {
  font-family: var(--font-display);
  font-size: clamp(34px, 9vw, 54px);
  line-height: 1;
  color: var(--gold);
  text-shadow: var(--glow-gold-strong);
  font-variant-numeric: tabular-nums;
}

.score-pod.is-pulsing {
  animation: pod-pulse 520ms ease-out;
}

@keyframes pod-pulse {
  0% { transform: scale(1); }
  35% { transform: scale(1.09); box-shadow: var(--glow-gold-strong); }
  100% { transform: scale(1); }
}

/* --- Board ------------------------------------------------------------- */

.board {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 7px;
  perspective: 1200px;
}

.board-row {
  position: relative;
  height: 56px;
}

.board-row__inner {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transition: transform var(--t-flip) var(--ease-overshoot);
}

.board-row.is-revealed .board-row__inner {
  transform: rotateX(180deg);
}

.board-face {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: var(--gap-sm);
  padding: 0 var(--gap) 0 0;
  border: var(--border-chunky) solid var(--stage-line);
  border-radius: var(--radius);
  backface-visibility: hidden;
  overflow: hidden;
}

.board-face--front {
  background: linear-gradient(180deg, var(--stage-raised) 0%, #0a1130 100%);
}

/* LED dot matrix standing in for the hidden answer. */
.board-face--front .board-face__body {
  flex: 1;
  height: 60%;
  margin-left: var(--gap-sm);
  border-radius: 2px;
  background-image: radial-gradient(circle, rgba(120, 150, 220, 0.55) 1.4px, transparent 1.6px);
  background-size: 9px 9px;
  background-position: 2px 2px;
  opacity: 0.5;
}

.board-face--back {
  background: linear-gradient(180deg, #14225a 0%, #0a1130 100%);
  border-color: var(--gold-deep);
  transform: rotateX(180deg);
  box-shadow: inset 0 0 26px rgba(255, 181, 46, 0.16);
}

.board-row__rank {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 100%;
  flex: none;
  border-right: var(--border-chunky) solid var(--stage-line);
  background: #060b1e;
  font-family: var(--font-display);
  font-size: 20px;
  color: var(--ink-faint);
}

.board-face--back .board-row__rank {
  border-right-color: var(--gold-deep);
  color: var(--gold-deep);
}

/* One line, and never an ellipsis. Answers are meant to be short — the
   pipeline aims for three words — so they fit at this size. The rare one that
   doesn't is stepped down by `fitLabel` in board.js until it does, and only a
   label that still overflows at its floor wraps onto a second line. */
.board-face__label {
  flex: 1;
  min-width: 0;
  margin-left: var(--gap-sm);
  font-family: var(--font-display);
  font-size: clamp(14px, 3.6vw, 22px);
  letter-spacing: 0.02em;
  color: var(--gold-bright);
  text-shadow: var(--glow-gold);
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
}

.board-face__label.is-wrapped {
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.1;
}

.board-face__points {
  flex: none;
  font-family: var(--font-display);
  font-size: clamp(18px, 4.6vw, 26px);
  color: var(--gold);
  text-shadow: var(--glow-gold-strong);
  font-variant-numeric: tabular-nums;
}

.board-face__mark {
  flex: none;
  font-family: var(--font-display);
  font-size: clamp(18px, 4.6vw, 24px);
  color: var(--gold-dim);
  letter-spacing: 0.06em;
}

/* Rows the player never found: revealed at the end, deliberately muted so a
   missed answer never reads as a win. */
.board-row.is-missed .board-face--back {
  border-color: var(--stage-line);
  box-shadow: none;
  background: linear-gradient(180deg, #0d1430 0%, #070c1e 100%);
}

.board-row.is-missed .board-face__label,
.board-row.is-missed .board-face__points {
  color: var(--ink-faint);
  text-shadow: none;
}

.board-row.is-missed .board-row__rank {
  border-right-color: var(--stage-line);
  color: var(--ink-faint);
}

.board-row.is-flashing .board-face--back {
  animation: row-flash 520ms ease-out;
}

@keyframes row-flash {
  0% { box-shadow: inset 0 0 0 999px rgba(255, 213, 121, 0.85); }
  100% { box-shadow: inset 0 0 26px rgba(255, 181, 46, 0.16); }
}

.board-row.is-bumping .board-face--back {
  animation: row-bump 480ms ease-out;
}

@keyframes row-bump {
  0%, 100% { transform: rotateX(180deg) translateX(0); }
  30% { transform: rotateX(180deg) translateX(6px); }
  60% { transform: rotateX(180deg) translateX(-4px); }
}

/* Intro cascade. */
.board-row.is-entering {
  animation: row-enter 420ms var(--ease-overshoot) backwards;
}

@keyframes row-enter {
  from { opacity: 0; transform: translateY(14px) scaleY(0.85); }
  to { opacity: 1; transform: none; }
}

/* --- Width overrides ---------------------------------------------------- */

/* These sit below every base rule on purpose. A rule inside @media carries no
   extra specificity, so an override written *above* the rule it overrides
   silently loses at every width — which is how the two-up label size, the
   phone rank cell and the HUD's tighter margin all shipped doing nothing.
   test_css_cascade.py now fails on any repeat. */

/* Above this width the board is the real thing: two columns of three, read
   down the left then down the right, exactly as the numbering says. It is
   worth more than the aesthetics — six stacked rows are 371px of a 768px
   laptop screen, which is what pushed the guess input and the strikes below
   the fold. Two columns give 189px of that back.

   900px rather than a round 960: at 900 the shell is already at its 860px
   max-width, so the columns get their full size the moment they appear
   instead of starting cramped. */
@media (min-width: 900px) {
  /* A two-up board needs more room than a reading measure. At the 860px stage
     each column leaves 286px for an answer, and real answers overflow it —
     TOILET PAPER ORIENTATION needs 363px, FINGER OVER THE LENS needs 306px,
     and a squeezed answer is a worse board than a narrow one. Only the
     gameplay stage widens; prose pages keep 860. */
  .shell--stage { max-width: 1040px; }

  .board {
    /* `repeat()` accepts a var here because custom-property substitution is
       textual and happens before the property is parsed. --board-rows is
       ceil(n/2), set by the template and refreshed by resetBoard. */
    grid-template-rows: repeat(var(--board-rows, 3), 56px);
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* Column-major fill is what makes 1,2,3 the left column and 4,5,6 the
       right one. Row-major would deal them 1,2 / 3,4 / 5,6. */
    grid-auto-flow: column;
    column-gap: var(--gap);
  }

  /* An odd board leaves the last cell empty rather than stretching a row
     across both columns — a 7-row board reads 1-4 down the left, 5-7 down
     the right, and the gap sits where the eighth answer would be. */

  /* One step down for the answer label, and only here: a half-width row has
     roughly half the room, and 20px is what makes the longest real answers
     fit outright instead of shrinking. Everything else — the question, the
     score, the rank, the points, the input — keeps its size. */
  .board-face__label { font-size: clamp(14px, 3.6vw, 20px); }

  /* Vertical rhythm, tightened only where the two-column board applies.
     Nothing gets smaller — the type, the rows, the pod and the input all keep
     their size. This is only the air between them, and it is the difference
     between the whole sequence landing on a 768px laptop and not. (The HUD's
     share of it lives in hud.css, which loads after this file.) */
  .question-block { padding: var(--gap) 0 var(--gap-sm); }
  .score-pod { margin: var(--gap-sm) auto var(--gap); }
}

/* Tight enough that an eight-row board and the HUD share a 667px viewport
   without scrolling — the board is the game, so it stays on screen. */
@media (max-width: 560px) {
  .board { gap: 4px; }
  .board-row { height: 40px; }
  .board-row__rank { width: 34px; font-size: 16px; }
  .question-block { padding: 10px 0 4px; }
  .score-pod {
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    padding: 4px 18px;
    margin: 8px auto 10px;
  }
  .score-pod__value { font-size: 30px; }
}

@media (prefers-reduced-motion: reduce) {
  .board-row__inner {
    transition: opacity var(--t-flip) ease;
    transform-style: flat;
  }
  .board-row.is-revealed .board-row__inner { transform: none; }
  .board-face {
    backface-visibility: visible;
    transition: opacity var(--t-flip) ease;
  }
  .board-face--back { transform: none; opacity: 0; }
  .board-row.is-revealed .board-face--front { opacity: 0; }
  .board-row.is-revealed .board-face--back { opacity: 1; }
  .board-row.is-bumping .board-face--back { animation: none; }
  .board-row.is-entering { animation: none; }
}
