/* ═══════════════════════════════════════════════════════════════
   ARROW TRACE — Multi-Theme Engine
   Themes: Amber (default) · Jungle · Sky Blue · Midnight · Rose Blush
           — each theme owns one fixed background image (--bg-image)
           and a color scheme tuned directly to that art's own
           accent colors, so every button/icon/text stays clearly
           readable on top of it. ─────────────────────────────────
═══════════════════════════════════════════════════════════════ */
/* Fonts: Crimson Pro and DM Sans are loaded via Google Fonts CDN (external network request required).
   CDN URL: https://fonts.googleapis.com
   To bundle fonts locally instead: download the font files, place them in a /fonts/ folder,
   remove this @import, and replace with @font-face declarations pointing to the local files. */
@import url("https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600&family=DM+Sans:wght@300;400;500&display=swap");
/* Cartoonic Mode font (Settings → Appearance → Cartoonic Mode) */
@import url("https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700;800&display=swap");
/* ── LAYOUT UTILITY CLASSES (replaces inline style attributes) ────── */
.hidden-init {
  display: none;
}

.svg-defs-hidden {
  position: absolute;
  overflow: hidden;
}
/* ─────────────────────────────────────────────────────────────────── */

/* ── THEME: AMBER (default) — bg-amber.webp — warm cream scene with
   an orange lollipop/leaf border. Deep burnt-orange ink on the
   cream paper reads cleanly straight off the art itself ──────── */
:root,
body[data-theme="warm"] {
  --game-sidebar-w: clamp(96px, 12vw, 152px);
  --bg-image: url("../images/bg-amber.webp");
  --paper: #fff8f0;
  --paper2: #fbe8d3;
  --paper3: #f0cd9e;
  --ink: #7a3410;
  --ink-mid: #834216;
  --ink-dim: #9d612f;
  --ink-faint: #edc79a;
  --accent: #e8720f;
  --accent-lt: #f5934a;
  --accent-bg: rgba(232, 114, 15, 0.14);
  --blue: #e8720f;
  --blue-lt: rgba(232, 114, 15, 0.1);
  --row-hl: rgba(232, 114, 15, 0.07);
  --same-hl: rgba(232, 114, 15, 0.14);
  --error-bg: rgba(200, 30, 30, 0.12);
  --error-txt: #c81e1e;
  --success: #2f8a4a;
  --given-bg: rgba(122, 52, 16, 0.06);
  --grid-thin: #f0cd9e;
  --grid-thick: #dba766;
  --box-border: #7a3410;
  --cell-bg: #fffdf9;
  --grid-bg: #fffdf9;
  --shadow: 0 4px 20px rgba(120, 52, 16, 0.16);
  --radius: 8px;
  --screen-bg: transparent;
  --card-bg: rgba(255, 255, 255, 0.72);
  --card-border: #f0cd9e;
  --btn-primary-bg: #e8720f;
  --btn-primary-color: #fff8f0;
  --btn-icon-white: #fffaf4;
  --bg-overlay: rgba(120, 52, 16, 0.05);
  --grid-wrap-bg: #fbe8d3;
  --grid-wrap-shadow: 0 8px 32px rgba(120, 52, 16, 0.18);
  --grid-wrap-border: #e0b37e;
}

/* ── THEME: JUNGLE — bg-jungle.webp — pastel blue sky with green
   and violet meadow hills. Deep indigo ink stays crisp against the
   light sky-blue paper and the art's own blue/purple palette ──── */
body[data-theme="jungle"] {
  --bg-image: url("../images/bg-jungle.webp");
  --paper: #f7f9fc;
  --paper2: #e9eef8;
  --paper3: #cdd9ef;
  --ink: #16264f;
  --ink-mid: #293962;
  --ink-dim: #4c5b86;
  --ink-faint: #c3ceec;
  --accent: #3d5fdb;
  --accent-lt: #6a86e8;
  --accent-bg: rgba(61, 95, 219, 0.14);
  --blue: #3d5fdb;
  --blue-lt: rgba(61, 95, 219, 0.1);
  --row-hl: rgba(61, 95, 219, 0.07);
  --same-hl: rgba(61, 95, 219, 0.14);
  --error-bg: rgba(200, 30, 30, 0.12);
  --error-txt: #c81e1e;
  --success: #2f8a4a;
  --given-bg: rgba(22, 38, 79, 0.06);
  --grid-thin: #cdd9ef;
  --grid-thick: #93aee0;
  --box-border: #16264f;
  --cell-bg: #fdfeff;
  --grid-bg: #fdfeff;
  --shadow: 0 4px 20px rgba(20, 40, 90, 0.16);
  --radius: 8px;
  --screen-bg: transparent;
  --card-bg: rgba(255, 255, 255, 0.72);
  --card-border: #cdd9ef;
  --btn-primary-bg: #3d5fdb;
  --btn-primary-color: #f7f9fc;
  --btn-icon-white: #fbfdff;
  --bg-overlay: rgba(20, 40, 90, 0.05);
  --grid-wrap-bg: #e9eef8;
  --grid-wrap-shadow: 0 8px 32px rgba(20, 40, 90, 0.18);
  --grid-wrap-border: #a9bde3;
}

/* ── THEME: SKY BLUE — bg-obsidian.webp — mint/coral/violet confetti
   scene. Deep teal ink on a mint-tinted paper pulls its color right
   from the art's strongest recurring accent ───────────────────── */
body[data-theme="neon"] {
  --bg-image: url("../images/bg-obsidian.webp");
  --paper: #fbfdfa;
  --paper2: #e6f5ee;
  --paper3: #c3e8d8;
  --ink: #0b4a3d;
  --ink-mid: #165e4e;
  --ink-dim: #3c7a6c;
  --ink-faint: #b9e2d4;
  --accent: #0f9c7e;
  --accent-lt: #3ec2a1;
  --accent-bg: rgba(15, 156, 126, 0.14);
  --blue: #0f9c7e;
  --blue-lt: rgba(15, 156, 126, 0.1);
  --row-hl: rgba(15, 156, 126, 0.07);
  --same-hl: rgba(15, 156, 126, 0.14);
  --error-bg: rgba(200, 30, 30, 0.12);
  --error-txt: #c81e1e;
  --success: #2f8a4a;
  --given-bg: rgba(11, 74, 61, 0.06);
  --grid-thin: #c3e8d8;
  --grid-thick: #7cc7ac;
  --box-border: #0b4a3d;
  --cell-bg: #ffffff;
  --grid-bg: #ffffff;
  --shadow: 0 4px 20px rgba(11, 74, 61, 0.15);
  --radius: 8px;
  --screen-bg: transparent;
  --card-bg: rgba(255, 255, 255, 0.72);
  --card-border: #c3e8d8;
  --btn-primary-bg: #0f9c7e;
  --btn-primary-color: #ffffff;
  --btn-icon-white: #ffffff;
  --bg-overlay: rgba(11, 74, 61, 0.05);
  --grid-wrap-bg: #e6f5ee;
  --grid-wrap-shadow: 0 8px 32px rgba(11, 74, 61, 0.15);
  --grid-wrap-border: #8ecdb4;
}

/* ── THEME: MIDNIGHT — bg-midnight.webp — black candy-party scene
   with gold, purple and teal sweets in the corners. A dark paper
   with warm gold ink (lifted from the art's own gold candy) and a
   violet accent (from the art's purple candy) keeps this the one
   true dark theme ───────────────────────────────────────────── */
body[data-theme="midnight"] {
  --bg-image: url("../images/bg-midnight.webp");
  --paper: #121016;
  --paper2: #1b1720;
  --paper3: #2a2433;
  --ink: #f2c14e;
  --ink-mid: #d9a53f;
  --ink-dim: #a8823f;
  --ink-faint: #4a3f2a;
  --accent: #a870d8;
  --accent-lt: #c79bea;
  --accent-bg: rgba(168, 112, 216, 0.18);
  --blue: #a870d8;
  --blue-lt: rgba(168, 112, 216, 0.12);
  --row-hl: rgba(168, 112, 216, 0.08);
  --same-hl: rgba(168, 112, 216, 0.16);
  --error-bg: rgba(220, 60, 50, 0.18);
  --error-txt: #ff8a75;
  --success: #4fd88a;
  --given-bg: rgba(242, 193, 78, 0.06);
  --grid-thin: #2a2433;
  --grid-thick: #4a3f5e;
  --box-border: #f2c14e;
  --cell-bg: #1a1620;
  --grid-bg: #100e14;
  --shadow: 0 8px 40px rgba(0, 0, 0, 0.55);
  --radius: 8px;
  --screen-bg: transparent;
  --card-bg: rgba(18, 16, 22, 0.82);
  --card-border: #2a2433;
  --btn-primary-bg: #a870d8;
  --btn-primary-color: #14121a;
  --btn-icon-white: #fff6e0;
  --bg-overlay: rgba(0, 0, 0, 0.35);
  --grid-wrap-bg: #1b1720;
  --grid-wrap-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  --grid-wrap-border: #4a3f5e;
}

/* ════════════════════════════════════════════════
   THEME: ROSE BLUSH (5th theme, key stays "rosegold")
   bg-crimson.webp — cream candy scene with a coral
   lollipop and pink/teal/gold sweets in the corners
════════════════════════════════════════════════ */
body[data-theme="rosegold"] {
  --bg-image: url("../images/bg-crimson.webp");
  --paper: #fffaf7;
  --paper2: #fbe9e4;
  --paper3: #f3cec3;
  --ink: #7a2a30;
  --ink-mid: #83363b;
  --ink-dim: #b3494f;
  --ink-faint: #edc3c0;
  --accent: #d9506a;
  --accent-lt: #ea7d90;
  --accent-bg: rgba(217, 80, 106, 0.14);
  --blue: #d9506a;
  --blue-lt: rgba(217, 80, 106, 0.1);
  --row-hl: rgba(217, 80, 106, 0.07);
  --same-hl: rgba(217, 80, 106, 0.14);
  --error-bg: rgba(200, 30, 30, 0.12);
  --error-txt: #c81e1e;
  --success: #2f8a4a;
  --given-bg: rgba(122, 42, 48, 0.06);
  --grid-thin: #f3cec3;
  --grid-thick: #dd9a95;
  --box-border: #7a2a30;
  --cell-bg: #fffdfb;
  --grid-bg: #fffdfb;
  --shadow: 0 4px 20px rgba(122, 42, 48, 0.16);
  --radius: 8px;
  --screen-bg: transparent;
  --card-bg: rgba(255, 255, 255, 0.72);
  --card-border: #f3cec3;
  --btn-primary-bg: #d9506a;
  --btn-primary-color: #fffaf7;
  --btn-icon-white: #fffaf7;
  --bg-overlay: rgba(122, 42, 48, 0.05);
  --grid-wrap-bg: #fbe9e4;
  --grid-wrap-shadow: 0 8px 32px rgba(122, 42, 48, 0.18);
  --grid-wrap-border: #e3aca3;
}

/* Monochrome brand — no text-shadow (logo/headings stay flat per theme ink color) */

/* Monochrome popup rule line */
body[data-theme="rosegold"] .popup-rule-line {
  background: var(--accent);
  opacity: 0.6;
}

/* Monochrome — accent-colored text is too close to the background to
   read; keep the accent underline but lighten the label itself. */
body[data-theme="rosegold"] .lb-tab.active {
  color: var(--ink);
}

/* Rose Blush theme preview */
.theme-preview--rosegold {
  background: #f3cec3;
  border: 1.5px solid #d9506a;
  position: relative;
  overflow: hidden;
}
.theme-preview--rosegold .tp-grid {
  border-color: #7a2a30;
  border-radius: 3px;
  overflow: hidden;
}
.theme-preview--rosegold .tp-cell {
  background: #fffdfb;
  border-right: 1px solid #f3cec3;
  border-bottom: 1px solid #f3cec3;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(9px, 2.5vw, 13px);
  font-weight: 600;
  color: #d9506a;
  aspect-ratio: 1;
}
.theme-preview--rosegold .tp-cell.tp-given {
  background: rgba(122, 42, 48, 0.06);
  color: #7a2a30;
}
.theme-preview--rosegold .tp-cell.tp-sel {
  background: rgba(217, 80, 106, 0.18);
  color: #d9506a;
}
.theme-preview--rosegold .tp-cell.tp-br {
  border-right: 2px solid #dd9a95;
}
.theme-preview--rosegold .tp-cell.tp-bb {
  border-bottom: 2px solid #dd9a95;
}

/* ════════════════════════════════════════════════
   PARTICLES CANVAS
════════════════════════════════════════════════ */
#particles-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
}

/* ════════════════════════════════════════════════
   CONFETTI CANVAS (complete screen)
════════════════════════════════════════════════ */
#confetti-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}
#s-complete > *:not(#confetti-canvas) {
  position: relative;
  z-index: 1;
}

/* NOTE: .lobby-xp-bar / .lobby-xp-level / .lobby-xp-track / .lobby-xp-fill /
   .lobby-xp-pts are styled in the LOBBY SCREEN section below, as part of
   the dashboard card design. */

/* ════════════════════════════════════════════════
   ACHIEVEMENT BADGES (lobby)
════════════════════════════════════════════════ */
.lobby-badges {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
  max-width: 340px;
  margin-bottom: 0;
  min-height: 0;
}
.lobby-badge {
  padding: 4px 10px;
  background: var(--card-bg);
  border: 1px solid var(--ink-faint);
  border-radius: 20px;
  font-size: 0.52rem;
  letter-spacing: 0.15em;
  color: var(--ink-dim);
  text-transform: uppercase;
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  gap: 5px;
  animation: badgePop 0.35s cubic-bezier(0.34, 1.4, 0.64, 1) both;
}
.lobby-badge.gold {
  border-color: var(--accent);
  color: var(--accent);
}
@keyframes badgePop {
  from {
    opacity: 0;
    transform: scale(0.7);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* Achievement banner on complete screen */
.achievement-banner {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0;
  max-width: 300px;
  width: 100%;
}
.achievement-item {
  padding: 8px 14px;
  background: var(--accent-bg);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  color: var(--accent);
  text-transform: uppercase;
  text-align: center;
  animation: badgePop 0.4s cubic-bezier(0.34, 1.4, 0.64, 1) both;
}

/* ════════════════════════════════════════════════
   XP display on complete screen
════════════════════════════════════════════════ */
#comp-xp {
  color: var(--success) !important;
}

/* ════════════════════════════════════════════════
   HINTS REMAINING display
════════════════════════════════════════════════ */
#hints-remaining-wrap {
  display: none;
}
#hints-remaining-wrap.visible {
  display: flex;
  flex-direction: column;
}

/* ════════════════════════════════════════════════
   TIME ATTACK BAR
════════════════════════════════════════════════ */
.time-attack-bar {
  width: 100%;
  max-width: 520px;
  height: 3px;
  background: var(--ink-faint);
  display: none;
  margin-bottom: 4px;
  border-radius: 2px;
  overflow: hidden;
  align-self: center;
}
.time-attack-bar.visible {
  display: block;
}
.time-attack-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
  transition:
    width 1s linear,
    background 0.5s;
  width: 100%;
}
.time-attack-fill.danger {
  background: var(--error-txt);
}

/* ════════════════════════════════════════════════
   CLASSIC PUZZLE — difficulty-screen options
   (Unlimited Hints / Chances Mode checkboxes)
════════════════════════════════════════════════ */
.diff-options-panel {
  width: 100%;
  max-width: 360px;
  margin: 6px auto 18px;
  padding: 12px 16px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 12px;
  display: flex;
  flex-direction: row;
  gap: 14px;
}
.diff-option-item {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  flex: 1 1 0;
  min-width: 0;
}
.diff-option-item + .diff-option-item {
  padding-left: 14px;
  border-left: 1px solid var(--card-border);
}
.diff-option-box {
  width: 22px;
  height: 22px;
  border: 1.5px solid var(--ink-faint);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  flex-shrink: 0;
  color: white;
}
.diff-option-box svg {
  width: 14px;
  height: 14px;
}
.diff-option-item.on .diff-option-box {
  background: var(--accent);
  border-color: var(--accent);
}
.diff-option-lbl {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.3;
}
.diff-option-sub {
  font-size: 0.66rem;
  color: var(--ink-dim);
  margin-top: 1px;
  line-height: 1.3;
}

/* ════════════════════════════════════════════════
   2D/3D SKIN PICKER — embedded on the difficulty screen
   (no separate skin-select screen)
════════════════════════════════════════════════ */
.skin-panel-2d3d {
  width: 100%;
  max-width: 360px;
  margin: 0 auto 18px;
}
.panel-section-label {
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-align: center;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: 10px;
}
/* 2-button segmented toggle — switches between 2D Skins / 3D Skins on
   the shared 2D/3D difficulty screen, replacing the old separate
   skin-select screen. */
