:root {
  --cell: 58px;

  /* Retro-arcade tokens borrowed from the QMoji homescreen (qmoji/style.css)
     -- Munchers keeps its own accent (yellow, matching its homescreen
     cabinet color) while sharing the same dark violet chrome, pixel font,
     and CRT/vignette overlay everywhere else, so the games read as one
     arcade rather than unrelated apps. */
  --bg-deep: #0a0014;
  --bg-mid: #170a2e;
  --panel: #1c0f33;
  --panel-line: #4a2a7a;
  --ink: #f4e9ff;
  --ink-soft: #b6a4d9;

  --accent: #ffe93f;
  --accent-soft: rgba(255, 233, 63, 0.35);
  --accent-glow: rgba(255, 233, 63, 0.6);
  --cyan: #33fff0;
  --magenta: #ff3fd8;
  --green: #3dff8a;
  --orange: #ff8a3f;

  --bg: var(--bg-deep);
  --panel-old: var(--panel);
  --grid-bg: #f4ecd8;
  --grid-border: #caa93f;
  --p1: #ffca28;
  --p2: #29b6f6;
  --p3: #ef5350;
  --p4: #ab47bc;

  --pixel-font: "Press Start 2P", "Noto Sans", sans-serif;
  --mono-font: "VT323", "Noto Sans", monospace;
}
* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0; min-height: 100%;
  background: radial-gradient(ellipse at 50% -10%, var(--bg-mid), var(--bg-deep) 70%);
  font-family: var(--mono-font);
  color: var(--ink);
  overflow-x: hidden;
}

/* ---------- CRT scanline + vignette overlays (matches qmoji/style.css) ---------- */
.crt-overlay {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 150;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.18) 0px,
    rgba(0, 0, 0, 0.18) 1px,
    transparent 1px,
    transparent 3px
  );
  mix-blend-mode: multiply;
  opacity: 0.5;
}
.vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 151;
  background: radial-gradient(ellipse at center, transparent 45%, rgba(0, 0, 0, 0.5) 100%);
}

.screen {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Extra top clearance keeps every screen's own content (the in-game top
     bar especially) from ever rendering underneath the fixed back-to-launchpad
     / sound-toggle corner buttons, which sit at top:12px on both sides
     regardless of viewport width. */
  padding: 64px 20px 20px;
  position: relative;
  z-index: 2;
}
.hidden { display: none !important; }

