/* TV-first styling: high contrast, no hover states, everything inside a 5%
   overscan-safe margin. Deliberately avoids flex `gap`, clamp() and :is() so
   that older TV browser engines (Tizen / webOS / Fire TV) render it correctly. */

:root {
  --bg: #0b0e17;
  --panel: #161b2b;
  --panel-2: #1f2537;
  --ink: #f2f5ff;
  --dim: #93a0c0;
  --accent: #ffd23f;
  --good: #38d17a;
  --bad: #ff5d5d;
  --line: #2c344c;
}

* { box-sizing: border-box; }

html {
  font-size: 18px;
  background: var(--bg);
}

/* Televisions and desktops scale with the viewport, so the layout holds at any
   panel size. Phones keep a fixed root and get their own block at the end of
   this file - scaling type to a phone's height makes it far too large. */
@media (min-width: 800px) and (min-height: 700px) {
  html { font-size: 2.2vh; }
}

body {
  margin: 0;
  padding: 5vh 5vw;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font-family: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: 1.4rem;
  line-height: 1.35;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: rgba(255, 210, 63, 0.22);
  overflow: hidden;
}

#screen {
  display: flex;
  flex-direction: column;
  min-height: 90vh;
  position: relative;      /* anchors the version tag to the safe area */
}

/* Title screen only. Sits inside the overscan-safe margin, not the raw corner
   of the panel, so a television does not crop it. */
.version {
  position: absolute;
  top: 0;
  right: 0;
  font-size: 0.9rem;
  letter-spacing: 0.1em;
  color: var(--dim);
  text-align: right;
}

/* The last key the page actually received. Blank until something arrives, so
   it costs nothing until it is the thing you need. */
.lastkey {
  display: block;
  margin-top: 0.3rem;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  opacity: 0.6;
}

/* ---------------------------------------------------------------- headings */

.eyebrow {
  font-size: 1.1rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.6rem;
}

h1 {
  font-size: 4.4rem;
  line-height: 1.05;
  margin: 0 0 1.5rem;
  letter-spacing: -0.01em;
}

h2 {
  font-size: 2.4rem;
  margin: 0 0 1.2rem;
}

.grow { flex: 1 1 auto; }

/* ------------------------------------------------------------------ status */

.statusbar {
  display: flex;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--line);
  padding-bottom: 0.8rem;
  margin-bottom: 1.6rem;
}

.statusbar .slot {
  margin-right: 1.6rem;
  font-size: 1.15rem;
  color: var(--dim);
}

.statusbar .slot b {
  color: var(--ink);
  font-weight: 700;
}

/* ------------------------------------------------------------------ player */

.playerstrip { display: flex; flex-wrap: wrap; margin-bottom: 1.4rem; }

.pcard {
  border: 3px solid var(--line);
  border-radius: 0.7rem;
  padding: 0.7rem 1.1rem;
  margin: 0 0.8rem 0.8rem 0;
  background: var(--panel);
  min-width: 9rem;
}

.pcard.up {
  border-color: var(--accent);
  background: var(--panel-2);
}