.skin-mode-toggle-row {
  display: flex;
  gap: 8px;
  width: 100%;
  margin-bottom: 12px;
}
.skin-mode-toggle-btn {
  flex: 1;
  padding: 10px 8px;
  font-family: inherit;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
  background: var(--card-bg);
  border: 1.5px solid var(--card-border);
  border-radius: var(--radius);
  cursor: pointer;
  transition:
    border-color 0.2s,
    color 0.2s,
    background 0.2s;
}
.skin-mode-toggle-btn:hover {
  border-color: var(--accent);
}
.skin-mode-toggle-btn.active {
  color: var(--ink);
  border-color: var(--accent);
  background: var(--accent-bg);
}

/* ════════════════════════════════════════════════
   CUSTOM PUZZLE IMPORT ROW
════════════════════════════════════════════════ */
.import-row {
  width: 100%;
  max-width: 360px;
  margin-bottom: 12px;
}
.import-toggle {
  background: none;
  border: none;
  color: var(--ink-dim);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  transition: color 0.18s;
}
.import-toggle:hover {
  color: var(--accent);
}
.import-toggle svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
}
.import-panel {
  display: none;
  gap: 8px;
  margin-top: 8px;
}
.import-panel.open {
  display: flex;
}
.import-input {
  flex: 1;
  padding: 8px 12px;
  background: var(--card-bg);
  border: 1px solid var(--ink-faint);
  border-radius: var(--radius);
  color: var(--ink);
  font-family: monospace;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  outline: none;
  backdrop-filter: blur(8px);
  transition: border-color 0.18s;
}
.import-input:focus {
  border-color: var(--accent);
}
.import-btn {
  padding: 8px 16px;
  background: rgba(255, 255, 255, 0.92);
  border: none;
  border-radius: var(--radius);
  color: var(--ink);
  font-size: 0.72rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.18s;
  white-space: nowrap;
}
.import-btn:hover {
  background: var(--accent);
  color: var(--btn-primary-color);
}

/* ════════════════════════════════════════════════
   LEADERBOARD SCREEN
════════════════════════════════════════════════ */
#s-leaderboard,
#s-achievements {
  justify-content: flex-start;
  align-items: stretch;
  padding: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

#s-leaderboard .page-header,
#s-achievements .page-header {
  align-self: center;
  flex-shrink: 0;
  width: 100%;
  max-width: 460px;
}

#s-leaderboard .lb-tabs,
#s-leaderboard .lb-clear {
  align-self: center;
}

#s-leaderboard .lb-list,
#s-achievements .lb-list {
  align-self: center;
}
.lb-tabs {
  display: flex;
  gap: 0;
  max-width: 460px;
  align-self: center;
  width: 100%;
  padding: 12px clamp(18px, 5vw, 32px) 0;
}
.lb-tab {
  flex: 1;
  padding: 8px;
  background: none;
  border: none;
  border-bottom: 2px solid var(--ink-faint);
  color: var(--ink-dim);
  font-family: "DM Sans", sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  cursor: pointer;
  transition: all 0.18s;
}
.lb-tab.active {
  border-bottom-color: var(--accent);
  color: var(--accent);
}
.lb-list {
  flex: 1;
  max-width: 460px;
  align-self: center;
  width: 100%;
  padding: clamp(14px, 3vw, 20px) clamp(18px, 5vw, 32px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
}
.lb-entry {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--radius);
  backdrop-filter: blur(8px);
  animation: badgePop 0.3s cubic-bezier(0.34, 1.4, 0.64, 1) both;
}
.lb-rank {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink-dim);
  min-width: 24px;
  text-align: center;
}
.lb-entry:nth-child(1) .lb-rank {
  color: #d4a820;
}
.lb-entry:nth-child(2) .lb-rank {
  color: #a0a8b0;
}
.lb-entry:nth-child(3) .lb-rank {
  color: #c07840;
}
.lb-time {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--accent);
  flex: 1;
}
.lb-meta {
  font-size: 0.55rem;
  letter-spacing: 0.2em;
  color: var(--ink-dim);
  text-transform: uppercase;
  text-align: right;
}
.lb-empty {
  text-align: center;
  color: var(--ink-dim);
  font-size: 0.75rem;
  padding: 40px 0;
  letter-spacing: 0.1em;
}
.lb-clear {
  align-self: center;
  background: none;
  border: 1px solid var(--ink-faint);
  border-radius: var(--radius);
  color: var(--ink-dim);
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 7px 16px;
  cursor: pointer;
  margin: 0 0 24px;
  transition: all 0.18s;
}
.lb-clear:hover {
  border-color: var(--error-txt);
  color: var(--error-txt);
}

/* ════════════════════════════════════════════════
   ACHIEVEMENTS PAGE (reuses .lb-list / .lb-entry)
════════════════════════════════════════════════ */
.lb-entry.locked {
  opacity: 0.45;
}
.lb-entry.locked .lb-rank {
  color: var(--ink-faint);
}
.lb-entry.locked .lb-time {
  color: var(--ink-dim);
}
.lb-entry.ach-entry .lb-rank svg {
  width: 1.3em;
  height: 1.3em;
  fill: currentColor;
}
.lb-entry:not(.locked).ach-entry .lb-rank {
  color: var(--accent);
}

/* "See More" pill in the lobby badges row */
.lobby-badge-more {
  cursor: pointer;
  font-family: "DM Sans", sans-serif;
  border-color: var(--accent);
  color: var(--accent);
}
.lobby-badge-more:hover {
  background: var(--accent-bg);
}

/* ════════════════════════════════════════════════
   AD POPUP SCREEN
════════════════════════════════════════════════ */

/* Ad popup — full-screen layout, no card wrapper */
.sponsor-card {
  max-width: 400px !important;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
}

.sponsor-header {
  text-align: center;
  margin-bottom: 20px;
  width: 100%;
}
.sponsor-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.7rem, 7.5vw, 3.2rem);
  font-weight: 600;
  color: var(--ink);
  line-height: 1.15;
  margin-bottom: 6px;
  white-space: normal;
}
.sponsor-title br {
  content: "";
}
.sponsor-sub {
  font-size: 0.62rem;
  letter-spacing: 0.28em;
  color: var(--ink-mid);
  text-transform: uppercase;
}

.sponsor-slot-wrap {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  margin-bottom: 20px;
}
.sponsor-slot-label {
  font-size: 0.5rem;
  letter-spacing: 0.4em;
  color: var(--ink-mid);
  text-transform: uppercase;
  align-self: center;
  text-align: center;
}
.sponsor-iframe {
  width: 300px;
  height: 250px;
  border: 0;
  display: block;
}
.sponsor-slot {
  width: 300px;
  height: 250px;
  border: 1.5px dashed var(--accent);
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
}
.sponsor-placeholder {
  text-align: center;
  color: var(--ink-dim);
  padding: 20px;
}
.sponsor-placeholder-size {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--accent);
  margin-bottom: 8px;
  letter-spacing: 0.04em;
}
.sponsor-placeholder-hint {
  font-size: 0.65rem;
  letter-spacing: 0.08em;
  line-height: 1.7;
  color: var(--ink-mid);
}

.sponsor-footer {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
}
.sponsor-thanks {
  font-size: 0.5rem;
  letter-spacing: 0.4em;
  color: var(--ink-mid);
  text-transform: uppercase;
}
.sponsor-skip-btn {
  padding: 0.75em 2em;
  background: rgba(255, 255, 255, 0.92);
  border: none;
  border-radius: var(--radius);
  color: var(--ink);
  font-family: "DM Sans", sans-serif;
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  cursor: pointer;
  transition:
    background 0.2s,
    opacity 0.2s;
  width: 100%;
}
.sponsor-skip-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.sponsor-skip-btn:not(:disabled):hover {
  background: var(--accent);
  color: var(--btn-primary-color);
}

/* ════════════════════════════════════════════════
   STAT-TIME hidden state (when timer disabled)
════════════════════════════════════════════════ */
#stat-time-wrap.hidden {
  display: none;
}

/* ════════════════════════════════════════════════
   RESET & BASE
════════════════════════════════════════════════ */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100%;
  height: 100%;
  color: var(--ink);
  font-family: "DM Sans", system-ui, sans-serif;
  overflow: hidden;
  transition:
    background 0.4s,
    color 0.4s;
}

/* ── BACKGROUND: fixed per-theme image + matching gradient overlay ─── */
/* Each theme now owns exactly one background image (--bg-image),
   set alongside its color variables above. No user-facing picker. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  background-image: var(--bg-image);
  background-size: cover;
  background-position: center;
  z-index: -2;
}

body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: var(--bg-overlay);
  z-index: -1;
  transition: background 0.4s;
}

/* Neon City — subtle scanline texture layered over its image */
body[data-theme="neon"]::after {
  background-image:
    repeating-linear-gradient(
      0deg,
      transparent,
      transparent 2px,
      rgba(6, 96, 214, 0.025) 2px,
      rgba(6, 96, 214, 0.025) 4px
    ),
    var(--bg-image);
  background-size: auto, cover;
  background-position: auto, center;
}

/* ════════════════════════════════════════════════
   SCREENS
════════════════════════════════════════════════ */
.screen {
  position: fixed;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: safe center;
  justify-content: safe center;
  padding: 20px;
  overflow-y: auto;
  transition:
    opacity 0.35s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  background: transparent;
}
.screen.out {
  opacity: 0;
  pointer-events: none;
  transform: scale(0.97) translateY(10px);
}
/* Arrow tiles set pointer-events:all on their hit rects (below) so they
   stay clickable even under other layered elements *while the game
   screen is showing*. But once the game screen itself is hidden (e.g.
   quitting back to the lobby, or any "out" screen), that override was
   winning over `.screen.out`'s pointer-events:none, leaving an
   invisible, still-clickable leftover arrow board sitting on top of
   whatever screen came next — freezing every button underneath it.
   This re-disables them whenever their screen is "out". */
.screen.out .arrow-tile-hit,
.screen.out .arrow-tile {
  pointer-events: none;
}

#s-loading {
  background: transparent;
}

/* ════════════════════════════════════════════════
   SHARED BRAND
════════════════════════════════════════════════ */
.loading-logo {
  display: block;
  width: clamp(130px, 55vw, 420px);
  aspect-ratio: 788 / 322;
  margin: 0 auto clamp(14px, 2.5vh, 22px);
  background-image: url("../images/logo/logo-warm.webp");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
body[data-theme="jungle"] .loading-logo {
  background-image: url("../images/logo/logo-jungle.webp");
}
body[data-theme="neon"] .loading-logo {
  background-image: url("../images/logo/logo-neon.webp");
}
body[data-theme="midnight"] .loading-logo {
  background-image: url("../images/logo/logo-midnight.webp");
}
body[data-theme="rosegold"] .loading-logo {
  background-image: url("../images/logo/logo-rosegold.webp");
}
.brand-logo {
  display: block;
  width: clamp(130px, 55vw, 420px);
  height: auto;
  margin: 0 auto clamp(14px, 2.5vh, 22px);
}
.brand {
  text-align: center;
}

.loading-sub {
  font-size: clamp(0.65rem, 2.2vw, 0.85rem);
  letter-spacing: 0.55em;
  text-indent: 0.55em;
  text-align: center;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: clamp(24px, 5vh, 40px);
}
.brand-sub {
  font-size: clamp(0.65rem, 2.2vw, 0.85rem);
  letter-spacing: 0.55em;
  text-indent: 0.55em;
  text-align: center;
  color: var(--ink);
  text-transform: uppercase;
  margin-bottom: clamp(30px, 6vh, 52px);
}

/* Every theme's logo/heading text simply uses that theme's own --ink
   color with no glow/shadow, so it reads as flat, clean text sitting
   directly on the wallpaper (each was chosen for contrast against
   that theme's own background art). */

/* ════════════════════════════════════════════════
   LOADING SCREEN
════════════════════════════════════════════════ */
#s-loading {
  gap: 0;
  z-index: 50;
}

.loading-bar-wrap {
  width: clamp(160px, 44vw, 240px);
  height: 2px;
  background: var(--ink-faint);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 16px;
}
.loading-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--accent), var(--accent-lt));
  border-radius: 2px;
  transition: width 0.08s linear;
}
.loading-hint {
  font-size: 0.6rem;
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-align: center;
  color: var(--ink-dim);
  text-transform: uppercase;
}

/* ════════════════════════════════════════════════
   LOBBY SCREEN
════════════════════════════════════════════════ */
#s-lobby {
  padding: clamp(18px, 4vh, 32px);
  gap: 0;
}

/* ── Corner-pinned icon buttons ── */
.lobby-corner {
  position: absolute;
  z-index: 6;
  display: flex;
  gap: clamp(16px, 3vh, 22px);
}
.lobby-corner-tl {
  top: clamp(16px, 4vh, 28px);
  left: clamp(16px, 4vw, 28px);
  flex-direction: column;
  align-items: flex-start;
}
.lobby-corner-tr {
  top: clamp(16px, 4vh, 28px);
  right: clamp(16px, 4vw, 28px);
  flex-direction: column;
  align-items: flex-end;
}
.lobby-corner-bl {
  bottom: clamp(16px, 4vh, 28px);
  left: clamp(16px, 4vw, 28px);
  flex-direction: column;
  align-items: flex-start;
}
.lobby-corner-br {
  bottom: clamp(16px, 4vh, 28px);
  right: clamp(16px, 4vw, 28px);
  flex-direction: column;
  align-items: flex-end;
}

/* ── Tablet and below: corner buttons move out of the fixed corners
   and sit as two centered rows (4 buttons each) below the mode chips ── */
@media (max-width: 1024px) {
  #s-lobby {
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "hero hero"
      "tl tr"
      "bottom bottom";
    row-gap: clamp(12px, 2.5vh, 20px);
    column-gap: clamp(16px, 4vw, 24px);
    align-items: center;
  }
  .lobby-hero {
    grid-area: hero;
  }
  .lobby-corner {
    position: static;
    flex-direction: row;
    align-items: center;
    gap: clamp(16px, 4vw, 24px);
  }
  .lobby-corner-tl {
    grid-area: tl;
    justify-self: end;
  }
  .lobby-corner-tr {
    grid-area: tr;
    justify-self: start;
  }
  /* Bottom corners (Info + Settings + Stats) live in one shared row that
     spans both columns. Centering that row as a single flex line keeps
     all three buttons together in the middle of the screen with even
     spacing — the old per-column end/start split jammed the lone Info
     button against the center and pushed the pair toward the right edge. */
  .lobby-corner-row {
    grid-area: bottom;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(16px, 4vw, 24px);
  }
}

/* ── Hero zone: brand + tagline + play button + mode chips, centered by
   the .screen base flex rules ── */
.lobby-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.lobby-hero-tag {
  font-size: clamp(0.6rem, 2vw, 0.78rem);
  letter-spacing: 0.45em;
  text-indent: 0.45em;
  color: var(--ink-dim);
  text-transform: uppercase;
  padding: 7px 18px;
  border: 1px solid var(--ink-faint);
  border-radius: 20px;
  background: var(--card-bg);
  backdrop-filter: blur(8px);
  margin-top: clamp(4px, 1.2vh, 10px);
  margin-bottom: clamp(10px, 2.5vh, 20px);
}

/* ── Mode preview chips under the play button ── */
.lobby-mode-chips {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: clamp(14px, 3vh, 24px);
}
.lobby-mode-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  background: rgba(255, 255, 255, 0.82);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 24px;
  backdrop-filter: blur(8px);
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  color: var(--ink-mid);
}
.lobby-mode-chip svg {
  width: 19px;
  height: 19px;
  fill: var(--accent);
  flex-shrink: 0;
}

/* Midnight — chip stays white, but this theme's ink is gold (too
   washed out on a white chip), so give it the same fixed dark-purple
   tint used for icon-btn/pill buttons. Every other theme already
   reads fine with the default --ink-mid above. */
body[data-theme="midnight"] .lobby-mode-chip {
  color: #3d2d52;
}

/* XP row: icon badge + level/points/track stacked */
.lobby-xp-bar {
  width: 100%;
  max-width: none;
  margin-bottom: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}
.lobby-xp-icon {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--accent) 0%, var(--accent-lt) 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
}
.lobby-xp-icon svg {
  width: 19px;
  height: 19px;
  fill: var(--btn-primary-color);
}
.lobby-xp-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.lobby-xp-toprow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}
.lobby-xp-level {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  color: var(--ink);
  font-weight: 600;
  text-transform: uppercase;
  white-space: nowrap;
}
.lobby-xp-track {
  flex: 1;
  height: 5px;
  background: var(--ink-faint);
  border-radius: 3px;
  overflow: hidden;
}
.lobby-xp-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--accent), var(--accent-lt));
  border-radius: 3px;
  transition: width 0.6s ease;
  width: 0%;
}
.lobby-xp-pts {
  font-size: 0.55rem;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
  white-space: nowrap;
}

