/* Vang Bros Cornhole
 *
 * Dark field, flame-gradient accents, team colours held deliberately apart from
 * the brand palette so a score readout is never confused with UI chrome. The
 * orange-yellow gradient never appears inside a team's score area.
 *
 * Sized for thumbs: nothing tappable is under 44px, and the two scores own the
 * top of the screen because that is what someone standing at a board is
 * actually looking for.
 */

:root {
  /* Brand — taken from the artwork itself, not guessed. */
  --flame-from: #FF8E09;
  --flame-to: #FCF608;
  --ink: #000000;
  --paper: #FFFFFF;

  /* Field */
  --bg: #000000;
  --surface: #111214;
  --surface-2: #191b1f;
  --line: #292c33;
  --text: #F2F3F5;
  --muted: #9AA1AC;

  /* Teams — chosen for contrast on black and for distance from the flame. */
  --blue: #3B82F6;
  --blue-soft: rgba(59, 130, 246, 0.14);
  --red: #F4374A;
  --red-soft: rgba(244, 55, 74, 0.14);

  /* Darker variants for team colour used as TEXT on the white score cards.
     The vivid --blue/--red read well on black but only reach about 3.7:1 on
     white, which is inside the large-text rule and outside any comfort margin
     for a phone in direct sun. These clear 6:1. */
  --blue-ink: #1D4ED8;
  --red-ink: #C41B29;

  --radius: 14px;
  --radius-sm: 10px;
  --tap: 48px;

  --font: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
  overscroll-behavior-y: none;
}

body {
  min-height: 100svh;
  padding-bottom: calc(72px + var(--safe-bottom));
}

button { font-family: inherit; }

.noscript { padding: 24px; color: var(--muted); }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------------ topbar */

.topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
  padding-top: calc(10px + env(safe-area-inset-top, 0px));
  background: var(--bg);
  position: sticky;
  top: 0;
  z-index: 20;
}

/* The logo carries its own black plate, so it needs a light ground. */
.logo-plate {
  background: var(--paper);
  border-radius: 8px;
  padding: 5px 9px;
  display: flex;
  align-items: center;
  line-height: 0;
}

.logo-plate img {
  display: block;
  width: 132px;
  height: auto;
}

.topbar-title {
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}

/* -------------------------------------------------------------------- view */

.app { display: block; }

.view {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px;
  max-width: 720px;
  margin: 0 auto;
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.card-title {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
}

.hint { margin: 0; color: var(--muted); font-size: 13px; }
.empty { margin: 0; color: var(--muted); }

.link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--flame-from);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

.row { display: flex; align-items: center; }
.row-gap { gap: 10px; flex-wrap: wrap; }
.row-mt { margin-top: 4px; }

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

.btn {
  min-height: var(--tap);
  padding: 0 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 0.06s ease, filter 0.12s ease;
}

.btn:active:not(:disabled) { transform: scale(0.97); }
.btn:disabled { opacity: 0.38; cursor: not-allowed; }

.btn-primary {
  background: linear-gradient(95deg, var(--flame-from), var(--flame-to));
  color: var(--ink);
  border-color: transparent;
  font-weight: 800;
}

.btn-ghost { background: transparent; }
.btn-danger { color: var(--red); border-color: rgba(244, 55, 74, 0.4); background: transparent; }
.btn-block { width: 100%; }
.btn-small { min-height: 38px; padding: 0 12px; font-size: 13px; }

.btn-step {
  min-width: 46px;
  min-height: 46px;
  padding: 0;
  font-size: 22px;
  line-height: 1;
}

.input {
  flex: 1 1 160px;
  min-height: var(--tap);
  padding: 0 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
  font-size: 16px; /* 16px or iOS zooms the page on focus */
}

.input::placeholder { color: var(--muted); }

/* ------------------------------------------------------------------- chips */

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chips-stack { flex-direction: column; }

.chip {
  min-height: 44px;
  padding: 0 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}

.chip.is-active {
  background: linear-gradient(95deg, var(--flame-from), var(--flame-to));
  color: var(--ink);
  border-color: transparent;
}