.pcard .pname {
  font-size: 1.2rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pcard .pscore { font-size: 2rem; font-weight: 800; color: var(--accent); }
.pcard .pledger { font-size: 1rem; color: var(--dim); letter-spacing: 0.08em; }

/* ----------------------------------------------------------------- options */

.question {
  font-size: 3.1rem;
  line-height: 1.2;
  font-weight: 700;
  margin: 0 0 2rem;
  max-width: 40ch;
}

.options { display: block; }

.opt {
  display: flex;
  align-items: center;
  border: 4px solid var(--line);
  border-radius: 0.7rem;
  background: var(--panel);
  padding: 0.85rem 1.2rem;
  margin-bottom: 0.8rem;
  font-size: 1.7rem;
  min-height: 4.2rem;
}

.opt .letter {
  font-weight: 800;
  color: var(--dim);
  margin-right: 1.1rem;
  min-width: 2rem;
}

.opt.hidden { opacity: 0.3; }
.opt.hidden .text { color: var(--dim); font-style: italic; }

/* The slot that reveals next, distinguished from the ones behind it without
   spending any words on it. */
.opt.hidden.tappable { opacity: 0.55; border-style: dashed; }

.opt.sel {
  border-color: var(--accent);
  box-shadow: 0 0 0 6px rgba(255, 210, 63, 0.28);
  background: var(--panel-2);
}

.opt.correct { border-color: var(--good); background: rgba(56, 209, 122, 0.18); }
.opt.wrong { border-color: var(--bad); background: rgba(255, 93, 93, 0.18); }
.opt.dead { opacity: 0.3; }

/* -------------------------------------------------------------------- tiles */

.tiles { display: flex; flex-wrap: wrap; }

.tile {
  border: 4px solid var(--line);
  border-radius: 0.7rem;
  background: var(--panel);
  padding: 1rem 1.4rem;
  margin: 0 0.9rem 0.9rem 0;
  font-size: 1.9rem;
  font-weight: 700;
  text-align: center;
  min-width: 4.5rem;
}

.tile.sel {
  border-color: var(--accent);
  box-shadow: 0 0 0 6px rgba(255, 210, 63, 0.28);
  background: var(--panel-2);
}

.tile.spent { opacity: 0.3; text-decoration: line-through; }
.tile.gone { opacity: 0.25; text-decoration: line-through; border-style: dashed; }
.tile.wide { min-width: 14rem; text-align: left; font-size: 1.5rem; }

/* Type scales down as the question and its options get longer, so a television
   never has to clip what it cannot scroll. See densityClass() in app.js. */
.qblock.dense-1 .question { font-size: 2.5rem; }
.qblock.dense-1 .opt { font-size: 1.45rem; min-height: 3.7rem; }

.qblock.dense-2 .question { font-size: 2.1rem; margin-bottom: 1.4rem; }
.qblock.dense-2 .opt { font-size: 1.3rem; min-height: 3.2rem; margin-bottom: 0.6rem; }

.qblock.dense-3 .question { font-size: 1.7rem; margin-bottom: 1rem; }
.qblock.dense-3 .opt { font-size: 1.1rem; min-height: 2.7rem; margin-bottom: 0.45rem; }

/* -------------------------------------------------------------------- verdict */

.verdict { font-size: 3.6rem; font-weight: 800; margin-bottom: 0.8rem; }
.verdict.tight { font-size: 2.3rem; margin-bottom: 0.4rem; }

/* Beside a question block the detail line has to stay on one row, so let it
   run wider rather than wrapping and pushing the hint bar off the screen. */
.verdict.tight + .note { max-width: 96ch; font-size: 1.15rem; margin-top: 0; }
.verdict.good { color: var(--good); }
.verdict.bad { color: var(--bad); }

.bignum { font-size: 6rem; font-weight: 800; color: var(--accent); line-height: 1; }
.answer { font-size: 2.6rem; font-weight: 700; color: var(--good); margin: 1rem 0; }
.note { font-size: 1.3rem; color: var(--dim); margin-top: 0.7rem; max-width: 46ch; }

.clock {
  font-size: 7rem;
  font-weight: 800;
  line-height: 1;
  margin-bottom: 1.4rem;
  font-variant-numeric: tabular-nums;
}
.clock.low { color: var(--bad); }

/* ------------------------------------------------------------------ name field */

/* Focusing this is what summons the TV's own keyboard. */
.namefield {
  display: block;
  width: 100%;
  max-width: 24rem;
  font-family: inherit;
  font-size: 2.4rem;
  font-weight: 700;
  color: var(--ink);
  background: var(--panel);
  border: 4px solid var(--line);
  border-radius: 0.7rem;
  padding: 0.7rem 1rem;
  margin-bottom: 1.4rem;
  -webkit-appearance: none;
  appearance: none;
}

.namefield:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 6px rgba(255, 210, 63, 0.28);
  background: var(--panel-2);
}