.panel {
  background: linear-gradient(180deg, var(--panel) 0%, #150a29 100%);
  border: 3px solid var(--panel-line);
  border-radius: 10px;
  padding: 28px 30px;
  width: 100%;
  max-width: 420px;
  text-align: center;
  box-shadow: 0 0 30px rgba(0, 0, 0, 0.4);
}
.panel h1 {
  margin: 0 0 10px;
  font-family: var(--pixel-font);
  font-size: 20px;
  line-height: 1.6;
  color: var(--accent);
  text-shadow: 0 0 8px var(--accent-glow), 0 0 22px var(--accent-glow);
}
.panel h2 {
  margin: 0 0 10px;
  font-family: var(--pixel-font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--accent);
  text-shadow: 0 0 8px var(--accent-glow);
}
.tag { color: var(--ink-soft); font-size: 15px; margin: 6px 0 18px; }
.field { display: block; text-align: left; margin-bottom: 14px; }
.field span { display: block; font-family: var(--pixel-font); font-size: 9px; letter-spacing: 0.04em; color: var(--ink-soft); margin-bottom: 8px; }
input {
  width: 100%;
  padding: 10px 12px;
  border-radius: 4px;
  border: 2px solid var(--panel-line);
  background: var(--bg-deep);
  color: var(--ink);
  font-family: var(--mono-font);
  font-size: 18px;
}
input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 10px var(--accent-soft); }
.btn {
  padding: 11px 18px;
  border-radius: 4px;
  border: 2px solid var(--panel-line);
  background: var(--bg-deep);
  color: var(--ink);
  font-family: var(--pixel-font);
  font-size: 11px;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease, transform 0.1s ease;
}
.btn:hover { border-color: var(--cyan); color: var(--cyan); }
.btn:active { transform: scale(0.97); }
.btn.primary {
  background: linear-gradient(90deg, var(--accent), #ffb43f);
  border-color: transparent;
  color: var(--bg-deep);
  width: 100%;
  font-weight: bold;
}
.btn.primary:hover { border-color: transparent; color: var(--bg-deep); filter: brightness(1.1); }
.error { color: var(--orange); font-size: 14px; min-height: 18px; margin-top: 10px; }

.back-to-launchpad {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 500;
  padding: 9px 13px;
  border-radius: 4px;
  border: 2px solid var(--panel-line);
  background: var(--panel);
  color: var(--ink-soft);
  font-family: var(--pixel-font);
  font-size: 13px;
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.back-to-launchpad:hover { border-color: var(--cyan); color: var(--cyan); }

.sound-toggle {
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: 200;
}
.sound-toggle.muted { opacity: 0.55; }
.player-list { list-style: none; padding: 0; margin: 14px 0; text-align: left; }
.player-list li {
  display: flex; justify-content: space-between; gap: 10px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--panel-line);
  padding: 8px 12px; border-radius: 6px; margin-bottom: 6px;
  font-size: 15px;
}
.player-list.small li { font-size: 14px; padding: 6px 10px; }

/* ---- game screen ---- */
#screen-game { align-items: flex-start; padding: 64px 12px 12px; }
/* max-width is set from JS (applyCellSize), sized off the board's actual
   column count -- it used to be hardcoded for a 7-column board here, which
   silently clipped the extra columns (including the flag's column) once
   the grid grew past 7 wide. The 480px fallback only matters before the
   first round's JS has run. */
#game { width: 100%; max-width: 480px; box-sizing: border-box; }

#topBar { display: flex; align-items: center; justify-content: flex-end; padding: 2px 2px 8px; }
#roundInfo { font-family: var(--pixel-font); font-size: 10px; font-weight: normal; color: var(--ink-soft); letter-spacing: 0.04em; }
.icon-btn {
  border: 2px solid var(--panel-line); background: var(--panel); color: var(--ink); width: 46px; height: 46px;
  border-radius: 50%; cursor: pointer; font-size: 22px; line-height: 1;
  transition: border-color 0.15s ease;
}
.icon-btn:hover { border-color: var(--cyan); }
#muteBtn.muted { opacity: 0.55; }
#homeBtnOver { margin-top: 8px; width: 100%; }

/* Big, unmistakable keyword prompt -- this is the single most important
   piece of text on screen, so it gets its own prominent card rather than
   being squeezed into a thin status strip. */
#keywordBanner {
  background: linear-gradient(135deg, var(--panel), #150a29);
  border: 2px solid var(--panel-line);
  border-radius: 10px;
  padding: 16px 14px;
  text-align: center;
  margin-bottom: 10px;
}
#keywordBanner b {
  font-family: var(--pixel-font);
  font-size: 22px; font-weight: normal; color: var(--accent);
  text-shadow: 0 0 10px var(--accent-glow);
  word-break: break-word;
  line-height: 1.4;
}

#timerBar { height: 10px; background: var(--bg-deep); border: 1px solid var(--panel-line); border-radius: 5px; overflow: hidden; margin-bottom: 10px; }
#timerFill { height: 100%; width: 100%; background: linear-gradient(90deg, var(--accent), var(--orange)); transition: width 0.2s linear; }

/* overflow-x is a deliberate safety net, not the primary fix -- JS sizes
   the board to fit, but if a future change ever gets that arithmetic wrong
   again, a scrollbar beats silently clipping the flag's column off-screen.
   The grid itself stays a bright "arcade screen" surface (rather than going
   full dark CRT) so the emoji glyphs stay easy to tell apart at a glance --
   a thick accent-colored bezel around it keeps it feeling like part of the
   same cabinet as everything around it. */
