:root {
  --honey: #f2a93b;
  --honey-deep: #d9821e;
  --honey-pale: #ffd98a;
  --ink: #2a1a0f;
  --cream: #fff6e6;
  --sting: #e15241;
  --clover: #3f8f52;
  --plum: #6b4a82;

  /* Reveal colours are fixed across both themes — "green means right" has to
     read identically in a bright classroom and a dark room. */
  --right: #2f9e57;
  --right-deep: #238144;
  --wrong: #d93b3b;
  --wrong-deep: #b32c2c;

  --bg: var(--cream);
  --bg-raised: #ffffff;
  --panel-2: #fdf1dc;
  --text: var(--ink);
  --text-soft: #6b5641;
  --border: #ecd9b8;
  --accent: var(--honey-deep);
  --accent-ink: #2a1a0f;
}

/* Dark palette lives in one place and is applied two ways: by system
   preference, and by an explicit data-theme the user picked. The :not()
   guard means choosing Light on a dark-set machine actually sticks. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1c130b;
    --bg-raised: #241a10;
    --panel-2: #2e2114;
    --text: #f6e9d4;
    --text-soft: #c9b191;
    --border: #3a2a17;
    --accent: var(--honey);
    --accent-ink: #1c130b;
  }
}
:root[data-theme="dark"] {
  --bg: #1c130b;
  --bg-raised: #241a10;
  --panel-2: #2e2114;
  --text: #f6e9d4;
  --text-soft: #c9b191;
  --border: #3a2a17;
  --accent: var(--honey);
  --accent-ink: #1c130b;
}
:root[data-theme="light"] {
  --bg: var(--cream);
  --bg-raised: #ffffff;
  --panel-2: #fdf1dc;
  --text: var(--ink);
  --text-soft: #6b5641;
  --border: #ecd9b8;
  --accent: var(--honey-deep);
  --accent-ink: #2a1a0f;
}

.theme-toggle {
  background: transparent; border: 1px solid var(--border); color: var(--text);
  border-radius: 999px; width: 38px; height: 38px; padding: 0; font-size: 1rem;
  display: inline-grid; place-items: center; cursor: pointer; flex: none;
}
.theme-toggle:hover { background: var(--bg); }

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, "Segoe UI", Roboto, ui-sans-serif, system-ui, sans-serif;
  line-height: 1.5;
}

a { color: var(--accent); }

.wrap {
  max-width: 720px;
  margin: 0 auto;
  padding: 32px 20px 80px;
}

.wrap.wide { max-width: 980px; }

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-raised);
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 900;
  font-size: 1.3rem;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--text);
}

.stripe-rule {
  height: 5px;
  border-radius: 3px;
  background: repeating-linear-gradient(90deg, var(--ink) 0 16px, var(--honey) 16px 32px);
  opacity: 0.85;
  margin: 18px 0 26px;
}
@media (prefers-color-scheme: dark) {
  .stripe-rule { background: repeating-linear-gradient(90deg, var(--honey) 0 16px, var(--ink) 16px 32px); }
}

h1, h2, h3 { font-weight: 800; letter-spacing: -0.01em; margin: 0 0 8px; }
p { margin: 0 0 14px; color: var(--text-soft); }

.card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 22px;
  box-shadow: 0 1px 2px rgba(42,26,15,0.06), 0 8px 24px -14px rgba(42,26,15,0.25);
  margin-bottom: 18px;
}

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label { font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-soft); }
input, select {
  font: inherit;
  padding: 11px 13px;
  border-radius: 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
}
input:focus, select:focus, button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font: inherit;
  font-weight: 800;
  padding: 11px 20px;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  text-decoration: none;
}
.btn-primary { background: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { filter: brightness(1.05); }
.btn-secondary { background: transparent; color: var(--text); border: 1px solid var(--border); }
.btn-danger { background: var(--sting); color: #fff; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-block { width: 100%; }

.error-text { color: var(--sting); font-size: 0.86rem; min-height: 1.2em; }
.hint { font-size: 0.82rem; color: var(--text-soft); }

.money-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--honey-pale);
  color: var(--ink);
  font-weight: 800;
  padding: 6px 13px;
  border-radius: 999px;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.kit-row, .list-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border);
}
.kit-row:last-child, .list-row:last-child { border-bottom: none; }
.kit-title { font-weight: 700; }
.kit-meta { font-size: 0.8rem; color: var(--text-soft); }
.row-actions { display: flex; gap: 8px; }

.code-display {
  font-size: clamp(2.4rem, 8vw, 3.6rem);
  font-weight: 900;
  letter-spacing: 0.12em;
  text-align: center;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  margin: 10px 0;
}

.leaderboard-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 4px;
  border-bottom: 1px solid var(--border);
  font-size: 0.95rem;
}
.leaderboard-row:last-child { border-bottom: none; }
.lb-name { display: flex; align-items: center; gap: 10px; font-weight: 700; }
.lb-rank { color: var(--text-soft); width: 1.6em; font-variant-numeric: tabular-nums; }

.qcard-prompt { font-size: 1.3rem; font-weight: 800; margin-bottom: 20px; text-wrap: balance; }
.qcard-opts { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 480px) { .qcard-opts { grid-template-columns: 1fr; } }
.qcard-opt {
  padding: 18px 16px;
  border-radius: 14px;
  background: var(--bg-raised);
  border: 2px solid var(--border);
  font-size: 1rem;
  font-weight: 700;
  cursor: pointer;
  text-align: left;
}
.qcard-opt:hover:not(:disabled) { border-color: var(--accent); }
.qcard-opt:disabled { cursor: default; }
.qcard-opt.correct { background: color-mix(in srgb, var(--clover) 20%, var(--bg-raised)); border-color: var(--clover); }
.qcard-opt.wrong { background: color-mix(in srgb, var(--sting) 18%, var(--bg-raised)); border-color: var(--sting); }

.stat-row { display: flex; gap: 22px; flex-wrap: wrap; margin: 16px 0; }
.stat { text-align: center; }
.stat .num { font-size: 1.8rem; font-weight: 900; font-variant-numeric: tabular-nums; }
.stat .lbl { font-size: 0.76rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-soft); }

/* ============================================================
   App shell — sidebar + content, replacing the centred column
   ============================================================ */

.shell { display: flex; min-height: 100vh; align-items: stretch; }

.side {
  flex: 0 0 232px;
  background: var(--bg-raised);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  padding: 18px 14px;
  position: sticky; top: 0; height: 100vh;
}
.side .brand { font-size: 1.35rem; padding: 0 8px 16px; }
.side-nav { display: flex; flex-direction: column; gap: 2px; }
.side-link {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: 10px;
  font-weight: 700; font-size: 0.92rem;
  color: var(--text); text-decoration: none;
  background: none; border: none; cursor: pointer; text-align: left; width: 100%;
  font-family: inherit;
}
.side-link:hover { background: color-mix(in srgb, var(--honey) 16%, transparent); }
.side-link.active { background: var(--accent); color: var(--accent-ink); }
.side-foot { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--border); }
.side-user { font-size: 0.82rem; font-weight: 700; padding: 0 8px 10px; }

.main { flex: 1 1 auto; min-width: 0; padding: 30px 34px 70px; max-width: 1180px; }
.main-head { display: flex; align-items: flex-start; gap: 16px; margin-bottom: 6px; }
.main-head h1 { font-size: 1.75rem; margin: 0; }
.main-head .spacer { flex: 1; }
.page-sub { color: var(--text-soft); margin: 0 0 22px; }

@media (max-width: 820px) {
  .shell { flex-direction: column; }
  .side { position: static; height: auto; flex: none; width: 100%; border-right: none; border-bottom: 1px solid var(--border); }
  .side-nav { flex-direction: row; overflow-x: auto; }
  .side-foot { margin-top: 12px; }
  .main { padding: 20px 16px 60px; }
}

/* ---------- kit cards ---------- */

.kit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)); gap: 16px; }
.kit-card {
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: 16px; padding: 18px; display: flex; flex-direction: column; gap: 6px;
  box-shadow: 0 1px 2px rgba(42,26,15,0.06), 0 10px 26px -18px rgba(42,26,15,0.4);
}
.kit-card h3 { margin: 0; font-size: 1.05rem; }
.kit-card .desc { font-size: 0.84rem; color: var(--text-soft); margin: 0; flex: 1; }
.kit-card .count { font-size: 0.76rem; font-weight: 800; color: var(--honey-deep); text-transform: uppercase; letter-spacing: 0.06em; }
.kit-card .actions { display: flex; gap: 8px; margin-top: 10px; }

/* ---------- set covers ----------
   Uploaded art when there is some, otherwise a deterministic two-tone
   gradient keyed off the title's hash so every set looks like itself. */
.set-cover {
  display: block; width: 100%; aspect-ratio: 16 / 9;
  background-size: cover; background-position: center;
  border-radius: 10px; border: 2px solid var(--edge);
  flex: 0 0 auto;
}
.set-cover-gen {
  display: grid; place-items: center;
  background-image: linear-gradient(140deg,
    hsl(var(--h) 72% 62%) 0%,
    hsl(calc(var(--h) + 38) 68% 48%) 100%);
}
.set-cover-mark {
  font-family: "Arial Black", Inter, sans-serif;
  font-size: clamp(1.4rem, 5vw, 2.2rem);
  color: #fff; letter-spacing: -0.03em;
  text-shadow: 2px 2px 0 rgba(0,0,0,.3);
}
/* Card covers sit above the title and bleed to the card's inner edge. */
.kit-card .set-cover { margin-bottom: 10px; }

/* ---------- shared set page ---------- */
.set-hero { display: grid; grid-template-columns: minmax(0, 300px) minmax(0, 1fr); gap: 22px; align-items: start; }
.set-cover-lg { aspect-ratio: 16 / 9; }
.set-title { margin: 4px 0 6px; font-size: clamp(1.6rem, 4vw, 2.3rem); line-height: 1.12; }
.set-meta { margin: 0 0 10px; font-size: 0.86rem; color: var(--text-soft); font-weight: 700; }
.set-desc { margin: 0 0 16px; font-size: 0.95rem; line-height: 1.55; }
.set-actions { display: flex; flex-wrap: wrap; gap: 10px; }

.set-q-list { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.set-q {
  border: 2px solid var(--border); border-radius: 12px;
  padding: 14px 16px; background: var(--bg-raised);
}
.set-q-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.set-q-num {
  flex: 0 0 auto; min-width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--honey, var(--yellow)); color: var(--edge);
  font-size: 0.78rem; font-weight: 900; border: 2px solid var(--edge);
}
.set-q-prompt { font-weight: 700; flex: 1; min-width: 0; }
.set-q-img { display: block; max-width: 260px; margin: 10px 0 0 36px; border-radius: 8px; border: 2px solid var(--border); }
/* The preview reuses the real .answer tiles so a set looks like the game.
   They are divs, not buttons -- nothing here is clickable, and marking one
   correct would turn a shared link into an answer key. */
.set-q-grid { margin: 12px 0 0 36px; gap: 10px; }
.set-q-grid .answer { padding: 13px 14px; font-size: 0.94rem; cursor: default; box-shadow: 0 4px 0 rgba(0,0,0,0.22); }
.set-q-grid .answer .key { flex-basis: 26px; height: 26px; font-size: 0.78rem; }

/* ---------- shared "More" dropdown ----------
   House rule: one primary action plus this menu. Used by the dashboard cards,
   Explore cards and the set page, so it is defined once here. */
.more-menu { position: relative; display: inline-block; }
.more-pop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 210px; padding: 6px;
  background: var(--bg-raised); border: 3px solid var(--edge);
  border-radius: 12px; box-shadow: 5px 5px 0 var(--edge);
}
/* Cards sit in a grid with overflow clipping, so a menu opening downward at
   the last row would be cut off. Anchoring right keeps it inside the card's
   horizontal bounds; z-index lifts it above sibling cards. */