/* Big play button — modern fancy style with glow ring + pulse */
.lobby-center {
  position: relative;
}
.lobby-center::before {
  content: "";
  position: absolute;
  inset: 50%;
  width: clamp(210px, 46vw, 300px);
  height: clamp(210px, 46vw, 300px);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: radial-gradient(circle, var(--accent) 0%, transparent 70%);
  opacity: 0.25;
  filter: blur(18px);
  animation: playGlowPulse 2.6s ease-in-out infinite;
  pointer-events: none;
  z-index: 0;
}
@keyframes playGlowPulse {
  0%,
  100% {
    transform: translate(-50%, -50%) scale(0.92);
    opacity: 0.2;
  }
  50% {
    transform: translate(-50%, -50%) scale(1.08);
    opacity: 0.4;
  }
}

.btn-play-big {
  width: clamp(110px, min(40vw, 32vh), 290px);
  height: clamp(110px, min(40vw, 32vh), 290px);
  margin: clamp(24px, 5vh, 40px) 0;
  background: transparent;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 1;
  padding: 0;
  transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
  flex-shrink: 0;
  animation: playFloat 3.2s ease-in-out infinite;
}
@keyframes playFloat {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-6px);
  }
}
.btn-play-big:hover {
  transform: translateY(-4px) scale(1.08);
}
.btn-play-big:active {
  transform: translateY(-1px) scale(1.02);
}
/* Themed play artwork — the image itself is the whole button face,
   no extra background/ring/shadow behind it */
.btn-play-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
}

/* Lobby stats strip — sits inside the dashboard card */
.lobby-meta {
  width: 100%;
  max-width: none;
  margin-bottom: 0;
}
.lobby-stat-row {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 0;
}
.lobby-stat {
  flex: 1;
  text-align: center;
  padding: 4px 6px;
  background: none;
  border: none;
  border-right: 1px solid var(--ink-faint);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  transition: transform 0.15s;
}
.lobby-stat:last-child {
  border-right: none;
}
.lobby-stat:hover {
  transform: translateY(-2px);
}
.lobby-stat-icon {
  width: 22px;
  height: 22px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lobby-stat-icon svg {
  width: 100%;
  height: 100%;
  fill: var(--accent);
  opacity: 0.85;
}
.lobby-stat-val {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.15rem, 4vw, 1.5rem);
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
}
.lobby-stat-lbl {
  font-size: 0.48rem;
  letter-spacing: 0.2em;
  color: var(--ink-dim);
  text-transform: uppercase;
}

/* Hide stat row when no stats are available */
.lobby-stat-row.hidden {
  display: none;
}
.lobby-meta:has(.lobby-stat-row.hidden) {
  display: none;
}

/* Corner icon buttons — sized for 1-2 per corner */
.lobby-corner .icon-btn {
  width: clamp(52px, 12.5vw, 64px);
  height: clamp(52px, 12.5vw, 64px);
}
.icon-btn {
  width: clamp(58px, 14.5vw, 74px);
  height: clamp(58px, 14.5vw, 74px);
  border-radius: 0;
  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    transform 0.15s,
    filter 0.2s;
  color: #fff;
}
.icon-btn:hover {
  transform: translateY(-2px) scale(1.06);
}
.icon-btn svg {
  width: 52%;
  height: 52%;
  fill: currentColor;
  stroke-width: 2.4;
  display: block;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}
.icon-btn.sound-muted {
  opacity: 0.55;
}
#btn-lobby-cartoonic.cartoonic-active {
  filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.85));
}

/* Themed background-cover artwork behind every corner icon button —
   one image per theme, icon glyph sits on top in white */
body[data-theme="warm"] .icon-btn,
body[data-theme="warm"] .diff-back-btn,
body[data-theme="warm"] .page-back-btn,
body[data-theme="warm"] .game-act-btn {
  background-image: url("../images/btn-bg/btn-bg-warm.webp");
}
body[data-theme="jungle"] .icon-btn,
body[data-theme="jungle"] .diff-back-btn,
body[data-theme="jungle"] .page-back-btn,
body[data-theme="jungle"] .game-act-btn {
  background-image: url("../images/btn-bg/btn-bg-jungle.webp");
}
body[data-theme="neon"] .icon-btn,
body[data-theme="neon"] .diff-back-btn,
body[data-theme="neon"] .page-back-btn,
body[data-theme="neon"] .game-act-btn {
  background-image: url("../images/btn-bg/btn-bg-neon.webp");
}
body[data-theme="midnight"] .icon-btn,
body[data-theme="midnight"] .diff-back-btn,
body[data-theme="midnight"] .page-back-btn,
body[data-theme="midnight"] .game-act-btn {
  background-image: url("../images/btn-bg/btn-bg-midnight.webp");
}
body[data-theme="rosegold"] .icon-btn,
body[data-theme="rosegold"] .diff-back-btn,
body[data-theme="rosegold"] .page-back-btn,
body[data-theme="rosegold"] .game-act-btn {
  background-image: url("../images/btn-bg/btn-bg-rosegold.webp");
}

/* Amber — these buttons keep a white pill background in every theme,
   so they use a fixed dark text color from this theme's ink family. */
body[data-theme="warm"] .import-btn,
body[data-theme="warm"] .sponsor-skip-btn,
body[data-theme="warm"] .btn-begin,
body[data-theme="warm"] .btn-comp.filled,
body[data-theme="warm"] .popup-btn-primary,
body[data-theme="warm"] .confirm-ok {
  color: #5a260c;
}

/* Midnight — same white-pill problem as above, fixed dark-purple text */
body[data-theme="midnight"] .import-btn,
body[data-theme="midnight"] .sponsor-skip-btn,
body[data-theme="midnight"] .btn-begin,
body[data-theme="midnight"] .btn-comp.filled,
body[data-theme="midnight"] .popup-btn-primary,
body[data-theme="midnight"] .confirm-ok {
  color: #3d2d52;
}

/* ════════════════════════════════════════════════
   DIFFICULTY SCREEN
════════════════════════════════════════════════ */
#s-difficulty {
  gap: 0;
}

.diff-back-btn {
  position: absolute;
  top: clamp(14px, 3vw, 24px);
  left: clamp(14px, 3vw, 24px);
  width: clamp(48px, 11vw, 58px);
  height: clamp(48px, 11vw, 58px);
  border-radius: 0;
  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition:
    transform 0.15s,
    filter 0.2s;
}
.diff-back-btn:hover {
  transform: translateY(-2px) scale(1.06);
}
.diff-back-btn svg {
  width: 40%;
  height: 40%;
  fill: currentColor;
  display: block;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}

.diff-heading {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(3rem, 10vw, 6rem);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1.05;
  margin-bottom: clamp(14px, 2.5vh, 24px);
  text-align: center;
}
.diff-heading-dot {
  color: var(--accent);
}

.diff-subheading {
  font-size: clamp(0.62rem, 2vw, 0.8rem);
  letter-spacing: 0.38em;
  text-indent: 0.38em;
  text-align: center;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: clamp(24px, 5vh, 40px);
}

.diff-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  width: 100%;
  max-width: 360px;
  margin-bottom: 24px;
}
/* Mode-select grid now only has 2 cards (Classic Puzzle, Skins
   Puzzle) — give them a wider, roomier layout instead of the cramped
   3-card sizing, so they don't look small/empty. */
.mode-grid-2col {
  grid-template-columns: repeat(2, 1fr);
  max-width: 420px;
  gap: 16px;
}
.mode-grid-2col .diff-card {
  padding: clamp(24px, 5vw, 34px) 14px;
}
.mode-grid-2col .diff-icon-wrap {
  width: 48px;
  height: 48px;
  margin-bottom: 14px;
}
.mode-grid-2col .diff-name {
  font-size: 1.05rem;
  margin-bottom: 6px;
}
.mode-grid-2col .diff-desc {
  font-size: 0.78rem;
  line-height: 1.35;
}
/* Continue button under the mode-select screen sat narrower than the
   2-card grid above it (grid grew to 420px but the button kept the
   generic 360px cap) -- match it to the grid so both edges align. */
#s-mode .btn-begin {
  max-width: 420px;
}
.mode-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  margin-top: 10px;
}
.mode-card-tag {
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  padding: 3px 9px;
  border-radius: 20px;
  background: var(--accent-bg);
  border: 1px solid var(--card-border);
  color: var(--ink-mid);
  white-space: nowrap;
}
.diff-card.selected .mode-card-tag {
  border-color: var(--accent);
  color: var(--accent);
}
.diff-card {
  background: var(--card-bg);
  border: 1.5px solid var(--card-border);
  border-radius: var(--radius);
  padding: clamp(14px, 3vw, 22px) 10px;
  cursor: pointer;
  text-align: center;
  transition:
    border-color 0.2s,
    transform 0.15s,
    box-shadow 0.2s;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  /* Without this, touch browsers wait ~300ms after touchend before
     firing the click (to detect double-tap-to-zoom). If the tap is
     even slightly off-center or the screen has any late layout
     settling, that delayed click can land on a neighboring card
     instead of the one that was actually touched — this is what
     caused the wrong-skin-gets-selected bug on the skin cards. */
  touch-action: manipulation;
}
.diff-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.16);
}
.diff-card.selected {
  border-color: var(--accent);
  background: var(--accent-bg);
  box-shadow: 0 0 0 3px var(--accent-bg);
}
.diff-icon-wrap {
  width: 32px;
  height: 32px;
  margin: 0 auto 8px;
  color: var(--ink-dim);
  transition: color 0.2s;
}
.diff-card.selected .diff-icon-wrap,
.diff-card:hover .diff-icon-wrap {
  color: var(--accent);
}
.diff-icon-wrap svg {
  width: 100%;
  height: 100%;
}
.skin-icon-wrap {
  width: 40px;
  height: 40px;
}
.skin-icon-wrap img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.diff-card.locked {
  opacity: 0.5;
}
.diff-card.locked:hover {
  border-color: var(--card-border);
  transform: none;
  box-shadow: none;
}
.mode-footnote {
  max-width: 460px;
  margin: 4px auto 18px;
  padding: 10px 16px;
  font-size: 0.8rem;
  line-height: 1.45;
  text-align: center;
  color: var(--text-dim, #8a8fa3);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--card-border);
  border-radius: 12px;
}
.diff-name {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.04em;
}
.diff-desc {
  font-size: 0.58rem;
  color: var(--ink-mid);
  margin-top: 3px;
}

.btn-begin {
  width: 100%;
  max-width: 360px;
  padding: 0.95em 2em;
  background: rgba(255, 255, 255, 0.92);
  border: none;
  border-radius: var(--radius);
  color: var(--ink);
  font-family: "DM Sans", sans-serif;
  font-size: 0.88rem;
  letter-spacing: 0.18em;
  cursor: pointer;
  text-transform: uppercase;
  transition:
    background 0.2s,
    transform 0.15s,
    box-shadow 0.2s;
}
.btn-begin:hover {
  background: var(--accent);
  color: var(--btn-primary-color);
  transform: translateY(-1px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
}

/* ════════════════════════════════════════════════
   LEVEL SELECT SCREEN — 50-level grid per tier
════════════════════════════════════════════════ */
#s-levels {
  overflow-y: auto;
  padding-top: clamp(70px, 12vh, 110px);
  padding-bottom: 24px;
}

.level-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
}

.level-btn {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--card-bg);
  border: 1.5px solid var(--card-border);
  border-radius: calc(var(--radius) * 0.6);
  color: var(--ink);
  font-family: "DM Sans", sans-serif;
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    border-color 0.2s,
    transform 0.15s,
    box-shadow 0.2s,
    background 0.2s;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.level-btn:hover:not(.locked) {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}
.level-btn.done {
  border-color: var(--accent);
  background: var(--accent-bg);
  color: var(--accent);
}
.level-btn.done::after {
  content: "";
  position: absolute;
  top: 3px;
  right: 3px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}
.level-btn.locked {
  cursor: not-allowed;
  opacity: 0.45;
  color: var(--ink-dim);
}
.level-btn.locked svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}
.level-btn.active {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-bg);
}

/* Pagination — keeps only 15 levels on screen at once so the level
   grid never needs to scroll. Same card/back-button visual language
   as the rest of the level-select screen. */
.level-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  max-width: 420px;
  margin: 22px auto 0;
}
.page-nav-btn {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--card-bg);
  border: 1.5px solid var(--card-border);
  color: var(--ink-mid);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: all 0.18s;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.page-nav-btn svg {
  width: 15px;
  height: 15px;
  fill: currentColor;
}
.page-nav-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-bg);
}
.page-nav-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.page-dots {
  display: flex;
  align-items: center;
  gap: 8px;
}
.page-dot {
  min-width: 36px;
  height: 36px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--card-bg);
  border: 1.5px solid var(--card-border);
  color: var(--ink-mid);
  font-family: "DM Sans", sans-serif;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  transition: all 0.18s;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.page-dot:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.page-dot.active {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--btn-primary-color);
}

/* ════════════════════════════════════════════════
   THEME SELECT SCREEN
════════════════════════════════════════════════ */
#s-theme {
  gap: 0;
  overflow-y: auto;
}

/* Theme grid: 3-col same as diff-grid but allow 5th card full-width */
.theme-diff-grid {
  grid-template-columns: repeat(3, 1fr);
  max-width: 360px;
}

.theme-diff-card:last-child:nth-child(3n + 2) {
  grid-column: 2 / 4;
}
.theme-diff-card:last-child:nth-child(3n + 1) {
  grid-column: 1 / -1;
}

/* When there are exactly 5 cards, the 5th spans last 2 cols */
.theme-diff-grid .theme-diff-card:nth-child(4):last-child {
  grid-column: 1 / -1;
}
.theme-diff-grid .theme-diff-card:nth-child(5) {
  grid-column: 2 / 4;
}

/* Skins grid: same compact 3-col pattern as the theme page. 4 skins ->
   3 in the first row, the 4th (Test Tube) spans the full row like the
   theme page's last "New" card spans 2 of its 3 columns. */
.skins-grid {
  grid-template-columns: repeat(3, 1fr);
  max-width: 360px;
}

/* Skin picker grids on difficulty screen: exactly 2 skins now (F1 Car + Car).
   Use 2-column layout so both get equal 50% width. */
#skin-grid-2d,
#skin-grid-3d {
  grid-template-columns: repeat(2, 1fr);
  max-width: 420px;
  gap: 16px;
}
#skin-grid-2d .diff-card,
#skin-grid-3d .diff-card {
  padding: clamp(24px, 5vw, 34px) 14px;
}
#skin-grid-2d .diff-icon-wrap,
#skin-grid-3d .diff-icon-wrap {
  width: 48px;
  height: 48px;
  margin-bottom: 14px;
}
#skin-grid-2d .diff-name,
#skin-grid-3d .diff-name {
  font-size: 1.05rem;
  margin-bottom: 6px;
}
#skin-grid-2d .diff-desc,
#skin-grid-3d .diff-desc {
  font-size: 0.78rem;
  line-height: 1.35;
}

/* Icon wrap holds the mini-preview */
.theme-icon-wrap {
  width: 100% !important;
  height: auto !important;
  margin-bottom: 8px !important;
  color: inherit !important;
}

.theme-icon-wrap .theme-preview {
  width: 100%;
  aspect-ratio: 1;
  border-radius: calc(var(--radius) - 4px);
  overflow: hidden;
  margin-bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
}

/* Preview backgrounds */
.theme-preview--warm {
  background: #fff8f0;
  border: 1.5px solid #e8720f;
}
.theme-preview--jungle {
  background: #cdd9ef;
  border: 1.5px solid #3d5fdb;
}
.theme-preview--neon {
  background: #c3e8d8;
  border: 1.5px solid #0f9c7e;
}
.theme-preview--midnight {
  background: #121016;
  border: 1.5px solid #f2c14e;
}

/* Mini grid inside preview */
.tp-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  width: 100%;
  height: 100%;
  border: 1.5px solid;
  position: relative;
  z-index: 1;
}

/* Amber mini cells */
.theme-preview--warm .tp-grid {
  border-color: #7a3410;
  border-radius: 2px;
  overflow: hidden;
}
.theme-preview--warm .tp-cell {
  background: #fffdf9;
  border-right: 1px solid #f0cd9e;
  border-bottom: 1px solid #f0cd9e;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(7px, 2vw, 11px);
  font-weight: 600;
  color: #e8720f;
  aspect-ratio: 1;
}
.theme-preview--warm .tp-cell.tp-given {
  background: rgba(122, 52, 16, 0.06);
  color: #7a3410;
}
.theme-preview--warm .tp-cell.tp-sel {
  background: rgba(232, 114, 15, 0.2);
  color: #e8720f;
}
.theme-preview--warm .tp-cell.tp-br {
  border-right: 2px solid #dba766;
}
.theme-preview--warm .tp-cell.tp-bb {
  border-bottom: 2px solid #dba766;
}

