/* Phone-first: large touch targets, portrait-friendly single column. */
* { box-sizing: border-box; }

/* The hidden attribute must always win — author display rules (button, flex
   containers) otherwise override the UA's [hidden] { display: none }. */
[hidden] { display: none !important; }

:root {
  --bg: #14162b;
  --card: #1f2240;
  --ink: #f2f3ff;
  --muted: #a9adce;
  --accent: #ff7a59;
  --accent-ink: #2a1008;
  --danger: #ff6b81;
  --ok: #4cd97b;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 18px;
}

#app {
  max-width: 480px;
  margin: 0 auto;
  padding: 16px 16px 48px;
}

h1 { font-size: 1.6rem; text-align: center; margin: 16px 0; }
h2 { font-size: 1.1rem; margin: 0 0 12px; }

.card {
  background: var(--card);
  border-radius: 14px;
  padding: 16px;
  margin-bottom: 16px;
}

label { display: block; color: var(--muted); font-size: 0.85rem; margin: 10px 0 4px; }

input {
  width: 100%;
  min-height: 48px;
  padding: 8px 12px;
  font-size: 1.1rem;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid #3a3e6b;
  border-radius: 10px;
}
#join-code { text-transform: uppercase; letter-spacing: 0.3em; font-weight: 700; }

select, textarea {
  width: 100%;
  min-height: 48px;
  padding: 8px 12px;
  font-size: 1.05rem;
  font-family: inherit;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid #3a3e6b;
  border-radius: 10px;
}
textarea { min-height: 72px; resize: vertical; }

button {
  display: block;
  width: 100%;
  min-height: 52px;
  margin-top: 14px;
  border: none;
  border-radius: 12px;
  font-size: 1.1rem;
  font-weight: 700;
  cursor: pointer;
  touch-action: manipulation;
}
button.primary { background: var(--accent); color: var(--accent-ink); }
button.secondary { background: transparent; color: var(--muted); border: 1px solid #3a3e6b; }
button:active { transform: scale(0.98); }

#lobby-code { color: var(--accent); letter-spacing: 0.15em; }

#roster { list-style: none; padding: 0; margin: 16px 0; }
#roster li {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--card);
  border-radius: 12px;
  padding: 14px 16px;
  margin-bottom: 8px;
  font-size: 1.05rem;
}
#roster .dot { width: 10px; height: 10px; border-radius: 50%; background: var(--ok); flex: none; }
#roster li.disconnected .dot { background: var(--muted); }
#roster li.disconnected { opacity: 0.55; }
#roster .badge {
  margin-left: auto;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 2px 8px;
}

.hint { color: var(--muted); text-align: center; font-size: 0.9rem; }

/* Phase 2: lobby deck picker (host-only) / deck-name label (everyone). */
#lobby-deck-picker { margin: 0 0 16px; text-align: left; }
#lobby-deck-label { margin: 0 0 16px; }

/* Phase 5: fake-players controls (public/bots.js) — host-only, rendered into
   #lobby-bots and #session-bots. */
#roster .badge-bot { color: var(--muted); border-color: #3a3e6b; }
#lobby-bots, #session-bots { margin: 0 0 16px; text-align: left; }
.bots-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.bots-row select { flex: 1 1 auto; min-width: 0; }
.bots-row button { flex: none; }

/* --- Question rounds (Phase 2) ------------------------------------------- */

#q-counter { margin-bottom: 0; }
#q-prompt { font-size: 1.35rem; margin: 6px 0 14px; }

#stage-outer { margin: 8px 0 4px; }
#stage-row { display: flex; align-items: center; gap: 8px; }

.axis-label {
  color: var(--muted);
  font-size: 0.8rem;
  text-align: center;
  margin: 6px 0;
}
.axis-label.side {
  flex: 0 0 64px;
  margin: 0;
  overflow-wrap: break-word;
}

