/* ── Design tokens ──────────────────────────────────────────────────────
   Same token names/structure as every other game's own theme.css (each
   game ships its own self-contained copy rather than a shared stylesheet).
   Snake only ever runs one (dark) palette — a phosphor-green arcade feel
   (the classic handheld LCD, grown up), so --accent is a bright green,
   kept distinct from the food colors (see game.js's FOOD_COLORS: warm red
   pellets, amber body pellets, gold). */
:root {
  /* Read by game.js to keep the minimap band clear of the notch / rounded
     corners (top-left on the player's screen; bottom-left on the TV). */
  --safe-top:      env(safe-area-inset-top, 0px);
  --safe-left:     env(safe-area-inset-left, 0px);
  --safe-bottom:   env(safe-area-inset-bottom, 0px);

  --bg:            #0D1020;
  --surface-1:     #151A33;
  --surface-2:     #11162B;

  --border:        #2A3260;
  --border-strong: #3A4478;

  --text:          #F2F4FF;
  --text-mid:      #CBD1EA;
  --text-muted:    #9AA3C6;

  --accent:        #5ee36a;
  --accent-hover:  #86f08f;
  --on-accent:     #06200a;

  --danger:        #ff6b6b;
  --danger-deep:   #4a1f22;

  --font-display: 'Fredoka', sans-serif;
  --font-body:    'Nunito', sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: radial-gradient(120% 100% at 50% -8%, #142a1c 0%, var(--bg) 55%);
  background-attachment: fixed;
  color: var(--text);
  font-family: var(--font-body);
  touch-action: none;
  /* WebKit (Safari, the iOS app's web view) ignores the unprefixed property:
     without the -webkit- forms a double-tap on the board selected "text" and
     flashed the grey tap highlight. The callout is the long-press menu. */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  height: 100%;
}
/* Typing still needs selection inside the fields (iOS won't focus an input
   that inherits user-select: none). */
input, textarea { -webkit-user-select: text; user-select: text; }

#game-canvas {
  display: none;
  width: 100vw;
  height: 100vh;
  background: #0a0e18;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}


/* ============================================================
   LOBBY / WAITING / MATCH OVER
============================================================ */

.auth-page {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 5.5rem 1rem 2rem;
  gap: 1.25rem;
  overflow-y: auto;
}

.auth-card {
  width: 100%;
  max-width: 440px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 2.25rem 2rem;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.35);
}

.game-title {
  text-align: center;
  font-family: var(--font-display);
  font-size: 2rem;
  letter-spacing: 4px;
  margin: 0 0 0.5rem;
  color: var(--accent);
  text-shadow: 0 0 24px rgba(94, 227, 106, 0.35);
}
.room-code-heading {
  text-align: center;
  font-family: var(--font-display);
  margin: 0 0 1.25rem;
}
#room-code-display { letter-spacing: 6px; color: var(--accent); }

#matchover-title {
  text-align: center;
  font-family: var(--font-display);
  margin: 0 0 1.25rem;
}

.tagline {
  margin: 0 0 1.75rem;
  color: var(--text-mid);
  font-size: 0.85rem;
  text-align: center;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
}

.auth-field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.auth-field label, .picker-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-mid);
}

input[type="text"] {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.7rem 0.9rem;
  font-size: 1rem;
  font-family: var(--font-body);
  color: var(--text);
  text-align: left;
  outline: none;
  width: 100%;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
input[type="text"]:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(94, 227, 106, 0.2);
}
#join-code { text-transform: uppercase; letter-spacing: 4px; }

.stats-hint {
  margin-top: 0.25rem;
  text-align: center;
  font-size: 0.75rem;
  color: var(--text-muted);
}

button {
  margin-top: 0;
  background: var(--accent);
  color: var(--on-accent);
  border: none;
  border-radius: 999px;
  padding: 0.8rem;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.1s ease;
}
button:hover  { filter: brightness(1.1); }
button:active { transform: scale(0.98); }
button:disabled { opacity: 0.4; cursor: default; transform: none; filter: none; }


.hint { color: var(--text-mid); font-size: 13px; text-align: center; margin: 0; }
.hint.small { font-size: 12px; color: var(--text-muted); }
/* Notes under the join form (bots hint, guest footnote) — same block the
   card games' join screen ends with. */
.join-notes { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 0.25rem; }
/* The quiet guest footnote ("Sign in to record stats"): link in the same
   muted colour with just an underline, so it reads as a note, not a button. */
.signin-note { line-height: 1.4; }
.signin-note a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.error-msg { color: var(--danger); font-size: 13px; min-height: 16px; margin: 0; text-align: center; }
/* An empty error line is dropped from the form flow entirely so it never
   leaves a blank gap above the notes under the buttons. */