.namefield::placeholder { color: var(--dim); font-weight: 400; }
.namefield::-webkit-input-placeholder { color: var(--dim); font-weight: 400; }

/* ---------------------------------------------------------------- scoreboard */

.rank { display: flex; align-items: baseline; margin-bottom: 0.9rem; font-size: 2.2rem; }
.rank .pos { color: var(--dim); min-width: 3.5rem; font-weight: 800; }
.rank .nm { flex: 1 1 auto; font-weight: 700; }
.rank .sc { color: var(--accent); font-weight: 800; margin-left: 1.5rem; }
.rank.first .nm, .rank.first .sc { color: var(--accent); }

/* ------------------------------------------------------------------ pointer */

/* Pointer is secondary input, so nothing here carries meaning on its own -
   the focus ring drawn for the remote stays the source of truth. */
.hint-key, .opt.tappable, .tile.tappable {
  cursor: pointer;
  touch-action: manipulation;
}

.hint-key.dead { cursor: default; }

@media (hover: hover) {
  .hint-key:hover, .opt.tappable:hover, .tile.tappable:hover {
    border-color: var(--dim);
  }
  .opt.sel:hover, .tile.sel:hover { border-color: var(--accent); }
}

/* --------------------------------------------------------------------- hints */

.hints {
  margin-top: auto;
  padding-top: 1.2rem;
  border-top: 2px solid var(--line);
  color: var(--dim);
  font-size: 1.15rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

/* Each hint is also a touch target: the chip dispatches the key it names. */
.hint {
  display: flex;
  align-items: center;
  margin-right: 1.6rem;
  margin-bottom: 0.3rem;
  white-space: nowrap;
}

.hint-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.6rem;
  min-height: 2.6rem;
  padding: 0 0.55rem;
  margin-right: 0.3rem;
  border: 2px solid var(--line);
  border-radius: 0.4rem;
  background: var(--panel);
  color: var(--ink);
  font-weight: 700;
}

/* A hint with no key behind it, e.g. a label. Not a target. */
.hint-key.dead {
  border-color: transparent;
  background: none;
  color: var(--dim);
  min-width: 0;
  min-height: 0;
  padding: 0;
}

.hint-label { margin-left: 0.35rem; }

.catlist { color: var(--dim); font-size: 1.2rem; margin-bottom: 1.2rem; }
.catlist b { color: var(--ink); }

/* ------------------------------------------------------------- small screens */

/* Phones and small tablets. The 5% overscan margin is a television concern and
   only wastes space here, so it gives way to the safe-area insets - the
   viewport is `viewport-fit=cover`, so without these the Dynamic Island and the
   home indicator would sit on top of the game. Content scrolls rather than
   being clipped, because unlike a television a phone cannot fit a whole screen
   of the game at a legible size.

   Narrow OR short: a phone held sideways is 874x402, wider than any phone
   breakpoint but far too short for the television layout. */