#stage {
  position: relative;
  flex: 1;
  min-width: 0;
  background: var(--card);
  border: 1px solid #3a3e6b;
  border-radius: 14px;
  overflow: hidden;
  touch-action: none; /* phone-first: the stage owns its touches */
  cursor: crosshair;
}
#stage.kind-scale { aspect-ratio: 5 / 2; }
#stage.kind-plane { aspect-ratio: 1 / 1; }
/* Map: rendered slightly narrower than the raw 585:250 viewBox (stretched via
   preserveAspectRatio="none") to soften plate-carrée E-W stretch. Normalized
   coordinates are aspect-independent, so geometry stays consistent. */
#stage.kind-image { aspect-ratio: 1.9 / 1; }
/* Phase 10: the Missouri board is near-square (raw viewBox 690:480), a very
   different shape from the whole-continent US map above — its own modifier
   class, layered on top of (not replacing) .kind-image. */
#stage.kind-image.asset-mo-map { aspect-ratio: 1.2 / 1; }
/* Phase 10: bullseye rings read best on a square board, like the plane. */
#stage.kind-bullseye { aspect-ratio: 1 / 1; }

#backdrop, #dots-layer { position: absolute; inset: 0; }
#dots-layer { pointer-events: none; }
#backdrop svg { width: 100%; height: 100%; display: block; }

/* Phase 2: a custom deck's image backdrop (data-URI), on the live stage,
   results mini-boards, and the replay stage alike. */
.backdrop-image { width: 100%; height: 100%; object-fit: cover; display: block; }

.map-land { fill: #2b2f57; stroke: #575da0; stroke-width: 1.5; }
.map-detail { fill: none; stroke: #575da0; stroke-width: 1; opacity: 0.6; }
.map-state { fill: none; stroke: #575da0; stroke-width: 1; opacity: 0.8; }

/* Phase 10: bullseye backdrop — quarter-circle rings from the board's
   lower-left corner, drawn as absolutely-positioned circles clipped by the
   stage's own overflow:hidden (see #stage above) so only the visible quarter
   shows. Radius/label position come from public/bullseye.js's ringRadii(). */
.bullseye-ring {
  position: absolute;
  left: 0; bottom: 0;
  border-radius: 50%;
  border: 1px solid #575da0;
  opacity: 0.7;
  transform: translate(-50%, 50%);
  pointer-events: none;
}
.bullseye-label {
  position: absolute;
  transform: translate(-50%, -50%);
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--muted);
  background: #0008;
  border-radius: 4px;
  padding: 0 4px;
  pointer-events: none;
  white-space: nowrap;
}

/* Phase 10: the target ring — the visible GOAL a string round is steered
   toward, distinct from .game-dot.answer (which only appears at reveal). */
.target-ring {
  position: absolute;
  width: 16%; aspect-ratio: 1 / 1;
  margin-left: -8%; margin-top: -8%;
  border-radius: 50%;
  border: 3px dashed var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  pointer-events: none;
}

.scale-line {
  position: absolute;
  left: 4%; right: 4%; top: 50%;
  height: 2px;
  background: #575da0;
  transform: translateY(-50%);
}
.plane-axis-h {
  position: absolute;
  left: 4%; right: 4%; top: 50%;
  height: 1px;
  background: #3a3e6b;
}
.plane-axis-v {
  position: absolute;
  top: 4%; bottom: 4%; left: 50%;
  width: 1px;
  background: #3a3e6b;
}

.game-dot {
  position: absolute;
  width: 28px; height: 28px;              /* large touch-scale visual */
  margin: -14px 0 0 -14px;                /* center on its coordinate */
  border-radius: 50%;
  background: var(--accent);
  border: 3px solid #fff3;
  box-shadow: 0 2px 8px #0006;
}
.game-dot.mine { background: var(--ok); }
.game-dot.answer {
  background: transparent;
  border: 3px dashed var(--danger);
}
.dot-name {
  position: absolute;
  top: -1.4em; left: 50%;
  transform: translateX(-50%);
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--ink);
  background: #0008;
  border-radius: 6px;
  padding: 1px 6px;
  white-space: nowrap;
}

#lock-chips, #pull-chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  padding: 0;
  margin: 12px 0 0;
}
#lock-chips li, #pull-chips li {
  font-size: 0.85rem;
  color: var(--muted);
  border: 1px solid #3a3e6b;
  border-radius: 999px;
  padding: 4px 10px;
}
#lock-chips li.locked { color: var(--ok); border-color: var(--ok); }
#lock-chips li.disconnected, #pull-chips li.disconnected { opacity: 0.45; }