/* Jungle mini cells */
.theme-preview--jungle .tp-grid {
  border-color: #16264f;
  border-radius: 1px;
  overflow: hidden;
}
.theme-preview--jungle .tp-cell {
  background: #fdfeff;
  border-right: 1px solid #cdd9ef;
  border-bottom: 1px solid #cdd9ef;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(7px, 2vw, 11px);
  font-weight: 600;
  color: #3d5fdb;
  aspect-ratio: 1;
}
.theme-preview--jungle .tp-cell.tp-given {
  background: rgba(22, 38, 79, 0.06);
  color: #16264f;
}
.theme-preview--jungle .tp-cell.tp-sel {
  background: rgba(61, 95, 219, 0.2);
  color: #3d5fdb;
}
.theme-preview--jungle .tp-cell.tp-br {
  border-right: 2px solid #93aee0;
}
.theme-preview--jungle .tp-cell.tp-bb {
  border-bottom: 2px solid #93aee0;
}

/* Sky Blue mini cells */
.theme-preview--neon .tp-grid {
  border-color: #0b4a3d;
  border-radius: 0;
  overflow: hidden;
}
.theme-preview--neon .tp-cell {
  background: #ffffff;
  border-right: 1px solid #c3e8d8;
  border-bottom: 1px solid #c3e8d8;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(7px, 2vw, 11px);
  font-weight: 600;
  color: #0f9c7e;
  aspect-ratio: 1;
}
.theme-preview--neon .tp-cell.tp-given {
  background: rgba(11, 74, 61, 0.05);
  color: #0b4a3d;
}
.theme-preview--neon .tp-cell.tp-sel {
  background: rgba(15, 156, 126, 0.2);
  color: #0f9c7e;
}
.theme-preview--neon .tp-cell.tp-br {
  border-right: 2px solid #7cc7ac;
}
.theme-preview--neon .tp-cell.tp-bb {
  border-bottom: 2px solid #7cc7ac;
}

/* Midnight mini cells */
.theme-preview--midnight .tp-grid {
  border-color: #f2c14e;
  border-radius: 2px;
  overflow: hidden;
}
.theme-preview--midnight .tp-cell {
  background: #1a1620;
  border-right: 1px solid #2a2433;
  border-bottom: 1px solid #2a2433;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(7px, 2vw, 11px);
  font-weight: 600;
  color: #f2c14e;
  aspect-ratio: 1;
}
.theme-preview--midnight .tp-cell.tp-given {
  background: rgba(242, 193, 78, 0.06);
  color: #f2c14e;
}
.theme-preview--midnight .tp-cell.tp-sel {
  background: rgba(168, 112, 216, 0.28);
  color: #c79bea;
}
.theme-preview--midnight .tp-cell.tp-br {
  border-right: 2px solid #4a3f5e;
}
.theme-preview--midnight .tp-cell.tp-bb {
  border-bottom: 2px solid #4a3f5e;
}

.theme-new-icon {
  width: 11px;
  height: 11px;
  vertical-align: middle;
  color: var(--accent);
  display: inline-block;
  margin: 0 1px;
}

/* ════════════════════════════════════════════════
   PREPARING SCREEN
════════════════════════════════════════════════ */
#s-preparing {
  gap: 0;
}

.prep-spinner {
  width: clamp(52px, 13vw, 68px);
  height: clamp(52px, 13vw, 68px);
  margin-bottom: 22px;
  animation: spinCW 1.1s linear infinite;
}
.prep-spinner svg {
  width: 100%;
  height: 100%;
}

@keyframes spinCW {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.prep-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.5rem, 5.5vw, 2.2rem);
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.4em;
}
.prep-sub {
  font-size: 0.65rem;
  letter-spacing: 0.35em;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: clamp(24px, 5vh, 36px);
}
.prep-dots {
  display: flex;
  gap: 8px;
}
.prep-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ink-faint);
  animation: prepDot 1.2s ease-in-out infinite;
}
.prep-dot:nth-child(2) {
  animation-delay: 0.2s;
}
.prep-dot:nth-child(3) {
  animation-delay: 0.4s;
}
@keyframes prepDot {
  0%,
  80%,
  100% {
    background: var(--ink-faint);
    transform: scale(1);
  }
  40% {
    background: var(--accent);
    transform: scale(1.4);
  }
}

/* ════════════════════════════════════════════════
   GAME SCREEN
════════════════════════════════════════════════ */
#s-game {
  justify-content: flex-start;
  padding: 0;
  gap: 0;
  overflow-y: auto;
  align-items: stretch;
}

/* Full-width game topbar — mirrors .page-header style */
.game-page-header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: clamp(14px, 3vw, 22px) clamp(18px, 5vw, 36px)
    clamp(12px, 2.5vw, 18px);
  border-bottom: 1px solid var(--paper3);
  flex-shrink: 0;
  background: var(--card-bg);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.game-header-left {
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex-shrink: 0;
}
/* Logo + mode badge stay stacked as a column inside the header's
   left group; on mobile the pause button is relocated next to this
   group (relocateGameMeta() in game.js), so .game-header-left flips
   to a row and the two sit side by side. */
.game-header-brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}

/* Main game body: board centered, left/right sidebar columns flank it
   at a FIXED width (not 1fr) — this is critical because puzzle boards
   vary a lot in size (small 3x3 vs a huge 12x12 shape). With flexible
   1fr side columns the sidebars would visibly shift position every
   time the board resized. Fixed-width columns pin both sidebars to
   the same spot on screen regardless of board size; only the center
   column (the board itself) grows or shrinks. */
.game-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: var(--game-sidebar-w, 108px) 1fr var(
      --game-sidebar-w,
      108px
    );
  grid-template-rows: auto 1fr;
  align-items: center;
  padding: clamp(12px, 2.5vw, 20px) clamp(12px, 3vw, 24px);
  gap: 0;
  position: relative;
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
}
.game-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(8px, 1.5vw, 14px);
  grid-column: 2;
  grid-row: 1 / span 2;
  justify-self: center;
  align-self: center;
  min-width: 0;
  width: auto;
}

/* Controls bar above board */
.game-above-board {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  width: 100%;
  padding: 0 2px;
  flex-wrap: wrap;
}

/* Right sidebar — vertical column of action buttons, pinned to a
   fixed-width column on the right edge of .game-body so its position
   never shifts as the puzzle board grows/shrinks. */
.game-action-sidebar {
  display: flex;
  flex-direction: column;
  gap: clamp(4px, 1.2vh, 10px);
  align-items: center;
  flex-shrink: 0;
  width: 100%;
  grid-column: 3;
  grid-row: 1 / span 2;
  justify-self: center;
  align-self: center;
}

/* Left sidebar — power-up buttons, exact mirror of .game-action-sidebar
   on the opposite fixed-width column (Classic/Arrow puzzle only) */
.game-power-sidebar {
  display: flex;
  flex-direction: column;
  gap: clamp(4px, 1.2vh, 10px);
  align-items: center;
  flex-shrink: 0;
  width: 100%;
  grid-column: 1;
  grid-row: 1 / span 2;
  justify-self: center;
  align-self: center;
}
.game-power-sidebar .game-act-btn {
  position: relative;
  overflow: visible;
}
.power-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  position: relative;
}
.power-count {
  position: absolute;
  top: -6px;
  right: -6px;
  min-width: 22px;
  height: 22px;
  padding: 0 5px;
  border-radius: 50%;
  background: var(--card-bg);
  color: var(--ink);
  font-family: "DM Sans", sans-serif;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--card-border);
  flex-shrink: 0;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  pointer-events: none;
  z-index: 1;
}
body[data-theme="neon"] .power-count {
  border-radius: 0;
}
.game-act-btn:disabled + .power-count {
  opacity: 0.55;
  filter: grayscale(0.6);
}
.game-act-btn {
  width: clamp(44px, min(8vw, 9vh), 80px);
  height: clamp(44px, min(8vw, 9vh), 80px);
  border-radius: 0;
  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    transform 0.15s,
    filter 0.2s;
  color: #fff;
}
.game-act-btn svg {
  width: 48%;
  height: 48%;
  fill: currentColor;
  display: block;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}
.game-act-btn:hover {
  transform: translateY(-2px) scale(1.06);
}
.game-act-btn:disabled {
  cursor: not-allowed;
  opacity: 0.4;
  filter: grayscale(0.5) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}
.game-act-btn:disabled:hover {
  transform: none;
}

/* ── Responsive breakpoints ──────────────────────────────────── */

/* Medium screens: shrink side panels and tighten gaps so nothing
   overlaps the board before it has to wrap */
@media (max-width: 1100px) {
  .game-body {
    gap: 0;
    --game-sidebar-w: clamp(84px, 10vw, 118px);
  }
  .game-act-btn {
    width: clamp(50px, 7.5vw, 68px);
    height: clamp(50px, 7.5vw, 68px);
  }
  .num-btn {
    width: clamp(38px, 6vw, 60px);
    height: clamp(38px, 6vw, 60px);
  }
}

/* Tablet / narrow: stack sidebar below board */
@media (max-width: 960px) {
  .game-body {
    display: flex;
    flex-direction: column;
    align-items: center;
    /* .game-center below now grows (flex: 1) to soak up any leftover
       vertical space and centers the board within itself, which pushes
       the action/power sidebars (order 3/4) down to sit right at the
       bottom edge — so flex-start here (not center) lets that flex-grow
       do the vertical layout instead of centering the whole stack as
       one block, which used to leave the topbar high and the board+
       buttons floating with dead space beneath them. */
    justify-content: flex-start;
    padding: clamp(10px, 3vw, 20px) clamp(8px, 3vw, 16px);
    gap: clamp(8px, 2vw, 14px);
  }
  /* Hard viewport-relative ceiling for the Classic/Skins Puzzle board —
     independent of the JS sizing math in sizeArrowBoard(), so even if
     that calculation is ever a beat off (e.g. header height measured
     before a webfont swap finishes), the board physically cannot push
     past the topbar or off the sides of the screen on phones/tablets. */
  .arrow-grid-wrap {
    max-width: 92vw !important;
    max-height: 60vh !important;
    margin: 14px 0;
  }
  /* Mobile: the pause button is relocated next to the logo (JS moves
     it from .top-stats into .game-header-left), so the header's left
     group becomes a row with the logo/badge column on the left and the
     pause button beside it. The logo also scales up for phones. */
  .game-header-left {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: clamp(12px, 3vw, 18px);
  }
  .game-header-brand {
    align-items: center;
  }
  .top-brand-logo {
    height: clamp(48px, 10vw, 68px);
  }
  #btn-pause {
    width: clamp(40px, 10vw, 50px);
    height: clamp(40px, 10vw, 50px);
  }
  .game-action-sidebar {
    order: 3;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    width: 100%;
    grid-column: auto;
    grid-row: auto;
    justify-self: auto;
    align-self: auto;
    margin: 0;
    padding: 0 0 max(14px, env(safe-area-inset-bottom));
  }
  .game-power-sidebar {
    order: 4;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    width: 100%;
    grid-column: auto;
    grid-row: auto;
    justify-self: auto;
    align-self: auto;
    margin: 0;
    padding: 0 0 max(14px, env(safe-area-inset-bottom));
  }
  .game-center {
    order: 2;
    width: 100%;
    max-width: 100%;
    grid-column: auto;
    grid-row: auto;
    justify-self: auto;
    align-self: auto;
    align-items: center;
    /* Grow to fill the leftover space between the topbar and the
       bottom action buttons, then center the board within that space
       (see the .game-body comment above). */
    flex: 1 1 auto;
    justify-content: center;
    min-height: 0;
  }
  /* .chances-row and .level-name-badge relocate into .top-stats
     (same row as Time/Moves/Hints) inside the topbar on mobile via
     relocateGameMeta() in game.js — see the .top-stats rules above. */
  .game-above-board {
    justify-content: center;
    width: 100%;
  }
  .grid-wrap {
    margin: 0 auto;
  }
  .game-numpad-panel {
    width: 100%;
    align-items: center;
  }
  .numpad {
    width: 100%;
    justify-content: center;
  }
  .num-btn {
    flex: 1 1 0;
    height: auto;
    aspect-ratio: 1;
    min-width: 0;
    max-width: 52px;
  }
  .game-act-btn {
    width: clamp(44px, 12vw, 56px);
    height: clamp(44px, 12vw, 56px);
  }
  .level-badge-top {
    flex: 1 1 100%;
    width: auto;
    max-width: 200px;
    margin: 0 auto 2px;
  }
}

/* Tablet portrait: additional tightening */
@media (max-width: 768px) {
  .arrow-grid-wrap {
    max-width: 90vw !important;
    max-height: 55vh !important;
  }
  .grid-wrap {
    width: min(380px, 88vw);
    max-width: 380px;
    padding: 8px;
  }
  .game-page-header {
    padding: clamp(10px, 2.5vw, 16px) clamp(12px, 3vw, 20px);
  }
  /* Topbar stacks on mobile instead of squeezing title + badge + all the
     stat boxes + pause button into one cramped row: title/badge on top,
     stats + pause below, everything centered. */
  .game-page-header {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
  }
  .game-header-left {
    align-items: center;
    text-align: center;
  }
  .top-diff-badge {
    align-self: center;
  }
  .top-stats {
    justify-content: center;
    flex-wrap: wrap;
  }
  .chances-row {
    justify-content: center;
  }
  .top-title {
    font-size: clamp(1.1rem, 4vw, 1.5rem);
  }
  .diff-grid {
    max-width: 320px;
  }
  .btn-begin {
    max-width: 320px;
  }
  .popup-card {
    max-width: 300px;
  }
  .popup-brand {
    font-size: clamp(2.2rem, 8vw, 3.2rem);
  }
  .lb-tabs,
  .lb-list {
    max-width: 360px;
  }
  .lobby-bottom {
    max-width: 340px;
  }
  .lobby-stat-val {
    font-size: clamp(1.1rem, 4vw, 1.5rem);
  }
}

/* Small mobile: tighten everything further */
@media (max-width: 480px) {
  .arrow-grid-wrap {
    max-width: 94vw !important;
    max-height: 50vh !important;
  }
  .game-act-btn {
    width: clamp(38px, 11vw, 48px);
    height: clamp(38px, 11vw, 48px);
  }
  .game-act-btn svg {
    width: 44%;
    height: 44%;
  }
  .power-count {
    min-width: 16px;
    height: 16px;
    font-size: 0.6rem;
    top: -4px;
    right: -4px;
    border-width: 1.5px;
  }
  .num-btn {
    font-size: clamp(0.9rem, 4vw, 1.2rem);
  }
  .toggle-lbl {
    font-size: 0.56rem;
  }
}

.top-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.5rem, 5vw, 2rem);
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
}
.top-brand-logo {
  display: block;
  height: clamp(36px, 7vw, 50px);
  width: auto;
  max-width: 100%;
  object-fit: contain;
}
.top-title-dot {
  color: var(--accent);
}
.top-diff-badge {
  font-size: 0.6rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: #fff;
  background: var(--accent);
  padding: 0.3em 0.75em;
  border-radius: 20px;
  display: inline-block;
  align-self: flex-start;
  margin-top: 3px;
}
/* Neon badge */
body[data-theme="neon"] .top-diff-badge {
  border-radius: 0;
}
.top-stats {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-shrink: 0;
}
@media (max-width: 960px) {
  /* On mobile, relocateGameMeta() (game.js) appends the level badge +
     chances row directly into .top-stats, so they share the exact same
     row as Time/Moves/Hints/Pause — this just lets that row wrap onto
     a second line if it doesn't all fit, instead of forcing a separate
     row. */
  .top-stats {
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 6px;
  }
  /* Reuse the exact Time/Moves/Hints stat look: no card/border/box,
     stacked on two lines (value line on top, label line below) just
     like .stat-val / .stat-lbl, so it reads the same as the other
     topbar stats instead of running name + level info inline. */
  .top-stats .level-badge-top {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    width: auto;
    max-width: none;
    min-height: auto;
    margin: 0;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    line-height: 1;
  }
  .top-stats .level-badge-top br {
    display: none;
  }
  .top-stats .level-badge-top .level-badge-line1 {
    order: 2;
    display: block;
    font-size: 0.6rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ink-dim);
    opacity: 1;
  }
  .top-stats .level-badge-top .level-badge-line2 {
    order: 1;
    display: block;
    font-family: "Crimson Pro", Georgia, serif;
    font-size: 1.3rem;
    font-weight: 600;
    color: var(--ink);
  }
  .top-stats .chances-row {
    flex-direction: column;
    align-items: center;
    width: auto;
    gap: 0;
    margin-top: 0;
    font-size: 0.6rem;
    letter-spacing: 0.2em;
    color: var(--ink-dim);
  }
  .top-stats .chances-row .chances-lbl {
    order: 2;
    margin-top: 0;
    text-transform: uppercase;
  }
  .top-stats .chance-hearts {
    order: 1;
  }
}
.stat-item {
  text-align: right;
}
.stat-val {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
}
.stat-lbl {
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  color: var(--ink-dim);
  text-transform: uppercase;
}