#boardWrap {
  position: relative;
  background: var(--grid-bg);
  border-radius: 10px;
  border: 4px solid var(--panel-line);
  box-shadow: 0 0 0 2px var(--accent-soft), 0 0 22px rgba(255, 233, 63, 0.18);
  overflow-x: auto;
  overflow-y: hidden;
}
#board { position: relative; margin: 0 auto; }
.cell {
  position: absolute;
  width: calc(var(--cell) - 6px); height: calc(var(--cell) - 6px); margin: 3px;
  background: #fffaf0; border: 2px solid var(--grid-border); border-radius: 8px;
  display: flex; align-items: center; justify-content: center; font-size: 21px;
}
/* Munched cells are shared across the room (see GameRoom._resolveMunch) --
   instead of vanishing they leave a very subtle "slime" tint in whichever
   player ate them first (background-color set inline per-cell in JS, since
   it's a dynamic per-player color), so the trail of who went where stays
   visible rather than just disappearing. */
.cell.slimed {
  transition: background-color 0.3s ease;
}
/* The destination used to be a subtle border pulse with a tiny 14px flag
   tucked in the corner -- easy to lose among 60+ same-sized emoji cells.
   A distinct fill + a big waving flag badge + a stronger pulse (that also
   scales the cell, not just its glow) makes it readable at a glance
   instead of something you have to hunt for. */
.cell.destination {
  background: linear-gradient(135deg, #fff3b0, #ffe066);
  border-color: var(--accent); border-width: 3px;
  box-shadow: 0 0 0 3px var(--accent-soft), 0 0 16px 4px var(--accent-glow);
  animation: destinationPulse 1.3s ease-in-out infinite;
  z-index: 5;
}
.cell.destination::after {
  content: "🚩";
  position: absolute;
  top: -16px; right: -12px;
  font-size: 26px;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,0.5));
  animation: destinationFlagWave 0.9s ease-in-out infinite;
  transform-origin: bottom left;
}
@keyframes destinationFlagWave {
  0%, 100% { transform: rotate(-8deg); }
  50% { transform: rotate(8deg); }
}
@keyframes destinationPulse {
  0%, 100% { box-shadow: 0 0 0 3px var(--accent-soft), 0 0 16px 4px var(--accent-glow); transform: scale(1); }
  50% { box-shadow: 0 0 0 6px rgba(255,233,63,0.85), 0 0 28px 8px rgba(255,233,63,0.95); transform: scale(1.08); }
}
.cell.correct-flash { animation: correctPop 0.32s ease; }
.cell.wrong-flash { animation: wrongShake 0.36s ease; border-color: #d94f4f; }
@keyframes correctPop {
  0% { transform: scale(1); }
  40% { transform: scale(1.22); box-shadow: 0 0 0 4px rgba(61,255,138,0.4); }
  100% { transform: scale(1); }
}
@keyframes wrongShake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-5px) rotate(-3deg); }
  40% { transform: translateX(4px) rotate(3deg); }
  60% { transform: translateX(-3px) rotate(-2deg); }
  80% { transform: translateX(3px) rotate(2deg); }
}
.muncher {
  position: absolute;
  width: calc(var(--cell) - 14px); height: calc(var(--cell) - 14px); margin: 7px;
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  font-size: 20px; font-weight: 800; color: #1a1d2e;
  transition: left 0.18s ease, top 0.18s ease;
  box-shadow: 0 2px 4px rgba(0,0,0,0.4);
}
.flying-emoji {
  position: fixed; font-size: 22px; pointer-events: none; z-index: 999;
  transform: translate(-50%, -50%);
}

#myStats { display: flex; justify-content: space-between; align-items: center; padding: 10px 4px 4px; }
.stat-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--panel-line); padding: 6px 12px; border-radius: 20px;
  font-family: var(--pixel-font); font-size: 13px; font-weight: normal; color: var(--accent);
}
.stat-icon { font-size: 17px; }
#myLives.stat-chip { color: var(--ink); }
.shields { display: inline-flex; gap: 3px; }
.shield-icon { font-size: 16px; }
.shield-icon.just-broke { animation: shieldHit 0.4s ease; }
@keyframes shieldHit {
  0% { transform: scale(1); }
  30% { transform: scale(1.5) rotate(-8deg); }
  60% { transform: scale(0.85) rotate(6deg); }
  100% { transform: scale(1) rotate(0); }
}

#hint { text-align: center; color: var(--ink-soft); font-size: 13px; margin-top: 4px; }