.chip-wide {
  border-radius: var(--radius-sm);
  width: 100%;
  text-align: left;
  padding: 10px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 56px;
}

.chip-title { font-weight: 700; }
.chip-hint { font-size: 12px; opacity: 0.72; font-weight: 500; }
.chip-player { font-weight: 500; }

/* -------------------------------------------------------------- team setup */

.teams { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.team-col {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.team-blue { border-color: rgba(59, 130, 246, 0.45); background: var(--blue-soft); }
.team-red { border-color: rgba(244, 55, 74, 0.45); background: var(--red-soft); }

.team-label {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
}

.team-blue .team-label { color: var(--blue); }
.team-red .team-label { color: var(--red); }

.slot {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  border: 1px dashed var(--line);
  background: transparent;
  color: var(--muted);
  font-size: 14px;
  padding: 0 8px;
  text-align: center;
}

.slot.is-filled {
  border-style: solid;
  border-color: var(--line);
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  cursor: pointer;
}

.pool { display: flex; flex-direction: column; gap: 8px; }

.target-value {
  font-size: 30px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  min-width: 60px;
  text-align: center;
}

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

.scoreboard {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 8px;
  align-items: stretch;
}

.score-block {
  border-radius: var(--radius);
  border: 1px solid var(--line);
  padding: 12px 8px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 2px;
  justify-content: flex-start;
}

.score-blue { border-color: rgba(59, 130, 246, 0.5); background: var(--blue-soft); }
.score-red { border-color: rgba(244, 55, 74, 0.5); background: var(--red-soft); }

.score-team {
  font-size: 12px;
  letter-spacing: 0.18em;
  font-weight: 800;
}

.score-blue .score-team { color: var(--blue); }
.score-red .score-team { color: var(--red); }

.score-value {
  font-size: clamp(56px, 20vw, 88px);
  line-height: 1;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.03em;
}

.score-delta { font-size: 12px; color: var(--muted); min-height: 16px; }

.score-names { display: flex; flex-direction: column; gap: 1px; margin-top: 4px; }
.score-name { font-size: 13px; color: var(--muted); }

.score-target {
  margin-top: 6px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.12em;
  color: var(--text);
}

.score-meta {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 4px;
}

.round-no {
  font-size: 20px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.mode-tag {
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  max-width: 84px;
}

/* --------------------------------------------------------- bag-by-bag mode */

/* One row per player, each with its own outcome buttons. The scorekeeper taps
   the row of whoever actually threw — the app suggests who is up next but never
   enforces it, because a real end alternates and people look away. */

.bag-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  border-left-width: 3px;
}

.bag-row.throw-blue { border-left-color: var(--blue); background: var(--blue-soft); }
.bag-row.throw-red { border-left-color: var(--red); background: var(--red-soft); }

.bag-row.is-next { border-color: var(--flame-from); border-left-color: var(--flame-from); }
.bag-row.is-done { opacity: 0.5; }

.bag-who { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.bag-dot { color: var(--flame-from); font-size: 12px; width: 12px; }
.bag-name { font-size: 17px; font-weight: 700; }

.bag-side {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  padding: 2px 7px;
  border-radius: 999px;
}

.bag-who .throw-bags { margin-left: auto; }

.bag-actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.bag-actions .btn { min-height: 56px; font-size: 14px; font-weight: 800; letter-spacing: 0.05em; }

.pill-blue { background: var(--blue-soft); color: var(--blue); }
.pill-red { background: var(--red-soft); color: var(--red); }

.bag-hole { border-color: rgba(52, 211, 153, 0.5); color: #34D399; }
.bag-board { border-color: rgba(148, 163, 184, 0.5); color: #CBD5E1; }
.bag-miss { border-color: var(--line); color: var(--muted); }

.throw-bags { display: flex; gap: 4px; }

.pip {
  width: 22px;
  height: 22px;
  border-radius: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  background: var(--surface-2);
  color: var(--muted);
}

.pip-hole { background: rgba(52, 211, 153, 0.22); color: #34D399; }
.pip-board { background: rgba(203, 213, 225, 0.18); color: #CBD5E1; }
.pip-miss { background: var(--surface-2); color: var(--muted); }
.pip-empty { opacity: 0.4; }

/* ------------------------------------------------------------- counts mode */

.count-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  padding: 8px;
  border-radius: 8px;
  border-left: 3px solid transparent;
}

.count-name { display: flex; flex-direction: column; }
.count-player { font-weight: 700; }
.count-raw { font-size: 12px; color: var(--muted); }

/* min-width:0 because a flex item defaults to min-width:auto, which is what
   let this block refuse to shrink and push its + button off the card. */
.count-steppers { display: flex; gap: 12px; flex-wrap: wrap; min-width: 0; }

.stepper { display: flex; align-items: center; gap: 6px; min-width: 0; }
.stepper-controls { display: flex; align-items: center; gap: 6px; }
.stepper-label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }
.stepper-value { min-width: 22px; text-align: center; font-weight: 800; font-variant-numeric: tabular-nums; }

/* Phones.
 *
 * Two steppers laid out side by side need about 353px of row; a 375px phone
 * offers 314px inside the card, so the second one used to hang off the right
 * edge with its + button flush against the screen. Stacking the label above
 * its controls drops each stepper to roughly 126px, which fits two across even
 * at 320px — without shrinking a single tap target. */
@media (max-width: 460px) {
  .count-row { flex-direction: column; align-items: stretch; gap: 8px; }
  .count-name { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 8px; }
  .count-steppers { width: 100%; gap: 10px; }
  .stepper { flex: 1 1 0; flex-direction: column; align-items: stretch; gap: 4px; }
  .stepper-label { text-align: center; }
  .stepper-controls { justify-content: space-between; }
  .btn-step { flex: 0 0 auto; }
}

/* The smallest phones still in use (320px). The 46px targets are kept; only
   the space between them gives way, which is the right thing to trade. */
@media (max-width: 360px) {
  .count-steppers { gap: 6px; }
  .stepper-controls { gap: 2px; }
  .stepper-value { min-width: 18px; }
}

/* --------------------------------------------------------------- taps mode */

.taps { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.tap-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
}

.tap-blue { border-color: rgba(59, 130, 246, 0.45); background: var(--blue-soft); }
.tap-red { border-color: rgba(244, 55, 74, 0.45); background: var(--red-soft); }
.tap-blue .team-label { color: var(--blue); }
.tap-red .team-label { color: var(--red); }

.btn-tap { min-height: 68px; font-size: 24px; font-weight: 800; }

/* ----------------------------------------------------------- round history */

.history-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  padding: 4px 0;
  border-bottom: 1px solid var(--line);
}

.history-row:last-child { border-bottom: 0; }
.history-round { font-weight: 700; min-width: 32px; color: var(--muted); }
.history-net { font-weight: 700; }
.history-net.is-blue { color: var(--blue); }
.history-net.is-red { color: var(--red); }
.history-net.is-wash { color: var(--muted); }
.history-detail { margin-left: auto; color: var(--muted); }

.controls { display: flex; flex-direction: column; gap: 10px; }
.controls .btn { flex: 1; }

/* ------------------------------------------------------- roster and tables */

.player-list { display: flex; flex-direction: column; gap: 8px; }

.player-row {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.player-row:last-child { border-bottom: 0; }
.player-main { display: flex; flex-direction: column; min-width: 0; }
.player-name { font-weight: 700; }
.player-name.is-archived { color: var(--muted); }
.player-line { font-size: 12px; color: var(--muted); }

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.stats-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.stats-table th, .stats-table td { padding: 8px 6px; text-align: right; white-space: nowrap; }
.stats-table th:first-child, .stats-table td:first-child { text-align: left; }
.stats-table thead th {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
}
.stats-table tbody tr { border-bottom: 1px solid var(--line); }
.stats-table tbody tr:last-child { border-bottom: 0; }
.stats-table td.is-sorted, .stats-table th.is-sorted { color: var(--flame-from); }
.cell-name { font-weight: 600; }

.th-btn {
  background: none;
  border: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-transform: inherit;
  letter-spacing: inherit;
}

.game-list { display: flex; flex-direction: column; gap: 10px; }

.game-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}

.game-row:last-child { border-bottom: 0; }

.game-score { display: flex; gap: 6px; align-items: baseline; font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.gs-blue { color: var(--blue); opacity: 0.55; }
.gs-red { color: var(--red); opacity: 0.55; }
.gs-blue.is-winner, .gs-red.is-winner { opacity: 1; }
.gs-dash { color: var(--muted); }

.game-teams { display: flex; gap: 6px; font-size: 13px; flex-wrap: wrap; }
.gt-blue { color: var(--blue); }
.gt-red { color: var(--red); }
.gt-vs { color: var(--muted); }
.game-meta { font-size: 12px; color: var(--muted); }

/* ------------------------------------------------------------ tournaments */

.t-header { display: flex; flex-direction: column; gap: 4px; }
.t-name { margin: 0; font-size: 22px; }

.match-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}

.match-row:last-child { border-bottom: 0; }
.match-teams { display: flex; gap: 6px; flex: 1; flex-wrap: wrap; font-size: 14px; min-width: 0; }
.mt-blue { color: var(--blue); font-weight: 600; }
.mt-red { color: var(--red); font-weight: 600; }
.mt-vs { color: var(--muted); }
.match-score { font-weight: 800; font-variant-numeric: tabular-nums; }

.board-tag {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  min-width: 62px;
}

.champion {
  margin: 0;
  font-size: 22px;
  font-weight: 800;
  background: linear-gradient(95deg, var(--flame-from), var(--flame-to));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.bracket-group { display: flex; flex-direction: column; gap: 8px; }

/* A 16-entrant bracket does not fit a phone; it scrolls sideways rather than
   squeezing every match into an unreadable column. */
.bracket-scroll {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 6px;
}

.bracket-col { display: flex; flex-direction: column; gap: 8px; min-width: 168px; }

.bracket-round-label {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.bracket-match {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.bracket-match.is-done { opacity: 0.72; }

.bm-side { font-size: 13px; color: var(--muted); }
.bm-side.is-winner { color: var(--text); font-weight: 700; }
.bm-tag { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; }

/* -------------------------------------------------------------------- tabs */

.tabs {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding-bottom: var(--safe-bottom);
  z-index: 30;
}

.tab {
  min-height: 58px;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  border-top: 2px solid transparent;
}

.tab.is-active {
  color: var(--text);
  border-top-color: var(--flame-from);
}

/* ------------------------------------------------------------------- toast */

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(84px + var(--safe-bottom));
  transform: translate(-50%, 12px);
  max-width: min(92vw, 460px);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 14px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  z-index: 40;
  text-align: center;
}

.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

@media (min-width: 560px) {
  .logo-plate img { width: 168px; }
  .bag-actions .btn { min-height: 64px; font-size: 15px; }
}

/* --------------------------------------------------------- sharing and QR */

.share-pill { font-variant-numeric: tabular-nums; letter-spacing: 0.04em; }
.share-pill.is-live { color: #34D399; border-color: rgba(52, 211, 153, 0.45); }
.share-pill.is-offline { color: var(--muted); }

.sheet {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 50;
  overflow-y: auto;
}

.sheet-inner {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
  max-width: 420px;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
  align-items: center;
  text-align: center;
}

.sheet-title { margin: 0; font-size: 18px; }

/* The QR needs a white quiet zone regardless of the app's dark field. */
.qr-plate {
  background: var(--paper);
  padding: 10px;
  border-radius: 12px;
  line-height: 0;
}

.qr { display: block; width: min(260px, 62vw); height: auto; image-rendering: pixelated; }

.share-code {
  font-size: 44px;
  font-weight: 800;
  letter-spacing: 0.18em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(95deg, var(--flame-from), var(--flame-to));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  padding-left: 0.18em; /* balance the trailing letter-spacing */
}

.share-url { word-break: break-all; font-size: 12px; }

/* ------------------------------------------------------------ watch page */

.watch-body { padding-bottom: 0; }

.watch {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  max-width: 900px;
  margin: 0 auto;
  min-height: calc(100svh - 70px);
  justify-content: center;
}

.watch-board { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.watch-side {
  border-radius: var(--radius);
  border: 1px solid var(--line);
  padding: 18px 10px;
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.watch-blue { border-color: rgba(59, 130, 246, 0.5); background: var(--blue-soft); }
.watch-red { border-color: rgba(244, 55, 74, 0.5); background: var(--red-soft); }

.watch-team { font-size: 13px; letter-spacing: 0.2em; font-weight: 800; }
.watch-blue .watch-team { color: var(--blue); }
.watch-red .watch-team { color: var(--red); }

/* Sized to be read from across a garden. */
.watch-score {
  font-size: clamp(72px, 26vw, 190px);
  line-height: 0.95;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.04em;
}

.watch-names { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.watch-name { font-size: clamp(13px, 3.4vw, 18px); color: var(--muted); }
.watch-attarget { margin-top: 8px; font-size: 12px; font-weight: 800; letter-spacing: 0.12em; }

.watch-foot {
  display: flex;
  gap: 14px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  font-size: 14px;
  color: var(--muted);
}

.watch-round { font-weight: 700; color: var(--text); }
.watch-status.is-live { color: #34D399; }
.watch-status.is-waiting { color: var(--flame-from); }

.watch-message {
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
}

.watch-msg-title { margin: 0; font-size: 24px; }

.watch-input {
  flex: 0 1 180px;
  text-align: center;
  font-size: 28px;
  font-weight: 800;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  min-height: 62px;
}

@media (orientation: landscape) and (min-width: 700px) {
  .watch-score { font-size: clamp(90px, 18vw, 230px); }
}

/* ------------------------------------------------------- basic / taps mode */

/* Two full-width tiles stacked one above the other, so the phone can sit flat
   between two teams and each side reaches its own half.

   The score card is the control: its upper half adds a point, its lower half
   takes one off. A half-card target needs no aiming, which is the whole point
   when you are holding a drink in the other hand. */

.quick-card { gap: 8px; }
.btn-quick { min-height: 62px; font-size: 18px; letter-spacing: 0.02em; }

.tap-board {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.tap-tile {
  border-radius: var(--radius);
  overflow: hidden;
  border: 3px solid var(--line);
  background: var(--line);
}

.tap-blue { border-color: var(--blue); background: var(--blue); }
.tap-red { border-color: var(--red); background: var(--red); }

/* White card, dark room or bright sun — this is the readable combination, and
   it matches the light plate the logo already needs. */
.tap-card {
  position: relative;
  background: var(--paper);
  border-radius: calc(var(--radius) - 4px);
  height: clamp(180px, 30vh, 300px);
  overflow: hidden;
}

.tap-zone {
  position: absolute;
  left: 0;
  width: 100%;
  height: 50%;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.tap-zone-up { top: 0; }

/* The hairline is the seam between the two halves — it shows where the split
   is without labelling it. */
.tap-zone-down {
  bottom: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.12);
}

.tap-zone:active { background: rgba(0, 0, 0, 0.06); }
.tap-zone:focus-visible { outline: 3px solid var(--flame-from); outline-offset: -3px; }

/* Sits above both halves and must never intercept a tap. */
.tap-number {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  font-size: clamp(96px, 30vw, 190px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}

.tap-blue .tap-number { color: var(--blue-ink); }
.tap-red .tap-number { color: var(--red-ink); }

.tap-band {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 8px 12px;
  min-height: 46px;
}

.tap-band-name {
  color: var(--paper);
  font-size: clamp(17px, 4.6vw, 22px);
  font-weight: 800;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Kept out of the card so it cannot be hit by accident while tapping a half. */
.tap-plus3 {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 0 12px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: rgba(0, 0, 0, 0.22);
  color: var(--paper);
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
}

.tap-plus3:active { background: rgba(0, 0, 0, 0.4); }

.tap-middle {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 2px 0;
}

.tap-reset {
  min-height: 52px;
  padding: 0 18px;
  background: transparent;
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  line-height: 1.25;
  white-space: pre-line;
}

.tap-target { color: var(--muted); font-size: 13px; }

@media (min-width: 560px) {
  .tap-card { height: clamp(220px, 32vh, 340px); }
  .tap-number { font-size: clamp(120px, 20vw, 210px); }
}

/* ------------------------------------------------------------------ FAQ ---
 * Built on <details>, so the disclosure behaviour, keyboard handling and
 * screen-reader semantics come from the browser. The card gaps are tightened
 * here because a stack of questions reads as a list, not as separate blocks.
 */

.card .faq-item + .faq-item { margin-top: -4px; }

.faq-item {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  overflow: hidden;
}

.faq-item[open] { border-color: rgba(255, 142, 9, 0.35); }

.faq-q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: var(--tap);
  padding: 12px 14px;
  cursor: pointer;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.35;
  color: var(--text);
  list-style: none;
}

/* Safari draws its own triangle unless both of these are turned off. */
.faq-q::-webkit-details-marker { display: none; }
.faq-q::marker { content: ''; }

.faq-q:hover { background: rgba(255, 255, 255, 0.03); }
.faq-q:focus-visible { outline: 2px solid var(--flame-from); outline-offset: -2px; }

.faq-chevron {
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  border-right: 2px solid var(--muted);
  border-bottom: 2px solid var(--muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 120ms ease;
}

.faq-item[open] .faq-chevron {
  transform: rotate(225deg) translate(-2px, -2px);
  border-color: var(--flame-from);
}

.faq-a {
  padding: 0 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}

.faq-p { margin: 0; font-size: 14px; line-height: 1.55; color: var(--text); }

.faq-list { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.faq-list li { font-size: 14px; line-height: 1.5; color: var(--text); }

/* The lines people most often get wrong, lifted out of the prose. */
.faq-note {
  margin: 0;
  padding: 10px 12px;
  border-left: 3px solid var(--flame-from);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: rgba(255, 142, 9, 0.08);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
}

.faq-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.faq-table th, .faq-table td { padding: 8px 6px; text-align: left; vertical-align: top; }
.faq-table thead th {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.faq-table tbody tr { border-bottom: 1px solid var(--line); }
.faq-table tbody tr:last-child { border-bottom: 0; }
.faq-table td:last-child { color: var(--muted); white-space: nowrap; }

.faq-goto { align-self: flex-start; font-size: 14px; }

/* Five tabs is tight on a small phone; let the labels shrink rather than wrap. */
@media (max-width: 360px) {
  .tab { font-size: 11px; letter-spacing: 0.03em; }
}

/* ------------------------------------------------- delete / stats additions */

/* A destructive action that still has to sit in a row of ordinary ones. Muted
   until touched, so it reads as available rather than as a warning. */
.btn-danger-ghost { color: var(--red); }
.btn-danger-ghost:hover { background: var(--red-soft); }

.game-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

/* The roster row now holds three actions; let them wrap rather than squeeze
   the name column on a phone. */
.player-row .row { flex-wrap: wrap; gap: 6px; }

/* The team draw, mid-spin. Names change under the cursor, so the slots dim and
   lift slightly rather than sitting there looking like a finished result. */
.team-col.is-drawing .slot {
  opacity: 0.75;
  transform: translateY(-1px);
  transition: opacity 90ms linear, transform 90ms linear;
}

@media (prefers-reduced-motion: reduce) {
  .team-col.is-drawing .slot { opacity: 1; transform: none; transition: none; }
}

/* ------------------------------------------------ fitting the screen ------
 *
 * Two separate problems, both only visible on a real phone.
 *
 * 1. Double-tap zoom. On a tap-to-score app the second tap of a quick two
 *    point run was being read as a zoom gesture instead of a score. The
 *    `manipulation` value keeps panning and pinch-zoom and drops only the
 *    double-tap gesture, so nothing an actual user wants is lost.
 */
html { touch-action: manipulation; }

/*
 * 2. The basic scorekeeper did not fit. At 375x667 the page wanted 865px, so
 *    the second score sat behind the fixed tab bar and the reset button was
 *    off the bottom entirely — on the one screen where seeing both numbers at
 *    once is the entire point.
 *
 *    Rather than guess a height, the whole shell becomes a flex column pinned
 *    to the viewport and the board takes whatever is left after the header,
 *    the controls and the tab bar have had theirs. That is correct on any
 *    screen without a single magic number. `dvh` rather than `vh` because
 *    mobile browser chrome grows and shrinks as you scroll.
 */
body.is-taps {
  height: 100dvh;
  min-height: 0;
  padding-bottom: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

body.is-taps .topbar { position: static; flex: 0 0 auto; }
body.is-taps .app { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* `width: 100%` matters more than it looks. `.view` carries `margin: 0 auto`,
   and an auto margin on a flex item cancels the default stretch — so the
   moment `.app` became a flex column the view collapsed to its content width
   and sat narrow in the middle of the screen. The max-width still caps it. */
body.is-taps .view { flex: 1 1 auto; min-height: 0; width: 100%; gap: 10px; }

/* Part of the column now, so it can no longer cover anything. */
body.is-taps .tabs { position: static; flex: 0 0 auto; }

body.is-taps .tap-board { flex: 1 1 auto; min-height: 0; }
body.is-taps .tap-tile { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
body.is-taps .tap-card { flex: 1 1 auto; height: auto; min-height: 0; }
body.is-taps .tap-band { flex: 0 0 auto; }

/* The number now sizes off the card rather than the viewport, so it fills
   whatever space the card ended up with instead of overflowing it. The vw cap
   stops it running into the sides on a wide screen. The plain clamp above
   stays as the fallback wherever container units are unavailable. */
body.is-taps .tap-card { container-type: size; }
body.is-taps .tap-number { font-size: min(30vw, 66cqh); }

/* The controls are two stacked rows everywhere else. Here they collapse to
   one, which hands about 60px back to the scores — worth more on this screen
   than the extra breathing room. `display: contents` dissolves the inner rows
   so their buttons join the single flex line directly. */
body.is-taps .controls { flex-direction: row; gap: 6px; }
body.is-taps .controls > .row { display: contents; }
body.is-taps .controls .btn {
  flex: 1 1 0;
  min-width: 0;
  padding: 0 8px;
  font-size: 13px;
  min-height: 44px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
body.is-taps .tap-middle { padding: 0; }
body.is-taps .tap-reset { min-height: 44px; }

/* A floor, so the cards can never be squeezed out of existence. Without it a
   short viewport (landscape, or a small phone with the browser bars showing)
   drove flex-shrink all the way to a zero-height card. */
body.is-taps .tap-card { min-height: 72px; }

/* And if it genuinely cannot fit, scroll rather than clip. Locking the
   viewport is worth doing right up until it would hide something. */
body.is-taps .view { overflow-y: auto; }

/* Landscape, or any short screen: stand the two scores side by side instead of
   stacked. Width is the axis with room to spare when height is not. */
@media (orientation: landscape) and (max-height: 560px) {
  body.is-taps .tap-board { flex-direction: row; gap: 8px; }
  body.is-taps .tap-tile { flex: 1 1 0; }
  body.is-taps .tap-middle {
    flex: 0 0 auto;
    flex-direction: column;
    gap: 6px;
    align-self: center;
  }
  body.is-taps .tap-reset { writing-mode: horizontal-tb; font-size: 11px; padding: 0 10px; }
  body.is-taps .tap-number { font-size: min(18vw, 62cqh); }
}

/* The one irreversible action in the app, marked as such. Sits last on the
   screen, under the backup controls, so the export button is passed on the
   way to it. */
.danger-zone { border-color: rgba(244, 55, 74, 0.4); }
.danger-zone .card-title { color: var(--red); }