/* Grid wrap — theme-specific backgrounds */
.grid-wrap {
  width: min(440px, 88vw);
  max-width: 440px;
  margin-bottom: clamp(10px, 2vw, 18px);
  padding: 10px;
  background: var(--grid-wrap-bg);
  border-radius: 8px;
  box-shadow: var(--grid-wrap-shadow);
  box-sizing: border-box;
}

/* Warm: subtle parchment frame */
body[data-theme="warm"] .grid-wrap {
  border: 1px solid var(--grid-wrap-border);
}

/* Jungle: dense forest floor, leafy border */
body[data-theme="jungle"] .grid-wrap {
  border: 1px solid var(--grid-wrap-border);
  position: relative;
  overflow: hidden;
}
body[data-theme="jungle"] .grid-wrap::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      ellipse at 10% 20%,
      rgba(92, 138, 46, 0.08) 0%,
      transparent 40%
    ),
    radial-gradient(
      ellipse at 90% 80%,
      rgba(92, 138, 46, 0.06) 0%,
      transparent 40%
    );
  pointer-events: none;
  z-index: 0;
}
body[data-theme="jungle"] #equation-grid {
  position: relative;
  z-index: 1;
}

/* Neon: electric grid frame */
body[data-theme="neon"] .grid-wrap {
  padding: 12px;
  border-radius: 0;
}

/* Midnight: deep space */
body[data-theme="midnight"] .grid-wrap {
  border-radius: 8px;
}

#equation-grid {
  display: grid;
  grid-template-columns: repeat(9, 1fr);
  border: 2.5px solid var(--box-border);
  border-radius: 3px;
  overflow: hidden;
  background: var(--grid-bg);
  box-shadow: var(--shadow);
  width: 100%;
  aspect-ratio: 1;
}

/* Neon grid — sharp corners, glowing border */
body[data-theme="neon"] #equation-grid {
  border-radius: 0;
  border-width: 2px;
  box-shadow:
    0 0 0 1px rgba(6, 96, 214, 0.4),
    0 0 30px rgba(6, 96, 214, 0.2);
}

.cell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  background: var(--cell-bg);
  border-right: 1px solid var(--grid-thin);
  border-bottom: 1px solid var(--grid-thin);
  transition: background 0.1s;
  aspect-ratio: 1;
}

/* Neon cells get scanline inset */
body[data-theme="neon"] .cell {
  background: #0c0c18;
}
body[data-theme="neon"] .cell:nth-child(odd) {
  background: #0e0e1c;
}

/* Jungle cells — very slightly varied */
body[data-theme="jungle"] .cell {
  background: #0f2412;
}
body[data-theme="jungle"] .cell:nth-child(even) {
  background: #0d2010;
}

/* ── OVERLAY SVG — shared full-grid layer for Consecutive Sudoku dots
   and Arrow Sum Sudoku arrows. Coordinate space is 0-900 (100 units per
   cell) so it never needs recalculating on resize. ────────────────── */
#equation-grid {
  position: relative;
}
.overlay-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 5;
}
.consec-dot {
  fill: var(--ink);
  stroke: var(--card-bg, #fff);
  stroke-width: 3;
}
.arrow-line {
  fill: none;
  stroke: var(--ink-mid);
  stroke-width: 4.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.62;
}
.arrow-circle {
  fill: none;
  stroke: var(--ink-mid);
  stroke-width: 4.5;
  opacity: 0.62;
}
.arrow-head {
  fill: var(--ink-mid);
  opacity: 0.62;
}

/* Cage borders — replace the classic 3x3-box lines with irregular
   equation-cage boundaries computed in JS (cage-edge-*) */
.cell.cage-edge-top {
  border-top: 2px solid var(--grid-thick);
}
.cell.cage-edge-right {
  border-right: 2px solid var(--grid-thick);
}
.cell.cage-edge-bottom {
  border-bottom: 2px solid var(--grid-thick);
}
.cell.cage-edge-left {
  border-left: 2px solid var(--grid-thick);
}
.cell:nth-child(9n) {
  border-right: none;
}
.cell:nth-child(n + 73) {
  border-bottom: none;
}
.cell.given {
  background: var(--given-bg);
}

/* Theme-specific given cells */
body[data-theme="warm"] .cell.given {
  background: rgba(42, 37, 32, 0.05);
}
body[data-theme="jungle"] .cell.given {
  background: rgba(92, 138, 46, 0.07);
}
body[data-theme="neon"] .cell.given {
  background: rgba(6, 96, 214, 0.06);
}
body[data-theme="midnight"] .cell.given {
  background: rgba(12, 34, 79, 0.06);
}

.cell.selected {
  background: rgba(217, 72, 15, 0.16) !important;
}
body[data-theme="jungle"] .cell.selected {
  background: rgba(92, 138, 46, 0.22) !important;
}
body[data-theme="neon"] .cell.selected {
  background: rgba(6, 96, 214, 0.28) !important;
}
body[data-theme="midnight"] .cell.selected {
  background: rgba(12, 34, 79, 0.28) !important;
}

.cell.row-hl {
  background: var(--row-hl);
}
.cell.same-num {
  background: var(--same-hl) !important;
}
.cell.error {
  background: var(--error-bg);
}

/* Neon cage borders glow */
body[data-theme="neon"] .cell.cage-edge-top {
  border-top: 2px solid rgba(6, 96, 214, 0.6);
}
body[data-theme="neon"] .cell.cage-edge-right {
  border-right: 2px solid rgba(6, 96, 214, 0.6);
}
body[data-theme="neon"] .cell.cage-edge-bottom {
  border-bottom: 2px solid rgba(6, 96, 214, 0.6);
}
body[data-theme="neon"] .cell.cage-edge-left {
  border-left: 2px solid rgba(6, 96, 214, 0.6);
}

/* Jungle cage borders glow */
body[data-theme="jungle"] .cell.cage-edge-top {
  border-top: 2px solid rgba(92, 138, 46, 0.5);
}
body[data-theme="jungle"] .cell.cage-edge-right {
  border-right: 2px solid rgba(92, 138, 46, 0.5);
}
body[data-theme="jungle"] .cell.cage-edge-bottom {
  border-bottom: 2px solid rgba(92, 138, 46, 0.5);
}
body[data-theme="jungle"] .cell.cage-edge-left {
  border-left: 2px solid rgba(92, 138, 46, 0.5);
}

/* Equation clue label — sits in the top-left corner of a cage's anchor cell */
.cage-clue {
  position: absolute;
  top: 2px;
  left: 3px;
  font-family: "Crimson Pro", Georgia, serif;
  font-weight: 700;
  color: var(--grid-thick);
  line-height: 1;
  pointer-events: none;
  user-select: none;
  z-index: 2;
  letter-spacing: 0.2px;
}
body[data-theme="neon"] .cage-clue {
  color: #0660d6;
  text-shadow: 0 0 6px rgba(6, 96, 214, 0.5);
}
body[data-theme="jungle"] .cage-clue {
  color: #5c8a2e;
  text-shadow: 0 0 6px rgba(92, 138, 46, 0.4);
}
body[data-theme="midnight"] .cage-clue {
  color: #9a8de0;
}

.cell-num {
  font-family: "Crimson Pro", Georgia, serif;
  font-weight: 600;
  color: var(--ink);
  line-height: 1;
  pointer-events: none;
  user-select: none;
}
.cell.given .cell-num {
  color: var(--ink);
}
.cell:not(.given) .cell-num {
  color: var(--blue);
}
.cell.error .cell-num {
  color: var(--error-txt);
}

/* Jungle user numbers */
body[data-theme="jungle"] .cell:not(.given) .cell-num {
  color: #5c8a2e;
  text-shadow: 0 0 8px rgba(92, 138, 46, 0.4);
}

/* Neon given numbers — pink; user numbers — cyan */
body[data-theme="neon"] .cell.given .cell-num {
  color: #f0f0ff;
}
body[data-theme="neon"] .cell:not(.given) .cell-num {
  color: #0660d6;
  text-shadow: 0 0 8px rgba(6, 96, 214, 0.5);
}

/* Midnight user numbers */
body[data-theme="midnight"] .cell:not(.given) .cell-num {
  color: #6a90e8;
}

.pencil-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  width: 90%;
  height: 90%;
  pointer-events: none;
}
.pencil-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "DM Sans", sans-serif;
  color: var(--ink-mid);
  line-height: 1;
}

/* ── Numpad panel — below the board, horizontal row ── */
.game-numpad-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  align-items: center;
}

.numpad {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: clamp(4px, 0.8vw, 8px);
  justify-content: center;
  width: 100%;
}
.num-btn {
  width: clamp(36px, 5vw, 52px);
  height: clamp(36px, 5vw, 52px);
  border: 1.5px solid var(--ink-faint);
  border-radius: 12px;
  background: var(--card-bg);
  color: var(--ink);
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(0.9rem, 1.8vw, 1.2rem);
  font-weight: 600;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  user-select: none;
}
.num-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-bg);
  transform: scale(1.05);
}
.num-btn:active {
  transform: scale(0.95);
}
.num-btn.erase-btn {
  font-size: clamp(0.9rem, 2vw, 1.2rem);
  color: var(--ink-mid);
  font-family: "DM Sans", sans-serif;
}
.num-btn.pencil-btn {
  font-size: clamp(0.85rem, 1.8vw, 1.1rem);
  font-family: "DM Sans", sans-serif;
  color: var(--ink-mid);
}
.num-btn.pencil-btn.active {
  border-color: var(--blue);
  background: var(--blue-lt);
  color: var(--blue);
}
.num-btn.complete {
  opacity: 0.25;
  pointer-events: none;
}

/* Neon numpad */
body[data-theme="neon"] .num-btn {
  border-radius: 0;
}
body[data-theme="neon"] .num-btn:hover {
  box-shadow: 0 0 10px rgba(6, 96, 214, 0.3);
}

/* Info row below numpad panel */
.numpad-info-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 2px 0;
  border-top: 1px solid var(--paper3);
}

.toggle-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}
.toggle-item {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  user-select: none;
}
.toggle-box {
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--ink-faint);
  border-radius: 3px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s;
  font-size: 0.7rem;
  color: white;
}
.toggle-item.on .toggle-box {
  background: var(--accent);
  border-color: var(--accent);
}
.toggle-lbl {
  font-size: 0.62rem;
  color: var(--ink-mid);
  letter-spacing: 0.08em;
}

.hint-bar {
  display: flex;
  gap: 12px;
  align-items: center;
  font-size: 0.62rem;
  color: var(--ink-mid);
}
.mistake-dots {
  display: flex;
  gap: 4px;
}
.mistake-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ink-faint);
  transition: background 0.3s;
}
.mistake-dot.used {
  background: var(--error-txt);
}
.mistake-overflow {
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--error-txt);
  line-height: 1;
  margin-left: 1px;
}

/* ════════════════════════════════════════════════
   COMPLETE SCREEN
════════════════════════════════════════════════ */
#s-complete {
  gap: 0;
}

/* Game-over screen (out of chances) — reuses the complete-screen
   layout; only the title takes a distinct "loss" color. */
#s-gameover {
  gap: 0;
}
.gameover-title {
  color: var(--error-txt);
}

.complete-star {
  width: clamp(48px, 12vw, 64px);
  height: clamp(48px, 12vw, 64px);
  margin-bottom: 14px;
  animation: popIn 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.complete-star svg {
  width: 100%;
  height: 100%;
  fill: var(--accent);
}
body[data-theme="neon"] .complete-star svg {
  filter: drop-shadow(0 0 12px var(--accent));
}
body[data-theme="jungle"] .complete-star svg {
  filter: drop-shadow(0 0 10px rgba(92, 138, 46, 0.5));
}

@keyframes popIn {
  from {
    transform: scale(0);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.complete-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(2.2rem, 7vw, 3.4rem);
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 0.2em;
  text-align: center;
}
.complete-sub {
  font-size: 0.7rem;
  letter-spacing: 0.35em;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: clamp(20px, 4vh, 36px);
}
.complete-stats {
  display: flex;
  gap: 28px;
  margin-bottom: clamp(24px, 4vh, 40px);
}
.cstat {
  text-align: center;
}
.cstat-val {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.8rem, 6vw, 2.8rem);
  font-weight: 600;
  color: var(--accent);
  line-height: 1;
}
.cstat-lbl {
  font-size: 0.55rem;
  letter-spacing: 0.3em;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-top: 3px;
}
.complete-btns {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}
.btn-comp {
  padding: 0.75em 2em;
  border-radius: var(--radius);
  font-family: "DM Sans", sans-serif;
  font-size: 0.78rem;
  letter-spacing: 0.15em;
  cursor: pointer;
  text-transform: uppercase;
  transition: all 0.2s;
}
.btn-comp.filled {
  background: rgba(255, 255, 255, 0.92);
  border: none;
  color: var(--ink);
}
.btn-comp.filled:hover {
  background: var(--accent);
  color: var(--btn-primary-color);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
}
.btn-comp.outline {
  background: transparent;
  border: 1.5px solid var(--ink-faint);
  color: var(--ink-mid);
}
.btn-comp.outline:hover {
  border-color: var(--ink);
  color: var(--ink);
}

/* ════════════════════════════════════════════════
   PAGE CHROME (settings & info)
════════════════════════════════════════════════ */
.page-header {
  width: 100%;
  max-width: 460px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: clamp(18px, 4vw, 30px) clamp(18px, 5vw, 32px) clamp(16px, 3vw, 22px);
  border-bottom: 1px solid var(--paper3);
  flex-shrink: 0;
  align-self: center;
}
.page-back-btn {
  width: clamp(46px, 10.5vw, 56px);
  height: clamp(46px, 10.5vw, 56px);
  border-radius: 0;
  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition:
    transform 0.15s,
    filter 0.2s;
  flex-shrink: 0;
}
.page-back-btn:hover {
  transform: translateY(-2px) scale(1.06);
}
.page-back-btn svg {
  width: 38%;
  height: 38%;
  fill: currentColor;
  display: block;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}
.page-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.5rem, 5.5vw, 2rem);
  font-weight: 600;
  color: var(--ink);
}

/* ════════════════════════════════════════════════
   SETTINGS PAGE
════════════════════════════════════════════════ */
#s-settings {
  justify-content: flex-start;
  align-items: stretch;
  padding: 0;
  overflow-y: auto;
}

#s-settings .page-header {
  align-self: center;
  flex-shrink: 0;
}

#s-settings .page-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  align-self: center;
  width: 100%;
  max-width: 460px;
  padding: clamp(14px, 3vw, 24px) clamp(18px, 5vw, 32px);
}

.settings-section-label {
  font-size: 0.58rem;
  letter-spacing: 0.35em;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin: 14px 0 4px;
  padding-left: 2px;
}
.settings-section-label:first-child {
  margin-top: 0;
}

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 16px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: var(--radius);
  gap: 12px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.settings-row--about {
  align-items: flex-start;
}
.settings-row-left {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}
.settings-row-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  fill: var(--ink-dim);
}
.settings-row-info {
  flex: 1;
  min-width: 0;
}
.settings-row-label {
  font-size: 0.82rem;
  color: var(--ink);
  font-weight: 500;
  margin-bottom: 1px;
}
.settings-row-desc {
  font-size: 0.62rem;
  color: var(--ink-dim);
  letter-spacing: 0.01em;
}

/* Toggle switch */
.sw {
  position: relative;
  width: 42px;
  height: 24px;
  flex-shrink: 0;
}
.sw input {
  opacity: 0;
  width: 0;
  height: 0;
  position: absolute;
}
.sw-track {
  position: absolute;
  inset: 0;
  background: var(--ink-faint);
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.2s;
}
.sw-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: white;
  transition: transform 0.2s;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}
.sw input:checked + .sw-track {
  background: var(--accent);
}
.sw input:checked + .sw-track::after {
  transform: translateX(18px);
}

/* ════════════════════════════════════════════════
   INFO PAGE
════════════════════════════════════════════════ */
#s-info {
  justify-content: flex-start;
  align-items: stretch;
  padding: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}
#s-info .page-header,
#popup-stats .page-header {
  max-width: clamp(480px, 92vw, 800px);
}

#s-info .page-header {
  align-self: center;
  flex-shrink: 0;
  padding-top: clamp(12px, 2.5vw, 18px);
  padding-bottom: clamp(10px, 2vw, 16px);
  border-bottom: none;
}

/* Reuses the popup-card divider look right under the title */
.info-rule-line {
  width: 100%;
  max-width: 200px;
  height: 1px;
  background: var(--card-border);
  align-self: center;
  margin: 0 auto clamp(10px, 2vh, 18px);
  flex-shrink: 0;
}