@media (max-width: 799px), (max-height: 550px) {
  /* An app shell. The page itself never scrolls - the content region does -
     so nothing is position:fixed and no height is measured in script. That
     matters most in a standalone PWA window, where a fixed bar above a
     body-scrolled page is exactly the arrangement that misbehaves. */
  html, body { height: 100%; }

  body {
    min-height: 0;
    padding:
      calc(env(safe-area-inset-top, 0px) + 0.9rem)
      calc(env(safe-area-inset-right, 0px) + 1rem)
      calc(env(safe-area-inset-bottom, 0px) + 0.5rem)
      calc(env(safe-area-inset-left, 0px) + 1rem);
    overflow: hidden;
  }

  #screen { height: 100%; min-height: 0; }

  .screen-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
  }

  h1 { font-size: 2.4rem; margin-bottom: 1rem; }
  h2 { font-size: 1.5rem; margin-bottom: 0.8rem; }
  .eyebrow { font-size: 0.85rem; letter-spacing: 0.16em; }

  .question { font-size: 1.7rem; max-width: none; margin-bottom: 1.2rem; }

  .opt {
    font-size: 1.15rem;
    min-height: 3.1rem;
    min-height: max(3.1rem, 34px);
    padding: 0.6rem 0.8rem;
    margin-bottom: 0.55rem;
    border-width: 3px;
  }
  .opt .letter { margin-right: 0.7rem; min-width: 1.3rem; }
  .opt.sel { box-shadow: 0 0 0 4px rgba(255, 210, 63, 0.28); }

  /* Spacing moves to a gap on the row, so a wrapped tile does not carry a
     trailing margin into the next column. */
  .tiles { gap: 0.5rem; }

  .tile {
    min-height: 34px;
    font-size: 1.4rem;
    min-width: 3.6rem;
    padding: 0.75rem 0.9rem;
    margin: 0;
    border-width: 3px;
  }
  .tile.sel { box-shadow: 0 0 0 4px rgba(255, 210, 63, 0.28); }

  /* Category names are long, so give each one a comfortable minimum and let
     the row pack as many columns as the width allows: one on a phone held
     upright, three or four held sideways. Stacked full width, eight of them
     could not be made to fit sideways at any type size - the tiles have a
     floor in px so a finger can still hit them - while 850 pixels of width
     sat unused beside them. */
  .tile.wide {
    width: auto;
    flex: 1 1 190px;
    min-width: 0;
    font-size: 1.15rem;
  }

  /* The density rules carry more specificity than a bare `.question`, and a
     media query adds none, so the phone scale has to be restated here. */
  .qblock.dense-1 .question { font-size: 1.5rem; }
  .qblock.dense-2 .question { font-size: 1.35rem; }
  .qblock.dense-3 .question { font-size: 1.2rem; }
  .qblock.dense-1 .opt { font-size: 1.1rem; min-height: max(2.9rem, 34px); }
  .qblock.dense-2 .opt {
    font-size: 1.05rem; min-height: max(2.7rem, 34px);
    padding: 0.45rem 0.7rem; line-height: 1.25;
  }
  .qblock.dense-3 .opt {
    font-size: 1rem; min-height: max(2.6rem, 34px);
    padding: 0.35rem 0.6rem; line-height: 1.2; margin-bottom: 0.4rem;
  }
  .qblock.dense-3 .question { line-height: 1.15; }

  .namefield { font-size: 1.6rem; max-width: none; border-width: 3px; }
  /* The field runs the full width here, so an outset glow would be clipped. */
  .namefield:focus { box-shadow: inset 0 0 0 3px rgba(255, 210, 63, 0.35); }

  .statusbar { margin-bottom: 1rem; padding-bottom: 0.6rem; }
  .statusbar .slot { font-size: 0.95rem; margin-right: 1rem; }

  .pcard { min-width: 6.5rem; padding: 0.5rem 0.7rem; margin: 0 0.5rem 0.5rem 0; }
  .pcard .pname { font-size: 0.95rem; }
  .pcard .pscore { font-size: 1.5rem; }
  .pcard .pledger { font-size: 0.85rem; }

  .verdict { font-size: 2.1rem; }
  .bignum { font-size: 3.4rem; }
  .answer { font-size: 1.5rem; }
  .clock { font-size: 3.4rem; margin-bottom: 0.9rem; }
  .note { font-size: 1rem; max-width: none; }
  .catlist { font-size: 0.95rem; }

  .rank { font-size: 1.4rem; margin-bottom: 0.6rem; }
  .rank .pos { min-width: 2.2rem; }

  /* The chips are the controls on a touch screen, so the bar holds its place
     at the bottom of the shell while the content scrolls beside it. As an
     ordinary flex sibling it cannot overlap that content at all - which is
     what a sticky, and then a fixed, bar both managed to do. */
  .hints {
    flex: 0 0 auto;
    margin-top: 0;
    font-size: 16px;
    padding-top: 12px;
    padding-bottom: 2px;
  }

  /* Fixed in px on purpose. These are the controls; shrinking the board to fit
     must never shrink what you have to hit to use it. */
  .hint-key {
    min-width: 44px;
    min-height: 44px;
    padding: 0 8px;
    font-size: 15px;
  }
  .hint { margin-right: 14px; margin-bottom: 3px; }
  .hint-label { font-size: 14px; margin-left: 5px; }
}