.more-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 11px; border: 0; border-radius: 8px;
  background: none; color: var(--text); font: inherit;
  font-weight: 700; font-size: 0.88rem;
  text-align: left; cursor: pointer; text-decoration: none;
  white-space: nowrap;
}
.more-item:hover, .more-item:focus-visible { background: var(--bg); }
.more-item.is-danger { color: var(--coral, #d14343); }
.more-item .icon { width: 17px; height: 17px; flex: 0 0 auto; }
.more-trigger { white-space: nowrap; }
.more-trigger .icon { width: 15px; height: 15px; }

/* ---------- card action rows ----------
   Consistent spacing wherever a card ends in actions: the primary button and
   the More trigger share one row, aligned to the card's bottom edge. */
.kit-card .actions,
.explore-actions {
  display: flex; align-items: center; gap: 8px;
  margin-top: auto; padding-top: 12px;
}
.kit-card .actions > .btn:first-child,
.explore-actions > .btn:first-child { flex: 1; }
/* Let an open menu escape the card instead of being clipped by it. */
.kit-card { overflow: visible; }

@media (max-width: 700px) {
  .set-hero { grid-template-columns: 1fr; }
  .set-q-grid, .set-q-img { margin-left: 0; }
  .set-actions { width: 100%; }
  .more-menu, .more-menu .btn { width: 100%; }
}

/* ---------- mode picker (was a dropdown in a modal) ---------- */

.mode-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 6px; }
@media (max-width: 560px) { .mode-grid { grid-template-columns: 1fr; } }
.mode-opt {
  text-align: left; padding: 14px; border-radius: 14px; cursor: pointer;
  border: 2px solid var(--border); background: var(--bg); font: inherit; color: var(--text);
}
.mode-opt strong { display: block; font-size: 0.98rem; margin-bottom: 3px; }
.mode-opt span { font-size: 0.79rem; color: var(--text-soft); line-height: 1.4; }
.mode-opt:hover { border-color: var(--accent); }
.mode-opt.selected { border-color: var(--accent); background: color-mix(in srgb, var(--honey) 15%, var(--bg-raised)); }

/* ---------- gameplay ---------- */

.play-shell { max-width: 860px; margin: 0 auto; padding: 20px 18px 60px; }

.timer-track { height: 10px; border-radius: 999px; background: var(--border); overflow: hidden; margin-bottom: 18px; }
.timer-fill { height: 100%; background: var(--clover); border-radius: 999px; transition: width 0.25s linear, background 0.3s ease; }
.timer-fill.warn { background: var(--honey-deep); }
.timer-fill.danger { background: var(--sting); }

.play-hud { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.play-hud .secs { font-weight: 900; font-variant-numeric: tabular-nums; font-size: 1.05rem; }

/* Four fixed colours, Gimkit-style, so answers are told apart by position and
   colour rather than by reading all four. */
.answer-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
@media (max-width: 560px) { .answer-grid { grid-template-columns: 1fr; } }
.answer {
  display: flex; align-items: center; gap: 12px; text-align: left;
  padding: 20px 18px; border-radius: 16px; border: none; cursor: pointer;
  font: inherit; font-weight: 800; font-size: 1.02rem; color: #fff;
  box-shadow: 0 5px 0 rgba(0,0,0,0.22); transition: transform 0.07s ease, box-shadow 0.07s ease, opacity 0.2s ease;
}
.answer:active:not(:disabled) { transform: translateY(4px); box-shadow: 0 1px 0 rgba(0,0,0,0.22); }
.answer .key {
  flex: 0 0 30px; height: 30px; border-radius: 8px; display: grid; place-items: center;
  background: rgba(255,255,255,0.25); font-weight: 900; font-size: 0.86rem;
}
.answer.c0 { background: #e15241; }
.answer.c1 { background: #2f7fd4; }
.answer.c2 { background: #d9821e; }
.answer.c3 { background: #3f8f52; }
.answer:disabled { cursor: default; }

/* ---- reveal ----
   On reveal every tile drops its own colour so the only thing left on screen
   is green = the right answer, red = what you picked and got wrong. The rest
   grey out. Overriding the base colour matters: leaving a wrong answer green
   because it happened to be tile D would be actively misleading. */
.answer.revealed { transition: background 0.25s ease, opacity 0.25s ease, transform 0.25s ease; }
.answer.reveal-right {
  background: var(--right) !important;
  box-shadow: 0 5px 0 var(--right-deep);
  transform: scale(1.03);
}
.answer.reveal-wrong {
  background: var(--wrong) !important;
  box-shadow: 0 5px 0 var(--wrong-deep);
}
.answer.reveal-muted { background: #8a8a8a !important; opacity: 0.4; box-shadow: none; }
.answer .mark { margin-left: auto; font-size: 1.3rem; font-weight: 900; }

/* Kahoot puts a shape on every tile so answers can be called out by shape as
   well as position — useful when the projector colours wash out. */
.answer .key { font-size: 1rem; }

/* Verdict banner, Blooket-style: says plainly what happened and, when you got
   it wrong, what the answer actually was. */
.verdict-banner {
  border-radius: 16px; padding: 16px 20px; margin-bottom: 16px;
  color: #fff; font-weight: 800; display: flex; align-items: center; gap: 14px;
  animation: verdictIn 0.28s ease-out both;
}
.verdict-banner.right { background: var(--right); }
.verdict-banner.wrong { background: var(--wrong); }
.verdict-banner .big { font-size: 1.45rem; font-weight: 900; }
.verdict-banner .sub { font-size: 0.86rem; opacity: 0.92; font-weight: 600; }
.verdict-banner .earned {
  margin-left: auto; background: rgba(255,255,255,0.22); border-radius: 999px;
  padding: 7px 16px; font-size: 1.05rem; font-weight: 900; white-space: nowrap;
}
@keyframes verdictIn { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .verdict-banner { animation: none; }
  .answer.reveal-right { transform: none; }
}

/* Countdown until the next question, so the pause doesn't feel like a hang. */
.next-countdown { display: flex; align-items: center; gap: 10px; margin-top: 16px; color: var(--text-soft); font-size: 0.85rem; }
.next-countdown .track { flex: 1; height: 5px; border-radius: 999px; background: var(--border); overflow: hidden; }
.next-countdown .fill { height: 100%; background: var(--accent); width: 100%; }

.q-prompt { font-size: 1.55rem; font-weight: 900; line-height: 1.28; margin: 0 0 22px; text-wrap: balance; }

/* Floating "+120" that rises and fades on a correct answer. */
.honey-pop {
  position: fixed; left: 50%; top: 42%; transform: translateX(-50%);
  font-size: 2.1rem; font-weight: 900; color: var(--honey-deep);
  pointer-events: none; animation: honeyPop 1s ease-out forwards; z-index: 60;
  text-shadow: 0 2px 0 rgba(255,255,255,0.6);
}
@keyframes honeyPop {
  0% { opacity: 0; transform: translate(-50%, 10px) scale(0.8); }
  22% { opacity: 1; transform: translate(-50%, -6px) scale(1.08); }
  100% { opacity: 0; transform: translate(-50%, -70px) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .honey-pop { animation: none; opacity: 0; }
  .answer:active:not(:disabled) { transform: none; }
}

.streak-flame { color: var(--sting); font-weight: 900; }

/* ============================================================
   Landing page
   ============================================================ */

.hero {
  min-height: 100vh; display: flex; flex-direction: column;
  align-items: center; justify-content: center; padding: 40px 20px; position: relative;
  overflow: hidden; text-align: center;
}
/* Drifting hex cells behind the hero — the honeycomb read, cheap to render. */
.hero::before {
  content: ""; position: absolute; inset: -20%;
  background-image:
    radial-gradient(circle at 20% 30%, color-mix(in srgb, var(--honey) 22%, transparent) 0 14px, transparent 15px),
    radial-gradient(circle at 70% 60%, color-mix(in srgb, var(--honey) 16%, transparent) 0 22px, transparent 23px),
    radial-gradient(circle at 45% 85%, color-mix(in srgb, var(--honey) 14%, transparent) 0 18px, transparent 19px),
    radial-gradient(circle at 88% 18%, color-mix(in srgb, var(--honey) 18%, transparent) 0 12px, transparent 13px);
  background-size: 620px 620px;
  animation: drift 34s linear infinite; pointer-events: none;
}
@keyframes drift { to { transform: translate(-620px, -620px); } }
@media (prefers-reduced-motion: reduce) { .hero::before { animation: none; } }

.hero > * { position: relative; z-index: 1; }
.hero .bee { font-size: 4.4rem; animation: bob 3.4s ease-in-out infinite; }
@keyframes bob { 0%,100% { transform: translateY(0) rotate(-4deg); } 50% { transform: translateY(-14px) rotate(4deg); } }
@media (prefers-reduced-motion: reduce) { .hero .bee { animation: none; } }

.hero h1 { font-size: clamp(2.8rem, 9vw, 4.6rem); margin: 6px 0 10px; letter-spacing: -0.03em; }
.hero .tagline { font-size: 1.08rem; max-width: 46ch; margin: 0 auto 30px; }

/* The join box is the point of the page, so it is the loudest thing on it. */
.join-box {
  background: var(--bg-raised); border: 2px solid var(--border);
  border-radius: 20px; padding: 22px; width: min(430px, 94vw);
  box-shadow: 0 10px 40px -18px rgba(42,26,15,0.55); margin-bottom: 18px;
}
.join-box input {
  width: 100%; text-align: center; font-size: 1.9rem; font-weight: 900;
  letter-spacing: 0.22em; text-transform: uppercase; padding: 14px 10px;
  border-radius: 14px; font-variant-numeric: tabular-nums;
}
.join-box input::placeholder { letter-spacing: 0.1em; font-size: 1.1rem; font-weight: 700; }

.feature-row { display: flex; gap: 26px; flex-wrap: wrap; justify-content: center; margin-top: 34px; }
.feature { max-width: 210px; }
.feature .ico { font-size: 1.9rem; }
.feature strong { display: block; margin: 4px 0 2px; }
.feature span { font-size: 0.82rem; color: var(--text-soft); line-height: 1.45; }

/* ---------- landing: the game modes ----------
   Cover art rather than icons, because the modes are the thing worth seeing
   and a generic glyph communicates none of it. */
.mode-strip { width: min(1040px, 94vw); margin: 54px auto 0; }
.mode-strip-title {
  margin: 0 0 20px;
  font-size: clamp(1.3rem, 3vw, 1.9rem);
  text-transform: uppercase;
  letter-spacing: -0.02em;
  text-align: center;
}
.mode-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.mode-tile {
  position: relative;
  isolation: isolate;
  min-height: 225px;
  display: flex; flex-direction: column;
  justify-content: flex-end;
  background: #111a31;
  color: #fff;
  border: 3px solid var(--edge);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  text-align: left;
  transition: transform .18s ease, box-shadow .18s ease;
}
.mode-tile:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--edge); }
.mode-tile::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 22%, rgba(7, 13, 29, .2) 48%, rgba(7, 13, 29, .8) 100%);
}
.mode-cover {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: var(--cover);
  background-size: cover; background-position: center;
}
.mode-text { position: relative; z-index: 2; padding: 26px 16px 17px; color: #fff; }
.mode-text strong { display: block; font-size: 1.1rem; margin-bottom: 4px; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .55); }
.mode-text span { font-size: 0.84rem; color: #f4f6ff; line-height: 1.4; text-shadow: 0 1px 3px rgba(0, 0, 0, .65); }
.mode-strip-foot {
  margin: 22px auto 0; max-width: 54ch;
  text-align: center; font-size: 0.9rem; color: var(--text-soft);
}
@media (prefers-reduced-motion: reduce) { .mode-tile:hover { transform: none; } }

/* ---------- landing: note from the creator ----------
   A square pinned card, rotated slightly off true so it reads as something
   set down on the page rather than another content block. */
.creator-note { display: flex; justify-content: center; margin: 58px auto 10px; padding: 0 16px; }
.note-card {
  position: relative;
  width: min(420px, 100%);
  /* Square is the point -- an index card, not a banner. It relaxes on
     narrow screens where forcing 1:1 would make the text tiny. */
  aspect-ratio: 1 / 1;
  display: flex; flex-direction: column; justify-content: center;
  gap: 14px;
  padding: 34px 30px;
  background: var(--yellow, #ffe24a);
  color: var(--edge);
  border: 3px solid var(--edge);
  border-radius: 4px;
  box-shadow: 7px 7px 0 var(--edge);
  transform: rotate(-1.4deg);
}
.note-card p { margin: 0; font-size: 0.95rem; line-height: 1.6; }
.note-sign {
  font-family: ui-serif, Georgia, "Times New Roman", serif;
  font-style: italic;
  font-size: 1.08rem;
  font-weight: 700;
  align-self: flex-end;
}
/* The pin. Purely decorative, hidden from assistive tech in the markup. */
.note-pin {
  position: absolute; top: -11px; left: 50%; margin-left: -11px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--coral, #ff5c5c);
  border: 3px solid var(--edge);
  box-shadow: 0 2px 0 rgba(0,0,0,.25);
}
@media (max-width: 520px) {
  .note-card { aspect-ratio: auto; padding: 28px 22px; }
}
@media (prefers-reduced-motion: reduce) { .note-card { transform: none; } }

/* ============================================================
   Host lobby — built for a projector
   ============================================================ */

.lobby {
  min-height: 100vh; display: flex; flex-direction: column; padding: 20px 24px 24px;
  /* Room for the fixed Start-Game bar so the last row of player chips never
     sits underneath it. Set from JS to the bar's real measured height (it
     wraps to two lines on narrow screens or once the button label grows to
     "Start Game (23)"), with a sane fallback before that measurement runs. */
  padding-bottom: calc(var(--lobby-foot-h, 96px) + 20px);
}

.lobby-bar {
  display: flex; align-items: stretch; gap: 18px; flex-wrap: wrap;
  background: var(--bg-raised); border: 1px solid var(--border);
  border-radius: 18px; padding: 16px 20px; margin-bottom: 18px;
}
.pin-block { display: flex; flex-direction: column; justify-content: center; }
.pin-label { font-size: 0.74rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.14em; color: var(--text-soft); }
.pin-code {
  font-size: clamp(2.6rem, 7vw, 4.6rem); font-weight: 900; line-height: 1;
  letter-spacing: 0.14em; font-variant-numeric: tabular-nums;
  /* Hardcoded white, not var(--accent) — .lobby-bar is unconditionally blue
     (see the global ".lobby-bar { background: var(--blue) }" override further
     down this file) and in the light theme --accent equals --blue exactly,
     so the code rendered blue text on a blue bar: invisible. .lobby-bar
     already sets color:#fff for everything in it; this just stops the more
     specific selector from overriding that with the colliding value. */
  color: #fff;
}
.join-at { display: flex; flex-direction: column; justify-content: center; }
.join-at .where { font-size: clamp(1rem, 2.4vw, 1.5rem); font-weight: 800; }
.lobby-bar .qr { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.lobby-bar .qr img { width: 116px; height: 116px; border-radius: 12px; background: #fff; padding: 5px; }

.lobby-main { flex: 1 1 auto; display: flex; flex-direction: column; }
.lobby-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.player-count { font-size: 2.1rem; font-weight: 900; font-variant-numeric: tabular-nums; line-height: 1; }
.player-count-lbl { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text-soft); font-weight: 800; }

.player-wall { display: flex; flex-wrap: wrap; gap: 12px; align-content: flex-start; }
.player-chip {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--bg-raised); border: 2px solid var(--border);
  border-radius: 999px; padding: 10px 18px 10px 12px;
  font-weight: 800; font-size: 1.05rem;
  animation: chipIn 0.34s cubic-bezier(0.2, 1.5, 0.4, 1) both;
}
.player-chip .face { font-size: 1.35rem; }
/* Now a button (click to remove), so it has to reset the UA button styling
   and only reveal the × on hover/focus rather than shouting at the host. */
.player-chip { font-family: inherit; color: inherit; cursor: pointer; position: relative; }
.player-chip .chip-x {
  display: inline-flex; opacity: 0;
  width: 16px; height: 16px; margin-left: 2px;
  transition: opacity .15s ease;
}
.player-chip .chip-x .icon { width: 16px; height: 16px; }
.player-chip:hover, .player-chip:focus-visible { border-color: var(--coral, #ff5c5c); }
.player-chip:hover .chip-x, .player-chip:focus-visible .chip-x { opacity: .9; }

/* Same affordance on the spectate board. */
.lb-kick {
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  cursor: pointer; text-align: left;
}
.lb-kick:hover, .lb-kick:focus-visible { text-decoration: underline; text-decoration-color: var(--coral, #ff5c5c); }
@keyframes chipIn {
  from { opacity: 0; transform: scale(0.5) translateY(12px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}
@media (prefers-reduced-motion: reduce) { .player-chip { animation: none; } }

.hive-group { margin-bottom: 20px; }
.hive-group h4 {
  margin: 0 0 9px; font-size: 0.78rem; text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--text-soft);
}

.lobby-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center;
  justify-content: center; color: var(--text-soft); gap: 8px; padding: 40px 0;
}
.lobby-empty .waiting-bee { font-size: 3rem; animation: bob 2.6s ease-in-out infinite; }

/* Pinned to the bottom of the viewport, not the bottom of the lobby content —
   the whole point is that Start Game is reachable without scrolling however
   long the player roster gets. Same fixed-bar pattern as .answer-feedback. */
.lobby-foot {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--bg-raised);
  border-top: 1px solid var(--border);
  box-shadow: 0 -12px 30px -18px rgba(0, 0, 0, 0.35);
  padding: 16px clamp(16px, 4vw, 40px);
  padding-bottom: max(16px, env(safe-area-inset-bottom));
}
.lobby-foot-inner {
  width: min(1280px, 100%); margin: 0 auto;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
}
.btn-huge { font-size: 1.15rem; padding: 16px 40px; border-radius: 16px; }

/* ---------- host-paced live view ---------- */

.live-stage { padding: 18px 24px 24px; }
.live-q {
  font-size: clamp(1.6rem, 4vw, 2.6rem); font-weight: 900; line-height: 1.22;
  text-wrap: balance; margin: 6px 0 20px;
}
.live-meta { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; }
.answered-pill {
  font-size: 1.1rem; font-weight: 900; font-variant-numeric: tabular-nums;
  background: var(--panel-2, var(--bg-raised)); border: 1px solid var(--border);
  border-radius: 999px; padding: 6px 16px;
}

/* Bar chart of how the room answered — one row per choice, bar width is the
   share of responses. The correct row is outlined rather than recoloured so
   the four answer colours stay meaningful. */
.dist { display: grid; gap: 10px; }
.dist-row { display: flex; align-items: center; gap: 12px; }
.dist-label {
  flex: 0 0 30px; height: 30px; border-radius: 8px; display: grid; place-items: center;
  font-weight: 900; color: #fff; font-size: 0.86rem;
}
.dist-label.c0 { background: #e15241; } .dist-label.c1 { background: #2f7fd4; }
.dist-label.c2 { background: #d9821e; } .dist-label.c3 { background: #3f8f52; }
.dist-bar-wrap { flex: 1; background: var(--bg); border-radius: 8px; overflow: hidden; height: 38px; position: relative; border: 1px solid var(--border); }
.dist-bar { height: 100%; border-radius: 7px 0 0 7px; transition: width 0.5s cubic-bezier(0.2,0.8,0.3,1); }
.dist-bar.c0 { background: #e15241; } .dist-bar.c1 { background: #2f7fd4; }
.dist-bar.c2 { background: #d9821e; } .dist-bar.c3 { background: #3f8f52; }
.dist-text {
  position: absolute; inset: 0; display: flex; align-items: center;
  gap: 8px; padding: 0 12px; font-weight: 700; font-size: 0.95rem;
}
.dist-text .n { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 900; }
.dist-row.is-correct .dist-bar-wrap { outline: 3px solid var(--clover); outline-offset: 1px; }
.dist-row.is-correct .dist-text::after { content: ""; }

/* ---------- podium ---------- */

.podium { display: flex; align-items: flex-end; justify-content: center; gap: 14px; margin: 26px 0 10px; }
.podium-col { display: flex; flex-direction: column; align-items: center; gap: 8px; width: min(150px, 28vw); }
.podium-face { font-size: 2.4rem; }
.podium-name { font-weight: 800; font-size: 0.95rem; text-align: center; overflow-wrap: anywhere; }
.podium-block {
  width: 100%; border-radius: 12px 12px 0 0; display: grid; place-items: center;
  font-weight: 900; font-size: 1.15rem; color: var(--accent-ink);
  animation: riseUp 0.7s cubic-bezier(0.2, 1.1, 0.3, 1) both;
}
.podium-col:nth-child(1) .podium-block { height: 92px;  background: #c8ccd2; }
.podium-col:nth-child(2) .podium-block { height: 132px; background: var(--honey); animation-delay: 0.15s; }
.podium-col:nth-child(3) .podium-block { height: 70px;  background: #cd7f4b; }
@keyframes riseUp { from { transform: scaleY(0.1); opacity: 0; transform-origin: bottom; } to { transform: scaleY(1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .podium-block { animation: none; } }

/* ---------- waiting for host ---------- */

.waiting-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; padding: 50px 20px; text-align: center;
}
.waiting-state .big { font-size: 3.2rem; animation: bob 2.4s ease-in-out infinite; }
.waiting-state .verdict { font-size: 1.35rem; font-weight: 900; }
.waiting-state .verdict.right { color: var(--clover); }
.waiting-state .verdict.wrong { color: var(--sting); }
@media (prefers-reduced-motion: reduce) { .waiting-state .big { animation: none; } }

/* ---------- import panel ---------- */

.prompt-box {
  background: var(--bg); border: 1px solid var(--border); border-radius: 12px;
  padding: 13px 14px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.74rem; line-height: 1.5; white-space: pre-wrap; max-height: 230px;
  overflow-y: auto; color: var(--text-soft); margin-bottom: 10px;
}
textarea.json-input {
  width: 100%; min-height: 150px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.8rem; padding: 12px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text); resize: vertical;
}
.drop-zone {
  border: 2px dashed var(--border); border-radius: 14px; padding: 26px 18px;
  text-align: center; color: var(--text-soft); cursor: pointer; background: var(--bg);
}
.drop-zone:hover, .drop-zone.over { border-color: var(--accent); color: var(--text); }

.center { text-align: center; }
.muted { color: var(--text-soft); }
.spacer { flex: 1; }
.flex-row { display: flex; align-items: center; gap: 10px; }
.gap { display: flex; flex-direction: column; gap: 14px; }

.badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 3px 9px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--honey) 30%, var(--bg-raised));
  color: var(--honey-deep);
}
.badge.status-active { background: color-mix(in srgb, var(--clover) 25%, var(--bg-raised)); color: var(--clover); }
.badge.status-ended { background: color-mix(in srgb, var(--sting) 20%, var(--bg-raised)); color: var(--sting); }

/* ========================================================================== */
/* Buzkit — electric neo-brutalist identity                                   */
/* ========================================================================== */

:root,
:root[data-theme="light"] {
  --honey: #ffe24a;
  --honey-deep: #2f5bff;
  --honey-pale: #fff29a;
  --ink: #111114;
  --cream: #fff9e8;
  --sting: #ff5c5c;
  --clover: #24c991;
  --plum: #ffffff;
  --bg: #fff9e8;
  --bg-raised: #ffffff;
  --panel-2: #f1f1ed;
  --text: #111114;
  --text-soft: #4b4960;
  --border: #111114;
  --accent: #2f5bff;
  --accent-ink: #111114;
  --blue: #2f5bff;
  --purple: #ffffff;
  --yellow: #ffe24a;
  --coral: #ff5c5c;
  --mint: #52e3b3;
  --paper: #fff9e8;
  --edge: #111114;
  --surface-ink: #111114;
  --surface-ink-soft: #55516a;
  --surface-link: #2447d8;
  --blue-ink: #2447d8;
  --input-bg: #ffffff;
  --button-primary-bg: var(--yellow);
  --button-secondary-bg: #ffffff;
  --button-danger-bg: var(--coral);
  --button-success-bg: var(--mint);
  --button-ink: var(--edge);
  --control-bg: #ffffff;
  --control-ink: var(--edge);
  --control-hover-bg: var(--yellow);
  --active-bg: var(--yellow);
  --active-ink: var(--edge);
  --shadow: 6px 6px 0 var(--edge);
  --shadow-sm: 3px 3px 0 var(--edge);
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #171936;
    --bg-raised: #232752;
    --panel-2: #1d2148;
    --text: #fffdf5;
    --text-soft: #cac7e0;
    --border: #111114;
    --accent: #ffe24a;
    --accent-ink: #111114;
    --surface-ink: #fffdf5;
    --surface-ink-soft: #c3bfdd;
    --surface-link: #9db0ff;
    --blue-ink: #9db0ff;
    --input-bg: #171936;
    --button-primary-bg: #2f5bff;
    --button-secondary-bg: #303665;
    --button-danger-bg: #a9364b;
    --button-success-bg: #167a62;
    --button-ink: #fffdf5;
    --control-bg: #303665;
    --control-ink: #fffdf5;
    --control-hover-bg: #2f5bff;
    --active-bg: #2f5bff;
    --active-ink: #fffdf5;
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg: #171936;
  --bg-raised: #232752;
  --panel-2: #1d2148;
  --text: #fffdf5;
  --text-soft: #cac7e0;
  --border: #111114;
  --accent: #ffe24a;
  --accent-ink: #111114;
  --surface-ink: #fffdf5;
  --surface-ink-soft: #c3bfdd;
  --surface-link: #9db0ff;
  --blue-ink: #9db0ff;
  --input-bg: #171936;
  --button-primary-bg: #2f5bff;
  --button-secondary-bg: #303665;
  --button-danger-bg: #a9364b;
  --button-success-bg: #167a62;
  --button-ink: #fffdf5;
  --control-bg: #303665;
  --control-ink: #fffdf5;
  --control-hover-bg: #2f5bff;
  --active-bg: #2f5bff;
  --active-ink: #fffdf5;
  color-scheme: dark;
}

* { box-sizing: border-box; }

body {
  background-color: var(--bg);
  background-image:
    linear-gradient(color-mix(in srgb, var(--blue) 13%, transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--blue) 13%, transparent) 1px, transparent 1px);
  background-size: 28px 28px;
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-weight: 600;
}

h1, h2, h3, h4,
.brand,
.code-display,
.pin-number,
.hero-copy h1 {
  font-family: "Arial Black", Inter, ui-sans-serif, system-ui, sans-serif;
  letter-spacing: -0.045em;
}

h1, h2, h3, h4 { text-wrap: balance; }

.topbar {
  min-height: 68px;
  padding: 10px clamp(16px, 4vw, 52px);
  background: var(--blue);
  color: #fff;
  border-bottom: 4px solid var(--edge);
  box-shadow: 0 5px 0 var(--yellow);
}

.topbar .brand { color: #fff; font-size: 1.35rem; text-transform: uppercase; }

.brand { display: inline-flex; align-items: center; gap: 10px; }

.brand-mark {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  display: inline-block;
  background: #fff url("buzkit-mark.svg") center / cover no-repeat;
  border: 2px solid var(--edge);
  box-shadow: 3px 3px 0 var(--edge);
}

.theme-toggle {
  color: var(--control-ink);
  border: 2px solid var(--edge);
  background: var(--control-bg);
  box-shadow: var(--shadow-sm);
  border-radius: 6px;
}
.theme-toggle:hover { background: var(--control-hover-bg); color: var(--control-ink); transform: translate(-1px, -1px); }

.stripe-rule {
  height: 9px;
  background: repeating-linear-gradient(135deg, var(--yellow) 0 16px, var(--coral) 16px 32px, var(--blue) 32px 48px);
  border: 0;
}

.wrap { width: min(1080px, calc(100% - 34px)); }
.wrap.wide { width: min(1280px, calc(100% - 34px)); }

.card,
.join-box,
.feature,
.kit-card,
.mode-opt,
.qcard,
.lobby-card,
.live-stage,
.waiting-state,
.prompt-box,
.drop-zone {
  border: 3px solid var(--edge);
  border-radius: 10px;
  box-shadow: var(--shadow);
  background: var(--bg-raised);
  color: var(--surface-ink);
}

.card { padding: clamp(18px, 3vw, 30px); }
.card h1, .card h2, .card h3, .card h4,
.kit-card h3, .mode-opt h3, .feature h3 { color: var(--surface-ink); }
.card .muted, .kit-card .muted, .feature p, .mode-opt p { color: var(--surface-ink-soft); }
.card .hint, .join-box .hint, .hero .join-box p { color: var(--surface-ink-soft); }
.card a { color: var(--surface-link); font-weight: 850; }

.btn {
  min-height: 46px;
  padding: 11px 18px;
  border: 3px solid var(--edge);
  border-radius: 7px;
  background: var(--button-primary-bg);
  color: var(--button-ink);
  box-shadow: 4px 4px 0 var(--edge);
  font-weight: 900;
  letter-spacing: .015em;
  text-transform: uppercase;
  transition: transform .12s ease, box-shadow .12s ease, background .12s ease;
}
.btn:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--edge); }
.btn:active { transform: translate(3px, 3px); box-shadow: 1px 1px 0 var(--edge); }
.btn.primary, .btn-primary { background: var(--button-primary-bg); color: var(--button-ink); }
.btn.secondary, .btn-secondary { background: var(--button-secondary-bg); color: var(--button-ink); }
.btn.danger, .btn-danger { background: var(--button-danger-bg); color: var(--button-ink); }
.btn.success, .btn-success { background: var(--button-success-bg); color: var(--button-ink); }
.btn.ghost { background: transparent; color: currentColor; }
.btn-primary:hover { filter: none; }

input, select, textarea,
.field input, .field select, textarea.json-input {
  border: 3px solid var(--edge);
  border-radius: 7px;
  background: var(--input-bg);
  color: var(--surface-ink);
  box-shadow: var(--shadow-sm);
  font-weight: 750;
}
input:focus, select:focus, textarea:focus {
  outline: 4px solid color-mix(in srgb, var(--yellow) 80%, transparent);
  outline-offset: 1px;
  border-color: var(--edge);
}
.field label { color: inherit; font-weight: 900; text-transform: uppercase; letter-spacing: .05em; }

/* Landing */
.hero {
  min-height: calc(100vh - 77px);
  width: min(1180px, calc(100% - 34px));
  margin: 0 auto;
  padding: clamp(44px, 8vh, 92px) 0 54px;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(320px, .95fr);
  align-items: center;
  /* Wider gutter at desktop sizes so the wordmark and the artwork are not
     nearly touching. The lower bound is unchanged -- on narrow screens the
     grid collapses to one column and the gap becomes vertical spacing. */
  gap: clamp(28px, 6vw, 96px);
  text-align: left;
  background: none;
}
.hero-copy { position: relative; z-index: 1; }
.hero-kicker {
  display: inline-block;
  margin-bottom: 18px;
  padding: 7px 11px;
  background: var(--coral);
  color: var(--edge);
  border: 3px solid var(--edge);
  box-shadow: var(--shadow-sm);
  font-weight: 950;
  text-transform: uppercase;
  letter-spacing: .09em;
  transform: rotate(-1.5deg);
}
.hero-copy h1 {
  margin: 0;
  color: var(--text);
  /* Capped smaller than the column allows: at the old 9rem the wordmark ran
     the full width of its grid cell and its 9px offset shadow crowded the
     artwork in the next column. */
  font-size: clamp(3.8rem, 10vw, 7.4rem);
  line-height: .78;
  text-transform: uppercase;
  text-shadow: 5px 5px 0 var(--blue), 9px 9px 0 var(--edge);
}
.hero .tagline {
  max-width: 660px;
  margin: 30px 0 24px;
  color: var(--text);
  font-size: clamp(1.08rem, 2vw, 1.38rem);
  line-height: 1.45;
  font-weight: 750;
}
.hero .join-box {
  width: min(100%, 590px);
  margin: 0;
  padding: 18px;
  background: var(--yellow);
  color: var(--edge);
  transform: rotate(.35deg);
}
.hero .join-box .join-row { gap: 12px; }
.hero .join-box input { min-height: 52px; font-size: 1.06rem; }
.hero .join-box .btn { min-height: 52px; background: var(--blue); color: #fff; }
.hero .join-box .hint, .hero .join-box p { color: #55516a; }
.hero-art {
  position: relative;
  isolation: isolate;
  transform: rotate(2deg);
}
.hero-art::before {
  content: "";
  position: absolute;
  inset: -12px 18px 20px -16px;
  background: #fff;
  border: 4px solid var(--edge);
  box-shadow: 10px 10px 0 var(--edge);
  z-index: -1;
}
.hero-art img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; border: 4px solid var(--edge); }
/* .hero is a two-column grid (headline+join box | artwork). Anything that is
   meant to sit BELOW that split has to be told to span both columns,
   otherwise it gets auto-placed into the next free cell -- which is what put
   the creator note on top of the mode tiles. */
.hero .mode-strip,
.hero .creator-note {
  grid-column: 1 / -1;
  width: 100%;
  margin-left: 0;
  margin-right: 0;
}

.hero .feature-row {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
  width: 100%;
  margin: 14px 0 0;
}
.hero .feature { padding: 18px; text-align: left; transform: rotate(-.35deg); }
.hero .feature:nth-child(2) { background: var(--mint); transform: rotate(.5deg); }
.hero .feature:nth-child(3) { background: var(--coral); transform: rotate(-.2deg); }
.hero .feature:nth-child(2), .hero .feature:nth-child(3),
.hero .feature:nth-child(2) h3, .hero .feature:nth-child(3) h3,
.hero .feature:nth-child(2) p, .hero .feature:nth-child(3) p { color: var(--edge); }
.hero .feature .icon { font-size: 2rem; }

/* App shell */
.shell { min-height: calc(100vh - 77px); }
.side {
  background: var(--bg-raised);
  color: var(--surface-ink);
  border-right: 4px solid var(--edge);
}
.side .brand { color: var(--surface-ink); }
.side-link {
  color: var(--surface-ink);
  border: 2px solid transparent;
  border-radius: 6px;
  font-weight: 850;
}
.side-link:hover { background: var(--panel-2); color: var(--surface-ink); border-color: var(--edge); }
.side-link.active { background: var(--active-bg); color: var(--active-ink); border: 3px solid var(--edge); box-shadow: var(--shadow-sm); }
.main { padding: clamp(22px, 4vw, 48px); }
.main > h1, .main > h2, .main > p { max-width: 1050px; }

.kit-card, .mode-opt { transition: transform .13s ease, box-shadow .13s ease; }
.kit-card:hover, .mode-opt:hover { transform: translate(-2px, -2px) rotate(-.3deg); box-shadow: 8px 8px 0 var(--edge); }
.kit-card .count { color: var(--blue-ink); }
.mode-opt.selected { border-color: var(--edge); background: var(--yellow); color: var(--edge); outline: 4px solid var(--blue); outline-offset: 2px; }
.mode-opt:nth-child(2n) { background: #fff; }
.mode-opt:nth-child(3n) { background: #dcfff3; }
.mode-opt:nth-child(2n), .mode-opt:nth-child(3n),
.mode-opt:nth-child(2n) h3, .mode-opt:nth-child(3n) h3,
.mode-opt:nth-child(2n) p, .mode-opt:nth-child(3n) p { color: var(--edge); }
.badge { border: 2px solid var(--edge); border-radius: 4px; background: var(--yellow); color: var(--edge); }

.code-display,
.pin-number {
  display: inline-block;
  padding: 8px 18px;
  background: var(--yellow);
  color: var(--edge);
  border: 4px solid var(--edge);
  border-radius: 8px;
  box-shadow: 7px 7px 0 var(--edge);
  letter-spacing: .08em;
}
.lobby-bar { background: var(--blue); color: #fff; border-bottom: 4px solid var(--edge); }
.lobby-card { background: var(--bg-raised); }
.lobby-empty .waiting-bee, .waiting-state .big { filter: none; }
.player-chip { border: 2px solid var(--edge); border-radius: 6px; background: var(--mint); color: var(--edge); box-shadow: 2px 2px 0 var(--edge); }
.hive-group { border-top: 3px solid var(--edge); padding-top: 14px; }
.hive-group h4 { color: var(--blue-ink); }

.play-shell { background: var(--bg); }
.play-topbar { background: var(--blue); color: #fff; border-bottom: 4px solid var(--edge); }
.money-chip { border: 2px solid var(--edge); border-radius: 5px; background: var(--yellow); color: var(--edge); box-shadow: 2px 2px 0 var(--edge); }
.qcard { background: var(--bg-raised); }
.answer {
  border: 3px solid var(--edge);
  border-radius: 8px;
  box-shadow: 5px 5px 0 var(--edge);
  color: var(--edge);
  font-weight: 900;
}
.answer:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 var(--edge); }
.answer.c0 { background: var(--coral); }
.answer.c1 { background: #67a7ff; }
.answer.c2 { background: var(--yellow); }
.answer.c3 { background: var(--mint); }
.answer.correct { outline: 5px solid #16a773; outline-offset: 3px; }
.answer.wrong { outline: 5px solid #d43131; outline-offset: 3px; }
.timer-track { border: 2px solid var(--edge); background: #fff; }
.timer-fill { background: var(--blue); }
.timer-fill.warn { background: var(--coral); }
.honey-pop { color: var(--blue-ink); text-shadow: 2px 2px 0 var(--yellow); }

.leaderboard-row, .dist-row { border-bottom: 2px solid var(--edge); }
.dist-bar-wrap { border: 2px solid var(--edge); border-radius: 4px; background: #fff; }
.dist-bar { border-radius: 0; }
.podium-block { border: 3px solid var(--edge); border-bottom: 0; border-radius: 5px 5px 0 0; }
.podium-col:nth-child(1) .podium-block { background: #d6d9e1; }
.podium-col:nth-child(2) .podium-block { background: var(--yellow); }
.podium-col:nth-child(3) .podium-block { background: var(--coral); }

.prompt-box, textarea.json-input, .drop-zone { background: var(--input-bg); color: var(--surface-ink); }
.drop-zone:hover, .drop-zone.over { border-color: var(--edge); background: var(--yellow); color: var(--edge); }

@media (max-width: 820px) {
  .hero { grid-template-columns: 1fr; padding-top: 42px; }
  .hero-copy h1 { font-size: clamp(4rem, 22vw, 7rem); }
  .hero-art { width: min(480px, 90%); margin: 16px auto; }
  .hero .feature-row { grid-template-columns: 1fr; }
  .shell { display: block; }
  .side { border-right: 0; border-bottom: 4px solid var(--edge); }
}

@media (max-width: 560px) {
  .topbar { min-height: 60px; }
  .brand-mark { width: 32px; height: 32px; flex-basis: 32px; }
  .hero { width: min(100% - 24px, 1180px); gap: 26px; }
  .hero-copy h1 { text-shadow: 3px 3px 0 var(--blue), 6px 6px 0 var(--edge); }
  .hero .join-box .join-row { flex-direction: column; }
  .hero .join-box .btn { width: 100%; }
  .wrap, .wrap.wide { width: min(100% - 24px, 1280px); }
  .main { padding: 20px 14px 34px; }
  .answer-grid { gap: 11px; }
  .answer { box-shadow: 3px 3px 0 var(--edge); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { scroll-behavior: auto !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* ========================================================================== */
/* Flow cleanup: shared icons, creation/play modals, countdown, larger quiz  */
/* ========================================================================== */

[hidden] { display: none !important; }

.icon {
  width: 1.15em;
  height: 1.15em;
  display: inline-block;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -.18em;
}

.theme-toggle .icon { width: 20px; height: 20px; }
.feature .ico { display: flex; align-items: center; margin-bottom: 8px; }
.feature .ico .icon { width: 34px; height: 34px; stroke-width: 1.8; }

.avatar-dot {
  --avatar-hue: 210;
  width: 34px;
  height: 34px;
  display: inline-grid;
  place-items: center;
  flex: 0 0 34px;
  border: 2px solid var(--edge);
  border-radius: 50%;
  background: hsl(var(--avatar-hue) 82% 70%);
  color: var(--edge);
  box-shadow: 2px 2px 0 var(--edge);
  font-size: .82rem;
  font-weight: 950;
}

body.modal-open { overflow: hidden; }
.modal-shell {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 18px;
  background: rgba(10, 10, 18, .78);
  backdrop-filter: blur(3px);
}
.modal-card {
  width: min(680px, 96vw);
  max-height: calc(100vh - 36px);
  overflow-y: auto;
  margin: 0;
}
.modal-card-wide { width: min(980px, 96vw); }
.modal-head { display: flex; align-items: flex-start; gap: 18px; margin-bottom: 20px; }
.modal-head > div { min-width: 0; flex: 1; }
.modal-head h2 { margin: 2px 0 0; }
.modal-head p { margin: 4px 0 0; overflow-wrap: anywhere; }
.eyebrow {
  color: var(--blue-ink);
  font-size: .72rem;
  font-weight: 950;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.icon-btn {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  flex: 0 0 42px;
  padding: 0;
  border: 3px solid var(--edge);
  border-radius: 7px;
  background: var(--control-bg);
  color: var(--control-ink);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}
.icon-btn:hover { background: var(--control-hover-bg); color: var(--control-ink); transform: translate(-1px, -1px); }

.create-grid { display: grid; grid-template-columns: .85fr 1.15fr; gap: 18px; }
.create-panel {
  min-width: 0;
  padding: 20px;
  border: 3px solid var(--edge);
  border-radius: 9px;
  background: var(--bg-raised);
  color: var(--surface-ink);
}
.create-panel-ai { background: var(--panel-2); }
.create-panel > p { color: var(--surface-ink-soft); }
.panel-icon,
.choice-icon {
  width: 48px;
  height: 48px;
  display: grid;
  place-items: center;
  margin-bottom: 12px;
  border: 3px solid var(--edge);
  border-radius: 7px;
  background: var(--yellow);
  color: var(--edge);
  box-shadow: var(--shadow-sm);
}
.panel-icon .icon, .choice-icon .icon { width: 26px; height: 26px; }
.prompt-details { margin: 12px 0; }
.prompt-details summary { cursor: pointer; color: var(--surface-link); font-weight: 900; }
.prompt-details .prompt-box { margin: 10px 0 0; box-shadow: none; }
.drop-zone { display: flex; flex-direction: column; align-items: center; gap: 5px; margin-top: 12px; }
.drop-icon { width: 28px; height: 28px; margin-bottom: 4px; }
.compact-field { margin: 12px 0 4px; }
.compact-field > span { font-size: .76rem; font-weight: 900; letter-spacing: .06em; text-transform: uppercase; }
.compact-field textarea { margin-top: 6px; min-height: 110px; }

.play-choice-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.mode-category + .mode-category { margin-top: 24px; padding-top: 20px; border-top: 3px solid var(--edge); }
.mode-category-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.mode-category-head h3 { margin: 0; font-size: 1.25rem; }
.mode-category-head .eyebrow { margin: 0; }
.play-back { margin-bottom: 14px; }
.choice-card {
  position: relative;
  min-width: 0;
  min-height: 220px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  padding: 22px;
  border: 3px solid var(--edge);
  border-radius: 9px;
  background: var(--bg-raised);
  color: var(--surface-ink);
  box-shadow: 5px 5px 0 var(--edge);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.choice-card:not(.choice-art):nth-child(2) { background: var(--yellow); }
.choice-card:not(.choice-art):nth-child(3) { background: var(--mint); }
.choice-card:not(.choice-art):nth-child(2), .choice-card:not(.choice-art):nth-child(3) { color: var(--edge); }
.choice-card:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 var(--edge); }
.choice-card:disabled { opacity: .55; cursor: wait; }

/* The game image is the card. A bottom gradient keeps its white title and
   description readable without hiding the artwork behind a separate band. */
.choice-card.choice-art {
  isolation: isolate;
  justify-content: flex-end;
  padding: 0;
  overflow: hidden;
  background: #111a31;
  color: #fff;
}
.choice-card.choice-art::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg, transparent 20%, rgba(7, 13, 29, .22) 48%, rgba(7, 13, 29, .82) 100%);
}
.choice-cover {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  background-image: var(--cover);
  background-size: cover;
  background-position: center;
  transition: transform .25s ease;
}
.choice-art:hover .choice-cover { transform: scale(1.04); }
.choice-body {
  display: flex; flex-direction: column; gap: 4px;
  position: relative;
  z-index: 2;
  margin-top: auto;
  padding: 32px 17px 17px;
  text-align: left; width: 100%;
  color: #fff;
}
.choice-card.choice-art .choice-body strong { font-size: 1.17rem; line-height: 1.2; color: #fff; text-shadow: 0 1px 3px rgba(0, 0, 0, .65); }
.choice-card.choice-art .choice-body span { font-size: .84rem; line-height: 1.35; color: #f4f6ff; font-weight: 650; text-shadow: 0 1px 3px rgba(0, 0, 0, .75); }
@media (prefers-reduced-motion: reduce) { .choice-art:hover .choice-cover { transform: none; } }
.choice-card strong { font-family: "Arial Black", Inter, sans-serif; font-size: 1.4rem; }
.choice-card > span:not(.choice-icon) { color: var(--surface-ink-soft); line-height: 1.45; }
.choice-card:not(.choice-art):nth-child(2) > span:not(.choice-icon),
.choice-card:not(.choice-art):nth-child(3) > span:not(.choice-icon) { color: var(--edge); }
.choice-card .choice-arrow { position: absolute; right: 18px; bottom: 18px; width: 25px; height: 25px; }


/* ---------- Explore, reports, and two-step joining ---------- */

.visibility-badge {
  width: fit-content;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 2px solid var(--edge);
  border-radius: 5px;
  background: #fff;
  color: var(--edge);
  font-size: .7rem;
  font-weight: 950;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.visibility-badge.is-public { background: var(--mint); }
.visibility-badge .icon { width: 15px; height: 15px; }
.kit-card .publish-btn { grid-column: auto; }
.kit-author { margin-top: auto; color: var(--surface-ink-soft); font-size: .78rem; font-weight: 850; }
.explore-card { display: flex; flex-direction: column; }
.explore-search {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  margin: 22px 0 28px;
  padding: 10px;
  border: 3px solid var(--edge);
  border-radius: 8px;
  background: var(--input-bg);
  color: var(--surface-ink);
  box-shadow: var(--shadow-sm);
}
.explore-search > .icon { margin-left: 5px; }
.explore-search input { min-width: 0; margin: 0; border: 0; background: transparent; box-shadow: none; }

.report-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; align-items: start; }
.report-list { display: grid; gap: 12px; }
.report-row, .progress-card {
  width: 100%;
  min-width: 0;
  padding: 16px;
  border: 3px solid var(--edge);
  border-radius: 8px;
  background: var(--bg-raised);
  color: var(--surface-ink);
  box-shadow: var(--shadow-sm);
  text-align: left;
}
.report-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 12px; font: inherit; cursor: pointer; }
.report-row:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow); }
.report-row span:first-child, .progress-card > div:first-child { display: flex; min-width: 0; flex-direction: column; }
.report-row strong, .progress-card strong { overflow-wrap: anywhere; }
.report-row small, .progress-card small { color: var(--surface-ink-soft); }
.report-metrics { font-size: .76rem; color: var(--surface-ink-soft); white-space: nowrap; }
.report-metrics b { color: var(--blue-ink); }
.progress-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; }
.progress-value { color: var(--blue-ink); font-family: "Arial Black", Inter, sans-serif; font-size: 1.7rem; }
.progress-track { grid-column: 1 / -1; height: 12px; overflow: hidden; border: 2px solid var(--edge); background: #eef0f7; }
.progress-track span { display: block; height: 100%; background: var(--yellow); }
.report-summary { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; }
.report-summary span { padding: 12px; border: 3px solid var(--edge); background: var(--yellow); color: var(--edge); }
.data-table { display: grid; margin: 8px 0 24px; }

/* ---------- operator analytics ---------- */
.analytics-stats { display: grid; grid-template-columns: repeat(4, minmax(130px, 1fr)); gap: 12px; margin: 20px 0 28px; }
.analytics-stat { padding: 18px; }
.analytics-stat strong { display: block; color: var(--surface-ink); font: 900 clamp(1.7rem, 4vw, 2.6rem) "Arial Black", Inter, sans-serif; }
.analytics-stat span { color: var(--surface-ink-soft); font-size: .76rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.analytics-section { margin-top: 28px; }
.analytics-section-head { display: flex; align-items: end; gap: 12px; margin-bottom: 10px; }
.analytics-section-head h2 { margin: 0; }
.analytics-section-head .spacer { flex: 1; }
.analytics-search { width: min(300px, 100%); }
.analytics-table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: 14px; background: var(--bg-raised); }
.analytics-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
.analytics-table th, .analytics-table td { padding: 12px 14px; text-align: left; border-bottom: 1px solid var(--border); white-space: nowrap; }
.analytics-table th { color: var(--text-soft); font-size: .7rem; letter-spacing: .07em; text-transform: uppercase; }
.analytics-table tr:last-child td { border-bottom: 0; }
.analytics-table .analytics-primary { color: var(--text); font-weight: 800; }
.analytics-table .analytics-secondary { display: block; color: var(--text-soft); font-size: .76rem; font-weight: 500; }
.analytics-empty { padding: 24px; color: var(--text-soft); text-align: center; }
.analytics-live-dot { display: inline-block; width: 9px; height: 9px; margin-right: 6px; border-radius: 50%; background: #28a865; box-shadow: 0 0 0 4px color-mix(in srgb, #28a865 20%, transparent); }
@media (max-width: 820px) { .analytics-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) {
  .analytics-section-head { align-items: stretch; flex-direction: column; }
  .analytics-search { width: 100%; }
}
.data-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 14px; padding: 12px 4px; border-bottom: 2px solid #d9dbe5; }
.data-row > span:first-child { display: flex; min-width: 0; align-items: center; gap: 9px; overflow-wrap: anywhere; }
.data-row > strong:last-child { color: var(--blue-ink); }
.empty-mini { color: var(--surface-ink-soft); }

.join-step { position: relative; }
.step-label { display: inline-block; margin-bottom: 10px; color: var(--blue-ink); font-size: .72rem; font-weight: 950; letter-spacing: .12em; text-transform: uppercase; }
.join-code-input { min-height: 76px; text-align: center; text-transform: uppercase; letter-spacing: .14em; font-family: "Arial Black", Inter, sans-serif; font-size: 2rem; }
.game-confirm { padding: 12px; border: 2px solid var(--edge); background: var(--yellow); color: var(--edge); font-weight: 900; }
.back-link { display: inline-flex; align-items: center; gap: 5px; margin-bottom: 14px; padding: 0; border: 0; background: transparent; color: var(--blue-ink); font: inherit; font-size: .8rem; font-weight: 900; cursor: pointer; }
.privacy-note { font-size: .76rem; line-height: 1.45; }
.reading { max-width: 820px; }
.legal-consent-shell { z-index: 1000; }
.legal-consent-card { width: min(720px, 96vw); }
.legal-consent-card h2 { margin: 5px 0 8px; }
.legal-consent-card .btn-link { min-height: 38px; background: transparent; color: var(--surface-ink-soft); border-color: transparent; box-shadow: none; font-size: .76rem; }
.legal-consent-card .btn-link:hover { color: var(--surface-ink); background: var(--panel-2); }
.legal-link-row { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 14px 0; font-weight: 900; }
.legal-check { display: flex; align-items: flex-start; gap: 10px; margin: 10px 0; padding: 12px; background: var(--panel-2); color: var(--surface-ink); border: 2px solid var(--edge); border-radius: 8px; font-size: .84rem; line-height: 1.45; cursor: pointer; }
.legal-check input { width: 20px; height: 20px; flex: 0 0 20px; margin: 1px 0 0; accent-color: var(--blue); }
.legal-check-compact { padding: 9px; margin: 0; font-size: .75rem; }
.legal-document { line-height: 1.65; }
.legal-document h1 { margin-bottom: 2px; }
.legal-document h2 { margin-top: 28px; }
.legal-document h3 { margin-top: 20px; }
.legal-document .legal-meta { color: var(--surface-ink-soft); font-size: .8rem; }
.legal-document .legal-callout { padding: 14px; border: 3px solid var(--edge); border-radius: 9px; background: var(--yellow); color: var(--edge); }
.legal-document { overflow-wrap: anywhere; }
.legal-document table { width: 100%; display: block; overflow-x: auto; border-collapse: collapse; font-size: .86rem; }
.legal-document th, .legal-document td { padding: 10px; border: 2px solid var(--edge); text-align: left; vertical-align: top; }
.legal-document th { background: var(--panel-2); }
.legal-footer-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }
.site-legal-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 20px; padding: 12px 18px 24px; color: var(--text-soft); font-size: .75rem; font-weight: 800; }
.result-stats { display: flex; flex-direction: column; margin-top: 16px; }
.result-stats strong { color: var(--blue-ink); font-family: "Arial Black", Inter, sans-serif; font-size: 2.5rem; }
.result-actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }

@media (max-width: 760px) {
  .report-columns { grid-template-columns: 1fr; }
  .report-row { grid-template-columns: minmax(0, 1fr) auto; }
  .report-row > .icon { display: none; }
}
@media (max-width: 560px) {
  .side { padding: 12px; }
  .side .brand { padding: 0 4px 8px; }
  .side-nav { gap: 6px; }
  .side-link { min-height: 42px; padding: 7px 9px; font-size: .78rem; }
  .side-foot { display: none; }
  .side-nav { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .side-link:last-child { grid-column: auto; }
  .explore-search { grid-template-columns: auto minmax(0, 1fr); }
  .explore-search .btn { grid-column: 1 / -1; }
  .data-row { grid-template-columns: minmax(0, 1fr) auto; }
  .data-row > span:nth-child(2) { grid-column: 1 / -1; }
  .result-actions { grid-template-columns: 1fr; }
}

/* ---------- Unified icon scale ---------- */

.icon {
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
  stroke-width: 2.15;
  vertical-align: middle;
}

.btn .icon,
.side-link .icon,
.timer-label .icon,
.report-row > .icon {
  width: 21px;
  height: 21px;
  flex-basis: 21px;
}

.btn-huge .icon {
  width: 24px;
  height: 24px;
  flex-basis: 24px;
}

.theme-toggle .icon,
.visibility-badge .icon,
.money-chip .icon,
.back-link .icon {
  width: 18px;
  height: 18px;
  flex-basis: 18px;
}

.icon-btn .icon {
  width: 22px;
  height: 22px;
  flex-basis: 22px;
}

.feature .ico .icon {
  width: 38px;
  height: 38px;
  flex-basis: 38px;
  stroke-width: 2;
}

.panel-icon .icon,
.choice-icon .icon {
  width: 28px;
  height: 28px;
  flex-basis: 28px;
}

.choice-card .choice-arrow {
  width: 26px;
  height: 26px;
  flex-basis: 26px;
}

.explore-search > .icon,
.lobby-head > .icon {
  width: 26px;
  height: 26px;
  flex-basis: 26px;
}

.empty-state > .icon {
  width: 44px;
  height: 44px;
  flex-basis: 44px;
}

.lobby-empty > .icon {
  width: 56px;
  height: 56px;
  flex-basis: 56px;
}

.answer .mark .icon,
.verdict-icon .icon {
  width: 30px;
  height: 30px;
  flex-basis: 30px;
  stroke-width: 2.6;
}

.result-energy > .icon {
  width: 40px;
  height: 40px;
  flex-basis: 40px;
}

@media (max-width: 560px) {
  .btn .icon,
  .side-link .icon { width: 20px; height: 20px; flex-basis: 20px; }
  .feature .ico .icon { width: 34px; height: 34px; flex-basis: 34px; }
}
.kit-card .actions .btn { font-size: .82rem; }
.empty-state > .icon { width: 46px; height: 46px; margin-bottom: 8px; color: var(--blue-ink); }

.start-countdown {
  min-height: calc(100vh - 78px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 34px;
  background: var(--blue);
  color: #fff;
  text-align: center;
}
.start-countdown .eyebrow { color: var(--yellow); }
.start-countdown p { color: #fff; font-size: 1.2rem; font-weight: 850; }
.countdown-number {
  min-width: 1.5em;
  font-family: "Arial Black", Inter, sans-serif;
  font-size: clamp(7rem, 26vw, 17rem);
  line-height: .9;
  color: var(--yellow);
  -webkit-text-stroke: 4px var(--edge);
  text-shadow: 9px 9px 0 var(--edge);
}
.compact-countdown { min-height: 520px; border: 4px solid var(--edge); box-shadow: var(--shadow); }

.game-topbar .hint { color: #fff; }
.streak-chip {
  padding: 5px 9px;
  border: 2px solid var(--edge);
  border-radius: 5px;
  background: var(--control-bg);
  color: var(--control-ink);
  font-size: .78rem;
  font-weight: 900;
}
.play-shell { width: min(1160px, 100%); max-width: 1160px; }
.question-stage { display: flex; flex-direction: column; min-height: calc(100vh - 190px); }
.q-prompt {
  margin: 10px auto 24px;
  max-width: 980px;
  color: var(--text);
  font-size: clamp(1.65rem, 3.5vw, 2.7rem);
  line-height: 1.18;
  text-align: center;
}
.timer-label { display: inline-flex; align-items: center; gap: 7px; font-size: 1.05rem; }
.answer-grid {
  flex: 1;
  min-height: min(58vh, 610px);
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: minmax(150px, 1fr);
  gap: 18px;
}
.answer {
  min-width: 0;
  min-height: 150px;
  padding: clamp(20px, 3vw, 34px);
  font-size: clamp(1.08rem, 2vw, 1.42rem);
  line-height: 1.35;
}
.answer .key {
  width: 46px;
  height: 46px;
  flex: 0 0 46px;
  border: 3px solid var(--edge);
  border-radius: 7px;
  background: rgba(255,255,255,.72);
  color: var(--edge);
  font-size: 1.05rem;
}
.answer-text { overflow-wrap: anywhere; }
.answer .mark { display: inline-flex; margin-left: auto; }
.answer .mark .icon { width: 30px; height: 30px; stroke-width: 3; }
.verdict-icon {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  flex: 0 0 46px;
  border: 3px solid rgba(255,255,255,.9);
  border-radius: 50%;
}
.verdict-icon .icon { width: 26px; height: 26px; stroke-width: 3; }
.verdict-banner .earned { display: inline-flex; align-items: center; gap: 6px; }
.continue-panel {
  position: fixed;
  left: 50%;
  bottom: 20px;
  z-index: 30;
  width: min(520px, calc(100% - 28px));
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 20px;
  border: 3px solid var(--edge);
  border-radius: 9px;
  background: var(--bg-raised);
  color: var(--surface-ink);
  box-shadow: var(--shadow);
  text-align: center;
  transform: translateX(-50%);
}
.continue-panel .btn { width: min(420px, 100%); }
.continue-panel .hint { color: var(--surface-ink-soft); }
#app.continue-ready { cursor: pointer; }
.honey-pop { display: inline-flex; align-items: center; gap: 7px; }
.result-energy { display: flex; flex-direction: column; align-items: center; gap: 7px; margin-top: 18px; }
.result-energy > .icon { width: 38px; height: 38px; color: var(--blue-ink); }
.winner-mark { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 18px; }
.lobby-head > .icon { width: 30px; height: 30px; }
.lobby-empty > .icon { width: 60px; height: 60px; color: var(--blue-ink); }

@media (max-width: 720px) {
  .create-grid, .play-choice-grid { grid-template-columns: 1fr; }
  .choice-card { min-height: 175px; }
  .modal-shell { padding: 10px; }
  .modal-card { max-height: calc(100vh - 20px); }
  .question-stage { min-height: auto; }
  .answer-grid { min-height: auto; grid-template-columns: 1fr; grid-auto-rows: auto; gap: 13px; }
  .answer { min-height: 112px; }
  .continue-panel { bottom: 12px; }
}

@media (max-width: 460px) {
  .modal-card { padding: 16px; }
  .create-panel { padding: 16px; }
  .game-topbar .brand > span:last-child { display: none; }
  .game-topbar .flex-row { flex-basis: 260px; }
  .q-prompt { text-align: left; }
  .answer { padding: 18px 15px; }
  .answer .key { width: 40px; height: 40px; flex-basis: 40px; }
}

/* ---------- responsive fit-and-finish ---------- */

.main-head { flex-wrap: wrap; }
.main-head .btn { flex: 0 0 auto; white-space: nowrap; }

.kit-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
  gap: 22px;
}
.kit-card { min-width: 0; }
.kit-card h3,
.kit-card .desc { overflow-wrap: anywhere; }
.kit-card .desc { color: var(--surface-ink-soft); }
/* Was a two-column grid for the old five-button row. The card now carries
   one primary button plus the More trigger, so it stays a flex row and only
   the sizing tightens. */
.kit-card .actions { min-width: 0; gap: 8px; }
.kit-card .actions .btn {
  min-width: 0;
  min-height: 42px;
  padding: 8px 10px;
  font-size: .82rem;
  white-space: nowrap;
}

.row-actions { flex-wrap: wrap; justify-content: flex-end; }
.row-actions .btn { min-width: 0; }
.list-row > :first-child { min-width: 0; overflow-wrap: anywhere; }
.wrap > .flex-row,
.card > .flex-row { flex-wrap: wrap; }
.wrap > .flex-row .field { min-width: min(100%, 260px); }
.mode-opt { min-width: 0; overflow-wrap: anywhere; }
.code-display, .pin-number { max-width: 100%; overflow-wrap: anywhere; }

@media (max-width: 820px) {
  .side { color: var(--surface-ink); }
  .side-nav { gap: 8px; padding-bottom: 5px; }
  .side-link { flex: 0 0 auto; width: auto; white-space: nowrap; }
  .side-foot { border-top: 3px solid var(--edge); }
}

@media (max-width: 560px) {
  .topbar { gap: 8px; padding: 8px 12px; flex-wrap: wrap; }
  .topbar .brand { gap: 6px; font-size: 1rem; }
  .topbar .flex-row { flex: 1 1 210px; gap: 7px; flex-wrap: wrap; justify-content: flex-end; }
  .topbar .btn {
    min-height: 40px;
    padding: 7px 9px;
    font-size: .72rem;
    white-space: nowrap;
  }
  .topbar .theme-toggle { width: 38px; height: 38px; }
  .main-head { align-items: center; }
  .main-head h1 { font-size: 1.55rem; }
  .main-head .btn { min-height: 40px; padding: 8px 10px; font-size: .76rem; }
  .side-nav {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    overflow: visible;
  }
  .side-link { width: 100%; white-space: normal; }
  .side-link:last-child { grid-column: 1 / -1; }
  .kit-grid { grid-template-columns: minmax(0, 1fr); }
  .list-row { align-items: flex-start; flex-wrap: wrap; }
  .wrap > .flex-row > .btn { width: 100%; }
  .row-actions { width: 100%; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .row-actions .btn { width: 100%; padding-inline: 8px; }
}


/* ============================================================
   Play screen: fixed to the viewport, never scrolls
   ============================================================
   The question and its four answers have to fit the screen exactly — a quiz
   you have to scroll to read is a quiz you lose. `body.playing` pins the page
   and the stage sizes itself off the space left under the topbar. */

body.playing { height: 100dvh; overflow: hidden; }
body.playing .play-shell {
  height: calc(100dvh - var(--play-topbar, 64px));
  padding: 14px 18px 18px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
body.playing #app { flex: 1; min-height: 0; display: flex; flex-direction: column; }
body.playing .question-stage { flex: 1; min-height: 0; }
body.playing .answer-grid { min-height: 0; grid-auto-rows: minmax(0, 1fr); gap: clamp(8px, 1.4vh, 18px); }
/* A fixed tile min-height wins over `1fr` rows and makes the grid overflow on
   short screens — which let the feedback bar sit on top of the last tile.
   Under the viewport lock the tiles must be free to shrink to whatever space
   is left after the prompt and the bar. */
body.playing .answer { min-height: 0; padding: clamp(8px, 1.5vh, 20px) 15px; }
body.playing .answer .key { flex: 0 0 26px; height: 26px; }
/* Long answers shrink rather than pushing the grid past the fold. */
body.playing .answer { overflow: hidden; }
body.playing .answer-text {
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden;
}
body.playing .q-prompt {
  margin: 4px auto 14px;
  font-size: clamp(1.3rem, 2.9vw, 2.3rem);
}

/* ---------- answer feedback overlay ----------
   Anchored to the bottom of the viewport and slides up over the lower tiles,
   rather than being a flex sibling that resizes the grid. Overlaying means
   the tiles never jump or shrink when feedback appears — the answers you were
   just looking at stay exactly where they were. */

.answer-feedback {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  padding: 16px clamp(16px, 4vw, 40px);
  padding-bottom: max(16px, env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 16px;
  color: #fff;
  box-shadow: 0 -18px 40px -20px rgba(0, 0, 0, 0.7);
  cursor: pointer;
  /* Slide-up done as a transition, not a keyframe animation, on purpose.
     A running animation applies its current keyframe, so anywhere animation
     time doesn't advance the bar stays pinned at `from` — off-screen, with
     the game looking frozen. A transition just lands on the final value if it
     can't animate, so the worst case is "appears instantly" rather than
     "never appears". */
  transform: translateY(100%);
  transition: transform 0.28s cubic-bezier(0.2, 0.9, 0.3, 1);
}
.answer-feedback.is-in { transform: translateY(0); }
.answer-feedback.right { background: var(--right); }
.answer-feedback.wrong { background: var(--wrong); }

@media (prefers-reduced-motion: reduce) { .answer-feedback { transition: none; } }

.answer-feedback .fb-inner {
  width: min(1160px, 100%); margin: 0 auto;
  display: flex; align-items: center; gap: 16px;
}
.answer-feedback .fb-icon { display: inline-flex; flex: none; }
.answer-feedback .fb-icon .icon { width: 32px; height: 32px; }
.answer-feedback .fb-text { min-width: 0; }
.answer-feedback .fb-headline { font-size: clamp(1.15rem, 2.5vw, 1.6rem); font-weight: 900; line-height: 1.15; }
.answer-feedback .fb-sub {
  font-size: clamp(0.88rem, 1.7vw, 1.05rem); font-weight: 700;
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 2px;
}
.answer-feedback .fb-label { opacity: 0.85; font-weight: 600; }

.answer-feedback .fb-continue {
  margin-left: auto; flex: none;
  border: 2px solid rgba(255, 255, 255, 0.55); cursor: pointer; font: inherit;
  background: rgba(0, 0, 0, 0.22); color: #fff;
  padding: 13px 34px; border-radius: 999px;
  font-size: clamp(1rem, 2vw, 1.18rem); font-weight: 900;
  transition: background 0.15s ease, opacity 0.15s ease;
}
.answer-feedback .fb-continue:hover:not(:disabled) { background: rgba(0, 0, 0, 0.4); }
.answer-feedback .fb-continue:disabled { opacity: 0.45; cursor: default; }

/* Once it's clickable, the whole screen is the button. */
body.continue-anywhere { cursor: pointer; }

@media (max-width: 620px) {
  .answer-feedback { padding: 13px 14px; }
  .answer-feedback .fb-inner { flex-wrap: wrap; gap: 10px; }
  .answer-feedback .fb-continue { margin-left: 0; width: 100%; padding: 12px 20px; }
}

/* ---------- "You're In!" waiting screen ---------- */

.waiting-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px;
  min-height: min(62vh, 520px);
  padding: clamp(28px, 6vh, 60px) 24px;
  text-align: center;
}
/* A green tick, so the "you made it" reads before any words do. */
.waiting-mark {
  width: 74px; height: 74px; border-radius: 50%;
  background: var(--right); position: relative; flex: none; margin-bottom: 4px;
}
.waiting-mark::after {
  content: ""; position: absolute; left: 26px; top: 18px;
  width: 18px; height: 32px;
  border: solid #fff; border-width: 0 6px 6px 0;
  transform: rotate(45deg); border-radius: 2px;
}
.waiting-title {
  margin: 0;
  font-size: clamp(2.1rem, 7vw, 3.4rem);
  font-weight: 900; line-height: 1.05;
}
.waiting-sub {
  margin: 0;
  font-size: clamp(0.98rem, 2.2vw, 1.2rem);
  color: var(--text-soft); font-weight: 600;
}
.waiting-kit {
  margin: 6px 0 0;
  font-size: 0.85rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-soft); opacity: 0.8;
}

/* ---------- explore card actions ----------
   Was a stacked grid back when the card carried two full-width buttons. It is
   now one primary action plus a More menu on a single row, and leaving the
   grid here overrode the shared .explore-actions rule and stacked them. */
.explore-actions { margin-top: auto; }

/* ---------- Prop Hunt ---------- */
.ph-root { background: #497f42; }
.ph-round { color: #fff; font-size: .82rem; font-weight: 900; white-space: nowrap; }
@media (max-width: 520px) { .ph-round-mode, .ph-round-label { display: none; } }
.ph-phase-card {
  position: fixed; z-index: 35; top: calc(64px + env(safe-area-inset-top, 0px)); left: 50%;
  transform: translateX(-50%); display: flex; align-items: center; gap: 10px;
  max-width: calc(100vw - 28px); padding: 8px 15px; border: 3px solid #24231f;
  border-radius: 14px; background: #fff6d8; color: #24231f; box-shadow: 0 4px 0 rgba(0,0,0,.3);
}
.ph-root .ff-prompt { pointer-events: auto; display: flex; align-items: center; max-width: calc(100vw - 24px); overflow-x: auto; }
.ph-prompt button { display: inline-flex; align-items: center; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; white-space: nowrap; }
.ph-prompt button:disabled { opacity: .5; cursor: default; }
.ph-prompt button:not(:disabled):hover { color: var(--yellow, #ffe24a); }
/* the taunt arrow orbits the seeker, pointing at the sound */
.ph-taunt-arrow { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 6; pointer-events: none; will-change: transform, opacity; }
.ph-taunt-arrow::before { content: ''; position: absolute; left: -34px; top: -34px; width: 68px; height: 68px; border-radius: 50%; background: radial-gradient(circle, rgba(255, 92, 92, .35), transparent 70%); }
.ph-taunt-arrow span { position: absolute; left: -32px; top: -28px; width: 64px; height: 56px; background: #111114; clip-path: polygon(0 28%, 52% 28%, 52% 0, 100% 50%, 52% 100%, 52% 72%, 0 72%); animation: phArrowPulse .5s ease-in-out infinite alternate; }
.ph-taunt-arrow span::after { content: ''; position: absolute; inset: 0; background: #ff5c5c; clip-path: polygon(10% 38%, 60% 38%, 60% 18%, 88% 50%, 60% 82%, 60% 62%, 10% 62%); }
@keyframes phArrowPulse { from { transform: translateX(-3px) scale(.95); } to { transform: translateX(5px) scale(1.08); } }
@media (prefers-reduced-motion: reduce) { .ph-taunt-arrow span { animation: none; } }
.ph-place { position: fixed; z-index: 30; left: 50%; top: calc(66px + env(safe-area-inset-top, 0px)); transform: translateX(-50%); padding: 4px 12px; border-radius: 999px; background: rgba(17, 17, 20, .72); color: #fff7e2; font-size: .74rem; font-weight: 900; letter-spacing: .04em; white-space: nowrap; pointer-events: none; }
.ph-phase-card strong { font: 900 1.55rem/1 "Arial Black", sans-serif; min-width: 2ch; text-align: center; }
.ph-phase-card span { font-size: .78rem; font-weight: 900; white-space: nowrap; }
.ph-phase-card .wait-dot { flex: 0 0 9px; }
.ph-hud {
  position: fixed; z-index: 36; left: max(12px, env(safe-area-inset-left)); bottom: max(12px, env(safe-area-inset-bottom));
  width: min(270px, calc(100vw - 24px)); display: grid; grid-template-columns: 1fr 1fr; gap: 7px;
  padding: 11px; border: 3px solid #24231f; border-radius: 14px; background: rgba(255,246,216,.94); color: #24231f;
  box-shadow: 0 5px 0 rgba(0,0,0,.28);
}
.ph-role { font-weight: 1000; text-transform: uppercase; letter-spacing: .08em; }
.ph-energy { height: 13px; align-self: center; overflow: hidden; border: 2px solid #24231f; border-radius: 999px; background: #c9c2ac; }
.ph-energy i { display: block; height: 100%; width: 0; background: #f5bd23; transition: width .15s; }
.ph-hud small { grid-column: 1/-1; font-weight: 800; }
.ph-hud .btn { min-height: 38px; padding: 7px 9px; font-size: .7rem; }
#questionBtn { grid-column: 1/-1; }
.ph-coin { position:absolute; width:36px; height:36px; border:4px solid #6d4211; border-radius:50%; background:#ffd43a; box-shadow:inset 0 0 0 5px #fff08c,0 3px 0 rgba(0,0,0,.25); animation:phCoin 1.1s ease-in-out infinite alternate; }
.ph-coin::after { content:'B'; display:grid; place-items:center; height:100%; color:#805011; font-weight:1000; }
@keyframes phCoin { to { transform: translateY(-6px) rotateY(180deg); } }
.ph-disguise { display:block; inset:0; margin:0!important; }
.g2d-player.is-caught { opacity:.48; filter:grayscale(1); }
.ph-root #props, .ph-root #phCoins, .ph-root #g2dPlayerLayer, .ph-root #phArrows { pointer-events: none; }
.ph-seeking .g2d-prop.is-searchable { pointer-events: auto; cursor: crosshair; }
.ph-seeking .g2d-player.is-taggable { pointer-events: auto; cursor: pointer; }
.ph-toast { position:fixed; z-index:90; left:50%; top:156px; transform:translateX(-50%); max-width:min(520px,calc(100vw - 24px)); background:#24231f; color:#fff7e2; border:3px solid #fff7e2; border-radius:12px; padding:11px 16px; font-weight:900; text-align:center; box-shadow:0 5px 0 rgba(0,0,0,.3); }
.ph-question-shell { position:fixed; inset:0; z-index:200; display:grid; place-items:center; padding:18px; background:rgba(15,18,17,.78); overflow:auto; }
.ph-question-card { width:min(760px,100%); padding:clamp(18px,4vw,34px); border:4px solid #24231f; border-radius:18px; background:var(--bg-raised,#fffaf0); color:var(--text,#24231f); box-shadow:0 8px 0 rgba(0,0,0,.35); }
.ph-question-card h2 { margin:8px 0 20px; font-size:clamp(1.25rem,4vw,2rem); }
.ph-answers { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.ph-answers button { min-height:78px; display:flex; align-items:center; gap:12px; padding:12px; border:3px solid var(--edge,#24231f); border-radius:12px; background:var(--bg-raised,#fff); color:var(--text,#24231f); text-align:left; font:800 1rem/1.25 inherit; cursor:pointer; }
.ph-answers button b { display:grid; place-items:center; flex:0 0 34px; height:34px; border-radius:8px; background:#f5bd23; color:#24231f; }
.ph-answers button.selected { background:#ffe989; }
.ph-question-card.correct { border-color:#21a762; }.ph-question-card.incorrect { border-color:#d84a4a; }
.ph-answer-result { margin-top:14px; display:flex; align-items:center; justify-content:space-between; gap:12px; font-size:1.15rem; }
.ph-floor-cell { position:absolute; width:var(--g2d-tile); height:var(--g2d-tile); }

/* ---- Maple Grove School (Prop Hunt map) ----
   Floors repeat every 4 tiles and line up with the world (.ph-tex, see
   alignWorldGround). Walls are autotiles: prop-hunt-walls.png has one row per
   style and one column per neighbour mask (1 N, 2 E, 4 S, 8 W), set by
   propHuntGroundHtml() in api.js. Both are baked into images once loaded. */
.ph-tex { background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4); background-repeat: repeat; }
.g2d-ground-ph-hall      { background-image: url('ph-floor-hall.png?v=20261004-1'); }
.g2d-ground-ph-library   { background-image: url('ph-floor-library.png?v=20261004-1'); }
.g2d-ground-ph-classroom { background-image: url('ph-floor-classroom.png?v=20261004-1'); }
.g2d-ground-ph-music     { background-image: url('ph-floor-music.png?v=20261004-1'); }
.g2d-ground-ph-cafe      { background-image: url('ph-floor-cafe.png?v=20261004-1'); }
.g2d-ground-ph-lab       { background-image: url('ph-floor-lab.png?v=20261004-2'); }
.g2d-ground-ph-lounge    { background-image: url('ph-floor-lounge.png?v=20261004-1'); }
.g2d-ground-ph-gym       { background-image: url('ph-floor-gym.png?v=20261004-1'); }
.g2d-ground-ph-concrete  { background-image: url('ph-floor-concrete.png?v=20261004-1'); }
.g2d-ground-ph-sidewalk  { background-image: url('ph-floor-sidewalk.png?v=20261004-1'); }
.g2d-ground-ph-asphalt   { background-image: url('ph-floor-asphalt.png?v=20261004-1'); }
.ph-wall:not(.g2d-wall) {
  background-image: url('prop-hunt-walls.png?v=20261004-2');
  background-size: calc(var(--g2d-tile) * 16) calc(var(--g2d-tile) * 4);
  background-repeat: no-repeat;
}
.ph-w-brick { background-position-y: 0; }
.ph-w-plaster { background-position-y: calc(var(--g2d-tile) * -1); }
.ph-w-hedge { background-position-y: calc(var(--g2d-tile) * -2); }
.ph-w-shed { background-position-y: calc(var(--g2d-tile) * -3); }
.ph-m0 { background-position-x: 0; }
.ph-m1 { background-position-x: calc(var(--g2d-tile) * -1); }
.ph-m2 { background-position-x: calc(var(--g2d-tile) * -2); }
.ph-m3 { background-position-x: calc(var(--g2d-tile) * -3); }
.ph-m4 { background-position-x: calc(var(--g2d-tile) * -4); }
.ph-m5 { background-position-x: calc(var(--g2d-tile) * -5); }
.ph-m6 { background-position-x: calc(var(--g2d-tile) * -6); }
.ph-m7 { background-position-x: calc(var(--g2d-tile) * -7); }
.ph-m8 { background-position-x: calc(var(--g2d-tile) * -8); }
.ph-m9 { background-position-x: calc(var(--g2d-tile) * -9); }
.ph-m10 { background-position-x: calc(var(--g2d-tile) * -10); }
.ph-m11 { background-position-x: calc(var(--g2d-tile) * -11); }
.ph-m12 { background-position-x: calc(var(--g2d-tile) * -12); }
.ph-m13 { background-position-x: calc(var(--g2d-tile) * -13); }
.ph-m14 { background-position-x: calc(var(--g2d-tile) * -14); }
.ph-m15 { background-position-x: calc(var(--g2d-tile) * -15); }

/* Paint and hangings. Lines are drawn with borders/gradients, so they stay
   crisp at any zoom and cost no image downloads. */
.ph-decal { position: absolute; pointer-events: none; }
.ph-decal-court { border: 4px solid rgba(255, 255, 255, .85); border-radius: 6px; }
.ph-decal-court::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; border-top: 4px solid rgba(255, 255, 255, .85); transform: translateY(-50%); }
.ph-decal-court::after { content: ''; position: absolute; left: 50%; top: 50%; width: calc(var(--g2d-tile) * 2.6); height: calc(var(--g2d-tile) * 2.6); transform: translate(-50%, -50%); border: 4px solid rgba(255, 255, 255, .85); border-radius: 50%; background: rgba(255, 92, 92, .55); }
.ph-decal-key { border: 4px solid rgba(255, 255, 255, .85); background: rgba(47, 91, 255, .32); }
.ph-decal-bays { border-bottom: 4px solid rgba(255, 255, 255, .78); background: repeating-linear-gradient(to bottom, rgba(255, 255, 255, .78) 0 4px, transparent 4px calc(var(--g2d-tile) * 2)); }
.ph-decal-bays-double::after { content: ''; position: absolute; left: 50%; top: 0; bottom: 0; border-left: 4px solid rgba(255, 226, 74, .85); transform: translateX(-50%); }
.ph-decal-rug { border-radius: 10px; background: #e0b54e; box-shadow: inset 0 0 0 5px #b8862c, inset 0 0 0 9px #f3d27a, inset 0 0 0 13px #c9453f; opacity: .92; }
.ph-decal-rug-round { border-radius: 999px; background: #f3d27a; box-shadow: inset 0 0 0 5px #6a58a6, inset 0 0 0 11px #ffe24a; }
.ph-decal-rug-teal { background: #52b6a6; box-shadow: inset 0 0 0 5px #2f7e73, inset 0 0 0 10px #a7e5da; }
.ph-decal-board { background: #fbfbf7; border: 3px solid #111114; border-radius: 3px; box-shadow: inset 0 -3px 0 #c9ccd3; }
.ph-decal-board::after { content: ''; position: absolute; left: 12%; top: 30%; width: 34%; height: 3px; background: #2f5bff; box-shadow: 0 6px 0 #ff5c5c; border-radius: 2px; }
.ph-decal-cork, .ph-decal-menu { border: 3px solid #111114; border-radius: 3px; background: #c98d4f; }
.ph-decal-cork::after { content: ''; position: absolute; inset: 3px 18% 3px 14%; background: linear-gradient(90deg, #fff 0 30%, transparent 30% 42%, #ffe24a 42% 70%, transparent 70% 80%, #52e3b3 80%); }
.ph-decal-menu { background: #2e3a35; }
.ph-decal-menu::after { content: ''; position: absolute; inset: 4px 12%; background: repeating-linear-gradient(90deg, #f6ecd3 0 6px, transparent 6px 10px); opacity: .8; }

/* Big solid scenery: one 3x3-tile cell each, bottom-centred on its footprint. */
.ph-struct {
  position: absolute; pointer-events: none;
  width: calc(var(--g2d-tile) * 3); height: calc(var(--g2d-tile) * 3);
  background-image: url('prop-hunt-structures.png?v=20261004-2');
  background-size: calc(var(--g2d-tile) * 9) calc(var(--g2d-tile) * 6);
  background-repeat: no-repeat;
}
.ph-struct-car_red   { background-position: 0 0; }
.ph-struct-car_blue  { background-position: calc(var(--g2d-tile) * -3) 0; }
.ph-struct-fountain  { background-position: calc(var(--g2d-tile) * -6) 0; }
.ph-struct-bleachers { background-position: 0 calc(var(--g2d-tile) * -3); }
.ph-struct-oak       { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -3); }
.ph-struct-busstop   { background-position: calc(var(--g2d-tile) * -6) calc(var(--g2d-tile) * -3); }
@media(max-width:680px){.g2d-actions .ff-action{padding:11px 16px;font-size:.85rem}.ph-place{top:calc(120px + env(safe-area-inset-top, 0px))}.ph-phase-card span{font-size:.74rem}.ph-hud{width:230px}.ph-answers{grid-template-columns:1fr}.ph-question-card{margin:auto}.ph-toast{top:146px}}
@media(prefers-reduced-motion:reduce){.ph-coin{animation:none}}
[data-theme="dark"] .ph-question-card { background:#282824; color:#fff7e2; }



/* ============================================================
   Walk & Answer — the 2D game layer
   ============================================================
   A game screen, not a page: .g2d-playing takes the body out of normal
   document flow so the world fills the viewport edge to edge with nothing to
   scroll. The world layer is the whole map at real pixel size, translated
   under a fixed viewport window -- that translate is the camera. HUD floats
   above it.

   Movement is continuous in pixel space, so nothing here snaps to cells: the
   grid survives only as the collision lattice the art is laid out on. */

:root { --g2d-tile: 64px; }

body.g2d-playing {
  height: 100dvh;
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;   /* the joystick owns drags; never pan the page under one */
}
body.g2d-playing .topbar { display: none; }

.g2d-root { position: fixed; inset: 0; overflow: hidden; background: #4a8a3f; }
.g2d-viewport { position: absolute; inset: 0; overflow: hidden; }
.g2d-world { position: absolute; left: 0; top: 0; will-change: transform; }

/* Ground is a seamless repeat of one tile rather than a node per cell --
   600 divs for a floor is wasteful when the art already tiles perfectly. */
.g2d-ground {
  position: absolute; inset: 0;
  background-image: url('ground-grass.png?v=20261003-5');
  background-size: calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12);
  background-repeat: repeat;
  image-rendering: auto;
}
.g2d-layer { position: absolute; inset: 0; }

.g2d-patch { position: absolute; background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4); background-repeat: repeat; background-attachment: local; }
/* Dirt and stone repeat every 4x4 tiles like the grass; the shared
   alignWorldGround() hook in api.js lines every cell up with the world. */
.g2d-ground-dirt, .g2d-ground-stone { background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4); background-repeat: repeat; }
.g2d-ground-dirt  { background-image: url('ground-dirt.png?v=20261003-7'); background-size: calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12); }
.g2d-ground-stone { background-image: url('ground-stone.png?v=20261003-1'); }

/* Prop Hunt's companion terrain follows the same exact 4x2 cell contract as
   terrain.png. Floor cells occupy the top row; solid blockers occupy row 2. */
.g2d-ground-wood, .g2d-ground-carpet, .g2d-ground-tile, .g2d-ground-concrete {
  background-image: url('prop-hunt-terrain.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 2);
  background-repeat: no-repeat;
}
.g2d-ground-wood { background-position: 0 0; }
.g2d-ground-carpet { background-position: calc(var(--g2d-tile) * -1) 0; }
.g2d-ground-tile { background-position: calc(var(--g2d-tile) * -2) 0; }
.g2d-ground-concrete { background-position: calc(var(--g2d-tile) * -3) 0; }

/* terrain.png is a 4x2 sheet of 128px cells; at --g2d-tile per cell the
   sheet scales to 4x2 tiles and each block picks its cell by position.
   Row 0: grass, grass-alt, dirt, stone. Row 1: crate, brick, hay, block. */
.g2d-wall {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('terrain.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 2);
  background-repeat: no-repeat;
}
.g2d-wall-crate { background-position: 0 calc(var(--g2d-tile) * -1); }
.g2d-wall-brick { background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -1); }
.g2d-wall-hay   { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.g2d-wall-block { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1); }
.g2d-wall-locker, .g2d-wall-bookcase, .g2d-wall-counter, .g2d-wall-toolwall {
  background-image: url('prop-hunt-terrain.png?v=20261003-1');
}
.g2d-wall-locker { background-position: 0 calc(var(--g2d-tile) * -1); }
.g2d-wall-bookcase { background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -1); }
.g2d-wall-counter { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.g2d-wall-toolwall { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1); }

/* props.png is a 4x2 sheet of 128px cells, every prop bottom-anchored in its
   cell. Props are decoration only -- they never block movement.
   Row 0: bush, tree, rock, flower. Row 1: sign, orb, barrel, plant. */
.g2d-prop {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('props.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 2);
  background-repeat: no-repeat;
  pointer-events: none;
}
.g2d-prop-bush   { background-position: 0 0; }
.g2d-prop-tree   { background-position: calc(var(--g2d-tile) * -1) 0; }
.g2d-prop-rock   { background-position: calc(var(--g2d-tile) * -2) 0; }
.g2d-prop-flower { background-position: calc(var(--g2d-tile) * -3) 0; }
.g2d-prop-sign   { background-position: 0 calc(var(--g2d-tile) * -1); }
.g2d-prop-barrel { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.g2d-prop-plant  { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1); }
.g2d-prop-chair, .g2d-prop-desk, .g2d-prop-bookshelf, .g2d-prop-globe,
.g2d-prop-fern, .g2d-prop-trash, .g2d-prop-cooler, .g2d-prop-vending {
  background-image: url('prop-hunt-props-a.png?v=20261003-1');
}
.g2d-prop-chair { background-position: 0 0; }
.g2d-prop-desk { background-position: calc(var(--g2d-tile) * -1) 0; }
.g2d-prop-bookshelf { background-position: calc(var(--g2d-tile) * -2) 0; }
.g2d-prop-globe { background-position: calc(var(--g2d-tile) * -3) 0; }
.g2d-prop-fern { background-position: 0 calc(var(--g2d-tile) * -1); }
.g2d-prop-trash { background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -1); }
.g2d-prop-cooler { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.g2d-prop-vending { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1); }
.g2d-prop-box, .g2d-prop-lamp, .g2d-prop-cone, .g2d-prop-cabinet,
.g2d-prop-table, .g2d-prop-ballrack, .g2d-prop-computer, .g2d-prop-trophy {
  background-image: url('prop-hunt-props-b.png?v=20261003-1');
}
.g2d-prop-box { background-position: 0 0; }
.g2d-prop-lamp { background-position: calc(var(--g2d-tile) * -1) 0; }
.g2d-prop-cone { background-position: calc(var(--g2d-tile) * -2) 0; }
.g2d-prop-cabinet { background-position: calc(var(--g2d-tile) * -3) 0; }
.g2d-prop-table { background-position: 0 calc(var(--g2d-tile) * -1); }
.g2d-prop-ballrack { background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -1); }
.g2d-prop-computer { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.g2d-prop-trophy { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1); }
.g2d-prop-bench, .g2d-prop-picnic, .g2d-prop-lamppost, .g2d-prop-hydrant,
.g2d-prop-armchair, .g2d-prop-piano, .g2d-prop-drum, .g2d-prop-backpack {
  background-image: url('prop-hunt-props-c.png?v=20261004-1');
}
.g2d-prop-bench { background-position: 0 0; }
.g2d-prop-picnic { background-position: calc(var(--g2d-tile) * -1) 0; }
.g2d-prop-lamppost { background-position: calc(var(--g2d-tile) * -2) 0; }
.g2d-prop-hydrant { background-position: calc(var(--g2d-tile) * -3) 0; }
.g2d-prop-armchair { background-position: 0 calc(var(--g2d-tile) * -1); }
.g2d-prop-piano { background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -1); }
.g2d-prop-drum { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.g2d-prop-backpack { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1); }
.g2d-prop-easel, .g2d-prop-basketball, .g2d-prop-guitar, .g2d-prop-musicstand,
.g2d-prop-books, .g2d-prop-toolbox, .g2d-prop-paintcan, .g2d-prop-duffel {
  background-image: url('prop-hunt-props-d.png?v=20261004-1');
}
.g2d-prop-easel { background-position: 0 0; }
.g2d-prop-basketball { background-position: calc(var(--g2d-tile) * -1) 0; }
.g2d-prop-guitar { background-position: calc(var(--g2d-tile) * -2) 0; }
.g2d-prop-musicstand { background-position: calc(var(--g2d-tile) * -3) 0; }
.g2d-prop-books { background-position: 0 calc(var(--g2d-tile) * -1); }
.g2d-prop-toolbox { background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -1); }
.g2d-prop-paintcan { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.g2d-prop-duffel { background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1); }

/* Trees read as landmarks rather than scenery when they break the tile grid,
   so they're drawn oversized and anchored to the bottom of their cell. */
.g2d-prop-tree {
  width: calc(var(--g2d-tile) * 1.5);
  height: calc(var(--g2d-tile) * 1.5);
  background-size: calc(var(--g2d-tile) * 6) calc(var(--g2d-tile) * 3);
  background-position: calc(var(--g2d-tile) * -1.5) 0;
  margin-left: calc(var(--g2d-tile) * -0.25);
  margin-top: calc(var(--g2d-tile) * -0.5);
}

.g2d-prop-label {
  position: absolute; left: 50%; top: -2px;
  transform: translateX(-50%);
  background: #f2d08a;
  border: 2px solid #5a3a1c;
  border-radius: 4px;
  padding: 2px 6px;
  font-size: .52rem; font-weight: 900; letter-spacing: .05em;
  color: #4a2f14; white-space: nowrap;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .25);
}

/* The orb sprite floats above its shadow so it reads as a pickup. */
.g2d-orb {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('props.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 2);
  background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -1);
  background-repeat: no-repeat;
  pointer-events: none;
  animation: g2dOrbFloat 1.7s ease-in-out infinite;
  filter: drop-shadow(0 0 7px rgba(255, 214, 92, .75));
}
@keyframes g2dOrbFloat {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-6px); }
}
@media (prefers-reduced-motion: reduce) { .g2d-orb { animation: none; } }

/* ---------- players ---------- */
.g2d-player {
  position: absolute; left: 0; top: 0;
  width: 64px; height: 64px;
  display: grid; place-items: center;
  z-index: 1;
  will-change: transform;
  /* Remote players arrive in ~90ms hops; easing between them turns those
     into continuous motion. The local player is exempt -- it updates every
     frame already, and a transition would add visible input lag. */
  transition: transform .1s linear;
}
.g2d-player.is-me { z-index: 3; transition: none; }
.g2d-shadow {
  position: absolute; left: 50%; bottom: 4px;
  width: 30px; height: 9px;
  background: rgba(17, 17, 20, .3);
  border-radius: 50%;
  transform: translateX(-50%);
}
/* characters.png: 4 columns (down/up/left/right) x 8 character rows. */
.blook {
  position: relative;
  width: 64px; height: 64px;
  background-image: url('characters.png?v=20261003-1');
  background-size: 256px 512px;
  background-repeat: no-repeat;
}
.g2d-name {
  position: absolute; left: 50%; bottom: -12px;
  transform: translateX(-50%);
  font-size: .62rem; font-weight: 900; white-space: nowrap;
  color: #fff;
  text-shadow: -2px -2px 0 #111114, 2px -2px 0 #111114, -2px 2px 0 #111114, 2px 2px 0 #111114;
  pointer-events: none;
}

/* ---------- HUD ---------- */
.g2d-topbar {
  position: fixed; top: 0; left: 0; right: 0;
  height: 52px;
  display: flex; align-items: center; gap: 8px;
  padding: 0 12px;
  padding-top: env(safe-area-inset-top, 0px);
  background: var(--edge);
  border-bottom: 3px solid rgba(0, 0, 0, .35);
  z-index: 40;
}
.g2d-brand {
  display: flex; align-items: center; gap: 8px;
  color: #fff; text-decoration: none;
  font-family: "Arial Black", Inter, sans-serif; font-size: 1rem;
}
.g2d-topbar button { flex: 0 0 auto; }
/* Phones: the game top bar holds the clock plus up to five buttons, so the
   wordmark and the label inside the clock make room. */
@media (max-width: 560px) {
  .g2d-topbar { gap: 6px; padding: 0 8px; }
  .g2d-brand > span:not(.brand-mark) { display: none; }
  .g2d-topbar .topbar-goal { padding: 4px 8px; }
  .g2d-topbar .topbar-goal span { display: none; }
  .g2d-topbar .topbar-goal.keep-label span { display: inline; }   /* Prop Hunt: "Hide" / "Hunt" */
  .g2d-topbar .g2d-leave { padding-inline: 10px; }
}
.g2d-leave {
  background: var(--coral, #ff5c5c);
  color: #fff; text-decoration: none;
  border: 2px solid rgba(0, 0, 0, .4); border-radius: 8px;
  padding: 6px 14px;
  font-weight: 900; font-size: .82rem;
}

.g2d-chip {
  position: fixed;
  top: calc(62px + env(safe-area-inset-top, 0px));
  display: flex; align-items: baseline; gap: 7px;
  background: var(--bg-raised, #fff);
  border: 3px solid var(--edge);
  border-radius: 11px;
  padding: 6px 13px;
  box-shadow: 0 3px 0 rgba(0, 0, 0, .25);
  z-index: 35;
}
.g2d-chip strong { font-family: "Arial Black", Inter, sans-serif; font-size: 1.05rem; color: var(--surface-ink); }
.g2d-chip-label {
  font-size: .58rem; font-weight: 900; text-transform: uppercase; letter-spacing: .08em;
  color: var(--surface-ink-soft);
}
.g2d-chip-points { left: 12px; }
.g2d-chip-orbs { right: 12px; }

.g2d-hint {
  position: fixed; left: 50%; bottom: 16px;
  transform: translateX(-50%);
  background: rgba(17, 17, 20, .75);
  color: #fff;
  border-radius: 999px;
  padding: 7px 16px;
  font-size: .76rem; font-weight: 700;
  white-space: nowrap;
  z-index: 35;
  pointer-events: none;
}

/* ---------- touch joystick ----------
   Only rendered on coarse-pointer devices, and analog now that movement is
   continuous -- a half push walks slowly, any angle is a real heading. */
.g2d-stick {
  position: fixed;
  right: calc(22px + env(safe-area-inset-right, 0px));
  bottom: calc(26px + env(safe-area-inset-bottom, 0px));
  width: 130px; height: 130px;
  border-radius: 50%;
  background: rgba(17, 17, 20, .28);
  border: 3px solid rgba(255, 255, 255, .5);
  z-index: 45;
  touch-action: none;
}
.g2d-stick.is-active { background: rgba(17, 17, 20, .38); }
.g2d-stick-knob {
  position: absolute; left: 50%; top: 50%;
  width: 58px; height: 58px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--yellow, #ffe24a);
  border: 3px solid var(--edge);
  box-shadow: 0 3px 0 rgba(0, 0, 0, .3);
}

/* ---------- question overlay ----------
   Covers the world but doesn't replace it -- the map stays visible and
   dimmed behind, so answering reads as something happening inside the
   game. Uses the same .answer / .reveal-* tiles as classic mode. */
/* The panel gets its own surface/ink pair instead of reusing
   --bg-raised/--text. Those two don't pair in dark mode: --bg-raised stays
   cream (#fff9e8) while --text flips to off-white (#fffdf5), which would put
   near-white prompt text on a near-white panel. Declaring both together per
   theme keeps the contrast guaranteed -- black on white in light, off-white
   on deep navy in dark. */
:root {
  --g2d-q-surface: #ffffff;
  --g2d-q-ink: #111114;
  --g2d-q-ink-soft: #55516a;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --g2d-q-surface: #232752;
    --g2d-q-ink: #f6f3e9;
    --g2d-q-ink-soft: #c3bfdd;
  }
}
:root[data-theme="dark"] {
  --g2d-q-surface: #232752;
  --g2d-q-ink: #f6f3e9;
  --g2d-q-ink-soft: #c3bfdd;
}

.g2d-question {
  position: fixed; inset: 0;
  z-index: 60;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: rgba(17, 17, 20, .68);
  backdrop-filter: blur(2px);
}
.g2d-question-panel {
  width: min(760px, 100%);
  max-height: 100%;
  display: flex; flex-direction: column;
  background: var(--g2d-q-surface);
  border: 4px solid var(--edge);
  border-radius: 18px;
  box-shadow: 0 10px 0 rgba(0, 0, 0, .35);
  padding: clamp(16px, 3vh, 26px);
}
.g2d-question-panel .q-prompt { color: var(--g2d-q-ink); }
.g2d-question-panel .eyebrow,
.g2d-question-panel .hint { color: var(--g2d-q-ink-soft); }
.g2d-question-top {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 6px;
}
.g2d-question-panel .q-prompt {
  margin: 4px 0 clamp(12px, 2.4vh, 22px);
  font-size: clamp(1.25rem, 3.4vw, 2.1rem);
  text-align: center;
}
.g2d-question-panel .answer-grid {
  min-height: 0;
  gap: clamp(8px, 1.4vh, 14px);
}
.g2d-question-panel .answer {
  min-height: 0;
  padding: clamp(10px, 1.8vh, 20px) 15px;
}
.g2d-question-panel .answer-text {
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden;
}

/* --g2d-tile deliberately does NOT shrink on small screens. The JS positions
   every wall, prop and orb using the tile size the server sent, so changing
   it here would slide the art off the collision lattice it's drawn on. Small
   screens simply see less of the world, which is what a camera is for. */
@media (max-width: 560px) {
  .g2d-chip { padding: 5px 10px; }
  .g2d-chip strong { font-size: .92rem; }
  .g2d-chip-label { display: none; }
}

/* ---------- character picker ---------- */

.avatar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
  gap: 12px;
  margin-top: 6px;
}
.avatar-pack-title {
  grid-column: 1 / -1;
  margin: 10px 0 -2px;
  color: var(--surface-ink);
  font-size: .82rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.avatar-pack-title:first-child { margin-top: 0; }
.avatar-pick {
  display: grid; place-items: center;
  gap: 5px;
  padding: 10px 4px;
  background: var(--panel-2, #f1f1ed);
  border: 3px solid var(--edge);
  border-radius: 12px;
  box-shadow: var(--shadow-sm, 3px 3px 0 var(--edge));
  cursor: pointer;
}
.avatar-pick:hover { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--edge); }
.avatar-pick.is-picked { background: var(--yellow, #ffe24a); color: var(--edge); }
.avatar-sprite { display: block; background-repeat: no-repeat; }
.avatar-name { font-size: .68rem; font-weight: 900; line-height: 1.1; }

.side-character { justify-content: flex-start; gap: 10px; margin-bottom: 8px; }
.side-character-sprite { display: inline-block; background-repeat: no-repeat; flex: 0 0 auto; }

/* ---------- avatar chips ----------
   The chosen character, inline, wherever a player is listed. Replaces the old
   initial-in-a-circle so one pick identifies a player in the lobby, on the
   leaderboard, in the world and in reports. */
.avatar-chip {
  display: inline-block;
  flex: 0 0 auto;
  background-repeat: no-repeat;
  vertical-align: middle;
}
.lb-name .avatar-chip { margin-right: 2px; }
.player-chip .face { display: inline-flex; align-items: center; }

/* ---------- 2D loading screen ----------
   Shown while sprite sheets decode. A player dropped into a half-painted
   world thinks the game is broken, so entry waits on the art. */
.g2d-loading {
  min-height: 70vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 40px 20px;
}
.g2d-loading strong { font-size: 1.15rem; }
.g2d-loading-mark { width: 54px; height: 54px; animation: g2dLoadPulse 1.1s ease-in-out infinite; }
@keyframes g2dLoadPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }
@media (prefers-reduced-motion: reduce) { .g2d-loading-mark { animation: none; } }
.g2d-loading-track {
  width: min(320px, 80vw); height: 14px;
  background: var(--panel-2, #f1f1ed);
  border: 3px solid var(--edge); border-radius: 999px; overflow: hidden;
}
.g2d-loading-fill {
  width: 0%; height: 100%;
  background: var(--yellow, #ffe24a);
  transition: width .18s linear;
}

/* ---------- host spectator view (2D modes) ----------
   Map on the left scaled to fit (see every player at once -- the opposite of
   the player's follow-camera), live leaderboard pinned alongside. */
body.spectating { height: 100dvh; overflow: hidden; }
body.spectating .topbar { position: relative; z-index: 2; }

.spectate {
  position: fixed;
  /* below the full topbar, including its 12px accent stripe */
  top: 76px; left: 0; right: 0; bottom: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
}
.spectate-stage {
  position: relative;
  overflow: hidden;
  background: #4a8a3f;
  border-right: 3px solid var(--edge);
}
.spectate-world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }

.spectate-side {
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px;
  background: var(--bg-raised);
  overflow-y: auto;
}
.spectate-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.spectate-count { display: flex; align-items: baseline; gap: 8px; }
.spectate-count strong { font-family: "Arial Black", Inter, sans-serif; font-size: 2rem; }
.spectate-count span { color: var(--text-soft); font-weight: 700; }
.spectate-side h3 { margin: 4px 0 0; }
.spectate-lb { flex: 1; display: flex; flex-direction: column; gap: 6px; min-height: 0; }

@media (max-width: 860px) {
  .spectate { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto; }
  .spectate-stage { border-right: 0; border-bottom: 3px solid var(--edge); }
  .spectate-side { max-height: 42vh; }
}

/* ============================================================
   Reel Rush
   ============================================================
   Same engine as Orb Quest (see the 2D game layer above) -- this only styles
   what's different: water, shops, ponds and the contextual action prompt.
   fishing.png is a 4x4 sheet of 128px cells:
     row 0  bait stall, sell stall, dock, sign
     row 1  bait bucket, rod, chest, padlock
     row 2  fish 1-4 (common -> legendary)
     row 3  splash, lily pad, reeds, coins                              */

.ff-root { background: #2f7fb8; }

/* Ponds are drawn under the wall layer: the water is the floor of the
   rectangle, and its tiles are solid so you fish from the bank. */
.ff-pond {
  position: absolute;
  background-image: url('water.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4);
  background-repeat: repeat;
  border: 4px solid #2a5d7a;
  border-radius: 14px;
  box-shadow: inset 0 0 22px rgba(0, 0, 0, .28);
  display: grid; place-items: center;
}
.ff-pond-name {
  position: absolute; top: 6px; left: 50%; transform: translateX(-50%);
  font-size: .62rem; font-weight: 900; letter-spacing: .06em;
  color: #fff; white-space: nowrap;
  text-shadow: -2px -2px 0 #16384a, 2px -2px 0 #16384a, -2px 2px 0 #16384a, 2px 2px 0 #16384a;
}
.ff-lock {
  width: 56px; height: 56px;
  background-image: url('fishing.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4);
  background-position: calc(var(--g2d-tile) * -3) calc(var(--g2d-tile) * -1);
  background-repeat: no-repeat;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .5));
}

/* Map edge — plain bank, distinct from Orb Quest's crates. */
.ff-edge {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background: linear-gradient(180deg, #6f9c4a 0%, #4f7233 100%);
  box-shadow: inset 0 3px 0 rgba(255,255,255,.2), inset 0 -3px 0 rgba(0,0,0,.25), inset 0 0 0 2px var(--edge);
}

/* The stall art is a square cell, so the box has to be square too -- drawing
   a 2x2-tile sprite into a 2x1 box clipped the whole lower half of the stall.
   The footprint on the map is still the single 2x1 wall row, so the sprite is
   pulled up one tile to stand on it rather than in front of it. */
.ff-shop {
  position: absolute;
  width: calc(var(--g2d-tile) * 2);
  height: calc(var(--g2d-tile) * 2);
  margin-top: calc(var(--g2d-tile) * -1);
  background-image: url('fishing.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 8) calc(var(--g2d-tile) * 8);
  background-repeat: no-repeat;
  background-position: 0 0;
}
.ff-shop-sell { background-position: calc(var(--g2d-tile) * -2) 0; }
.ff-shop-name {
  position: absolute; top: -18px; left: 50%; transform: translateX(-50%);
  background: #f2d08a; border: 2px solid #5a3a1c; border-radius: 5px;
  padding: 2px 8px; white-space: nowrap;
  font-size: .58rem; font-weight: 900; color: #4a2f14;
}

.ff-prop {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('fishing.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4);
  background-repeat: no-repeat;
  pointer-events: none;
}
.ff-prop-sign  { background-position: calc(var(--g2d-tile) * -3) 0; }
.ff-prop-chest { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -1); }
.ff-prop-lily  { background-position: calc(var(--g2d-tile) * -1) calc(var(--g2d-tile) * -3); }
.ff-prop-reeds { background-position: calc(var(--g2d-tile) * -2) calc(var(--g2d-tile) * -3); }

/* ---------- HUD ---------- */
.ff-hud {
  position: fixed;
  top: calc(62px + env(safe-area-inset-top, 0px));
  left: 12px; right: 12px;
  display: flex; gap: 8px; flex-wrap: wrap;
  z-index: 35;
  pointer-events: none;
}
.ff-hud .g2d-chip { position: static; }
.ff-icon {
  display: inline-block; width: 22px; height: 22px;
  background-image: url('fishing.png?v=20261003-1');
  background-size: 88px 88px;      /* 4 cells at 22px */
  background-repeat: no-repeat;
}
.ff-icon-bait { background-position: 0 -22px; }
.ff-icon-fish { background-position: 0 -44px; }
.ff-icon-coin { background-position: -66px -66px; }

/* Contextual action prompt -- one verb, whatever you're standing next to. */
.ff-prompt {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%);
  background: rgba(17, 17, 20, .82); color: #fff;
  border-radius: 999px; padding: 9px 18px;
  font-size: .85rem; font-weight: 800; white-space: nowrap;
  z-index: 36; pointer-events: none;
}
.ff-prompt kbd {
  background: var(--yellow, #ffe24a); color: var(--edge);
  border-radius: 5px; padding: 1px 7px; margin-right: 6px;
  font-family: inherit; font-weight: 900;
}
.ff-action {
  position: fixed;
  left: calc(22px + env(safe-area-inset-left, 0px));
  bottom: calc(40px + env(safe-area-inset-bottom, 0px));
  background: var(--yellow, #ffe24a); color: var(--edge);
  border: 3px solid var(--edge); border-radius: 14px;
  padding: 16px 22px; font-weight: 900; font-size: .95rem;
  box-shadow: 0 4px 0 rgba(0,0,0,.35);
  z-index: 46;
}

/* ---------- casting & catch ---------- */
.ff-cast, .ff-catch {
  position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  background: var(--bg-raised); border: 4px solid var(--edge);
  border-radius: 16px; padding: 22px 30px;
  box-shadow: 0 8px 0 rgba(0,0,0,.35);
  z-index: 62;
}
.ff-cast strong, .ff-catch strong { font-size: 1.2rem; }
.ff-splash {
  width: 64px; height: 64px;
  background-image: url('fishing.png?v=20261003-1');
  background-size: 256px 256px;
  background-position: 0 -192px;
  animation: ffRipple 1s ease-in-out infinite;
}
@keyframes ffRipple { 0%,100% { transform: scale(.85); opacity: .7; } 50% { transform: scale(1.1); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .ff-splash { animation: none; } }
/* fish.png is 8 species on a 4x2 grid of 128px cells. Displayed at 96px, so
   the sheet is scaled to 384x192 and each cell steps by 96/48. */
.ff-fish {
  width: 96px; height: 96px;
  background-image: url('fish.png?v=20261003-1');
  background-size: 384px 192px;
  background-repeat: no-repeat;
}
.ff-fish-0 { background-position: 0 0; }
.ff-fish-1 { background-position: -96px 0; }
.ff-fish-2 { background-position: -192px 0; }
.ff-fish-3 { background-position: -288px 0; }
.ff-fish-4 { background-position: 0 -96px; }
.ff-fish-5 { background-position: -96px -96px; }
.ff-fish-6 { background-position: -192px -96px; }
.ff-fish-7 { background-position: -288px -96px; }

.ff-toast {
  position: fixed; left: 50%; top: calc(120px + env(safe-area-inset-top, 0px));
  transform: translateX(-50%);
  background: var(--edge); color: #fff;
  border-radius: 999px; padding: 9px 20px;
  font-weight: 800; font-size: .85rem; white-space: nowrap;
  z-index: 64;
  animation: ffToast 1.8s ease forwards;
}
/* gameToast(): long messages wrap instead of running off a phone screen */
.ff-toast { max-width: calc(100vw - 24px); white-space: normal; text-align: center; }
/* A chip with a small meter under its value (energy) */
.g2d-chip-meter { display: block; width: 64px; height: 8px; margin-top: 3px; overflow: hidden; border: 2px solid var(--edge); border-radius: 999px; background: #d8d2c0; }
.g2d-chip-meter i { display: block; height: 100%; width: 0; background: var(--yellow, #ffe24a); transition: width .15s; }
.g2d-chip.is-hot { background: var(--yellow, #ffe24a); }
.g2d-chip.is-hot strong, .g2d-chip.is-hot .g2d-chip-label { color: #111114; }
/* Several actions at once (Prop Hunt): the prompt lists each key, and on
   touch screens the yellow action buttons stack bottom-left. */
.ff-prompt .ff-sep { opacity: .45; margin: 0 8px; }
.g2d-actions { position: fixed; z-index: 46; left: calc(22px + env(safe-area-inset-left, 0px)); bottom: calc(40px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
.g2d-actions .ff-action { position: static; }
.ff-action:disabled { opacity: .55; }
.ff-action.is-alt { background: var(--bg-raised, #fff); }
@keyframes ffToast {
  0% { opacity: 0; transform: translate(-50%, -8px); }
  12%, 78% { opacity: 1; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -8px); }
}

/* ---------- goal chip, ranks button, in-game leaderboard ---------- */

.g2d-chip-goal.is-urgent {
  background: var(--coral, #ff5c5c);
  animation: goalPulse .9s ease-in-out infinite;
}
.g2d-chip-goal.is-urgent strong, .g2d-chip-goal.is-urgent .g2d-chip-label { color: #fff; }
@keyframes goalPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@media (prefers-reduced-motion: reduce) { .g2d-chip-goal.is-urgent { animation: none; } }

.g2d-chip-btn {
  cursor: pointer;
  gap: 6px;
  pointer-events: auto;   /* the fishing HUD row is pointer-events:none */
}
.g2d-chip-btn .icon { width: 16px; height: 16px; }
.g2d-chip-btn:active { background: var(--yellow, #ffe24a); color: var(--edge); }
/* Orb Quest's chips are individually fixed, so this one needs a home. */
.g2d-chip-ranks { right: 12px; top: calc(112px + env(safe-area-inset-top, 0px)); }
.g2d-chip-goal:not(.ff-hud .g2d-chip-goal) { left: 12px; top: calc(112px + env(safe-area-inset-top, 0px)); }

.live-lb-shell {
  position: fixed; inset: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
  background: rgba(17, 17, 20, .6);
  animation: lbBackdrop .32s ease both;
}
/* The panel swoops up as the backdrop darkens, and the rows cascade in
   behind it, so a score reveal lands rather than just appearing. */
.live-lb-shell .live-lb { animation: lbSwoop .46s cubic-bezier(.16, 1.1, .3, 1) both; }
@keyframes lbBackdrop { from { opacity: 0; } to { opacity: 1; } }
@keyframes lbSwoop {
  from { transform: translateY(38px) scale(.94); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.live-lb-rows .leaderboard-row {
  animation: lbRow .38s ease both;
  animation-delay: calc(var(--row, 0) * 55ms + 140ms);
}
@keyframes lbRow {
  from { transform: translateX(-18px); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}
/* The host's side panel gets the same cascade, but only on a place change. */
.spectate-lb.lb-cascade .leaderboard-row {
  animation: lbRow .38s ease both;
  animation-delay: calc(var(--row, 0) * 45ms);
}
@media (prefers-reduced-motion: reduce) {
  .live-lb-shell, .live-lb-shell .live-lb, .live-lb-rows .leaderboard-row,
  .spectate-lb.lb-cascade .leaderboard-row { animation: none; }
}
.live-lb {
  width: min(460px, 100%); max-height: 80vh;
  display: flex; flex-direction: column; gap: 10px;
  background: var(--bg-raised);
  border: 4px solid var(--edge); border-radius: 16px;
  box-shadow: 0 8px 0 rgba(0, 0, 0, .35);
  padding: 18px;
}
.live-lb-head { display: flex; align-items: center; justify-content: space-between; }
.live-lb-head h2 { margin: 0; }
.live-lb-rows { overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.live-lb-rows .leaderboard-row.is-you { background: var(--yellow, #ffe24a); color: var(--edge); border-radius: 8px; }
.live-lb-rows .leaderboard-row.is-you .live-lb-sub { color: #55516a; }
.live-lb-sub {
  display: block; font-size: .62rem; font-weight: 700;
  color: var(--text-soft); margin-left: 4px;
}

/* ---------- Game Show ---------- */
.gs-host, .gs-player-board {
  width: min(1040px, 100%); margin: 0 auto;
  background: var(--bg-raised); color: var(--surface-ink);
  border: 4px solid var(--edge); border-radius: 18px;
  box-shadow: 0 9px 0 var(--edge); padding: clamp(18px, 3vw, 34px);
}
.game-show-host {
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
  background: var(--bg-raised);
  background-image: none;
}
.game-show-host .topbar { display: none; }
.gs-host-wrap { position: fixed; inset: 0; width: 100%; height: 100dvh; margin: 0; padding: 0; }
.game-show-host .gs-host {
  width: 100%;
  height: 100dvh;
  min-height: 0;
  margin: 0;
  padding: clamp(18px, 3vh, 34px) clamp(22px, 4vw, 64px) 64px;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: hidden;
  position: relative;
}
.gs-host { min-height: calc(100vh - 150px); display: flex; flex-direction: column; gap: 16px; }
.gs-round-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-weight: 900; }
.gs-round-meta { display: flex; align-items: center; gap: 12px; }
.gs-clock { min-width: 72px; display: flex; justify-content: center; align-items: baseline; gap: 2px; padding: 6px 10px; background: var(--panel-2); border: 3px solid var(--edge); border-radius: 999px; }
.gs-clock strong { font: 900 clamp(1.45rem, 3vw, 2.2rem)/1 "Arial Black", Inter, sans-serif; color: var(--accent); font-variant-numeric: tabular-nums; }
.gs-clock span { font-weight: 900; }
.gs-question-image { display: block; max-width: min(540px, 100%); max-height: 28vh; object-fit: contain; margin: 0 auto; border-radius: 12px; }
.gs-preview { align-items: center; justify-content: flex-start; text-align: center; }
.gs-preview .badge { order: 0; align-self: flex-start; }
.gs-preview .gs-question-image { order: 1; max-height: 18vh; }
.gs-preview .live-q { order: 2; }
.gs-preview-count { order: 3; flex: 1; min-height: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; color: var(--surface-ink); }
.gs-preview-count strong { font: 900 clamp(8rem, 28vw, 20rem)/.72 "Arial Black", Inter, sans-serif; color: var(--yellow); text-shadow: 0 8px 0 var(--edge); font-variant-numeric: tabular-nums; }
.gs-preview-count span { font-size: clamp(1.15rem, 2.6vw, 2rem); font-weight: 900; text-transform: uppercase; letter-spacing: .1em; }
.gs-preview-hint { order: 4; margin: 0; font-size: clamp(.85rem, 1.5vw, 1.15rem); font-weight: 800; }
.game-show-host .gs-host .live-q { text-align: center; margin: 4px auto 8px; max-width: 1200px; font-size: clamp(2rem, 4.7vw, 4.8rem); line-height: 1.08; }
.gs-answer-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; flex: 1; }
.gs-answer { min-height: 92px; border: 3px solid var(--edge); border-radius: 12px; box-shadow: 4px 4px 0 var(--edge); color: var(--edge); display: flex; align-items: center; gap: 14px; padding: clamp(18px, 3vw, 34px); }
.game-show-host .gs-answer-grid { min-height: 0; grid-template-rows: repeat(2, minmax(0, 1fr)); gap: clamp(8px, 1.8vh, 14px); }
.game-show-host .gs-answer { min-height: 0; overflow: hidden; }
.game-show-host .gs-answer strong { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; }
.gs-answer .key { font-size: 1.55rem; }
.game-show-host .gs-answer strong { font-size: clamp(1.35rem, 2.8vw, 2.5rem); }
/* Game Show uses the same answer palette as every other question screen. */
.gs-answer.c0 { background: var(--coral); } .gs-answer.c1 { background: #67a7ff; }
.gs-answer.c2 { background: var(--yellow); } .gs-answer.c3 { background: var(--mint); }
.game-show-player .answer { color: var(--edge); }
.game-show-player .answer.c0 { background: var(--coral); }
.game-show-player .answer.c1 { background: #67a7ff; }
.game-show-player .answer.c2 { background: var(--yellow); }
.game-show-player .answer.c3 { background: var(--mint); }
.gs-end-btn {
  position: absolute;
  right: 14px;
  bottom: 12px;
  z-index: 3;
  min-height: 0;
  padding: 5px 9px;
  font-size: .68rem;
  opacity: .72;
  color: var(--wrong);
  box-shadow: 2px 2px 0 var(--edge);
}
.gs-end-btn:hover, .gs-end-btn:focus-visible { opacity: 1; }
.gs-player-link {
  position: absolute; left: 14px; bottom: 12px; z-index: 3;
  min-height: 0; padding: 5px 9px; font-size: .68rem;
  box-shadow: 2px 2px 0 var(--edge);
}
.gs-between { justify-content: flex-start; text-align: center; }
.game-show-host .gs-between { overflow-y: auto; padding-bottom: 58px; }
.gs-between h1, .gs-player-board h1 { margin: 4px 0; font-size: clamp(2rem, 5vw, 3.5rem); }
.gs-correct-line { margin: 0 0 8px; font-weight: 900; color: var(--right); }
.gs-reveal-overview { width: min(1180px, 100%); margin: 0 auto; display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(280px, .65fr); gap: 16px; align-items: stretch; }
.gs-reveal-grid { width: 100%; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 9px; }
.gs-reveal-answer { min-height: 78px; padding: 9px 12px; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 5px 12px; border: 3px solid var(--edge); border-radius: 11px; color: #fffdf5; text-align: left; }
.gs-reveal-answer.is-correct { background: var(--right); }
.gs-reveal-answer.is-muted { background: #5f6070; color: #dedde5; opacity: .72; }
.gs-reveal-choice { min-width: 0; display: flex; align-items: center; gap: 9px; }
.gs-reveal-choice strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gs-reveal-answer b { grid-column: 2; grid-row: 1; font-size: .76rem; white-space: nowrap; }
.gs-response-chart { min-height: 165px; padding: 12px 14px 9px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); align-items: stretch; gap: 10px; background: var(--panel-2); border: 3px solid var(--edge); border-radius: 12px; box-shadow: 3px 3px 0 var(--edge); }
.gs-chart-column { min-width: 0; display: grid; grid-template-rows: auto minmax(90px, 1fr) auto; gap: 5px; text-align: center; color: var(--surface-ink); }
.gs-chart-column > strong { font: 900 1.2rem/1 "Arial Black", Inter, sans-serif; }
.gs-chart-track { min-height: 90px; display: flex; align-items: flex-end; overflow: hidden; background: color-mix(in srgb, var(--edge) 10%, transparent); border: 2px solid var(--edge); border-radius: 7px 7px 3px 3px; }
.gs-chart-bar { display: block; width: 100%; height: var(--bar-height); background: #777986; transform-origin: bottom; animation: gsBarRise .7s cubic-bezier(.2,.9,.25,1) both; }
.gs-chart-column.is-correct .gs-chart-bar { background: var(--right); }
.gs-chart-key { font-size: 1.25rem; font-weight: 900; }
.gs-chart-column.is-correct .gs-chart-key { color: var(--right); }
.gs-chart-column.is-muted .gs-chart-key { color: #777986; }
@keyframes gsBarRise { from { transform: scaleY(0); } }
.gs-ranking-title { margin: 1px 0 -4px; font-size: clamp(1.1rem, 2.4vw, 1.6rem); }
.gs-cinematic-ranking { width: min(720px, 100%); margin: 0 auto; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: end; gap: 10px; }
.gs-cinematic-ranking.count-1 { width: min(250px, 100%); grid-template-columns: 1fr; }
.gs-cinematic-ranking.count-2 { width: min(490px, 100%); grid-template-columns: repeat(2, minmax(0, 1fr)); }
.gs-reveal-place { min-height: 96px; padding: 8px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 2px; background: var(--panel-2); color: var(--surface-ink); border: 3px solid var(--edge); border-radius: 12px; box-shadow: 3px 3px 0 var(--edge); opacity: 0; animation: gsPlaceReveal .55s cubic-bezier(.2,1.45,.35,1) var(--reveal-delay) forwards; }
.gs-reveal-place.place-1 { min-height: 128px; background: var(--yellow); color: var(--edge); }
.gs-reveal-place.place-2 { min-height: 112px; }
.gs-reveal-place > span:last-child { font-size: .7rem; font-weight: 800; }
@keyframes gsPlaceReveal { from { opacity: 0; transform: translateY(26px) scale(.85); } to { opacity: 1; transform: none; } }
.gs-runners { width: min(720px, 100%); margin: 0 auto; display: flex; justify-content: center; gap: 8px; }
.gs-runner { min-width: 170px; padding: 6px 10px; display: flex; justify-content: space-between; gap: 12px; background: var(--panel-2); color: var(--surface-ink); border: 2px solid var(--edge); border-radius: 9px; opacity: 0; animation: gsPlaceReveal .4s ease var(--reveal-delay) forwards; }
.gs-runner span { color: var(--surface-ink-soft); font-size: .72rem; }
.gs-leaderboard { display: flex; flex-direction: column; gap: 9px; width: min(760px, 100%); margin: 0 auto; }
.gs-rank-row {
  display: grid; grid-template-columns: 42px 48px minmax(0, 1fr) 52px 70px auto;
  align-items: center; gap: 10px; min-height: 62px; padding: 8px 12px;
  background: var(--panel-2); color: var(--surface-ink); border: 3px solid var(--edge); border-radius: 11px;
  box-shadow: 3px 3px 0 var(--edge); text-align: left;
  animation: lbRow .38s ease both; animation-delay: calc(var(--row, 0) * 65ms);
}
.gs-rank-row.is-you { background: var(--yellow); color: var(--edge); }
.gs-rank { font: 900 1.25rem "Arial Black", Inter, sans-serif; text-align: center; }
.gs-move { font-weight: 900; text-align: center; color: var(--text-soft); }
.gs-move.up { color: var(--right); } .gs-move.down { color: var(--wrong); }
.gs-round-points { font-weight: 900; color: var(--honey-deep); text-align: right; }
.gs-between > .btn-primary { align-self: center; margin-top: 12px; }
.gs-player-board { margin-top: 20px; text-align: center; }
.gs-player-wait { min-height: calc(100vh - 180px); display: grid; place-content: center; justify-items: center; gap: 12px; text-align: center; }
.gs-player-wait h1 { margin: 0; font-size: clamp(2.2rem, 8vw, 4rem); }
.gs-wait-icon { width: 84px; height: 84px; display: grid; place-items: center; border-radius: 50%; background: var(--yellow); color: var(--edge); border: 4px solid var(--edge); }
.gs-wait-icon .icon { width: 44px; height: 44px; }
.gs-player-result {
  min-height: calc(100dvh - 150px);
  width: min(680px, 100%);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
}
.gs-player-preview { min-height: calc(100dvh - 150px); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; text-align: center; }
.gs-player-preview h1 { max-width: 900px; margin: 0; font-size: clamp(2rem, 7vw, 4.5rem); line-height: 1.08; }
.gs-player-preview .gs-question-image { max-height: 30vh; }
.gs-player-result h1 { margin: 0; font-size: clamp(2.8rem, 10vw, 5rem); }
.gs-result-mark { width: 94px; height: 94px; display: grid; place-items: center; border: 4px solid var(--edge); border-radius: 50%; color: var(--edge); box-shadow: 5px 5px 0 var(--edge); }
.gs-result-mark .icon { width: 52px; height: 52px; }
.gs-player-result.is-correct .gs-result-mark { background: var(--right); color: #fff; }
.gs-player-result.is-incorrect .gs-result-mark { background: var(--wrong); color: #fff; }
.gs-result-points { font: 900 clamp(1.7rem, 6vw, 2.6rem)/1 "Arial Black", Inter, sans-serif; color: var(--honey-deep); }
.gs-result-points span { display: block; margin-top: 5px; font: 800 .72rem/1.2 Inter, sans-serif; color: var(--text-soft); text-transform: uppercase; letter-spacing: .08em; }
.gs-place-card { width: min(430px, 100%); padding: 16px 20px; background: var(--bg-raised); color: var(--surface-ink); border: 4px solid var(--edge); border-radius: 14px; box-shadow: 5px 5px 0 var(--edge); }
.gs-place-card > span { font-size: .72rem; font-weight: 900; text-transform: uppercase; letter-spacing: .08em; color: var(--surface-ink-soft); }
.gs-place-card strong { display: block; margin: 2px 0; font: 900 clamp(2.4rem, 9vw, 4rem)/1 "Arial Black", Inter, sans-serif; }
.gs-place-card p { margin: 6px 0 0; color: var(--surface-ink-soft); font-weight: 850; }

.gs-finale-wrap { position: fixed; inset: 0; z-index: 80; }
.gs-finale { position: absolute; inset: 0; overflow: auto; background: #a94f19 var(--fall) center/cover no-repeat; color: #fffaf0; }
.gs-finale-shade { position: fixed; inset: 0; background: linear-gradient(rgba(32,12,3,.2), rgba(32,12,3,.38)); }
.gs-finale-content { position: relative; z-index: 1; min-height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: space-between; gap: 16px; padding: clamp(26px, 5vh, 60px) 18px 28px; text-align: center; }
.gs-finale h1 { margin: 0; font: 900 clamp(2.3rem, 7vw, 5rem)/1 "Arial Black", Inter, sans-serif; text-shadow: 0 4px 0 rgba(65,24,5,.75); }
.gs-finale-five { width: min(1000px, 100%); display: flex; align-items: flex-end; justify-content: center; gap: clamp(8px, 2vw, 22px); }
.gs-finalist { width: min(170px, 18vw); min-height: 150px; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 5px; padding: 10px 8px; color: var(--edge); background: rgba(255,250,230,.92); border: 4px solid var(--edge); border-radius: 16px 16px 6px 6px; box-shadow: 0 7px 0 rgba(53,20,5,.75); }
.gs-finalist.place-1 { order: 3; min-height: 245px; background: #ffd84a; }
.gs-finalist.place-2 { order: 2; min-height: 205px; } .gs-finalist.place-3 { order: 4; min-height: 180px; }
.gs-finalist.place-4 { order: 1; } .gs-finalist.place-5 { order: 5; }
.gs-finalist.is-you { outline: 5px solid #fff; outline-offset: 4px; }
.gs-place { font: 900 1.2rem "Arial Black", Inter, sans-serif; }
.gs-finalist strong { overflow-wrap: anywhere; }
.gs-finalist > span:last-child { font-size: .78rem; font-weight: 800; }
.gs-finale .result-actions { margin: 0; }
@media (max-width: 680px) {
  .gs-answer-grid { grid-template-columns: 1fr; }
  .game-show-host .gs-answer-grid { grid-template-rows: repeat(4, minmax(0, 1fr)); }
  .gs-reveal-grid { grid-template-columns: 1fr; }
  .gs-cinematic-ranking { gap: 5px; }
  .gs-reveal-place { min-width: 0; }
  .gs-runners { flex-direction: column; }
  .gs-runner { min-width: 0; width: 100%; }
  .gs-rank-row { grid-template-columns: 32px 42px minmax(0, 1fr) 42px auto; }
  .gs-round-points { display: none; }
  .gs-finale-five { align-items: stretch; flex-direction: column; }
  .gs-finalist, .gs-finalist.place-1, .gs-finalist.place-2, .gs-finalist.place-3, .gs-finalist.place-4, .gs-finalist.place-5 { order: initial; width: 100%; min-height: 0; flex-direction: row; justify-content: flex-start; }
}
@media (max-width: 900px) {
  .gs-reveal-overview { grid-template-columns: 1fr; }
  .gs-response-chart { min-height: 145px; }
}
@media (max-height: 680px) {
  .game-show-host .gs-host { gap: 9px; padding-top: 12px; padding-bottom: 52px; }
  .game-show-host .gs-question-image { max-height: 19vh; }
  .game-show-host .gs-host .live-q { margin: 0 auto 3px; font-size: clamp(1.55rem, 4vw, 3rem); }
  .game-show-host .gs-answer { padding: clamp(9px, 2vw, 18px); }
  .game-show-host .gs-answer strong { font-size: clamp(1rem, 2.3vw, 1.75rem); -webkit-line-clamp: 3; }
  .game-show-host .gs-clock { padding: 3px 8px; }
  .gs-preview .gs-question-image { max-height: 12vh; }
  .gs-preview-count strong { font-size: clamp(5rem, 24vh, 9rem); text-shadow: 0 5px 0 var(--edge); }
  .gs-preview-count span { font-size: clamp(.9rem, 2.4vh, 1.25rem); }
}
@media (prefers-reduced-motion: reduce) { .gs-rank-row { animation: none; } }
@media (prefers-reduced-motion: reduce) { .gs-chart-bar, .gs-reveal-place, .gs-runner { animation: none; opacity: 1; } }

/* ---------- host game settings ---------- */
.setting-options { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 12px; }
.setting-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px;
  border: 3px solid var(--edge); border-radius: 10px;
  background: var(--panel-2, #f1f1ed);
  cursor: pointer;
}
.setting-row:has(input:checked) { background: var(--yellow, #ffe24a); color: var(--edge); }
.setting-row input { margin-top: 3px; }
.setting-row strong { display: block; }
.setting-row em { font-style: normal; font-size: .8rem; color: var(--surface-ink-soft); }
.setting-row:has(input:checked) em { color: #55516a; }

/* ---------- top-bar controls ----------
   Ranks / Bag / goal live up here beside Leave rather than floating over the
   world -- they're chrome, not part of the map. */
.topbar-btn {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  border: 2px solid rgba(255, 255, 255, .35);
  border-radius: 8px;
  padding: 6px 12px;
  font-weight: 800; font-size: .8rem;
  cursor: pointer;
  flex: 0 0 auto;
}
.topbar-btn:hover { background: rgba(255, 255, 255, .24); }
.topbar-btn .icon { width: 16px; height: 16px; }
.topbar-goal {
  display: inline-flex; align-items: baseline; gap: 7px;
  background: rgba(255, 255, 255, .14);
  border: 2px solid rgba(255, 255, 255, .35);
  border-radius: 8px;
  padding: 5px 12px;
  color: #fff; flex: 0 0 auto;
}
.topbar-goal span { font-size: .58rem; font-weight: 900; text-transform: uppercase; letter-spacing: .08em; opacity: .85; }
.topbar-goal strong { font-family: "Arial Black", Inter, sans-serif; font-size: .95rem; }
.topbar-goal.is-urgent { background: var(--coral, #ff5c5c); border-color: #fff; }

@media (max-width: 640px) {
  .topbar-btn span:not(.icon) { display: none; }   /* icons only on narrow screens */
  .topbar-btn { padding: 6px 9px; }
  .topbar-goal { padding: 5px 9px; }
}

/* ---------- inventory ---------- */
.bag-summary {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
  padding: 10px; margin-bottom: 4px;
  background: var(--panel-2, #f1f1ed);
  border: 3px solid var(--edge); border-radius: 10px;
}
.bag-summary div { display: flex; flex-direction: column; align-items: center; }
.bag-summary strong { font-family: "Arial Black", Inter, sans-serif; font-size: 1.15rem; }
.bag-summary span { font-size: .58rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: var(--text-soft); }
.bag-rows { display: flex; flex-direction: column; gap: 6px; overflow-y: auto; }
.bag-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px;
  border: 2px solid var(--edge); border-radius: 9px;
  background: var(--bg-raised);
}
/* Same sheet at 44px a cell: 4x2 grid scales to 176x88. These rows carry
   .bag-fish, not .ff-fish, so the image has to be named again here. */
.bag-fish {
  width: 44px; height: 44px; flex: 0 0 auto;
  background-image: url('fish.png?v=20261003-1');
  background-size: 176px 88px;
  background-repeat: no-repeat;
}
.bag-fish.ff-fish-0 { background-position: 0 0; }
.bag-fish.ff-fish-1 { background-position: -44px 0; }
.bag-fish.ff-fish-2 { background-position: -88px 0; }
.bag-fish.ff-fish-3 { background-position: -132px 0; }
.bag-fish.ff-fish-4 { background-position: 0 -44px; }
.bag-fish.ff-fish-5 { background-position: -44px -44px; }
.bag-fish.ff-fish-6 { background-position: -88px -44px; }
.bag-fish.ff-fish-7 { background-position: -132px -44px; }
.bag-name { flex: 1; display: flex; flex-direction: column; }
.bag-name em { font-style: normal; font-size: .7rem; color: var(--text-soft); }

/* ---------- islands, ocean and docks ----------
   The base layer is open water; land is drawn on top of it. Islands are
   unreachable on foot by design -- boats are the only way between them. */

.ff-ocean {
  position: absolute; inset: 0;
  background-image: url('water.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4);
  background-repeat: repeat;
}
.ff-spectate-ocean { background-image: url('water.png?v=20261003-1'); background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4); }

.ff-dock {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('fishing.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4);
  background-position: calc(var(--g2d-tile) * -2) 0;   /* dock plank cell */
  background-repeat: no-repeat;
  pointer-events: none;
}
.ff-dock-name {
  position: absolute; top: -20px; left: 50%; transform: translateX(-50%);
  background: #f2d08a; border: 2px solid #5a3a1c; border-radius: 5px;
  padding: 2px 8px; white-space: nowrap;
  font-size: .56rem; font-weight: 900; color: #4a2f14;
}

/* ---------- boat launch ---------- */
.travel-rows { display: flex; flex-direction: column; gap: 8px; overflow-y: auto; }
.travel-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 14px;
  border: 3px solid var(--edge); border-radius: 11px;
  background: var(--panel-2, #f1f1ed);
  box-shadow: var(--shadow-sm, 3px 3px 0 var(--edge));
  color: var(--surface-ink);
  cursor: pointer; text-align: left;
}
.travel-row:hover:not(:disabled) { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 var(--edge); }
.travel-row.is-here { background: var(--mint, #52e3b3); color: var(--edge); cursor: default; }
.travel-row.is-here .travel-name em { color: #36554b; }
.travel-row.is-locked { opacity: .5; cursor: not-allowed; }
.travel-name { display: flex; flex-direction: column; }
.travel-name em { font-style: normal; font-size: .72rem; color: var(--text-soft); }
.travel-cost {
  font-family: "Arial Black", Inter, sans-serif; font-size: .95rem;
  white-space: nowrap;
}

/* ---------- coastline ----------
   Land is drawn a tile at a time and each tile knows which of its sides meet
   water, so the shore follows the generated shape instead of a rectangle's
   outline. A sand edge is inset on exactly the exposed sides. */
.ff-land {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('ground-grass.png?v=20261003-5');
  background-size: calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12);
  background-repeat: repeat;
}
.ff-land.edge-n { box-shadow: inset 0 7px 0 #e8d29a; }
.ff-land.edge-s { box-shadow: inset 0 -7px 0 #e8d29a; }
.ff-land.edge-w { box-shadow: inset 7px 0 0 #e8d29a; }
.ff-land.edge-e { box-shadow: inset -7px 0 0 #e8d29a; }
/* Corners need both edges at once, so the combinations are spelled out --
   box-shadow doesn't accumulate across rules. */
.ff-land.edge-n.edge-w { box-shadow: inset 0 7px 0 #e8d29a, inset 7px 0 0 #e8d29a; }
.ff-land.edge-n.edge-e { box-shadow: inset 0 7px 0 #e8d29a, inset -7px 0 0 #e8d29a; }
.ff-land.edge-s.edge-w { box-shadow: inset 0 -7px 0 #e8d29a, inset 7px 0 0 #e8d29a; }
.ff-land.edge-s.edge-e { box-shadow: inset 0 -7px 0 #e8d29a, inset -7px 0 0 #e8d29a; }
.ff-land.edge-n.edge-s { box-shadow: inset 0 7px 0 #e8d29a, inset 0 -7px 0 #e8d29a; }
.ff-land.edge-w.edge-e { box-shadow: inset 7px 0 0 #e8d29a, inset -7px 0 0 #e8d29a; }
.ff-land.edge-n.edge-w.edge-e { box-shadow: inset 0 7px 0 #e8d29a, inset 7px 0 0 #e8d29a, inset -7px 0 0 #e8d29a; }
.ff-land.edge-s.edge-w.edge-e { box-shadow: inset 0 -7px 0 #e8d29a, inset 7px 0 0 #e8d29a, inset -7px 0 0 #e8d29a; }
.ff-land.edge-n.edge-s.edge-w { box-shadow: inset 0 7px 0 #e8d29a, inset 0 -7px 0 #e8d29a, inset 7px 0 0 #e8d29a; }
.ff-land.edge-n.edge-s.edge-e { box-shadow: inset 0 7px 0 #e8d29a, inset 0 -7px 0 #e8d29a, inset -7px 0 0 #e8d29a; }
.ff-land.edge-n.edge-s.edge-w.edge-e {
  box-shadow: inset 0 7px 0 #e8d29a, inset 0 -7px 0 #e8d29a, inset 7px 0 0 #e8d29a, inset -7px 0 0 #e8d29a;
}

/* ---------- waymarking ----------
   Worn paths between the places that matter, and signposts naming them. The
   path tiles round off only on the sides where the route stops, so a run of
   them reads as one continuous track. */
.ff-path {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('ground-dirt.png?v=20261003-7');
  background-size: calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12);
  background-repeat: repeat;
  border-radius: 14px;
  opacity: .92;
}
.ff-path.link-n { border-top-left-radius: 0; border-top-right-radius: 0; }
.ff-path.link-s { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.ff-path.link-w { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.ff-path.link-e { border-top-right-radius: 0; border-bottom-right-radius: 0; }

.ff-sign {
  position: absolute;
  width: var(--g2d-tile); height: var(--g2d-tile);
  background-image: url('fishing.png?v=20261003-1');
  background-size: calc(var(--g2d-tile) * 4) calc(var(--g2d-tile) * 4);
  background-position: calc(var(--g2d-tile) * -3) 0;   /* signpost cell */
  background-repeat: no-repeat;
  pointer-events: none;
}
.ff-sign-label {
  position: absolute; top: -6px; left: 50%; transform: translateX(-50%);
  background: #f2d08a; border: 2px solid #5a3a1c; border-radius: 5px;
  padding: 2px 7px; white-space: nowrap;
  font-size: .55rem; font-weight: 900; letter-spacing: .03em;
  color: #4a2f14;
  box-shadow: 0 2px 0 rgba(0, 0, 0, .28);
}

/* ---------- spectator view picker ---------- */
.spectate-views { display: flex; flex-direction: column; gap: 4px; }
.spectate-view-label {
  font-size: .58rem; font-weight: 900; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-soft);
}
.spectate-select {
  width: 100%;
  border: 3px solid var(--edge); border-radius: 9px;
  background: var(--panel-2, #f1f1ed);
  padding: 8px 10px;
  font-family: inherit; font-weight: 800; font-size: .85rem;
  color: var(--text);
}

/* ---------- bait shop: next-question bar ---------- */
.ff-next {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 14px; padding: 12px 16px;
  border: 3px solid var(--edge); border-radius: 12px;
  background: var(--mint, #52e3b3);
}
.ff-next.wrong { background: var(--coral, #ff5c5c); }
.ff-next-text { font-weight: 900; font-size: 1rem; color: var(--edge); }
.ff-next .btn { flex: 0 0 auto; }

/* ---------- question pictures & multi-answer ---------- */
.q-image {
  display: block;
  max-width: min(420px, 100%);
  max-height: 30vh;
  margin: 0 auto 14px;
  border: 3px solid var(--edge);
  border-radius: 12px;
  object-fit: contain;
  background: var(--panel-2, #f1f1ed);
}
.q-multi-hint {
  display: block; text-align: center; margin: -6px 0 12px;
  font-size: .78rem; font-weight: 800;
  color: var(--text-soft);
}
/* A picked-but-not-yet-submitted answer. Distinct from the post-submit
   reveal colours so "chosen" never looks like "correct". */
.answer.is-picked {
  outline: 4px solid var(--edge);
  outline-offset: -4px;
  transform: translate(-2px, -2px);
}
.answer .pick-tick {
  position: absolute; top: 6px; right: 8px;
  width: 20px; height: 20px; border-radius: 50%;
  background: var(--edge); color: #fff;
  display: grid; place-items: center;
  font-size: .7rem; font-weight: 900;
}
.multi-submit { margin-top: 12px; }

/* editor */
.correct-picks { display: flex; gap: 8px; flex-wrap: wrap; }
.correct-pick {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px;
  border: 3px solid var(--edge); border-radius: 10px;
  background: var(--panel-2, #f1f1ed);
  font-weight: 900; cursor: pointer;
}
.correct-pick:has(input:checked) { background: var(--mint, #52e3b3); color: var(--edge); }

/* all-vs-any picker, shown only once two answers are ticked */
.answer-mode { display: flex; flex-direction: column; gap: 8px; }
.mode-pick {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px;
  border: 3px solid var(--edge); border-radius: 10px;
  background: var(--panel-2, #f1f1ed);
  cursor: pointer;
}
.mode-pick:has(input:checked) { background: var(--mint, #52e3b3); color: var(--edge); }
.mode-pick input { margin-top: 3px; flex: 0 0 auto; }
.mode-pick span { display: flex; flex-direction: column; gap: 2px; }
.mode-pick strong { font-size: .9rem; }
.mode-pick em { font-style: normal; font-size: .74rem; color: var(--text-soft); }
.mode-pick:has(input:checked) em { color: #1c2a24; }
.mode-tag {
  display: inline-block; margin-left: 8px; padding: 1px 7px;
  border: 2px solid var(--edge); border-radius: 999px;
  font-size: .62rem; font-weight: 900; text-transform: uppercase; letter-spacing: .05em;
  background: var(--bg-raised);
}
.q-image-preview { display: flex; align-items: center; gap: 12px; margin-top: 8px; }
.q-image-preview img { max-width: 120px; max-height: 90px; border: 3px solid var(--edge); border-radius: 8px; }
.q-thumb { max-width: 90px; max-height: 70px; border: 2px solid var(--edge); border-radius: 6px; margin-top: 6px; }

/* ---------- lobby free-roam ----------
   Players can walk the world before the host starts, so this says plainly
   that nothing is scoring yet rather than blocking the screen. */
.wait-banner {
  position: fixed; left: 50%; top: calc(64px + env(safe-area-inset-top, 0px));
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 10px;
  max-width: calc(100vw - 28px);
  background: #fff6d8; color: #24231f;
  border: 3px solid #24231f; border-radius: 14px;
  padding: 8px 15px; box-shadow: 0 4px 0 rgba(0,0,0,.3);
  font-size: .78rem; font-weight: 900; white-space: nowrap;
  z-index: 44; pointer-events: none;
}
.wait-dot {
  width: 9px; height: 9px; flex: 0 0 9px; border-radius: 50%;
  background: #f5bd23;
  animation: waitPulse 1.2s ease-in-out infinite;
}
@keyframes waitPulse { 0%,100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .wait-dot { animation: none; } }

/* Fade to black over everything, including the HUD and the joystick, so the
   world can be reset underneath without the player seeing it happen. */
.screen-wipe {
  position: fixed; inset: 0;
  background: #000;
  opacity: 0;
  transition: opacity .45s ease;
  z-index: 900; pointer-events: none;
}

/* 3-2-1-GO shown over the world for players already walking around. */
.world-countdown {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(10, 10, 14, .55);
  z-index: 880; pointer-events: none;
}
.world-countdown .countdown-number {
  font-family: "Arial Black", Inter, sans-serif;
  font-size: clamp(5rem, 22vw, 12rem);
  color: #fff;
  text-shadow: 0 6px 0 rgba(0, 0, 0, .45);
  line-height: 1;
}
.countdown-number.pulse { animation: countPulse .45s cubic-bezier(.2, 1.4, .4, 1); }
@keyframes countPulse {
  0%   { transform: scale(.45); opacity: 0; }
  55%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .countdown-number.pulse { animation: none; }
  .screen-wipe { transition-duration: .2s; }
}

/* Kit-details card in the editor: cover beside the text fields. */
.kit-details-grid { display: grid; grid-template-columns: minmax(0, 220px) minmax(0, 1fr); gap: 20px; align-items: start; }
.kit-cover-col .set-cover { margin-bottom: 10px; }
.cover-actions { display: flex; flex-direction: column; gap: 6px; }
.field-label { display: block; font-weight: 700; margin-bottom: 6px; font-size: 0.9rem; }
.kit-details-fields textarea {
  width: 100%; resize: vertical; font: inherit;
  padding: 10px 12px; border-radius: 10px;
  border: 2px solid var(--border); background: var(--bg); color: var(--text);
}
.set-card-link { color: inherit; text-decoration: none; }
.set-card-link:hover { text-decoration: underline; }
@media (max-width: 700px) { .kit-details-grid { grid-template-columns: 1fr; } }

/* ---------- Trick or Treat ---------- */

/* ---- Hollow Lane (Trick or Treat map, October 2026) ----
   Drawn by trickGroundHtml/trickDecalsHtml/trickSceneHtml in api.js for both
   the player and the host. Floors and fences are baked with the ground. */
.g2d-ground-tot-road      { background-image: url('tot-floor-road.png?v=20261005-1'); }
.g2d-ground-tot-sidewalk  { background-image: url('tot-floor-sidewalk.png?v=20261005-1'); }
.g2d-ground-tot-cobble    { background-image: url('tot-floor-cobble.png?v=20261005-1'); }
.g2d-ground-tot-leaves    { background-image: url('tot-floor-leaves.png?v=20261005-1'); }
.g2d-ground-tot-graveyard { background-image: url('tot-floor-graveyard.png?v=20261005-1'); }
.ph-wall.tot-fence { background-image: url('tot-fences.png?v=20261005-2'); background-size: calc(var(--g2d-tile) * 16) calc(var(--g2d-tile) * 3); }
.tot-f-picket { background-position-y: 0; }
.tot-f-iron { background-position-y: calc(var(--g2d-tile) * -1); }
.tot-f-hedge { background-position-y: calc(var(--g2d-tile) * -2); }
.g2d-root.tot-root { background: #1b2622; }

.tot-decal { position: absolute; pointer-events: none; }
.tot-decal-lane-h { border-top: 4px dashed rgba(255, 214, 90, .7); transform: translateY(-2px); }
.tot-decal-lane-v { border-left: 4px dashed rgba(255, 214, 90, .7); transform: translateX(-2px); }
.tot-decal-glow { border-radius: 50%; background: radial-gradient(circle, rgba(255, 205, 110, .34), rgba(255, 205, 110, .12) 45%, transparent 70%); }

.tot-home, .tot-npc, .tot-item, .tot-decor { position: absolute; background-repeat: no-repeat; }
.tot-home { background-image: url('tot-houses-v3.webp?v=20261005-1'); background-size: 600% 300%; pointer-events: none; }
.tot-art-a0 { background-position: 0% 0%; }
.tot-art-a1 { background-position: 20% 0%; }
.tot-art-a2 { background-position: 40% 0%; }
.tot-art-a3 { background-position: 60% 0%; }
.tot-art-a4 { background-position: 80% 0%; }
.tot-art-a5 { background-position: 100% 0%; }
.tot-art-b0 { background-position: 0% 50%; }
.tot-art-b1 { background-position: 20% 50%; }
.tot-art-b2 { background-position: 40% 50%; }
.tot-art-b3 { background-position: 60% 50%; }
.tot-art-b4 { background-position: 80% 50%; }
.tot-art-b5 { background-position: 100% 50%; }
.tot-art-pumpkin { background-position: 0% 100%; }
.tot-art-witch { background-position: 20% 100%; }
.tot-art-manor { background-position: 40% 100%; }
.tot-art-lab { background-position: 60% 100%; }
.tot-art-ghost { background-position: 80% 100%; }
.tot-art-castle { background-position: 100% 100%; }
/* porch light: on while the house has candy for you, off while it rests */
.tot-porch { position: absolute; left: 50%; bottom: -14%; width: 44%; height: 26%; transform: translateX(-50%); border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255, 210, 110, .55), rgba(255, 190, 80, .18) 50%, transparent 72%); pointer-events: none; z-index: -1; }
.tot-home.is-dark { filter: brightness(.55) saturate(.65); }
.tot-home.is-dark .tot-porch { display: none; }
.tot-home.is-locked { filter: saturate(.75); }
.tot-tag { position: absolute; left: 50%; bottom: 36%; transform: translateX(-50%); display: none; align-items: center; gap: 6px; white-space: nowrap;
  padding: 4px 10px 4px 5px; border: 2px solid #111114; border-radius: 999px; background: #fff4d5; color: #2a1d34; font-size: .74rem; font-weight: 900; z-index: 2; }
.tot-tag em { font-style: normal; color: #b0402f; }
.tot-tag em:empty { display: none; }
.tot-home.is-near .tot-tag { display: inline-flex; }
.tot-home.is-dark .tot-tag { filter: brightness(1.8) saturate(1.5); }
.tot-icon { display: inline-block; width: 22px; height: 22px; background: url('tot-items.webp?v=20261005-1') no-repeat; background-size: 400% 500%; flex: 0 0 auto; }
.tot-candy-corn { background-position: 0% 0%; }
.tot-candy-lollipop { background-position: 33.3333% 0%; }
.tot-candy-chocolate { background-position: 66.6667% 0%; }
.tot-candy-gummy { background-position: 100% 0%; }
.tot-candy-apple { background-position: 0% 25%; }
.tot-candy-jellybean { background-position: 33.3333% 25%; }
.tot-candy-peppermint { background-position: 66.6667% 25%; }
.tot-candy-cotton { background-position: 100% 25%; }
.tot-candy-golden { background-position: 0% 50%; }
.tot-candy-key { background-position: 33.3333% 50%; }
.tot-item { background-image: url('tot-items.webp?v=20261005-1'); background-size: 400% 500%; }
.tot-item.c0 { background-position: 0% 0%; }
.tot-item.c1 { background-position: 33.3333% 0%; }
.tot-item.c2 { background-position: 66.6667% 0%; }
.tot-item.c3 { background-position: 100% 0%; }
.tot-item.c4 { background-position: 0% 25%; }
.tot-item.c5 { background-position: 33.3333% 25%; }
.tot-item.c6 { background-position: 66.6667% 25%; }
.tot-item.c7 { background-position: 100% 25%; }
.tot-item.c8 { background-position: 0% 50%; }
.tot-item.c9 { background-position: 33.3333% 50%; }
.tot-item.c10 { background-position: 66.6667% 50%; }
.tot-item.c11 { background-position: 100% 50%; }
.tot-item.c12 { background-position: 0% 75%; }
.tot-item.c13 { background-position: 33.3333% 75%; }
.tot-item.c14 { background-position: 66.6667% 75%; }
.tot-item.c15 { background-position: 100% 75%; }
.tot-item.c16 { background-position: 0% 100%; }
.tot-item.c17 { background-position: 33.3333% 100%; }
.tot-item.c18 { background-position: 66.6667% 100%; }
.tot-item.c19 { background-position: 100% 100%; }
.tot-decor { background-size: 400% 400%; pointer-events: none; }
.tot-d2 { background-image: url('trick-or-treat-decor-v2.png?v=20261003-1'); }
.tot-d3 { background-image: url('trick-or-treat-decor-v3.png?v=20261003-1'); }
.tot-decor.c0 { background-position: 0% 0%; }
.tot-decor.c1 { background-position: 33.3333% 0%; }
.tot-decor.c2 { background-position: 66.6667% 0%; }
.tot-decor.c3 { background-position: 100% 0%; }
.tot-decor.c4 { background-position: 0% 33.3333%; }
.tot-decor.c5 { background-position: 33.3333% 33.3333%; }
.tot-decor.c6 { background-position: 66.6667% 33.3333%; }
.tot-decor.c7 { background-position: 100% 33.3333%; }
.tot-decor.c8 { background-position: 0% 66.6667%; }
.tot-decor.c9 { background-position: 33.3333% 66.6667%; }
.tot-decor.c10 { background-position: 66.6667% 66.6667%; }
.tot-decor.c11 { background-position: 100% 66.6667%; }
.tot-decor.c12 { background-position: 0% 100%; }
.tot-decor.c13 { background-position: 33.3333% 100%; }
.tot-decor.c14 { background-position: 66.6667% 100%; }
.tot-decor.c15 { background-position: 100% 100%; }
.tot-npc { pointer-events: none; }
.tot-npc-name { position: absolute; left: 50%; bottom: -8px; transform: translateX(-50%); white-space: nowrap; padding: 2px 7px; border-radius: 999px;
  background: rgba(26, 18, 38, .82); color: #fff4d5; font-size: .62rem; font-weight: 900; }
.tot-mark { position: absolute; left: 50%; top: -14px; transform: translateX(-50%); width: 26px; height: 26px; display: grid; place-items: center;
  border: 3px solid #111114; border-radius: 50%; background: #ffe24a; color: #111114; font: 1000 .95rem/1 "Arial Black", sans-serif; }
.tot-mark.is-turnin { background: #52e3b3; }
.tot-lantern.is-lit { background-position: 33.3333% 100%; }
.tot-lantern.is-lit::after { content: ''; position: absolute; inset: -60%; border-radius: 50%; background: radial-gradient(circle, rgba(255, 200, 80, .45), transparent 65%); z-index: -1; }
.tot-lantern.is-goal::before, .tot-ingredient::before, .tot-cat::before { content: ''; position: absolute; inset: -18%; border: 3px dashed rgba(255, 226, 74, .85); border-radius: 50%; }
.tot-place { position: fixed; z-index: 45; left: 50%; top: calc(66px + env(safe-area-inset-top, 0px)); transform: translateX(-50%); padding: 4px 12px; border-radius: 999px; background: rgba(26, 18, 38, .8); color: #fff4d5; font-size: .74rem; font-weight: 900; letter-spacing: .04em; white-space: nowrap; pointer-events: none; }
.tot-side { position: fixed; z-index: 46; right: 12px; top: calc(64px + env(safe-area-inset-top, 0px)); display: flex; flex-direction: column; align-items: flex-end; gap: 8px; max-height: calc(100dvh - 170px); }
.tot-map { position: relative; padding: 4px; border: 3px solid #111114; border-radius: 12px; background: #1a1226; cursor: pointer; line-height: 0; box-shadow: 0 4px 0 rgba(0, 0, 0, .3); }
.tot-map canvas { display: block; image-rendering: pixelated; }
.tot-map canvas + canvas { position: absolute; left: 4px; top: 4px; }
.tot-side.is-big-map .tot-map { transform-origin: top right; transform: scale(2.4); }
.tot-quests { display: none; min-height: 0; width: 240px; overflow: auto; padding: 10px 12px; border: 3px solid #111114; border-radius: 12px; background: rgba(32, 23, 47, .93); color: #f9e8ff; box-shadow: 0 4px 0 rgba(0, 0, 0, .3); }
.tot-side.is-open .tot-quests { display: block; }
.tot-side.is-big-map .tot-quests { visibility: hidden; }
.tot-quests h3 { margin: 2px 0 6px; color: #ffd15e; font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; }
.tot-quests h3 + .tot-quest { border-top: 0; }
.tot-quest { padding: 6px 0; border-top: 1px solid rgba(255, 255, 255, .12); }
.tot-quest strong { display: flex; justify-content: space-between; gap: 6px; font-size: .8rem; }
.tot-quest strong span { color: #ffd15e; font-size: .72rem; }
.tot-quest small { display: block; margin-top: 2px; color: #d9c8ea; font-size: .72rem; font-weight: 700; }
.tot-quest.ready small { color: #52e3b3; }
.tot-quest.done { opacity: .6; }
.tot-quest.done small::before { content: '✓ '; color: #52e3b3; }
.tot-bag-grid { display: flex; flex-wrap: wrap; gap: 5px; }
.tot-bag-slot { position: relative; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px; background: rgba(255, 255, 255, .1); }
.tot-bag-slot .tot-icon { width: 28px; height: 28px; }
.tot-bag-slot b { position: absolute; right: -3px; bottom: -4px; min-width: 16px; padding: 0 3px; border-radius: 999px; background: #ffd15e; color: #2a1d34; font-size: .62rem; text-align: center; }
.tot-bag-slot.is-missing .tot-icon { filter: grayscale(1) brightness(.6); opacity: .55; }
.tot-bag-slot.is-missing b { display: none; }
.tot-results-bag { justify-content: center; margin-top: 14px; }
.tot-pips { display: inline-flex; gap: 5px; margin-left: auto; }
.tot-pips i { width: 14px; height: 14px; border: 2px solid #111114; border-radius: 50%; background: #e6e0ef; }
.tot-pips i.is-now { background: #ffe24a; }
.tot-pips i.is-right { background: #21a762; }
.tot-pips i.is-wrong { background: #d84a4a; }
.tot-pips i.is-done { background: #9a92ae; }
.tot-leave { min-height: 34px; padding: 5px 12px; font-size: .74rem; }
.tot-talk { position: fixed; z-index: 210; left: 50%; bottom: 80px; transform: translateX(-50%); display: flex; align-items: center; gap: 14px; width: min(620px, calc(100vw - 24px));
  padding: 14px 16px; border: 3px solid #111114; border-radius: 16px; background: #fff4d5; color: #2a1d34; box-shadow: 0 6px 0 rgba(0, 0, 0, .35); }
.tot-talk-face { position: relative; flex: 0 0 76px; height: 76px; border-radius: 12px; background-color: #3a2a50; }
.tot-talk strong { font-size: 1rem; }
.tot-talk p { margin: 4px 0 0; font-weight: 700; line-height: 1.35; }
.tot-talk .tot-talk-reward { color: #1d8a54; font-weight: 1000; }
.tot-talk .btn { flex: 0 0 auto; }
@media (max-width: 760px) {
  .tot-side { top: calc(118px + env(safe-area-inset-top, 0px)); right: 8px; max-height: calc(100dvh - 330px); }
  .tot-map canvas { width: 126px !important; height: 90px !important; }
  .tot-quests { width: min(260px, calc(100vw - 24px)); }
  .tot-place { top: calc(122px + env(safe-area-inset-top, 0px)); left: 12px; transform: none; }
  .tot-talk { bottom: 190px; flex-wrap: wrap; }
  .tot-talk-face { flex-basis: 56px; height: 56px; }
}
.tot-cat { position: absolute; background-image: url('trick-or-treat-decor-v2.png?v=20261003-1'); background-size: 400% 400%; background-position: 66.6667% 66.6667%; }
.tot-playing { overflow:hidden; background:#100d29; }
.tot-root .g2d-ground,.tot-world .g2d-ground {
  background-color:#34584f;
  background-image:url('ground/night-grass.png?v=20261003-5');
  background-size:calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12);
  background-repeat:repeat;
}
/* Night tint as a plain overlay, not filter: saturate() brightness() -- a
   filter on the whole moving world is re-applied every frame, which held
   Trick or Treat near 35fps on school Chromebooks. */
.tot-world::after { content:""; position:absolute; inset:0; z-index:40; pointer-events:none; background:rgba(14,10,36,.17); }
.tot-root .g2d-topbar,.tot-hud,.tot-clock { filter:none; }
.tot-title { color:#fff4d5; font-weight:1000; letter-spacing:.02em; text-shadow:0 2px #3c1d59; }
#totHouses { pointer-events:none; z-index:12; }
.tot-house {
  position:absolute; display:block; pointer-events:auto; cursor:pointer; padding:0;
  border:0; background:linear-gradient(90deg,#5c345e 0 7%,#754174 7% 93%,#4a284c 93%);
  box-shadow:inset 0 0 0 6px #261b35,0 10px 0 rgba(7,5,16,.38); color:#fff7e6;
  image-rendering:pixelated; font:900 17px/1.1 Inter,sans-serif; z-index:2;
}
.tot-house::before,.tot-house::after { content:""; position:absolute; pointer-events:none; }
.tot-house::before { left:-18px; right:-18px; top:-58px; height:72px; background:#3a204d; clip-path:polygon(50% 0,100% 78%,92% 100%,8% 100%,0 78%); box-shadow:inset 0 -8px rgba(0,0,0,.22); }
.tot-house::after { inset:20px 32px auto; height:52px; background:repeating-linear-gradient(90deg,#ffd067 0 31px,#402b5b 31px 43px); border:6px solid #24192f; box-shadow:0 75px 0 -6px #f0b855; }
.tot-house strong { position:absolute; left:50%; top:-40px; z-index:4; transform:translateX(-50%); width:max-content; max-width:95%; padding:6px 11px; border:3px solid #261b35; border-radius:9px; background:#171227; color:#fff5d6; text-shadow:0 2px #000; }
.tot-house small { position:absolute; z-index:5; left:50%; bottom:12px; transform:translateX(-50%); padding:5px 9px; border-radius:999px; background:#20172e; color:#ffd374; }
.tot-door { position:absolute; z-index:4; width:50px; height:82px; border:6px solid #24192f; border-radius:24px 24px 2px 2px; background:linear-gradient(90deg,#7d4528,#b86c35 50%,#704022 51%); box-shadow:inset 0 0 0 5px rgba(255,193,83,.18); }
.tot-door::after { content:""; position:absolute; right:8px; top:38px; width:8px; height:8px; border-radius:50%; background:#ffd455; box-shadow:0 0 10px #ffb62e; }
.tot-house-orange { background:linear-gradient(90deg,#7f3c24 0 7%,#b35a2b 7% 93%,#67301f 93%); }
.tot-house-orange::before { background:#5b2638; }
.tot-house-green { background:linear-gradient(90deg,#29443e 0 7%,#3e6b58 7% 93%,#20372f 93%); }
.tot-house-green::before { background:#35204b; }
.tot-house-red { background:linear-gradient(90deg,#44263b 0 7%,#6e3045 7% 93%,#351d30 93%); }
.tot-house-red::before { background:#19182f; }
.tot-house-blue { background:linear-gradient(90deg,#29435b 0 7%,#376c7c 7% 93%,#213647 93%); }
.tot-house-blue::before { background:#44305b; }
.tot-house-white { background:linear-gradient(90deg,#756e85 0 7%,#b0a9bd 7% 93%,#625c72 93%); }
.tot-house-white::before { background:#4b4764; }
.tot-house-purple { background:linear-gradient(90deg,#573079 0 7%,#8751a8 7% 93%,#462463 93%); }
.tot-house-purple::before { background:#251638; }
.tot-house.is-near { filter:brightness(1.2) drop-shadow(0 0 16px #ffbb45); }
.tot-house.is-cooling { cursor:not-allowed; filter:saturate(.5) brightness(.7); }
.tot-clock { position:fixed; z-index:45; top:88px; left:50%; transform:translateX(-50%); display:flex; gap:9px; align-items:center; padding:8px 15px; border:3px solid #332344; border-radius:999px; background:rgba(22,16,38,.92); color:#fff4da; box-shadow:0 4px 0 rgba(0,0,0,.3); }
.tot-clock strong { font-size:1.2rem; }
.tot-clock span { color:#ffd064; font-weight:900; }
.tot-hud { position:fixed; z-index:45; left:50%; bottom:22px; transform:translateX(-50%); display:flex; align-items:center; gap:9px; width:min(780px,calc(100vw - 28px)); padding:10px 12px; border:3px solid #2c203c; border-radius:16px; background:rgba(25,18,42,.95); color:#fff4dd; box-shadow:0 6px 0 rgba(0,0,0,.34); }
.tot-hud strong { font-size:1.5rem; color:#ffd15e; }
.tot-hud small { padding:5px 8px; border-radius:999px; background:#3b2a50; color:#f9e8ff; font-weight:800; }
.tot-hud .btn { margin-left:auto; min-width:190px; }
.tot-bag { width:34px; height:31px; border:4px solid #2a1d34; border-radius:5px 5px 13px 13px; background:#ef7d28; position:relative; flex:0 0 auto; }
.tot-bag::before { content:""; position:absolute; left:7px; right:7px; top:-16px; height:19px; border:4px solid #2a1d34; border-bottom:0; border-radius:12px 12px 0 0; }
.tot-bag::after { content:""; position:absolute; width:8px; height:6px; left:9px; top:10px; border-radius:0 0 8px 8px; background:#2a1d34; box-shadow:8px 0 #2a1d34; }
.tot-trick-layer { position:fixed; inset:0; z-index:35; pointer-events:none; overflow:hidden; opacity:0; transition:opacity .25s; }
.tot-bats .tot-trick-layer,.tot-fog .tot-trick-layer,.tot-pumpkin .tot-trick-layer,
.tot-ghost .tot-trick-layer,.tot-web .tot-trick-layer,.tot-cat .tot-trick-layer { opacity:1; }
.tot-bats .tot-trick-layer span { position:absolute; width:70px; height:28px; background:#16101f; clip-path:polygon(0 45%,23% 0,50% 43%,77% 0,100% 45%,74% 100%,50% 65%,26% 100%); animation:totBat 2.2s linear infinite; }
.tot-bats .tot-trick-layer span:nth-child(1){top:18%;left:-80px}.tot-bats .tot-trick-layer span:nth-child(2){top:36%;left:-160px;animation-delay:.5s}.tot-bats .tot-trick-layer span:nth-child(3){top:62%;left:-110px;animation-delay:1.1s}
@keyframes totBat { to { transform:translateX(calc(100vw + 260px)) translateY(-80px); } }
.tot-fog .tot-trick-layer { background:radial-gradient(circle at 50% 50%,transparent 12%,rgba(218,214,235,.68) 52%,rgba(188,184,210,.88)); }
.tot-pumpkin .tot-trick-layer span:first-child { position:absolute; left:-120px; bottom:16%; width:105px; height:105px; border:8px solid #33203f; border-radius:48% 52% 46% 54%; background:#ef7a22; animation:totPumpkin 2.8s linear infinite; }
@keyframes totPumpkin { to { transform:translateX(calc(100vw + 250px)) rotate(900deg); } }
.tot-ghost .tot-trick-layer span:first-child { position:absolute; left:50%; top:32%; width:120px; height:145px; transform:translate(-50%,-50%); border-radius:60% 60% 25% 25%; background:rgba(225,244,255,.82); box-shadow:0 0 45px #bcaaff; animation:totGhost 1.4s ease-in-out infinite alternate; }
.tot-ghost .tot-trick-layer span:first-child::before { content:"••"; position:absolute; left:31px; top:35px; color:#382950; font:900 38px/1 monospace; letter-spacing:18px; }
@keyframes totGhost { to { transform:translate(-50%,-60%) rotate(4deg); } }
.tot-web .tot-trick-layer { background:repeating-radial-gradient(circle at 0 0,transparent 0 46px,rgba(235,233,244,.7) 48px 50px,transparent 52px 70px); }
.tot-cat .tot-trick-layer { box-shadow:inset 0 0 90px 20px rgba(255,199,71,.72); animation:totLucky .7s ease-in-out infinite alternate; }
@keyframes totLucky { to { box-shadow:inset 0 0 130px 30px rgba(164,105,255,.62); } }
.tot-results { background:linear-gradient(145deg,#2a173d,#6e3156); color:#fff5df; }
/* The shared card rule colours headings and labels for a light surface; this
   card is always dark, so its text is pinned light in both themes. */
.tot-results h1, .tot-results .num { color:#fff5df; }
.tot-results .lbl, .tot-results .result-energy span { color:#e6d6f2; }
.tot-results .result-energy svg { color:#ffd15e; }
@media (max-width:700px) {
  .tot-title { display:none; }
  .tot-clock { top:72px; }
  .tot-hud { bottom:max(12px,env(safe-area-inset-bottom)); flex-wrap:wrap; gap:6px; }
  .tot-hud .btn { order:5; width:100%; margin-left:0; min-width:0; }
  .tot-hud > span:not(.tot-bag) { font-size:.82rem; }
}


/* ---------- living world (World art v2) ----------
   Shared by every 2D mode; the classes are added by the living-world module
   in api.js. Prop Hunt never gets motion: anything moving that isn't a
   player would be a false clue, and swaying props would expose disguises. */

/* Edge depth: floor patches read as set into the ground. Light comes from
   the top-left, so exposed top/left edges are in shade and bottom/right
   edges catch a lip of light. One rule, four variables. */
.g2d-shaded {
  --edge-n: 0 0 0 transparent; --edge-s: 0 0 0 transparent; --edge-w: 0 0 0 transparent; --edge-e: 0 0 0 transparent;
  box-shadow: var(--edge-n), var(--edge-s), var(--edge-w), var(--edge-e);
}
.g2d-shaded.edge-n { --edge-n: inset 0 calc(var(--g2d-tile) * .09) 0 rgba(17,17,20,.16); }
.g2d-shaded.edge-w { --edge-w: inset calc(var(--g2d-tile) * .06) 0 0 rgba(17,17,20,.11); }
.g2d-shaded.edge-s { --edge-s: inset 0 calc(var(--g2d-tile) * -.05) 0 rgba(255,255,255,.18); }
.g2d-shaded.edge-e { --edge-e: inset calc(var(--g2d-tile) * -.04) 0 0 rgba(255,255,255,.12); }

/* Moving water: the surface drifts slowly while two layers of glints slide
   across it in different directions. Stepped animations repaint ~10 times a
   second instead of every frame, which keeps big oceans cheap on phones. */
.ff-ocean::before, .ff-pond::before {
  content: ''; position: absolute; pointer-events: none;
  top: calc(var(--g2d-tile) * -4); left: calc(var(--g2d-tile) * -4); right: 0; bottom: 0;
  background-image: inherit; background-size: inherit; background-position: var(--wx, 0px) var(--wy, 0px);
  animation: g2dWaterMove64 80s linear infinite;
}
/* Literal pixels (game modes always use a 64px tile), so this runs on the GPU
   and costs nothing to start -- no var() in keyframes. */
@keyframes g2dWaterMove64 { to { transform: translate(256px, 256px); } }
.ff-ocean, .ff-pond { overflow: hidden; }
/* Water and clouds move by transform only: the browser slides an already
   painted layer instead of repainting the sea every step, which is what kept
   school Chromebooks out of 60fps. Each moves one texture period, so it loops
   without a jump. */
@keyframes g2dWaterDrift {
  from { background-position: var(--wx, 0px) var(--wy, 0px); }
  to { background-position: calc(var(--wx, 0px) + var(--g2d-tile) * 4) calc(var(--wy, 0px) + var(--g2d-tile) * 2); }
}
@keyframes g2dWaterGlint {
  from { background-position: 0 0, 0 0; }
  to { background-position: calc(var(--g2d-tile) * 4) 0, calc(var(--g2d-tile) * -5) calc(var(--g2d-tile) * 5); }
}
@keyframes g2dWaterPulse { from { opacity: .45; } to { opacity: 1; } }

/* Plants breathe: trees, bushes and flowers sway from their base, each on
   its own beat so a field never moves in lockstep. */
/* `.live` = on screen (set by api.js): off-screen plants don't animate. */
.g2d-root:not(.ph-root) .g2d-prop-tree.live,
.g2d-root:not(.ph-root) .g2d-prop-bush.live,
.g2d-root:not(.ph-root) .g2d-prop-flower.live,
.g2d-root:not(.ph-root) .g2d-prop-plant.live,
.ff-prop-reeds.live, .ff-prop-lily.live {
  transform-origin: 50% 92%;
  animation: g2dSway 3.6s ease-in-out infinite alternate;
}
.g2d-root:not(.ph-root) .g2d-prop-bush.live, .g2d-root:not(.ph-root) .g2d-prop-flower.live { animation-duration: 2.8s; }
.ff-prop-lily.live { transform-origin: 50% 50%; animation-name: g2dBob; }
:is(.g2d-prop, .ff-prop):nth-child(3n+1) { animation-delay: -1.1s; }
:is(.g2d-prop, .ff-prop):nth-child(3n+2) { animation-delay: -2.3s; }
:is(.g2d-prop, .ff-prop):nth-child(5n) { animation-duration: 4.4s; }
@keyframes g2dSway { from { transform: rotate(-1.6deg); } to { transform: rotate(1.6deg); } }
@keyframes g2dBob { from { transform: translateY(-2px) rotate(-3deg); } to { transform: translateY(2px) rotate(3deg); } }

/* Ambient layer: cloud shadows drift over the whole map; butterflies (day)
   or fireflies (night) wander. Never interactive, never in Prop Hunt. */
.g2d-life { position: absolute; inset: 0; pointer-events: none; z-index: 6; overflow: hidden; }
.g2d-clouds {
  position: absolute; top: 0; bottom: 0; right: 0; left: calc(var(--g2d-tile) * -16);
  background-image: url('ground/cloud-shadows.png?v=20261003-6');
  background-size: calc(var(--g2d-tile) * 16) calc(var(--g2d-tile) * 16);
  /* moved by driftClouds() in api.js */
}
.g2d-butterfly, .g2d-firefly { position: absolute; left: var(--x); top: var(--y); }  /* path: wander() in api.js */
.g2d-butterfly b { display: block; width: 28px; height: 22px; position: relative; }
/* A plain shadow shape, not filter: drop-shadow -- a filter is repainted on
   the CPU every time a wing flaps. */
.g2d-butterfly::after { content: ''; position: absolute; left: 6px; top: 26px; width: 20px; height: 6px; border-radius: 50%; background: rgba(17,17,20,.16); }
.g2d-butterfly b::before, .g2d-butterfly b::after {
  content: ''; position: absolute; top: 0; width: 14px; height: 19px; box-sizing: border-box;
  border: 2.5px solid #111114; background: var(--wing, #ffe24a);
}
.g2d-butterfly.live b::before, .g2d-butterfly.live b::after { animation: g2dFlap .22s ease-in-out infinite alternate; }
.g2d-butterfly b::before { left: 0; border-radius: 70% 20% 50% 60%; transform-origin: 100% 50%; }
.g2d-butterfly b::after { right: 0; border-radius: 20% 70% 60% 50%; transform-origin: 0 50%; }
.g2d-butterfly.c1 { --wing: #ff5c5c; } .g2d-butterfly.c2 { --wing: #67a7ff; } .g2d-butterfly.c3 { --wing: #fff9e8; }
@keyframes g2dFlap { to { transform: scaleX(.3); } }
.g2d-firefly { width: 6px; height: 6px; border-radius: 50%; background: #fff3a0; box-shadow: 0 0 0 3px rgba(255,226,74,.35); }
.g2d-firefly::after { content: ''; position: absolute; inset: 0; border-radius: inherit; background: inherit; }
.g2d-firefly.live::after { animation: g2dBlink 2.4s ease-in-out infinite alternate; }
.g2d-firefly::after { animation-delay: var(--delay); }
@keyframes g2dBlink { 0%, 40% { opacity: .15; } 100% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .ff-ocean::before, .ff-pond::before,
  .g2d-prop, .ff-prop, .g2d-clouds, .g2d-butterfly, .g2d-firefly, .g2d-butterfly b::before, .g2d-butterfly b::after { animation: none !important; }
}

/* Natural ground blends: a soft wavy outline from tools/art/edges.py
   (256 shapes; --ex/--ey picked by api.js) plus a toon rim inside it. */
.g2d-blend { -webkit-mask: url('edges/edge-mask.png?v=20261003-7') no-repeat; mask: url('edges/edge-mask.png?v=20261003-7') no-repeat;
  -webkit-mask-size: 1600% 1600%; mask-size: 1600% 1600%; -webkit-mask-position: var(--ex) var(--ey); mask-position: var(--ex) var(--ey);
  box-shadow: none; border-radius: 0; opacity: 1; }
.g2d-blend::after { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: url('edges/edge-shade.png?v=20261003-7') no-repeat; background-size: 1600% 1600%; background-position: var(--ex) var(--ey); }
.ff-path.g2d-blend { background-size: calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12); }

/* Reel Rush islands: sand beach and foam at a wavy coastline, grass inside. */
.ff-land.g2d-shore { box-shadow: none !important;
  background-image: url('ground/beach.png?v=20261003-5'); background-size: calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12); background-position: var(--wx) var(--wy);
  -webkit-mask: url('edges/coast-mask.png?v=20261003-7') no-repeat; mask: url('edges/coast-mask.png?v=20261003-7') no-repeat;
  -webkit-mask-size: 1600% 1600%; mask-size: 1600% 1600%; -webkit-mask-position: var(--ex) var(--ey); mask-position: var(--ex) var(--ey); }
.ff-land.g2d-shore::before, .ff-land.g2d-shore::after { content: ''; position: absolute; inset: 0; pointer-events: none; }
.ff-land.g2d-shore::after { background: url('edges/beach-foam.png?v=20261003-7') no-repeat; background-size: 1600% 1600%; background-position: var(--ex) var(--ey); }
.ff-land.g2d-shore::before { z-index: 1;
  background-image: url('ground-grass.png?v=20261003-5'); background-size: calc(var(--g2d-tile) * 12) calc(var(--g2d-tile) * 12); background-position: var(--wx) var(--wy);
  -webkit-mask: url('edges/beach-mask.png?v=20261003-7') no-repeat; mask: url('edges/beach-mask.png?v=20261003-7') no-repeat;
  -webkit-mask-size: 1600% 1600%; mask-size: 1600% 1600%; -webkit-mask-position: var(--ex) var(--ey); mask-position: var(--ex) var(--ey); }
/* The masked island, patch and path tiles are static; giving them their own
   compositing layer stops the drifting ocean beneath from repainting them
   (Reel Rush went from ~51 to 61fps on a throttled phone). */
#ffIslands, #ffPatches, #ffPaths { will-change: transform; }

/* Baked ground (api.js paints static ground tiles into a few images). */
.g2d-baked { position: absolute; display: block; max-width: none; pointer-events: none; user-select: none; }

/* Lite graphics: picked automatically on devices that can't hold a smooth
   frame rate (see api.js), or forced with localStorage buzzkitGfx = "lite".
   The world looks the same, it just stands still. */
.g2d-lite .g2d-life, .g2d-lite .race-life { display: none !important; }
.g2d-lite .ff-ocean::before, .g2d-lite .ff-pond::before, .g2d-lite .race-water-fx::before { display: none; }
.g2d-lite .ff-ocean::before, .g2d-lite .ff-pond::before, .g2d-lite .race-water-fx::before,
.g2d-lite .g2d-prop, .g2d-lite .ff-prop, .g2d-lite .race-prop i { animation: none !important; }

/* Ground waiting to be baked is not rendered at all: masked tiles are costly
   to style and paint, and each one appears as part of its baked image. */
.g2d-unbaked > .g2d-blend, .g2d-unbaked > .g2d-shore { display: none; }
/* While the ground is painted, the mode's loading screen covers everything
   (same look as the asset loading screen), then fades away. */
.g2d-map-loading {
  position: fixed; inset: 0; z-index: 1000; min-height: 0; margin: 0;
  background: var(--bg); color: var(--text); transition: opacity .2s ease;
}
.g2d-map-loading.is-done { opacity: 0; pointer-events: none; }

/* ---------- What's new popup (js/whats-new.js) ---------- */
.wn-card { width: min(620px, 96vw); }
.wn-hero { display: block; width: 100%; height: auto; aspect-ratio: 1200 / 433; margin: 0 0 18px; border: 3px solid var(--edge); border-radius: 10px; object-fit: cover; background: var(--panel-2); }
.wn-sections { display: grid; gap: 18px; margin-bottom: 20px; }
.wn-section h3 { display: flex; align-items: center; gap: 9px; margin: 0 0 8px; padding-bottom: 6px; border-bottom: 2px solid var(--border); font-size: 1.05rem; color: var(--surface-ink); }
.wn-section-icon { display: inline-grid; place-items: center; width: 28px; height: 28px; flex: none; border: 2px solid var(--edge); border-radius: 7px; background: var(--yellow); color: var(--edge); }
.wn-section-icon .icon { width: 16px; height: 16px; }
.wn-section ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 7px; }
.wn-section li { display: flex; align-items: baseline; gap: 10px; color: var(--surface-ink); font-weight: 650; line-height: 1.4; }
.wn-tag { flex: none; width: 82px; box-sizing: border-box; padding: 2px 6px; border: 2px solid var(--edge); border-radius: 4px; color: var(--edge); font-size: .68rem; font-weight: 900; letter-spacing: .05em; text-align: center; text-transform: uppercase; }
.wn-tag-new { background: var(--mint); }
.wn-tag-better { background: #67a7ff; }
.wn-tag-changed { background: var(--yellow); }
.wn-tag-fixed { background: var(--coral); }
.wn-earlier { margin: 0 0 16px; border-top: 2px solid var(--border); padding-top: 12px; }
.wn-earlier summary { cursor: pointer; font-weight: 850; color: var(--surface-ink); }
.wn-release h3 { margin: 14px 0 4px; color: var(--surface-ink); }
.wn-release h3 small { font-weight: 700; color: var(--text-soft); margin-left: 6px; }
.side-link-button { width: 100%; }
.wn-join-link { margin-top: 18px; }
.link-button { display: inline-flex; align-items: center; gap: 6px; border: 0; background: none; padding: 6px; color: var(--surface-link, var(--accent)); font: inherit; font-weight: 800; cursor: pointer; text-decoration: underline; }
.link-button .icon { width: 16px; height: 16px; }

/* ---------- Moderation, removed sets, set page extras (2026-10-21) ---------- */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.visibility-badge.is-removed { background: var(--coral); }
.visibility-badge.is-flagged { background: var(--yellow); }
.set-removed-notice { margin-bottom: 18px; border-color: var(--coral); }
.set-removed-notice p { margin: 6px 0 0; }
.set-more { margin-top: 6px; margin-bottom: 36px; }
.set-more h2 { margin: 0 0 14px; }
.set-more > p { margin-top: 18px; }
.mod-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin: 18px 0 10px; }
.mod-filters { display: flex; flex-wrap: wrap; gap: 8px; }
.mod-filters .btn, .mod-actions .btn { min-height: 44px; padding: 8px 14px; font-size: .82rem; }
.mod-actions { display: flex; gap: 6px; justify-content: flex-end; }
.analytics-table td.mod-wrap { white-space: normal; min-width: 220px; max-width: 380px; }
.mod-flag { display: block; margin-top: 6px; color: var(--text-soft); font-size: .76rem; white-space: normal; }
.mod-check { display: flex; gap: 10px; align-items: center; min-height: 44px; font-weight: 700; color: var(--text); }
.mod-check input { width: 20px; height: 20px; }
#modDialog .flex-row { gap: 10px; margin-top: 8px; }