.info-body {
  flex: 1;
  width: 100%;
  max-width: clamp(480px, 92vw, 800px);
  padding: clamp(10px, 2.5vw, 18px) clamp(18px, 5vw, 32px)
    clamp(24px, 4vh, 32px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
  align-self: center;
}

.info-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 14px;
  padding: 12px 14px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.08);
}
.info-card-icon {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  background: var(--accent-bg);
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.info-card-icon svg {
  width: 16px;
  height: 16px;
  fill: var(--accent);
}
.info-card-body {
  flex: 1;
  min-width: 0;
}
.info-card-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 3px;
}
.info-card-text {
  font-size: 0.72rem;
  color: var(--ink-mid);
  line-height: 1.55;
}

.info-three-col {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 7px;
}
.info-mini-card {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 14px;
  padding: 10px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  text-align: center;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.08);
}
.info-mini-card svg {
  width: 18px;
  height: 18px;
  fill: var(--accent);
}
.info-mini-card strong {
  font-size: 0.72rem;
  color: var(--ink);
  font-weight: 600;
  font-family: "Crimson Pro", Georgia, serif;
}
.info-mini-card span {
  font-size: 0.6rem;
  color: var(--ink-dim);
}

.info-shortcuts-grid {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 14px;
  padding: 10px 14px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px 20px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.08);
}
.info-close-btn {
  margin-top: 6px;
}
.info-sc-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.7rem;
  color: var(--ink-mid);
}

#popup-stats {
  justify-content: flex-start;
  align-items: stretch;
  padding: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

/* ── "Your Stats" popup — reuses the info-card look instead of the
   borderless dashboard-strip style (that style only reads correctly
   inside the lobby's own dashboard card). ── */
#popup-stats .lobby-xp-bar {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-radius: 14px;
  padding: 12px 14px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.08);
}
#popup-stats .lobby-stat-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 7px;
}
#popup-stats .lobby-stat {
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  border-right: none;
  border-radius: 14px;
  padding: 10px 8px;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.08);
}
#popup-stats .lobby-badges {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: none;
}
#popup-stats .lb-more-entry {
  width: 100%;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--ink-mid);
}
#popup-stats .lb-more-entry .lb-rank {
  color: var(--accent);
}
#popup-stats .lb-more-entry .lb-time {
  color: var(--ink-mid);
  font-family: "DM Sans", sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
}
#popup-stats .lb-more-entry:hover {
  border-color: var(--accent);
}
#popup-stats .settings-section-label {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--ink);
}

/* ── Themed scrollbar, global — matches each theme's accent color
   instead of the browser's default gray bar, and stays invisible
   until the element is actually being scrolled (JS toggles the
   .is-scrolling class in game.js). Applies to every scrollable
   screen/popup, not just a couple of pages. NOTE: the puzzle board
   wrap (.arrow-grid-wrap) is the EXCEPTION — it overrides these rules
   further down to keep its scrollbar ALWAYS visible whenever the
   board overflows, so no content ever looks unreachable. ── */
.screen,
.popup-screen,
.arrow-grid-wrap,
.grid-wrap,
html {
  scrollbar-width: none;
  scrollbar-color: transparent transparent;
}
.screen.is-scrolling,
.popup-screen.is-scrolling,
.arrow-grid-wrap.is-scrolling,
.grid-wrap.is-scrolling,
html.is-scrolling {
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}
.screen::-webkit-scrollbar,
.popup-screen::-webkit-scrollbar,
.arrow-grid-wrap::-webkit-scrollbar,
.grid-wrap::-webkit-scrollbar,
html::-webkit-scrollbar {
  width: 8px;
}
.screen::-webkit-scrollbar-track,
.popup-screen::-webkit-scrollbar-track,
.arrow-grid-wrap::-webkit-scrollbar-track,
.grid-wrap::-webkit-scrollbar-track,
html::-webkit-scrollbar-track {
  background: transparent;
}
.screen::-webkit-scrollbar-thumb,
.popup-screen::-webkit-scrollbar-thumb,
.arrow-grid-wrap::-webkit-scrollbar-thumb,
.grid-wrap::-webkit-scrollbar-thumb,
html::-webkit-scrollbar-thumb {
  background-color: transparent;
  border-radius: 8px;
  border: 2px solid transparent;
  background-clip: padding-box;
  transition: background-color 0.25s ease;
}
.screen.is-scrolling::-webkit-scrollbar-thumb,
.popup-screen.is-scrolling::-webkit-scrollbar-thumb,
.arrow-grid-wrap.is-scrolling::-webkit-scrollbar-thumb,
.grid-wrap.is-scrolling::-webkit-scrollbar-thumb,
html.is-scrolling::-webkit-scrollbar-thumb {
  background-color: var(--accent);
}
.screen.is-scrolling::-webkit-scrollbar-thumb:hover,
.popup-screen.is-scrolling::-webkit-scrollbar-thumb:hover,
.arrow-grid-wrap.is-scrolling::-webkit-scrollbar-thumb:hover,
.grid-wrap.is-scrolling::-webkit-scrollbar-thumb:hover,
html.is-scrolling::-webkit-scrollbar-thumb:hover {
  background-color: var(--accent-lt);
}

/* Cartoonic Mode — chunkier, squared-off sticker scrollbar, still
   only shown while actively scrolling */
body.cartoonic-mode .screen.is-scrolling,
body.cartoonic-mode .popup-screen.is-scrolling,
body.cartoonic-mode .arrow-grid-wrap.is-scrolling,
body.cartoonic-mode .grid-wrap.is-scrolling,
body.cartoonic-mode html.is-scrolling {
  scrollbar-color: var(--accent) var(--card-bg);
}
body.cartoonic-mode .screen::-webkit-scrollbar,
body.cartoonic-mode .popup-screen::-webkit-scrollbar,
body.cartoonic-mode .arrow-grid-wrap::-webkit-scrollbar,
body.cartoonic-mode .grid-wrap::-webkit-scrollbar,
body.cartoonic-mode html::-webkit-scrollbar {
  width: 11px;
}
body.cartoonic-mode .screen.is-scrolling::-webkit-scrollbar-track,
body.cartoonic-mode .popup-screen.is-scrolling::-webkit-scrollbar-track,
body.cartoonic-mode .arrow-grid-wrap.is-scrolling::-webkit-scrollbar-track,
body.cartoonic-mode .grid-wrap.is-scrolling::-webkit-scrollbar-track,
body.cartoonic-mode html.is-scrolling::-webkit-scrollbar-track {
  background: var(--card-bg);
  border-radius: 6px;
}

/* ── Custom cursor — matches theme accent, swaps to a pointer-style
   cursor over anything clickable. ── */
html,
body {
  cursor:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="26" height="26" viewBox="0 0 26 26"><path d="M6 2 L6 22 L11 17.2 L14.3 24 L17.6 22.4 L14.4 15.6 L21 15.6 Z" fill="%23e8720f" stroke="white" stroke-width="1.6" stroke-linejoin="round"/></svg>')
      4 2,
    auto;
}
a,
button,
.icon-btn,
.game-act-btn,
.btn-play-big,
.num-btn,
.lobby-mode-chip,
.chance-heart,
[role="button"],
.diff-option-item,
.theme-card,
.skin-card,
input[type="checkbox"],
input[type="radio"],
select,
.popup-btn-primary,
.popup-btn-secondary,
.popup-btn-danger {
  cursor:
    url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28"><circle cx="14" cy="14" r="8" fill="%23e8720f" fill-opacity="0.85" stroke="white" stroke-width="2"/></svg>')
      14 14,
    pointer;
}
body.cartoonic-mode #s-info::-webkit-scrollbar-thumb,
body.cartoonic-mode #popup-stats::-webkit-scrollbar-thumb {
  border-radius: 6px;
  border: 2px solid var(--box-border);
  background-clip: padding-box;
}
.kbd-inline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 20px;
  padding: 0 5px;
  background: var(--paper2);
  border: 1px solid var(--ink-faint);
  border-bottom-width: 2px;
  border-radius: 4px;
  font-size: 0.62rem;
  color: var(--ink);
  font-family: monospace;
  flex-shrink: 0;
  white-space: nowrap;
}

/* ════════════════════════════════════════════════
   TOAST
════════════════════════════════════════════════ */
#toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%) translateY(80px);
  background: var(--ink);
  color: var(--paper);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  padding: 0.65em 1.6em;
  border-radius: 20px;
  z-index: 100;
  transition:
    transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
    opacity 0.3s;
  opacity: 0;
  white-space: nowrap;
  pointer-events: none;
}
#toast.show {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
}
#toast.success {
  background: var(--success);
  color: var(--paper);
}
#toast.error {
  background: var(--error-txt);
}

body[data-theme="neon"] #toast {
  border-radius: 0;
}
body[data-theme="jungle"] #toast.success {
  color: #0a1a0c;
}

/* ════════════════════════════════════════════════
   ANIMATIONS
════════════════════════════════════════════════ */
@keyframes cellPop {
  0% {
    transform: scale(1);
  }
  40% {
    transform: scale(1.18);
  }
  100% {
    transform: scale(1);
  }
}
.cell-pop {
  animation: cellPop 0.15s ease;
}

@keyframes shake {
  0%,
  100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-4px);
  }
  40% {
    transform: translateX(4px);
  }
  60% {
    transform: translateX(-3px);
  }
  80% {
    transform: translateX(3px);
  }
}
.shake {
  animation: shake 0.3s ease;
}

@keyframes cellWin {
  0% {
    background: var(--cell-bg);
  }
  50% {
    background: var(--accent-bg);
  }
  100% {
    background: rgba(40, 120, 64, 0.1);
  }
}
.cell-win {
  animation: cellWin 0.6s ease forwards;
}

/* ════════════════════════════════════════════════
   IN-GAME POPUP SCREENS
   (Resume, New Game, Quit — full-screen lobby style)
════════════════════════════════════════════════ */

/* Overlay backdrop behind popup screen — solid lobby-style page */
.popup-screen {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  /* Solid background matching the lobby: theme's fixed image + overlay */
  background-image: var(--bg-image);
  background-size: cover;
  background-position: center;
  transition:
    opacity 0.32s cubic-bezier(0.4, 0, 0.2, 1),
    transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Theme overlay on top of the bg image — mirrors body::before */
.popup-screen::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--bg-overlay);
  transition: background 0.4s;
  pointer-events: none;
}
/* Obsidian Night scanlines on popup */
body[data-theme="neon"] .popup-screen {
  background-image:
    repeating-linear-gradient(
      0deg,
      transparent,
      transparent 2px,
      rgba(6, 96, 214, 0.025) 2px,
      rgba(6, 96, 214, 0.025) 4px
    ),
    var(--bg-image);
  background-size: auto, cover;
  background-position: auto, center;
}
/* Ensure card sits above the pseudo-element overlay */
.popup-screen .popup-card {
  position: relative;
  z-index: 1;
}
.popup-screen.out {
  opacity: 0;
  pointer-events: none;
  transform: scale(1.02);
}

/* Central card — lobby style panel */
.popup-card {
  width: 100%;
  max-width: 340px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  animation: popupSlideIn 0.28s cubic-bezier(0.34, 1.4, 0.64, 1) both;
}
@keyframes popupSlideIn {
  from {
    opacity: 0;
    transform: scale(0.9) translateY(20px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

/* Popup brand title */
.popup-brand {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(2.8rem, 9vw, 4.2rem);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1.05;
  margin-bottom: clamp(8px, 1.5vh, 14px);
  text-align: center;
}
.popup-brand-dot {
  color: var(--accent);
}

/* Image logo used in place of the text wordmark on the preparing
   screen and the in-game pause popup — smaller than the lobby logo */
.popup-brand-logo {
  display: block;
  width: clamp(130px, 32vw, 190px);
  height: auto;
  margin: 0 auto clamp(10px, 2vh, 16px);
}

/* Larger on the puzzle-solved page now that the star icon above it is
   gone — it has the room to be a proper brand mark instead of a small
   discreet one. */
.complete-page-logo {
  width: clamp(150px, 34vw, 210px);
  margin: 0 auto clamp(10px, 2vh, 18px);
}

.popup-sub {
  font-size: clamp(0.62rem, 2vw, 0.78rem);
  letter-spacing: 0.48em;
  color: var(--ink-dim);
  text-transform: uppercase;
  margin-bottom: clamp(18px, 4vh, 30px);
  text-align: center;
}

.popup-rule-line {
  width: clamp(100px, 30vw, 180px);
  height: 1px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--grid-thick),
    transparent
  );
  margin: 0 auto clamp(20px, 4vh, 32px);
}
body[data-theme="neon"] .popup-rule-line {
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 6px var(--accent);
}
body[data-theme="jungle"] .popup-rule-line {
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
}

/* Game info strip (time + moves) inside popups */
.popup-info-strip {
  display: flex;
  gap: 10px;
  width: 100%;
  margin-bottom: clamp(16px, 3vh, 26px);
}
.popup-info-cell {
  flex: 1;
  text-align: center;
  padding: 12px 8px 10px;
  background: var(--card-bg);
  border: 1px solid var(--ink-faint);
  border-radius: 12px;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
body[data-theme="neon"] .popup-info-cell {
  border-radius: 0;
}
.popup-info-val {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.2rem, 4vw, 1.6rem);
  font-weight: 600;
  color: var(--accent);
  line-height: 1;
}
.popup-info-lbl {
  font-size: 0.48rem;
  letter-spacing: 0.25em;
  color: var(--ink-dim);
  text-transform: uppercase;
}

/* Popup action buttons — big primary + secondary */
.popup-btn-stack {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.popup-btn-primary {
  width: 100%;
  padding: 1em 2em;
  background: rgba(255, 255, 255, 0.92);
  border: none;
  border-radius: var(--radius);
  color: var(--ink);
  font-family: "DM Sans", sans-serif;
  font-size: 0.85rem;
  letter-spacing: 0.2em;
  cursor: pointer;
  text-transform: uppercase;
  transition:
    background 0.2s,
    transform 0.15s,
    box-shadow 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.popup-btn-primary:hover {
  background: var(--accent);
  color: var(--btn-primary-color);
  transform: translateY(-1px);
}
.popup-btn-primary:disabled {
  cursor: not-allowed;
  opacity: 0.45;
  filter: grayscale(0.5);
}
.popup-btn-primary:disabled:hover {
  background: rgba(255, 255, 255, 0.92);
  color: var(--ink);
  transform: none;
}
.popup-btn-primary svg {
  width: 18px;
  height: 18px;
  fill: currentColor;
  flex-shrink: 0;
}

.popup-btn-secondary {
  width: 100%;
  padding: 0.8em 2em;
  background: var(--card-bg);
  border: 1.5px solid var(--ink-faint);
  border-radius: var(--radius);
  color: var(--ink-mid);
  font-family: "DM Sans", sans-serif;
  font-size: 0.78rem;
  letter-spacing: 0.15em;
  cursor: pointer;
  text-transform: uppercase;
  transition:
    border-color 0.2s,
    color 0.2s,
    transform 0.15s;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.popup-btn-secondary:hover {
  border-color: var(--ink);
  color: var(--ink);
  transform: translateY(-1px);
}
.popup-btn-secondary svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
  flex-shrink: 0;
}

.popup-btn-danger {
  width: 100%;
  padding: 0.8em 2em;
  background: transparent;
  border: 1.5px solid var(--ink-faint);
  border-radius: var(--radius);
  color: var(--ink-dim);
  font-family: "DM Sans", sans-serif;
  font-size: 0.78rem;
  letter-spacing: 0.15em;
  cursor: pointer;
  text-transform: uppercase;
  transition:
    border-color 0.2s,
    color 0.2s,
    transform 0.15s;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.popup-btn-danger:hover {
  border-color: var(--error-txt);
  color: var(--error-txt);
  transform: translateY(-1px);
}
.popup-btn-danger:disabled {
  cursor: not-allowed;
  opacity: 0.45;
  filter: grayscale(0.5);
}
.popup-btn-danger:disabled:hover {
  border-color: var(--ink-faint);
  color: var(--ink-dim);
  transform: none;
}
.popup-btn-danger svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
  flex-shrink: 0;
}

/* Neon popup buttons */
body[data-theme="neon"] .popup-btn-primary,
body[data-theme="neon"] .popup-btn-secondary,
body[data-theme="neon"] .popup-btn-danger {
  border-radius: 0;
}
body[data-theme="neon"] .popup-btn-primary:hover {
  box-shadow: 0 0 20px rgba(6, 96, 214, 0.4);
}

/* Pause icon button (top bar) */
.btn-pause,
#btn-sound-game {
  width: clamp(38px, 9vw, 48px);
  height: clamp(38px, 9vw, 48px);
  border-radius: 0;
  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition:
    transform 0.15s,
    filter 0.2s;
  flex-shrink: 0;
}
.btn-pause:hover,
#btn-sound-game:hover {
  transform: translateY(-2px) scale(1.06);
}
.btn-pause:disabled,
#btn-sound-game:disabled {
  cursor: not-allowed;
  opacity: 0.4;
  filter: grayscale(0.5) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}