/* Always shown now, not just under 700px -- this is the primary way to
   move (see client.js's sendMove: clicks and arrow keys are the exact same
   code path), not a mobile-only fallback for players without a keyboard.
   Sized and styled to actually invite clicking rather than reading as an
   afterthought: bigger targets, a real accent-colored press state, and a
   center gap so it reads as a d-pad at a glance instead of six identical
   squares. */
#touchpad {
  display: grid;
  margin-top: 14px;
  grid-template-columns: repeat(3, 64px);
  grid-template-rows: repeat(2, 64px);
  gap: 8px;
  justify-content: center;
}
#touchpad button {
  font-size: 26px;
  border-radius: 12px;
  border: 2px solid var(--panel-line);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
  transition: transform 0.06s ease, border-color 0.12s ease, background 0.12s ease;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
#touchpad button:hover {
  border-color: var(--accent);
  color: var(--accent);
}
/* .is-pressed is toggled from JS on click/keydown-equivalent, not just
   :active -- a move waits out MIN_STEP_MS (client.js) before the next one
   is allowed, so without this a click during that window would look like
   it did nothing at all rather than "registered, please wait a beat." */
#touchpad button:active,
#touchpad button.is-pressed {
  transform: scale(0.9);
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg-deep);
}
#touchpad button:disabled {
  opacity: 0.5;
  cursor: default;
}

.final-score {
  font-family: var(--pixel-font);
  font-size: 16px;
  color: var(--accent);
  text-shadow: 0 0 8px var(--accent-glow);
  margin: 4px 0 18px;
}

/* ---- onboarding ---- */
.howto {
  text-align: left;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 16px;
  font-size: 14px;
}
.howto b { display: block; margin-bottom: 4px; color: var(--accent); }
.howto ol { margin: 0; padding-left: 18px; color: var(--ink-soft); }
.howto li { margin-bottom: 2px; }

.round-one-banner {
  background: linear-gradient(135deg, var(--green), #2bcf72);
  color: #0e1a12;
  font-weight: 700;
  font-size: 14px;
  text-align: center;
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 10px;
  animation: bannerFade 3.4s ease forwards;
}
@keyframes bannerFade {
  0%, 70% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-6px); }
}

.next-round-note {
  text-align: center;
  color: var(--accent);
  font-weight: 700;
  font-size: 14px;
  margin: -4px 0 10px;
}

/* Shown when a move is taking noticeably longer than usual to confirm
   (see client.js's sendMove) -- almost always a cold serverless/DB
   connection warming up on the very first move or two of a session, not a
   dropped keypress. Without this, that wait looked exactly like the game
   having silently frozen. */
.connecting-note {
  text-align: center;
  color: var(--ink-soft);
  font-size: 13px;
  margin-top: 4px;
}

/* ---- accounts ---- */
.account-box { margin-top: 16px; border-top: 1px solid var(--panel-line); padding-top: 12px; text-align: left; }
.link-btn {
  background: none;
  border: none;
  color: var(--cyan);
  font-size: 13px;
  cursor: pointer;
  padding: 4px 0;
  text-decoration: underline;
}
.link-btn:hover { color: #7dfff5; }
.auth-form { margin-top: 8px; }
.auth-form input { margin-bottom: 8px; }
#accountSignedIn { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; color: var(--ink-soft); }

.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(5, 0, 12, 0.78);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.modal-backdrop.hidden { display: none; }
.modal-backdrop .panel { max-width: 360px; }

/* ---------- loading screen (return-to-launchpad transition) ---------- */
.loading-screen {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: var(--bg-deep);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}
.loading-screen.is-visible {
  opacity: 1;
  pointer-events: auto;
}
.loading-text {
  font-family: var(--pixel-font);
  font-size: 0.9rem;
  color: var(--accent);
  text-shadow: 0 0 10px var(--accent-glow);
}
.loading-dots { animation: loadingPulse 0.6s steps(1) infinite; }
@keyframes loadingPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
.loading-bar {
  width: 220px;
  height: 14px;
  border: 2px solid var(--panel-line);
  border-radius: 3px;
  overflow: hidden;
  background: var(--panel);
}
.loading-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--accent), var(--orange));
  transition: width 0.35s ease;
}