.error-msg:empty { display: none; }


/* ---- Mode picker (host) — same segmented-control look every other
   game's mode-toggle uses. ---- */
.seg {
  display: inline-flex;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.seg-btn {
  background: var(--surface-2);
  color: var(--text-mid);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 13px;
  padding: 8px 14px;
  border-radius: 0;
  margin: 0;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.seg-btn:hover { color: var(--text); }
.seg-btn.active { background: rgba(94, 227, 106, 0.16); color: var(--accent); }
.seg-count { padding: 0 14px; display: inline-flex; align-items: center; font-weight: 700; color: var(--text); background: var(--surface-2); }

.seg-modes { flex-wrap: wrap; justify-content: center; width: 100%; }
.seg-modes .seg-btn { flex: 1 1 auto; }
/* Map chips: a colour swatch of the ground before the name, and a vote
   count after it on the match-over screen. */
.seg-btn .map-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; border: 1px solid rgba(255,255,255,0.25); }
.seg-btn .map-count { margin-left: 6px; font-size: 11px; opacity: 0.8; }
.seg-btn:disabled { opacity: 0.7; cursor: default; }
#map-setup .setup-row { flex-direction: column; gap: 6px; }
#map-vote { align-items: center; }

.icon-btn {
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text);
  font-size: 1rem;
  line-height: 1;
  margin: 0;
}
.icon-btn:hover { border-color: var(--accent); }
.icon-btn:active { transform: scale(0.92); }

/* ---- Player list ---- */
#player-list {
  list-style: none;
  padding: 0;
  margin: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#player-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
}
#player-list .p-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
#player-list .p-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#player-list .p-tag { font-size: 11px; color: var(--text-muted); }

#host-setup { align-items: center; }
.setup-row { display: flex; align-items: center; justify-content: center; gap: 10px; }
.setup-label { font-size: 13px; color: var(--text-mid); }

/* ---- Match over ---- */
#matchover-standings {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}
.standing-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 14px;
}
.standing-row.winner { outline: 2px solid var(--accent); }
.standing-place { font-weight: 800; width: 22px; text-align: center; color: var(--text-mid); }
.standing-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.standing-score { font-weight: 700; color: var(--text); }

/* ============================================================
   IN-GAME CHROME
============================================================ */


/* ---- HUD — score/lives/clock readout top-center, a status banner
   underneath (respawn countdown, "you're out", final seconds), everyone's
   lives+score along the side. Sits in DOM over the canvas so text stays crisp on
   high-DPI screens, same reasoning as every other game's #hud. ---- */
#hud {
  position: fixed;
  top: calc(14px + env(safe-area-inset-top, 0px));
  /* Full width, no transform: the score/turn pills centre themselves via
     align-items, and — the real reason — a transformed element becomes the
     containing block for its fixed-position children, which pinned the
     "right-hand" scores column to the HUD's own narrow box instead of the
     viewport's right edge (so it sat just under the score pills, in the
     middle of a phone screen). */
  left: 0;
  right: 0;
  transform: none;
  z-index: 15;
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  pointer-events: none;
}
#hud-top {
  display: flex;
  gap: 10px;
}
/* Room for the gear on the right and the Leave pill's absence on the left:
   four pills fit a phone at this size. */
@media (max-width: 480px) {
  /* Leave the gear's column free (it's fixed top-right, 36px + margins)
     so the pills centre in the space beside it instead of under it. */
  #hud { right: 58px; }
  #hud-top { gap: 6px; }
  .hud-stat { min-width: 56px; padding: 4px 8px; }
  .hud-label { font-size: 9px; }
  .hud-stat span:last-child { font-size: 0.95rem; }
}
.hud-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 74px;
  padding: 6px 14px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}
.hud-label { font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); }
.hud-stat span:last-child { font-family: var(--font-display); font-size: 1.15rem; color: var(--accent); }
#hud-banner {
  font-size: 13px;
  font-weight: 700;
  padding: 4px 14px;
  border-radius: 999px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  color: var(--text-mid);
  display: none;
}
#hud-banner.active { color: var(--on-accent); background: var(--accent); border-color: var(--accent); }
/* The side panel: everyone's scores and lives, then the message feed right
   under them (see feedMessage() in game.js). The board is the whole screen
   (the camera follows your snake), so the panel sits over it top-right,
   under the gear, on EVERY screen size — the minimap and the burst pill take
   the top-left (drawMinimap() / updateHudLayout() in game.js) — so the
   bottom of the screen, where the steering thumb lives, is left completely
   clear. pointer-events stay off so a thumb-stick can start underneath it. */