.btn-pause:disabled:hover,
#btn-sound-game:disabled:hover {
  transform: none;
}
.btn-pause svg,
#btn-sound-game svg {
  width: 50%;
  height: 50%;
  fill: currentColor;
  display: block;
  flex-shrink: 0;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
}
body[data-theme="warm"] .btn-pause,
body[data-theme="warm"] #btn-sound-game {
  background-image: url("../images/btn-bg/btn-bg-warm.webp");
}
body[data-theme="jungle"] .btn-pause,
body[data-theme="jungle"] #btn-sound-game {
  background-image: url("../images/btn-bg/btn-bg-jungle.webp");
}
body[data-theme="neon"] .btn-pause,
body[data-theme="neon"] #btn-sound-game {
  background-image: url("../images/btn-bg/btn-bg-neon.webp");
}
body[data-theme="midnight"] .btn-pause,
body[data-theme="midnight"] #btn-sound-game {
  background-image: url("../images/btn-bg/btn-bg-midnight.webp");
}
body[data-theme="rosegold"] .btn-pause,
body[data-theme="rosegold"] #btn-sound-game {
  background-image: url("../images/btn-bg/btn-bg-rosegold.webp");
}

/* ════════════════════════════════════════════════
   CONFIRM DIALOG (legacy, kept for safety)
════════════════════════════════════════════════ */
#confirm-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, 0.55);
  align-items: center;
  justify-content: center;
}
.confirm-box {
  background: var(--paper);
  border: 1px solid var(--grid-thick);
  border-radius: 10px;
  padding: 28px 24px 22px;
  width: min(300px, 86vw);
  text-align: center;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.3);
  animation: confirmSlide 0.2s ease both;
}
@keyframes confirmSlide {
  from {
    opacity: 0;
    transform: scale(0.93) translateY(10px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}
.confirm-icon {
  font-size: 2rem;
  margin-bottom: 8px;
}
.confirm-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 6px;
}
.confirm-msg {
  font-size: 0.72rem;
  color: var(--ink-mid);
  line-height: 1.6;
  margin-bottom: 22px;
}
.confirm-btns {
  display: flex;
  gap: 10px;
  justify-content: center;
}
.confirm-cancel {
  flex: 1;
  max-width: 110px;
  padding: 0.6em 1em;
  background: transparent;
  border: 1.5px solid var(--ink-faint);
  border-radius: 6px;
  color: var(--ink-mid);
  font-family: "DM Sans", sans-serif;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  cursor: pointer;
  text-transform: uppercase;
  transition: all 0.18s;
}
.confirm-cancel:hover {
  border-color: var(--ink);
  color: var(--ink);
}
.confirm-ok {
  flex: 1;
  max-width: 110px;
  padding: 0.6em 1em;
  background: rgba(255, 255, 255, 0.92);
  border: none;
  border-radius: 6px;
  color: var(--ink);
  font-family: "DM Sans", sans-serif;
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  cursor: pointer;
  text-transform: uppercase;
  transition: all 0.18s;
}
.confirm-ok:hover {
  background: var(--accent);
  color: var(--btn-primary-color);
}

/* ════════════════════════════════════════════════
   BROWSER NOT SUPPORTED SCREEN
   Reuses loader screen structure
════════════════════════════════════════════════ */
#s-nosupport {
  display: none; /* shown via JS only when needed */
  position: fixed;
  inset: 0;
  z-index: 200;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  text-align: center;
}

#s-nosupport.visible {
  display: flex;
}

.nosupport-icon {
  width: 56px;
  height: 56px;
  margin-bottom: 24px;
  color: var(--accent);
  opacity: 0.85;
}
.nosupport-icon svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.nosupport-title {
  font-family: "Crimson Pro", Georgia, serif;
  font-size: clamp(1.4rem, 5vw, 2rem);
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 10px;
  letter-spacing: -0.01em;
}

.nosupport-msg {
  font-size: clamp(0.7rem, 2.2vw, 0.85rem);
  color: var(--ink-mid);
  line-height: 1.7;
  max-width: 320px;
  margin-bottom: 28px;
}

.nosupport-browsers {
  display: flex;
  gap: 16px;
  align-items: center;
  justify-content: center;
  margin-bottom: 28px;
  flex-wrap: wrap;
}

.nosupport-browser {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  opacity: 0.7;
}

.nosupport-browser-icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--card-bg);
  border: 1px solid var(--ink-faint);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
}

.nosupport-browser-name {
  font-size: 0.5rem;
  letter-spacing: 0.2em;
  color: var(--ink-dim);
  text-transform: uppercase;
}

.nosupport-bar-wrap {
  width: clamp(140px, 45vw, 220px);
  height: 2px;
  background: var(--ink-faint);
  border-radius: 2px;
  overflow: hidden;
  opacity: 0.4;
}

/* ═══════════════════════════════════════════════════════════════
   CARTOONIC MODE — Settings → Appearance → Cartoonic Mode
   Adds chunky sticker-style borders + a playful heading font on
   top of whichever theme is active. Every color below is pulled
   from that theme's own CSS variables, so no theme color changes —
   only borders / shadows / font / radius.
═══════════════════════════════════════════════════════════════ */

/* Headings & logo — playful rounded font */
body.cartoonic-mode .brand,
body.cartoonic-mode .loading-brand,
body.cartoonic-mode .popup-brand {
  font-family: "Baloo 2", "Crimson Pro", Georgia, serif;
  font-weight: 700;
}
body.cartoonic-mode .page-title,
body.cartoonic-mode .popup-sub,
body.cartoonic-mode .brand-sub,
body.cartoonic-mode .loading-sub,
body.cartoonic-mode .lobby-mode-chip span,
body.cartoonic-mode .diff-name,
body.cartoonic-mode .lobby-xp-level,
body.cartoonic-mode .settings-row-label,
body.cartoonic-mode .info-card-title,
body.cartoonic-mode .hint-bar,
body.cartoonic-mode .toggle-lbl,
body.cartoonic-mode .diff-subheading,
body.cartoonic-mode .prep-sub {
  font-family: "Baloo 2", "DM Sans", sans-serif;
  font-weight: 600;
}

/* Preparing-puzzle screen + mode/difficulty card descriptions —
   pick up the cartoonic font too, same treatment as .diff-name */
body.cartoonic-mode .prep-title {
  font-family: "Baloo 2", "Crimson Pro", Georgia, serif;
  font-weight: 700;
}
body.cartoonic-mode .diff-desc {
  font-family: "Baloo 2", "DM Sans", sans-serif;
  font-weight: 500;
}

/* Chunky sticker borders on UI chrome. */
body.cartoonic-mode .popup-btn-primary,
body.cartoonic-mode .popup-btn-secondary,
body.cartoonic-mode .popup-btn-danger,
body.cartoonic-mode .lobby-mode-chip,
body.cartoonic-mode .diff-card,
body.cartoonic-mode .settings-row,
body.cartoonic-mode .info-card,
body.cartoonic-mode .info-mini-card,
body.cartoonic-mode .info-shortcuts-grid,
body.cartoonic-mode .lobby-stat,
body.cartoonic-mode .lobby-xp-bar {
  border: 3px solid var(--box-border) !important;
  box-shadow: 4px 4px 0 var(--box-border) !important;
}

/* Play button and lobby icon buttons keep their plain themed artwork
   in cartoonic mode too — no sticker border/shadow on either. */

/* Chunky press-down feel on tap */
body.cartoonic-mode .popup-btn-primary:active,
body.cartoonic-mode .popup-btn-secondary:active,
body.cartoonic-mode .popup-btn-danger:active {
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--box-border) !important;
}

/* Rounder, stickier corners */
body.cartoonic-mode .lobby-mode-chip,
body.cartoonic-mode .diff-card,
body.cartoonic-mode .settings-row,
body.cartoonic-mode .info-card {
  border-radius: 16px !important;
}
body.cartoonic-mode .popup-btn-primary,
body.cartoonic-mode .popup-btn-secondary,
body.cartoonic-mode .popup-btn-danger {
  border-radius: 12px !important;
}

/* Toggle switches get an outline to match the sticker look */
body.cartoonic-mode .sw-track {
  border: 2px solid var(--box-border) !important;
  border-radius: 999px !important;
}
body.cartoonic-mode .toggle-box {
  border-width: 2.5px !important;
  border-color: var(--box-border) !important;
  border-radius: 5px !important;
}
body.cartoonic-mode .toggle-item.on .toggle-box {
  border-color: var(--box-border) !important;
}
body.cartoonic-mode .mistake-dot {
  border: 1.5px solid var(--box-border);
}

/* ── In-game screen + remaining buttons (previously missed) ── */
/* diff-back-btn / game-act-btn keep their plain themed artwork in
   cartoonic mode too, same as the lobby icon buttons — no sticker
   border/shadow on any of them. */
body.cartoonic-mode .btn-begin,
body.cartoonic-mode .btn-pause,
body.cartoonic-mode .num-btn,
body.cartoonic-mode .btn-comp,
body.cartoonic-mode .lb-entry,
body.cartoonic-mode .lb-clear {
  border: 3px solid var(--box-border) !important;
  box-shadow: 4px 4px 0 var(--box-border) !important;
}
body.cartoonic-mode .btn-pause {
  box-shadow: 3px 3px 0 var(--box-border) !important;
}
body.cartoonic-mode .num-btn {
  border-radius: 14px !important;
  box-shadow: 2px 2px 0 var(--box-border) !important;
}
body.cartoonic-mode .btn-begin,
body.cartoonic-mode .btn-comp {
  border-radius: 12px !important;
}

/* Press-down feel for the newly added buttons too */
body.cartoonic-mode .btn-begin:active,
body.cartoonic-mode .btn-pause:active,
body.cartoonic-mode .num-btn:active,
body.cartoonic-mode .btn-comp:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--box-border) !important;
}

/* Extra headings pick up the cartoonic font too */
body.cartoonic-mode .diff-heading,
body.cartoonic-mode .complete-title,
body.cartoonic-mode .top-title,
body.cartoonic-mode #popup-stats .settings-section-label {
  font-family: "Baloo 2", "Crimson Pro", Georgia, serif;
  font-weight: 700;
}

/* Popup cards (pause / stats / new-game / reset) — a clean floating
   card with no chunky outline, just rounded corners + soft shadow.
   Keeps the buttons inside them cartoonic without the messy look of
   a border-inside-a-border. NOTE: .sponsor-card is intentionally
   excluded — it's a full-bleed layout with no card wrapper, so this
   shadow/radius would float around empty space with no background
   under it. */
body.cartoonic-mode .popup-card:not(.sponsor-card),
body.cartoonic-mode .confirm-box {
  border: none !important;
  border-radius: 20px !important;
  box-shadow: none !important;
}

/* Sponsor / ad page — its own elements get the cartoonic treatment
   directly, instead of a floating card shadow around the whole page. */
body.cartoonic-mode .sponsor-title {
  font-family: "Baloo 2", "Crimson Pro", Georgia, serif;
  font-weight: 700;
  font-size: clamp(1.5rem, 6vw, 2.5rem);
}
body.cartoonic-mode .sponsor-slot {
  border: 3px solid var(--box-border) !important;
  border-radius: 16px !important;
  box-shadow: 4px 4px 0 var(--box-border) !important;
}
body.cartoonic-mode .sponsor-skip-btn {
  border: 3px solid var(--box-border) !important;
  border-radius: 12px !important;
  box-shadow: 3px 3px 0 var(--box-border) !important;
}
body.cartoonic-mode .sponsor-skip-btn:active {
  transform: translate(2px, 2px);
  box-shadow: 1px 1px 0 var(--box-border) !important;
}

/* ── In-game topbar — badge, stat boxes, header bar, board ── */
body.cartoonic-mode .top-diff-badge {
  border: 2.5px solid var(--box-border) !important;
  box-shadow: 2px 2px 0 var(--box-border) !important;
}
body.cartoonic-mode .stat-item {
  background: var(--card-bg);
  border: 2.5px solid var(--box-border) !important;
  border-radius: 12px !important;
  padding: 4px 10px !important;
  box-shadow: 2px 2px 0 var(--box-border) !important;
}
body.cartoonic-mode .game-page-header {
  border-bottom: 3px solid var(--box-border) !important;
  box-shadow: 0 4px 0 var(--box-border) !important;
}
body.cartoonic-mode .grid-wrap {
  border: 4px solid var(--box-border) !important;
  box-shadow: 5px 5px 0 var(--box-border) !important;
}

/* Board numbers — match the Cartoonic Mode font instead of the
   default serif so the puzzle grid text looks consistent with the
   rest of the cartoonic UI. */
body.cartoonic-mode .cell-num {
  font-family: "Baloo 2", "DM Sans", sans-serif;
  font-weight: 700;
}
body.cartoonic-mode .pencil-mark {
  font-family: "Baloo 2", "DM Sans", sans-serif;
  font-weight: 600;
}