/* --- Tug-of-war (Phase 3) -------------------------------------------------- */

#pull-chips li.pulling { color: var(--ok); border-color: var(--ok); }
#pull-chips li.waiting { color: var(--danger); border-color: var(--danger); }

/* The ONE shared dot: bigger than player dots, eased between 15 Hz frames. */
.game-dot.shared {
  width: 40px; height: 40px;
  margin: -20px 0 0 -20px;
  background: #ffd166;
  border: 3px solid #fff6;
  transition: left 70ms linear, top 70ms linear;
}

/* Hold-round countdown: drains right-to-left while everyone is pulling, and
   vanishes the moment the window resets. Scaled by holdTotalMs from the server
   (the window is env-tunable), never by a hardcoded duration here. */
#hold-timer {
  width: min(320px, 70%);
  height: 8px;
  margin: 10px auto 0;
  background: #2a2e55;
  border-radius: 999px;
  overflow: hidden;
}

#hold-bar {
  height: 100%;
  width: 100%;
  background: var(--ok);
  border-radius: 999px;
  transition: width 70ms linear; /* matches the shared dot's 15 Hz easing */
}

/* --- String mode (Phase 4) --------------------------------------------- */

/* Rope layer: sits under the dots (game dots stay visible while pulling),
   never intercepts touches — #stage keeps owning them (touch-action: none,
   the pointer handlers bound there). Created/sized by string-view.js. */
#string-canvas {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* The armed -> countdown -> live start gate's own countdown bar — a separate
   element from #hold-timer even though the two share #tug-status for text,
   because they never run at the same time (pre-live vs post-live). */
#string-countdown {
  width: min(320px, 70%);
  height: 8px;
  margin: 10px auto 0;
  background: #2a2e55;
  border-radius: 999px;
  overflow: hidden;
}

#string-countdown-bar {
  height: 100%;
  width: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width 70ms linear;
}

/* Per-card start timing (Phase 9): big "Start pulling in 10..." numerals and
   the ~1s "PULL!" beat at go-live. clamp() keeps the number readable at party
   distance without pushing the board off a phone screen in portrait. */
#start-beat {
  text-align: center;
  margin: 4px 0 10px;
}

#start-beat-label {
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

#start-beat-number {
  margin: 0;
  font-size: clamp(3rem, 22vw, 5rem);
  font-weight: 800;
  line-height: 1;
  color: var(--accent);
}

/* The "PULL!" flash reuses the same number line — a scale/opacity pulse marks
   the instant the round goes live. */
#start-beat.pull #start-beat-label { visibility: hidden; }
#start-beat.pull #start-beat-number {
  color: var(--ok);
  animation: start-beat-pull 0.9s ease-out;
}