/* Narrow phones. The control bar wrapped to three rows here - a quarter of the
   screen - which pushed the last option underneath it. Shrink the labels and
   the gaps rather than the chips, so the touch targets stay full size. */
@media (max-width: 420px) {
  .hint { margin-right: 10px; }
  .hint-label { font-size: 13px; margin-left: 4px; }
  .hint-key { padding: 0 6px; font-size: 14px; }

  .statusbar { margin-bottom: 0.7rem; }
  .statusbar .slot { font-size: 0.85rem; margin-right: 0.7rem; }

  .catlist { font-size: 0.85rem; margin-bottom: 0.7rem; }
  .question { margin-bottom: 0.9rem; }
  .opt { min-height: 2.9rem; margin-bottom: 0.45rem; }
}

/* A phone held sideways: the same rules, with the vertical rhythm squeezed. */
@media (max-height: 550px) and (max-width: 1100px) {
  h1 { font-size: 1.9rem; margin-bottom: 0.6rem; }
  .question { font-size: 1.35rem; margin-bottom: 0.7rem; }
  .qblock.dense-1 .question { font-size: 1.25rem; }
  .qblock.dense-2 .question { font-size: 1.15rem; }
  .qblock.dense-3 .question { font-size: 1.05rem; }
  .clock, .bignum { font-size: 2.6rem; margin-bottom: 0.5rem; }
  .verdict { font-size: 1.7rem; }
  .verdict.tight { font-size: 1.3rem; }
  .playerstrip { margin-bottom: 0.6rem; }
  .statusbar { margin-bottom: 0.6rem; }
  .catlist { margin-bottom: 0.6rem; }
}

/* Sideways there is width to spare and no height at all, so the options go
   two-up. In one column the last of them fell below the fold - and the one
   above it landed under the control bar - which is what made the bottom half
   of the board untappable without discovering that the page scrolls. */
@media (max-height: 550px) and (min-width: 600px) and (max-width: 1100px) {
  .options { display: flex; flex-wrap: wrap; }

  .opt {
    width: calc(50% - 0.3rem);
    margin-right: 0.6rem;
    margin-bottom: 0.5rem;
    min-height: max(2.6rem, 34px);
    font-size: 1.05rem;
  }
  .opt:nth-child(2n) { margin-right: 0; }

  .qblock.dense-1 .opt,
  .qblock.dense-2 .opt,
  .qblock.dense-3 .opt { min-height: max(2.5rem, 34px); font-size: 1rem; }
}

/* Sideways on something narrow enough that two columns would not fit. */
@media (max-height: 550px) and (max-width: 599px) {
  .opt { min-height: max(2.5rem, 34px); margin-bottom: 0.35rem; font-size: 1rem; }
}

/* Diagnostics on the error screens. Small, dim, and allowed to break anywhere,
   since a user agent string has no spaces to wrap at. */
.note.diag {
  font-size: 0.95rem;
  opacity: 0.65;
  word-break: break-all;
  max-width: 70ch;
  margin-top: 0.4rem;
}

/* Samsung televisions offer "link browsing", where the D-pad walks the
   browser's own focus between focusable elements instead of driving a pointer.
   The focus ring is the only thing showing where you are, so it has to be as
   loud as the cursor highlight - and it must never be removed, which is the
   one thing an outline reset would do here. */
[data-act]:focus,
[data-pick]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 5px rgba(255, 210, 63, 0.45);
  background: var(--panel-2);
}

/* Where the browser distinguishes them, keep the ring for keyboard and remote
   focus and drop it for a plain click, which already has the pressed state. */
[data-act]:focus:not(:focus-visible),
[data-pick]:focus:not(:focus-visible) {
  box-shadow: none;
}