/* ════════════════════════════════════════════════════════════
   CLASSIC PUZZLE MODE — ported from Arrow Trace (arrow board)
   Colors use the SAME theme variables as the rest of Arrow Trace
   (--accent, --ink, --error-txt) so every theme auto-matches.
════════════════════════════════════════════════════════════ */
.arrow-grid-wrap {
  display: flex;
  /* `safe` alignment: when the board is taller/wider than the wrap the
     fallback is flex-start, so the TOP of the shape is never clipped and
     unreachable — the overflow stays reachable via the scrollbar instead
     of being hidden above the fold. */
  align-items: safe center;
  justify-content: safe center;
  background: transparent !important;
  border: none !important;
  outline: none !important;
  box-shadow: none !important;
  padding: 0 !important;
  /* Hard safety ceiling: sizeArrowBoard() in game.js computes an exact
     pixel width for this wrap based on the header/sidebar layout, but
     if that measurement ever runs a beat too early (e.g. before a
     webfont finishes loading and the header grows a little taller), the
     wrap could end up wider/taller than what's actually available and
     spill out past the topbar. These caps make that impossible — the
     wrap (and the SVG inside it, which is width:100%/height:auto) can
     never exceed the viewport no matter what the JS math comes out to.
     On very short screens the board can still be taller than this cap
     even at the minimum cell size (ARROW_CELL_PX_MIN in game.js) — in
     that case scroll instead of hard-clipping it away. */
  overflow-y: auto !important;
  overflow-x: hidden !important;
  max-width: 100% !important;
  max-height: 100% !important;
  box-sizing: border-box;
  /* The board wrap's scrollbar is ALWAYS visible whenever the board
     overflows — no scroll-event/hover dependency and no hiding — so
     players can always tell the shape extends past the viewport. */
  scrollbar-width: thin;
  scrollbar-color: var(--accent) transparent;
}
.arrow-grid-wrap::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.arrow-grid-wrap::-webkit-scrollbar-track {
  background: transparent;
}
.arrow-grid-wrap::-webkit-scrollbar-thumb {
  background-color: var(--accent);
  border-radius: 8px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.arrow-grid-wrap::-webkit-scrollbar-thumb:hover {
  background-color: var(--accent-lt);
}
body.cartoonic-mode .arrow-grid-wrap {
  scrollbar-color: var(--accent) var(--card-bg);
}
body.cartoonic-mode .arrow-grid-wrap::-webkit-scrollbar {
  width: 11px;
}
body.cartoonic-mode .arrow-grid-wrap::-webkit-scrollbar-track {
  background: var(--card-bg);
  border-radius: 6px;
}
/* Skin (2D/3D Puzzle) boards use the EXACT same fit behavior as classic
   boards on every screen: the JS sizes the board to the available space
   at all breakpoints (smaller cells on phones, medium on tablets, larger
   on PCs) so the whole shape always fits and no scrollbar ever appears. */
.arrow-board {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}
.arrow-tile {
  cursor: pointer;
}
.arrow-tile-hit {
  fill: transparent;
  pointer-events: all;
}
.arrow-tile-line {
  fill: none;
  stroke: var(--ink);
  stroke-width: var(--arrow-stroke, 0.2);
  stroke-linecap: round;
  stroke-linejoin: round;
  transition:
    stroke 0.15s,
    filter 0.15s,
    opacity 0.28s,
    transform 0.28s;
  pointer-events: none;
}
.arrow-tile-head {
  fill: var(--ink);
  transition:
    fill 0.15s,
    opacity 0.28s,
    transform 0.28s;
  pointer-events: none;
}
.skin-tile-img {
  transition:
    opacity 0.28s,
    filter 0.15s;
  pointer-events: none;
}
/* Hover/hint highlight used to live on a never-rotated rect. On hover it's
   now hidden entirely (see below) so no full-box border shows — the glow
   instead comes from a drop-shadow on the skin <image> itself. The rect
   still exists for the gold HINT pulse (and stays invisible otherwise). */
.skin-tile-highlight {
  fill: none;
  stroke: transparent;
  stroke-width: 0.05;
  opacity: 0;
  transition:
    opacity 0.15s,
    stroke 0.15s;
  pointer-events: none;
}
/* Hover: subtle glow that follows the skin art only — NO full-box border or
   box tint. The highlight rect is hidden on hover and a drop-shadow filter
   on the (rotated) skin <image> glows the actual skin shape under the
   pointer, so the effect always hugs exactly the skin being hovered, never
   its cell/parent container. */
.arrow-tile.skin-tile.hovered .skin-tile-highlight {
  opacity: 0;
}
.arrow-tile.skin-tile.hovered .skin-tile-img {
  filter: drop-shadow(0 0 0.06 var(--accent-lt))
    drop-shadow(0 0 0.14 var(--accent));
}
.arrow-tile.hinted .skin-tile-highlight {
  stroke: gold;
  fill: gold;
  fill-opacity: 0.12;
  opacity: 1;
  animation: arrowHintPulse 1.1s ease-in-out infinite;
}

/* Bomb power-up explosion burst — white-hot flash, orange shockwave
   ring, flame petals, rising embers and drifting smoke, spawned at the
   cell of the arrow the bomb clears. .bomb-burst-big scales it up for
   the Big Bomb power-up. */
.bomb-burst {
  pointer-events: none;
}
.bomb-burst-flash {
  fill: #fff8e6;
  opacity: 0.95;
  transform-box: fill-box;
  transform-origin: center;
  animation: bombFlash 0.24s ease-out forwards;
}
@keyframes bombFlash {
  0% {
    r: 0.05;
    opacity: 0.95;
  }
  100% {
    r: 0.6;
    opacity: 0;
  }
}
.bomb-burst-ring {
  fill: none;
  stroke: #ff8a3d;
  stroke-width: 0.06;
  opacity: 0.9;
  transform-box: fill-box;
  transform-origin: center;
  animation: bombRing 0.46s ease-out forwards;
}
.bomb-burst-big .bomb-burst-ring {
  stroke-width: 0.08;
}
@keyframes bombRing {
  0% {
    r: 0.1;
    opacity: 0.9;
    stroke-width: 0.07;
  }
  100% {
    r: 0.85;
    opacity: 0;
    stroke-width: 0.01;
  }
}

/* Flame petals — teardrop shapes fired outward from the blast center,
   spinning slightly and shrinking as they cool from yellow to red. */
.bomb-burst-flame {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0;
  animation: bombFlame 0.5s cubic-bezier(0.15, 0.7, 0.3, 1) forwards;
}
.flame-tone-0 {
  fill: #ffd469;
}
.flame-tone-1 {
  fill: #ff8a3d;
}
.flame-tone-2 {
  fill: #ff4d3d;
}
@keyframes bombFlame {
  0% {
    opacity: 1;
    transform: translate(0, 0) scale(var(--flame-scale, 1)) rotate(0deg);
  }
  100% {
    opacity: 0;
    transform: translate(var(--flame-x, 0), var(--flame-y, 0)) scale(0.15)
      rotate(35deg);
  }
}

/* Rising embers — small glowing dots that drift up and flicker out. */
.bomb-burst-ember {
  fill: #ffb454;
  opacity: 0;
  filter: drop-shadow(0 0 0.03px #ff8a3d);
  animation: bombEmber 0.6s ease-out forwards;
}
@keyframes bombEmber {
  0% {
    opacity: 0;
    transform: translate(0, 0);
  }
  15% {
    opacity: 1;
  }
  60% {
    opacity: 0.85;
  }
  100% {
    opacity: 0;
    transform: translate(var(--ember-x, 0), var(--ember-rise, -0.3));
  }
}

/* Smoke puffs — soft blurred circles blooming up and away after the
   flash, fading out slower than the flames for a lingering-blast feel. */
.bomb-burst-smoke {
  fill: #6b6660;
  opacity: 0;
  filter: blur(0.02px);
  transform-box: fill-box;
  transform-origin: center;
  animation: bombSmoke 0.72s ease-out forwards;
}
@keyframes bombSmoke {
  0% {
    opacity: 0;
    r: 0.05;
    transform: translate(0, 0);
  }
  20% {
    opacity: 0.4;
  }
  100% {
    opacity: 0;
    r: var(--smoke-r, 0.3);
    transform: translate(var(--smoke-x, 0), var(--smoke-rise, -0.4));
  }
}
.arrow-tile.hovered .arrow-tile-line {
  stroke: var(--accent);
}
.arrow-tile.hovered .arrow-tile-head {
  fill: var(--accent);
}
.arrow-tile.hinted .arrow-tile-line {
  stroke: var(--accent);
  animation: arrowHintPulse 1.1s ease-in-out infinite;
}
.arrow-tile.hinted .arrow-tile-head {
  fill: var(--accent);
}
@keyframes arrowHintPulse {
  0%,
  100% {
    opacity: 1;
    filter: drop-shadow(0 0 3px var(--accent));
  }
  50% {
    opacity: 0.5;
  }
}
.arrow-tile.blocked .arrow-tile-line {
  stroke: var(--error-txt);
}
.arrow-tile.blocked .arrow-tile-head {
  fill: var(--error-txt);
}
.arrow-tile.blocked {
  animation: arrowShake 0.36s ease;
}
/* Path Reveal power-up — sweeps a golden glow across the full solve
   order, distinct from the single-arrow hint pulse. */
.arrow-tile.path-revealed .arrow-tile-line {
  stroke: #ffc55c;
  animation: pathRevealPulse 0.5s ease-out;
}
.arrow-tile.path-revealed .arrow-tile-head {
  fill: #ffc55c;
}
/* Skin puzzle tiles — golden glow on the skin image itself, applied via
   the shared #path-reveal-glow SVG filter. CSS `filter: drop-shadow()`
   on an <image> inside an SVG renders inconsistently across mobile
   WebViews (the same problem the ghost imprints already solved by
   switching to a real SVG <filter>) — an actual SVG filter is applied
   identically everywhere. Only opacity is animated; the gold halo
   itself stays a static filter for the whole 2s reveal. */
.arrow-tile.skin-tile.path-revealed .skin-tile-img {
  filter: url(#path-reveal-glow);
  animation: pathRevealPulseSkin 0.5s ease-out;
}
@keyframes pathRevealPulseSkin {
  0% {
    opacity: 0.45;
  }
  40% {
    opacity: 1;
  }
  100% {
    opacity: 1;
  }
}
@keyframes pathRevealPulse {
  0% {
    opacity: 0.3;
    filter: drop-shadow(0 0 0 #ffc55c);
  }
  40% {
    opacity: 1;
    filter: drop-shadow(0 0 4px #ffc55c);
  }
  100% {
    opacity: 1;
    filter: drop-shadow(0 0 2px #ffc55c);
  }
}
/* Level badge now sits above the right action-button sidebar,
   styled to match the numbered power-count boxes on the opposite
   sidebar — bordered box on the card surface, not a solid pill. */
.level-badge-top {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--card-bg);
  border: 1.5px solid var(--card-border);
  border-radius: calc(var(--radius) * 0.6);
  padding: 0.75em 0.6em;
  min-height: 52px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1.35;
  white-space: normal;
  width: 100%;
  max-width: 128px;
  margin: 0 auto;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.level-badge-top .level-badge-line1 {
  display: block;
  opacity: 0.75;
  font-size: 0.92em;
}
.level-badge-top .level-badge-line2 {
  display: block;
  margin-top: 0.1em;
}
/* Neon theme squares off every badge — match that here too */
body[data-theme="neon"] .level-badge-top {
  border-radius: 0;
}
.chances-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ink-dim);
  text-transform: uppercase;
  width: 100%;
  margin-top: 0;
}
.chance-hearts {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 3px;
}
.chance-heart {
  width: 14px;
  height: 14px;
  color: var(--error-txt);
  transition:
    transform 0.25s,
    opacity 0.25s;
}
.chance-heart svg {
  width: 100%;
  height: 100%;
  fill: currentColor;
}
.chance-heart.lost {
  color: var(--ink-faint);
  opacity: 0.5;
  transform: scale(0.75);
}
@keyframes arrowShake {
  0%,
  100% {
    transform: translateX(0);
  }
  20% {
    transform: translateX(-2px);
  }
  40% {
    transform: translateX(2px);
  }
  60% {
    transform: translateX(-1.5px);
  }
  80% {
    transform: translateX(1.5px);
  }
}
.arrow-tile.clearing {
  pointer-events: none;
}
.arrow-ghost {
  pointer-events: none;
  opacity: 0.45;
}
.arrow-ghost .arrow-tile-line,
.arrow-ghost .arrow-tile-head {
  filter: grayscale(1);
}
.arrow-ghost.skin-ghost .skin-tile-img {
  filter: grayscale(1);
}
.level-shape-icon {
  width: 100%;
  height: 100%;
}
.level-shape-icon rect {
  fill: currentColor;
}

/* ════════════════════════════════════════════════
   REAL-TIME TUTORIAL (first two Classic levels)
   Card + target ring float above the board inside
   .game-body (position: relative). The overlay itself
   never eats clicks — only the card and its buttons do.
   Styled to match the game's card language: frosted
   card-bg surfaces, accent borders on active steps,
   pill buttons, and full Cartoonic-mode support.
════════════════════════════════════════════════ */
.tutorial-overlay {
  position: absolute;
  inset: 0;
  z-index: 12;
  pointer-events: none;
  overflow: hidden;
}
.tutorial-overlay[hidden] {
  display: none;
}

/* ── Target highlight: pulsing ring + tapping hand ── */
.tutorial-target {
  position: absolute;
  pointer-events: none;
  z-index: 1;
}
.tutorial-target[hidden] {
  display: none;
}
.tutorial-ring {
  position: absolute;
  inset: 0;
  border: 3px solid var(--accent);
  border-radius: 14px;
  box-shadow:
    0 0 0 3px rgba(255, 255, 255, 0.75),
    0 0 0 8px var(--accent-bg),
    0 0 26px 6px var(--accent);
  animation: tutorialRingPulse 1.2s ease-in-out infinite;
}
@keyframes tutorialRingPulse {
  0%,
  100% {
    transform: scale(1);
    opacity: 1;
  }
  50% {
    transform: scale(1.06);
    opacity: 0.72;
  }
}
.tutorial-hand {
  position: absolute;
  width: 40px;
  height: 40px;
  right: -20px;
  bottom: -20px;
  fill: var(--accent);
  stroke: rgba(255, 255, 255, 0.9);
  stroke-width: 1.6;
  paint-order: stroke;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.4));
  animation: tutorialHandTap 0.95s ease-in-out infinite;
}
@keyframes tutorialHandTap {
  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }
  45% {
    transform: translate(-4px, -6px) scale(0.9);
  }
  62% {
    transform: translate(0, 0) scale(1.08);
  }
}

/* ── Tutorial card ── */
.tutorial-card {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  width: min(430px, calc(100% - 24px));
  display: flex;
  flex-direction: column;
  gap: 11px;
  padding: 13px 16px 15px;
  background: var(--card-bg);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1.5px solid var(--card-border);
  border-radius: var(--radius);
  box-shadow:
    0 10px 30px rgba(0, 0, 0, 0.22),
    0 2px 8px rgba(0, 0, 0, 0.12);
  color: var(--ink);
  pointer-events: auto;
  animation: tutorialCardIn 0.3s cubic-bezier(0.34, 1.4, 0.64, 1);
  transition:
    border-color 0.25s,
    box-shadow 0.25s;
}
/* Active (guided) steps glow with the theme accent — same treatment the
   game uses on selected cards, so the player knows it's their turn to act. */
.tutorial-card.live {
  border-color: var(--accent);
  box-shadow:
    0 0 0 3px var(--accent-bg),
    0 10px 30px rgba(0, 0, 0, 0.24),
    0 0 24px 4px var(--accent);
}
@keyframes tutorialCardIn {
  from {
    transform: translateX(-50%) translateY(22px);
    opacity: 0;
  }
  to {
    transform: translateX(-50%) translateY(0);
    opacity: 1;
  }
}

/* Brand row: wordmark kicker + step counter pill */
.tutorial-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.tutorial-kicker {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: "DM Sans", sans-serif;
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.tutorial-kicker::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent);
  flex-shrink: 0;
}
.tutorial-step {
  font-family: "Baloo 2", "DM Sans", sans-serif;
  font-weight: 600;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-dim);
  background: var(--card-bg);
  border: 1.5px solid var(--card-border);
  border-radius: 999px;
  padding: 2px 10px;
  white-space: nowrap;
}

/* Illustration sits in an accent-tinted panel like the game's icons */
.tutorial-illo {
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: var(--radius);
  background: var(--accent-bg);
  border: 1px solid var(--card-border);
  padding: 8px 10px;
}
.tutorial-illo svg {
  width: 100%;
  max-width: 210px;
  height: auto;
  display: block;
}
.tutorial-text {
  display: flex;
  flex-direction: column;
  gap: 5px;
  text-align: center;
}
.tutorial-title {
  font-family: "Baloo 2", "DM Sans", sans-serif;
  font-weight: 700;
  font-size: 1.08rem;
  letter-spacing: 0.01em;
  line-height: 1.2;
  color: var(--ink);
}
.tutorial-body {
  font-family: "DM Sans", sans-serif;
  font-size: 0.86rem;
  line-height: 1.5;
  color: var(--ink-mid);
}
.tutorial-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
}
.tutorial-btn {
  padding: 0.68em 1.6em;
  border-radius: var(--radius);
  font-family: "DM Sans", sans-serif;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  cursor: pointer;
  text-transform: uppercase;
  transition:
    background 0.2s,
    color 0.2s,
    border-color 0.2s,
    transform 0.15s,
    box-shadow 0.2s;
}
.tutorial-btn.primary {
  background: rgba(255, 255, 255, 0.92);
  border: none;
  color: var(--ink);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.16);
}
.tutorial-btn.primary:hover {
  background: var(--accent);
  color: var(--btn-primary-color);
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
}
.tutorial-btn.ghost {
  background: transparent;
  border: 1.5px solid var(--ink-faint);
  color: var(--ink-mid);
}
.tutorial-btn.ghost:hover {
  border-color: var(--ink);
  color: var(--ink);
}

/* Cartoonic mode — chunky sticker borders + playful font, matching the
   game's other cards/buttons exactly. */
body.cartoonic-mode .tutorial-card {
  border: 3px solid var(--box-border) !important;
  border-radius: 16px !important;
  box-shadow: 4px 4px 0 var(--box-border) !important;
}
body.cartoonic-mode .tutorial-btn {
  border-radius: 12px !important;
}
body.cartoonic-mode .tutorial-btn.primary:active,
body.cartoonic-mode .tutorial-btn.ghost:active {
  transform: translate(2px, 2px);
  box-shadow: 2px 2px 0 var(--box-border) !important;
}
body.cartoonic-mode .tutorial-kicker,
body.cartoonic-mode .tutorial-step {
  font-family: "Baloo 2", "DM Sans", sans-serif;
  font-weight: 600;
}
body.cartoonic-mode .tutorial-step {
  border-width: 2px;
}

/* ── Illustration mini-diagram ── */
.t-illo-board {
  fill: rgba(0, 0, 0, 0.04);
  stroke: var(--ink-faint);
  stroke-width: 1.5;
}
.t-illo-cell {
  fill: rgba(0, 0, 0, 0.05);
  stroke: var(--ink-faint);
  stroke-width: 1;
}
.t-illo-arrow {
  stroke: var(--ink);
  stroke-width: 3.5;
  stroke-linecap: round;
}
.t-illo-arrow.accent {
  stroke: var(--accent);
}
.t-illo-head {
  fill: var(--ink);
}
.t-illo-head.accent {
  fill: var(--accent);
}
.t-illo-dash {
  stroke: var(--accent);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 0.1 6;
  animation: tIlloDashMove 0.8s linear infinite;
}
@keyframes tIlloDashMove {
  from {
    stroke-dashoffset: 12;
  }
  to {
    stroke-dashoffset: 0;
  }
}
.t-illo-blocked {
  stroke: var(--error-txt);
  stroke-width: 3;
  stroke-linecap: round;
}
.t-illo-check {
  fill: none;
  stroke: var(--accent);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: tIlloCheckPop 0.5s ease 0.3s both;
}
@keyframes tIlloCheckPop {
  from {
    opacity: 0;
    transform: scale(0.5);
    transform-origin: center;
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}
/* Accent glow on the arrow the tutorial is pointing at (same pulse as the
   Hint highlight, but in the theme accent color instead of gold). */
.arrow-tile.tutorial-hint .arrow-tile-line {
  stroke: var(--accent);
  animation: arrowHintPulse 1.1s ease-in-out infinite;
}
.arrow-tile.tutorial-hint .arrow-tile-head {
  fill: var(--accent);
}