@keyframes start-beat-pull {
  0% { transform: scale(0.6); opacity: 0; }
  30% { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

/* --- "I had no idea" poll + results (Phase 4) ------------------------------ */

#btn-noidea:disabled { color: var(--ok); border-color: var(--ok); opacity: 0.8; }
#result-line { color: var(--ink); font-weight: 700; margin: 10px 0 0; }
#noidea-count { margin: 6px 0 0; }

/* Players who pressed "I had no idea" — same signal Phase 5's replay uses. */
.game-dot.noidea { background: #b57edc; }

#results-view { text-align: left; margin-top: 28px; }
#results-view h2 { text-align: center; margin: 20px 0 12px; }

.result-card {
  background: var(--card);
  border-radius: 14px;
  padding: 12px 12px 14px;
  margin-bottom: 12px;
}
.result-head { color: var(--muted); font-size: 0.75rem; margin: 0 0 4px; }
.result-prompt { font-size: 0.95rem; font-weight: 700; margin: 0 0 10px; }
.result-meta { color: var(--muted); font-size: 0.8rem; margin: 8px 0 0; }

/* Same aspect ratios as the live stage so outcomes read geometrically true. */
.mini-stage {
  position: relative;
  background: var(--bg);
  border: 1px solid #3a3e6b;
  border-radius: 10px;
  overflow: hidden;
}
.mini-stage.kind-scale { aspect-ratio: 5 / 2; }
.mini-stage.kind-plane { aspect-ratio: 1 / 1; }
.mini-stage.kind-image { aspect-ratio: 1.9 / 1; }
.mini-stage.kind-image.asset-mo-map { aspect-ratio: 1.2 / 1; }
.mini-stage.kind-bullseye { aspect-ratio: 1 / 1; }
.mini-stage svg { width: 100%; height: 100%; display: block; }
.mini-stage .game-dot {
  width: 14px; height: 14px;
  margin: -7px 0 0 -7px;
  border-width: 2px;
  box-shadow: none;
}
.mini-stage .game-dot.shared { width: 20px; height: 20px; margin: -10px 0 0 -10px; }

.compare-row { display: flex; gap: 8px; }
.compare-row > div { flex: 1; min-width: 0; }
.compare-label { color: var(--muted); font-size: 0.75rem; text-align: center; margin: 0 0 6px; }
.verdict { color: var(--ok); font-size: 0.85rem; text-align: center; margin: 10px 0 0; }

/* --- Awards ceremony (bonus) ------------------------------------------------ */
/* Reuses .result-card's panel; each card fades in on its own animation-delay
   (set inline by renderAwards) for a small staggered reveal beat. */

.award-card {
  display: flex;
  align-items: center;
  gap: 14px;
  opacity: 0;
  animation: award-in 0.45s ease-out forwards;
}
@keyframes award-in {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
.award-emoji { font-size: 2rem; line-height: 1; flex: none; }
.award-text { min-width: 0; }
.award-title { color: var(--accent, #ffd166); font-weight: 700; margin: 0; font-size: 0.95rem; }
.award-name { font-size: 1.1rem; font-weight: 700; margin: 2px 0 0; }
.award-stat { color: var(--muted); font-size: 0.8rem; margin: 2px 0 0; }

/* --- Session replay (Phase 5) ---------------------------------------------- */

.replay-btn { min-height: 44px; margin-top: 10px; font-size: 0.95rem; }

/* Full-screen scrim so the replay reads as its own moment on the shared
   display. [hidden]'s display:none !important still wins over the flex. */
#replay-panel {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  background: #14162be6;
}
#replay-card {
  background: var(--card);
  border-radius: 14px;
  padding: 14px;
  width: min(560px, 100%);
}
#replay-head { margin: 0 0 4px; }
#replay-prompt { margin: 0 0 10px; }

#replay-stage {
  position: relative;
  background: var(--bg);
  border: 1px solid #3a3e6b;
  border-radius: 10px;
  overflow: hidden;
}
#replay-stage.kind-scale { aspect-ratio: 5 / 2; }
#replay-stage.kind-plane { aspect-ratio: 1 / 1; }
#replay-stage.kind-image { aspect-ratio: 1.9 / 1; }
#replay-stage.kind-image.asset-mo-map { aspect-ratio: 1.2 / 1; }
#replay-stage.kind-bullseye { aspect-ratio: 1 / 1; }
#replay-stage svg { width: 100%; height: 100%; display: block; }
#replay-backdrop, #replay-dots { position: absolute; inset: 0; }
#replay-dots { pointer-events: none; }
/* Positions are rAF-driven; CSS easing (e.g. .shared's 70 ms) would fight
   scrubbing. The timeline core already interpolates. */
#replay-dots .game-dot { transition: none; }

/* Tug touch points: smaller than real dots, no background override so the
   .noidea purple still applies to the clueless crowd's touches. */
.game-dot.touch {
  width: 18px; height: 18px;
  margin: -9px 0 0 -9px;
  border-width: 2px;
  box-shadow: none;
}
/* Disengaged (gap in a tug touch stream): linger, faded, at the last touch. */
.game-dot.faded { opacity: 0.25; }

#replay-controls { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
#replay-controls button {
  width: auto;
  flex: none;
  min-height: 44px;
  min-width: 56px;
  margin: 0;
  padding: 0 12px;
  background: var(--accent);
  color: var(--accent-ink);
}
#btn-replay-speed { background: transparent; color: var(--muted); border: 1px solid #3a3e6b; }
#replay-scrub { flex: 1; min-width: 0; accent-color: var(--accent); height: 32px; }
#replay-time { margin: 8px 0 0; }
#btn-replay-close { margin-top: 12px; }

/* --- Handshake module (Phase 6) --------------------------------------------- */

.hs-partner { text-align: center; font-size: 1.15rem; font-weight: 700; margin: 4px 0 10px; }

/* The chain so far — emoji move chips, on phones and on the host's cards. */
.hs-chain {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  min-height: 1.8em;
  margin: 8px 0;
}
.hs-chip {
  font-size: 0.9rem;
  background: var(--bg);
  border: 1px solid #3a3e6b;
  border-radius: 999px;
  padding: 5px 12px;
  white-space: nowrap;
}

/* Move picker grid: emoji-forward, thumb-sized. */
#hs-moves {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin: 12px 0 0;
}
.hs-move {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: auto;
  min-height: 64px;
  margin: 0;
  padding: 8px 4px;
  background: var(--card);
  color: var(--ink);
  border: 1px solid #3a3e6b;
  border-radius: 12px;
  font-weight: 700;
}
.hs-move:disabled { opacity: 0.4; }
.hs-move-emoji { font-size: 1.5rem; line-height: 1.2; }
.hs-move-label { font-size: 0.68rem; color: var(--muted); }

.hs-card-name { font-size: 1.25rem; font-weight: 700; text-align: center; margin: 6px 0; }
.hs-card .hs-chain { justify-content: flex-start; }
.hs-progress { text-align: left; margin: 4px 0 0; }
#hs-cards { margin-top: 16px; text-align: left; }
#hs-host-status { font-weight: 700; }
#hs-done { margin-top: 16px; }

#btn-lock:disabled { opacity: 0.45; }
#host-controls { margin-top: 8px; }
#ended-view { text-align: center; padding-top: 15vh; }
#ended-view.has-results { padding-top: 4vh; }
.error { color: var(--danger); text-align: center; min-height: 1.2em; }
.conn {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  margin: 0;
  padding: 8px;
  text-align: center;
  background: var(--danger);
  color: var(--bg);
  font-weight: 700;
}

/* --- Settings screen (Phase 1) -------------------------------------------- */

#screen-settings { text-align: center; }
#screen-settings .card { text-align: left; }
.settings-group {
  border: 1px solid #3a3e6b;
  border-radius: 12px;
  padding: 6px 14px 14px;
  margin: 0 0 16px;
}
.settings-group legend {
  color: var(--accent);
  font-weight: 700;
  padding: 0 6px;
}
.setting-unit { color: var(--muted); font-weight: 400; }
/* On/off rows put the box first so a switch reads as a switch; the label sits
   beside it and the whole row stays a comfortable phone tap target. */
.setting-toggle {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 48px;
}
.setting-toggle input[type='checkbox'] {
  width: 24px;
  min-height: 24px;
  flex: 0 0 auto;
  accent-color: var(--accent);
}
.setting-toggle label { margin: 0; }
select.field-error { border-color: var(--danger); }
input.field-error { border-color: var(--danger); }
#btn-open-settings { max-width: 480px; }