#hud-side {
  position: fixed;
  top: calc(62px + env(safe-area-inset-top, 0px));
  right: calc(14px + env(safe-area-inset-right, 0px));
  left: auto;
  transform: none;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  max-width: 170px;
  max-height: calc(100vh - 140px);
  overflow: hidden;
}
@media (max-width: 700px) {
  #hud-side {
    right: calc(12px + env(safe-area-inset-right, 0px));
    max-width: min(176px, calc(100vw - 150px));
    max-height: 45vh; /* never down to the bottom: that strip stays empty for the thumb */
  }
  #hud-side .feed-row { white-space: normal; text-align: right; }
  /* On a phone the minimap band (top-left) and the side panel (top-right)
     sit level with the banner's row, leaving too little room between them
     for a sentence — so the banner and the connection pill drop below the
     band. --hud-band is set by game.js from the measured layout (0 on a
     wide screen, where the centre column is clear). */
  #hud-net, #hud-banner { margin-top: var(--hud-band, 0px); }
  #hud-net.show + #hud-banner { margin-top: 0; }
}
#hud-opponents {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: 100%;
}
#hud-feed {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 3px;
  margin-top: 4px;
  max-width: 100%;
}
.feed-row {
  padding: 4px 8px;
  background: rgba(19, 27, 44, 0.85);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-mid);
  text-align: right;
  max-width: 100%;
  animation: feed-in-out 3.2s ease forwards;
}
.feed-row--strong { color: var(--on-accent); background: var(--accent); border-color: var(--accent); font-weight: 700; }
.feed-row--again { animation: feed-again 0.35s ease; }
@keyframes feed-in-out {
  0%   { opacity: 0; transform: translateX(8px); }
  8%   { opacity: 1; transform: translateX(0); }
  85%  { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes feed-again { 0% { transform: scale(1.06); } 100% { transform: scale(1); } }
.opp-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  background: rgba(19, 27, 44, 0.85);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 11px;
  white-space: nowrap;
}
.opp-row .opp-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.opp-row .opp-name { flex: 1; overflow: hidden; text-overflow: ellipsis; }
.opp-row.finished { opacity: 0.55; }
.opp-row.active { border-color: var(--accent); color: var(--accent); }

/* ---- Dialogs (pause menu, confirm/alert) ---- */
.dialog-overlay {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(5, 8, 14, 0.72);
}
.dialog-overlay.open { display: flex; }

.dialog-box {
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 24px;
  width: 88%;
  max-width: 340px;
  text-align: center;
}
.dialog-message { margin: 0 0 16px; color: var(--text); font-size: 15px; line-height: 1.4; }
.dialog-input {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 14px;
}
.dialog-actions { display: flex; gap: 10px; justify-content: center; }
.dialog-btn { padding: 10px 20px; margin: 0; }
.dialog-btn.secondary { background: var(--surface-2); color: var(--text); border: 1px solid var(--border); }


/* ---- Toasts ---- */
#toast-layer {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  pointer-events: none;
}
.toast {
  background: var(--surface-1);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  opacity: 0;
  animation: toast-in-out 2.6s ease forwards;
  white-space: nowrap;
}
@keyframes toast-in-out {
  0%   { opacity: 0; transform: translateY(-8px); }
  12%  { opacity: 1; transform: translateY(0); }
  82%  { opacity: 1; }
  100% { opacity: 0; transform: translateY(-6px); }
}

@media (max-width: 480px) {
  .auth-card { padding: 1.75rem 1.25rem; }
  .game-title { font-size: 1.6rem; letter-spacing: 3px; }
  #hud-top { gap: 8px; }
}

/* ---- Room code in the Settings sheet ---- */
.settings-room { text-align: center; }
.settings-room-code { font-family: var(--font-display); font-size: 2rem; letter-spacing: 8px; color: var(--accent); margin: 4px 0 10px; user-select: text; -webkit-user-select: text; }
.settings-room-actions { display: flex; gap: 8px; }
.settings-room-actions .tbl-settings-btn { flex: 1 1 0; margin: 0; }
/* The friends card inside the join / waiting card: full width, no outer margin. */
#friends-online-card.friends-panel-card { max-width: none; margin: 1rem 0 0; }

/* ---- Connection indicator: three bars, amber for weak, red for bad /
   reconnecting; only shown while the link is worse than fine. ---- */
#hud-net {
  display: none;
  align-items: center;
  gap: 7px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-1);
  border: 1px solid var(--border);
  font-size: 11px;
  font-weight: 700;
  color: #ffc46b;
}
#hud-net.show { display: inline-flex; }
#hud-net.bad { color: #ff8a8a; border-color: var(--danger-deep); background: var(--danger-deep); }
.net-bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 11px; }
.net-bars i { display: block; width: 3px; background: currentColor; border-radius: 1px; opacity: 0.35; }
.net-bars i:nth-child(1) { height: 4px; }
.net-bars i:nth-child(2) { height: 7px; }
.net-bars i:nth-child(3) { height: 11px; }
#hud-net.weak .net-bars i:nth-child(-n+2) { opacity: 1; }
#hud-net.bad  .net-bars i:nth-child(1) { opacity: 1; animation: net-blink 0.9s steps(2, start) infinite; }
@keyframes net-blink { to { opacity: 0.2; } }

/* ---- Snake-specific HUD bits ---- */
#hud-lives { letter-spacing: 1px; color: #ff6b8a !important; }
#hud-clock.low { color: var(--danger) !important; }
#hud-banner { display: none; }
#hud-banner.show { display: block; }
#hud-banner.danger { color: #ff9b9b; border-color: var(--danger-deep); background: var(--danger-deep); }
.opp-row .opp-lives { color: #ff6b8a; font-size: 10px; letter-spacing: 1px; margin-left: 2px; }
.opp-row.out { opacity: 0.45; text-decoration: line-through; }
.opp-row.me { border-color: var(--border-strong); }
/* Spectating (out of lives): the live names become buttons — the HUD is
   otherwise pointer-events:none so a thumb-stick can start anywhere — and
   the one the camera follows is lit with a play mark. */
#hud.spectating .opp-row:not(.out):not(.me) { pointer-events: auto; cursor: pointer; }
#hud.spectating .opp-row:not(.out):not(.me):active { transform: scale(0.97); }
.opp-row.watching { border-color: var(--accent); color: var(--accent); background: rgba(94, 227, 106, 0.14); }
.opp-row.watching::before { content: "▶"; font-size: 8px; margin-right: 2px; }

/* ---- Burst status pill: a small read-only readout right under the minimap
   (top-left; game.js sets left/top from the measured layout). Not a button —
   the burst is a gesture (double-tap & hold / hold Space) — so it takes no
   taps and the bottom of the screen stays empty. Hidden unless you're alive;
   a thin bar along the bottom fills as it recharges; lit when ready; pulses
   while sprinting. ---- */
#hud-burst {
  position: fixed;
  left: 12px; top: 90px;              /* placeholders: game.js positions it */
  z-index: 16;
  height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  background: rgba(19, 27, 44, 0.85);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 22px;
  white-space: nowrap;
  display: none;
  overflow: hidden;
  pointer-events: none;
  user-select: none;
}
#hud-burst.show { display: block; }
#hud-burst .burst-bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 3px;
  background: linear-gradient(to right, var(--accent) calc(var(--p, 100) * 1%), transparent 0);
  opacity: 0.7;
}
#hud-burst.short { color: var(--text-muted); }
#hud-burst.short .burst-bar { opacity: 0.25; }
#hud-burst.ready { color: var(--accent); border-color: var(--accent); box-shadow: 0 0 12px rgba(94, 227, 106, 0.3); }
#hud-burst.ready .burst-bar { opacity: 0; }
#hud-burst.bursting { color: var(--on-accent); background: var(--accent); border-color: var(--accent); animation: burst-pulse 0.3s ease-in-out infinite alternate; }
#hud-burst.bursting .burst-bar { opacity: 0; }
@keyframes burst-pulse { from { transform: scale(1); } to { transform: scale(1.06); } }

/* ---- Crash flash: a red tint over the whole screen for a third of a
   second when your own snake crashes (see flashCrash() in game.js). ---- */
#crash-flash {
  position: fixed;
  inset: 0;
  z-index: 14;
  pointer-events: none;
  background: radial-gradient(80% 80% at 50% 50%, rgba(255,80,80,0) 40%, rgba(255,60,60,0.55) 100%);
  opacity: 0;
}
#crash-flash.run { animation: crash-flash 0.42s ease-out forwards; }
@keyframes crash-flash {
  0%   { opacity: 0; }
  12%  { opacity: 1; }
  100% { opacity: 0; }
}

#rules-blurb { line-height: 1.45; }
#matchover-sub { margin: -0.75rem 0 1rem; }
#matchover-sub:empty { display: none; }
.standing-lives { color: #ff6b8a; font-size: 12px; letter-spacing: 1px; min-width: 34px; text-align: right; }
.standing-row.out .standing-name { color: var(--text-muted); }

/* The back/leave pills, icon buttons, in-match gear and the lobby share row
   are shared with the other action games: /shared/arcade-chrome.css. */

/* Settings → TV camera (only while the room is on a TV): a 2-column grid of
   the same buttons the shared choice row uses, so seven fit on a phone. */
.tv-cam-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
.tv-cam-grid .tbl-settings-btn { flex: none; margin-top: 0; }
