:root {
  --bg1: #1a2438; --bg2: #0e1524;
  --tile: #223049;        /* empty slot */
  --tile-b: #33456a;      /* empty slot border */
  --tile-hover: #2b3c5c;
  --wall: #6b7690;        /* walls — clearly lighter, solid */
  --wall-b: #8b96ad;
  --room: #33415e;        /* room card */
  --room-b: #4a5c80;
  --text: #f2f6ff; --muted: #a9b6cf;
  --gold: #ffcf5c; --green: #56d98a; --red: #ff6b7a; --accent: #6ea8ff;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Dark, subtle scrollbars that match the theme (Chromium/Safari + Firefox) */
* { scrollbar-width: thin; scrollbar-color: #3a4a6f transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #3a4a6f; border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:hover { background: #4f6291; }
::-webkit-scrollbar-corner { background: transparent; }
html, body {
  margin: 0; width: 100%; height: 100%; overflow: hidden;
  background: radial-gradient(1200px 800px at 50% -5%, var(--bg1), var(--bg2)) fixed;
  color: var(--text); font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; -webkit-font-smoothing: antialiased;
}

/* Responsive centered column — works on phone & desktop */
#app {
  height: 100%; width: 100%; max-width: 620px; margin: 0 auto;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 10px;
}

/* HUD */
#hud { display: flex; align-items: center; gap: 10px; }
.brand { font-size: 19px; letter-spacing: .01em; white-space: nowrap; }
.brand-ico { width: 18px; height: 18px; vertical-align: -3px; filter: drop-shadow(0 0 4px rgba(255,207,92,.6)); }
.brand b { font-weight: 800; }
#hud-level { color: var(--muted); font-size: 13px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hud-right { margin-left: auto; display: flex; align-items: center; gap: 10px; font-variant-numeric: tabular-nums; font-weight: 800; }
#hud-timer { color: var(--gold); font-size: 16px; }
#hud-stars { font-size: 14px; }
#hud .hud-right button { width: 34px; height: 32px; border-radius: 9px; background: #223049; border: 1px solid var(--tile-b); color: var(--text); font-weight: 800; font-size: 15px; cursor: pointer; }
#hud .hud-right button:hover { filter: brightness(1.2); }
#hud .hud-right button .hud-ico { width: 17px; height: 17px; display: block; margin: 0 auto; }

/* Sub bar: progress + goal */
#subbar { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--muted); }
.prog-bar { flex: 1 1 auto; height: 8px; background: #0e1626; border: 1px solid var(--tile-b); border-radius: 999px; overflow: hidden; }
#prog-fill { height: 100%; width: 0; background: linear-gradient(90deg, var(--accent), var(--green)); transition: width .25s ease; }
#prog-txt { font-weight: 700; color: var(--text); white-space: nowrap; }
#goal { white-space: nowrap; }
#goal #par { color: var(--gold); font-weight: 700; }

/* Board */
#board-wrap { flex: 1 1 auto; display: flex; align-items: center; justify-content: center; min-height: 0; position: relative; }
/* --stage-cap is set inline by renderGrid for tiny authored teaching boards (3×3/4×4) so their
   cells stay sensibly sized; normal boards fall back to the default cap. */
#board-stage { position: relative; height: min(100%, 94vw, var(--stage-cap, 560px)); aspect-ratio: 1/1; }

/* One-line teaching nudge above the board (authored levels) — never blocks input */
#nudge {
  position: absolute; top: 2px; left: 0; right: 0; z-index: 3; text-align: center;
  pointer-events: none; color: var(--gold); font-weight: 800; font-size: 15px;
  text-shadow: 0 1px 3px rgba(0,0,0,.6);
}
#beams { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
#board {
  --n: 6; position: relative; z-index: 1; width: 100%; height: 100%;
  display: grid;
  grid-template-columns: repeat(var(--n), 1fr);
  grid-template-rows: repeat(var(--n), 1fr);   /* equal square cells */
  gap: clamp(4px, 1.4vmin, 8px);
  transition: opacity .15s;
}
.cell {
  border-radius: clamp(7px, 1.6vmin, 12px); position: relative;
  display: flex; align-items: center; justify-content: center;
  font-size: clamp(15px, 5.2vmin, 30px); font-weight: 800; user-select: none;
}

/* Walls — light solid slate with a subtle raised bevel, clearly NOT a slot */
.cell.wall {
  background:
    repeating-linear-gradient(135deg, rgba(255,255,255,.05) 0 3px, transparent 3px 7px),
    linear-gradient(180deg, var(--wall), #59637c);
  border: 1px solid var(--wall-b);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.14), inset 0 -3px 6px rgba(0,0,0,.3);
}

/* Empty slots — clearly a dark, tappable slot with a defined border */
.cell.empty {
  background: var(--tile); border: 1.5px solid var(--tile-b); cursor: pointer;
  transition: background .12s, box-shadow .12s;
}
.cell.empty:hover { background: var(--tile-hover); }
.cell.empty .spot { display: none; width: 100%; height: 100%; align-items: center; justify-content: center; }
.cell.empty .spot svg { width: 66%; height: 66%; filter: drop-shadow(0 0 6px rgba(255,207,92,.95)); }
.cell.empty.cam .spot { display: flex; animation: spot-in .2s ease; }
@keyframes spot-in { from { transform: scale(.35); } to { transform: scale(1); } }
.cell.empty.cam .spot svg { animation: spin-slow 9s linear infinite; }
@keyframes spin-slow { to { transform: rotate(360deg); } }

/* Beam (a lit empty cell) — warm glow */
.cell.empty.lit {
  background: radial-gradient(circle at 50% 50%, rgba(255,214,120,.26), rgba(255,214,120,.10));
  box-shadow: inset 0 0 10px rgba(255,214,120,.22);
}
/* Spotlight cell */
.cell.empty.cam {
  background: radial-gradient(circle at 50% 50%, rgba(255,207,92,.22), rgba(255,207,92,.06));
  border-color: var(--gold);
  box-shadow: 0 0 10px rgba(255,207,92,.3), inset 0 0 0 2px rgba(255,207,92,.5);
}
.cell.empty.cam .spot { display: flex; }
.cell.empty.cam .spot svg { position: relative; z-index: 3; }
.cell.empty.blind { border-color: var(--red); box-shadow: 0 0 12px rgba(255,107,122,.5), inset 0 0 0 2px var(--red); }
/* Coach pulse — the suggested cell on a teaching level, cleared on the first tap */
.cell.empty.coach { border-color: var(--gold); animation: coachPulse 1.1s ease-in-out infinite; }
@keyframes coachPulse {
  0%, 100% { transform: scale(1);    box-shadow: 0 0 0 2px rgba(255,207,92,.45), 0 0 10px rgba(255,207,92,.35); }
  50%      { transform: scale(1.09); box-shadow: 0 0 0 3px rgba(255,207,92,.7),  0 0 20px rgba(255,207,92,.55); }
}

/* Rooms — clear card with big number */
.cell.room {
  background: linear-gradient(180deg, var(--room), #2a3550); border: 2px solid var(--room-b);
  flex-direction: column; gap: 0; transition: background .12s, border-color .12s, box-shadow .12s, transform .12s;
}
.cell.room .num { line-height: 1; text-shadow: 0 1px 2px rgba(0,0,0,.5); }
.cell.room .cnt { font-size: clamp(9px, 1.8vmin, 12px); color: var(--muted); font-weight: 700; line-height: 1; margin-top: 2px; }
.cell.room.exact { border-color: var(--green); background: linear-gradient(180deg, #1f4a33, #17351f); box-shadow: 0 0 14px rgba(86,217,138,.35); }
.cell.room.exact .cnt { color: #b9f2cf; }
.cell.room.over { border-color: var(--red); background: linear-gradient(180deg, #4a2129, #351619); box-shadow: 0 0 14px rgba(255,107,122,.35); }
.cell.pop { animation: pop .32s ease; }   /* placement/hint bump — any cell */
@keyframes pop { 40% { transform: scale(1.13); } }
/* Room satisfied — the core-loop dopamine moment: gold flare + scale, then settle to green */
.cell.room.justdone { animation: satisfyPop .6s ease; }
@keyframes satisfyPop {
  30% { transform: scale(1.22); border-color: var(--gold);
        box-shadow: 0 0 26px rgba(255,207,92,.8), 0 0 12px rgba(86,217,138,.6); }
}
/* A room that just went over-lit shakes — wordless "exactly, never more" feedback */
.cell.room.overpop { animation: overshake .42s ease; }
@keyframes overshake {
  15%, 55% { transform: translateX(-3px) scale(1.07); }
  35%, 75% { transform: translateX(3px) scale(1.07); }
}

/* Toolbar */
#toolbar { display: flex; gap: 8px; }
#toolbar button {
  flex: 1; background: #223049; border: 1px solid var(--tile-b); color: var(--text);
  border-radius: 12px; padding: 13px 6px; font-weight: 700; font-size: 14px; cursor: pointer; white-space: nowrap;
}
.tb-ico { width: 15px; height: 15px; vertical-align: -3px; }
#toolbar button:hover { filter: brightness(1.22); }
#toolbar button:active { transform: translateY(1px); }
#toolbar button:disabled { opacity: .38; cursor: not-allowed; filter: none; transform: none; }

/* Overlays */
.overlay { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(6,11,20,.9); backdrop-filter: blur(3px); z-index: 20; padding: 16px; }
.overlay.hidden { display: none; }
.primary { background: linear-gradient(180deg, #4f79d8, #325bb0) !important; border: 1px solid var(--accent) !important; color: #fff !important; }

/* Mechanic line-icons: align inline with text; block-centered inside chip/card icon slots. */
.mico { vertical-align: -0.18em; }
.chap-ico .mico, .mc-ico .mico { vertical-align: middle; }
.mico-emoji { line-height: 1; }

/* Level select */
.sel-card { width: min(760px, 96%); max-height: 92%; background: linear-gradient(180deg, #1b2740, #131c2e); border: 1px solid var(--tile-b); border-radius: 20px; padding: 20px; overflow-y: auto; }
.sel-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sel-head h2 { margin: 0; font-size: 22px; }
.sel-total { color: var(--gold); font-weight: 800; white-space: nowrap; }
.sel-sub { color: var(--muted); margin: 6px 0 16px; font-size: 13px; }
.sel-sub-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sel-sub-btns { display: inline-flex; gap: 6px; margin-left: auto; }   /* Lessons + How to play chips */
/* small inline chip button (same family as the splash chips) */
.chip-btn { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: 999px;
  background: #223049; border: 1px solid var(--tile-b); color: var(--muted); font-size: 12px; font-weight: 700;
  white-space: nowrap; cursor: pointer; transition: border-color .15s, color .15s, background .15s; }
.chip-btn:hover { color: #fff; border-color: var(--accent); background: #26344f; }
.lvl-grid { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: clamp(3px, 0.8vmin, 6px); }
.lvl-chip { aspect-ratio: 1/1; background: linear-gradient(180deg, #26344f, #1d2a41); border: 1px solid var(--tile-b); border-radius: clamp(7px, 1.4vmin, 12px); color: var(--text); cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px; padding: 1px; transition: transform .1s, border-color .15s, box-shadow .15s; overflow: hidden; }
.lvl-chip:hover:not(.locked) { transform: translateY(-2px); border-color: var(--accent); box-shadow: 0 6px 18px rgba(0,0,0,.4); }
.lvl-chip.locked { opacity: .4; cursor: not-allowed; }
.lvl-chip.perfect { border-color: var(--gold); box-shadow: 0 0 14px rgba(255,207,92,.3); }
/* Curated "set-piece" opening levels get a small sparkle so authored boards read as special */
.lvl-chip.featured:not(.locked)::before {
  content: "✦"; position: absolute; top: 1px; right: 3px; font-size: clamp(7px, 1.6vmin, 11px);
  color: var(--accent); opacity: .9; pointer-events: none;
}
.lvl-chip { position: relative; }
.lvl-n { font-weight: 800; font-size: clamp(11px, 2.5vmin, 18px); line-height: 1; }
.lvl-st { font-size: clamp(6px, 1.5vmin, 11px); color: var(--gold); letter-spacing: -1px; line-height: 1; }
.lvl-time { font-size: clamp(6px, 1.3vmin, 10px); color: var(--muted); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1; }
.sel-btn { background: #223049; border: 1px solid var(--tile-b); color: var(--text); border-radius: 10px; padding: 8px 14px; font-weight: 700; cursor: pointer; }

/* Win */
.win-card { width: min(400px, 92%); background: linear-gradient(180deg, #1b2740, #131c2e); border: 1px solid var(--tile-b); border-radius: 22px; padding: 26px; text-align: center; box-shadow: 0 24px 70px rgba(0,0,0,.65); }
.win-stars { font-size: 48px; letter-spacing: 8px; margin-bottom: 6px; }
.win-stars .ws { color: #2c3a56; display: inline-block; }
.win-stars .ws.on { color: var(--gold); text-shadow: 0 0 16px rgba(255,207,92,.6); animation: starpop .5s ease both; }
@keyframes starpop { 0% { transform: scale(0) rotate(-40deg); } 60% { transform: scale(1.3); } 100% { transform: scale(1); } }
.win-card h2 { margin: 8px 0 10px; }
.win-stats { display: flex; gap: 16px; justify-content: center; color: var(--muted); font-weight: 700; margin-bottom: 18px; }
.win-row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.win-row button { background: #223049; border: 1px solid var(--tile-b); color: #fff; border-radius: 12px; padding: 12px 18px; font-weight: 800; cursor: pointer; }

/* Win card actions: full-width primary on top, an even secondary row below (no wrapping) */
.win-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 2px; }
.win-actions .primary { width: 100%; padding: 14px; font-size: 16px; border-radius: 12px; }
.win-row-2 { display: flex; gap: 10px; }
.win-row-2 button { flex: 1; background: #223049; border: 1px solid var(--tile-b); color: #fff; border-radius: 12px; padding: 12px; font-weight: 800; cursor: pointer; }
.win-row-2 button:hover { filter: brightness(1.2); }
.win-row-2 button:active { transform: translateY(1px); }

/* Tutorial */
.sheet { width: min(440px, 96%); background: linear-gradient(180deg, #1b2740, #131c2e); border: 1px solid var(--tile-b); border-radius: 20px; padding: 22px; }
.sheet h2 { margin: 0 0 12px; }
.sheet ul { padding-left: 18px; line-height: 1.6; font-size: 14px; color: #d7e0f2; margin: 0; }
.sheet .g { color: var(--green); font-weight: 700; } .sheet .r { color: var(--red); font-weight: 700; }
.sheet .beamword { color: var(--gold); }
.sheet button { margin-top: 16px; width: 100%; border-radius: 12px; padding: 13px; font-weight: 800; cursor: pointer; }
/* Tabbed, animated tutorial */
.tut-sheet { width: min(520px, 96%); }
.tut-tabs { display: flex; gap: 5px; margin: 0 0 12px; }
.tut-tab { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  background: #223049; border: 1px solid var(--tile-b); color: var(--muted);
  border-radius: 10px; padding: 8px 4px; font-weight: 800; font-size: 12px; cursor: pointer; white-space: nowrap; }
.tut-tab .mico { flex: 0 0 auto; }
.tut-tab:hover { filter: brightness(1.15); }
.tut-tab.active { color: #fff; border-color: var(--accent); background: linear-gradient(180deg, #2c4066, #223049); box-shadow: 0 0 0 1px var(--accent); }

/* All panels occupy the SAME grid cell → the stack is as tall as the tallest panel, so switching
   tabs never resizes the modal. Only the active panel is visible. */
.tut-stack { display: grid; }
.tut-panel { grid-area: 1 / 1; visibility: hidden; }
.tut-panel.active { visibility: visible; }
/* fixed-height stage centers the board (1-row vs 3×3 demos read consistently) */
.tut-stage { height: 134px; display: flex; align-items: center; justify-content: center; }
.tut-board { display: grid; gap: 5px; justify-content: center; }
.tcell { width: 40px; height: 40px; border-radius: 8px; position: relative; display: flex; align-items: center; justify-content: center;
  font-weight: 800; font-size: 17px; color: #fff; transition: background .35s ease, border-color .35s ease, box-shadow .35s ease; }
.tcell.empty { background: var(--tile); border: 1.5px solid var(--tile-b); }
.tcell.wall { background: linear-gradient(180deg, var(--wall), #59637c); border: 1px solid var(--wall-b); }
.tcell.room { flex-direction: column; gap: 0; background: linear-gradient(180deg, var(--room), #2a3550); border: 2px solid var(--room-b); }
.tcell.room .tc-num { line-height: 1; }
.tcell.room .tc-cnt { font-size: 9px; color: var(--muted); font-weight: 700; line-height: 1; height: 10px; margin-top: 1px; }
.tcell.room.exact { border-color: var(--green); background: linear-gradient(180deg, #1f4a33, #17351f); box-shadow: 0 0 12px rgba(86,217,138,.4); }
.tcell.room.exact .tc-cnt { color: #b9f2cf; }
.tcell.room.over { border-color: var(--red); background: linear-gradient(180deg, #4a2129, #351619); box-shadow: 0 0 12px rgba(255,107,122,.4); }
.tcell.lit { background: radial-gradient(circle at 50% 50%, rgba(255,214,120,.26), rgba(255,214,120,.1)); box-shadow: inset 0 0 8px rgba(255,214,120,.22); }
.tcell.cam { background: radial-gradient(circle at 50% 50%, rgba(255,207,92,.22), rgba(255,207,92,.06)); border-color: var(--gold); box-shadow: 0 0 8px rgba(255,207,92,.3), inset 0 0 0 2px rgba(255,207,92,.5); }
.tcell.blind { border-color: var(--red); box-shadow: 0 0 10px rgba(255,107,122,.55), inset 0 0 0 2px var(--red); }
.tcell.pick { outline: 3px solid var(--accent); outline-offset: 1px; }
.tcell .tc-spot { display: none; width: 66%; height: 66%; }
.tcell .tc-spot svg { width: 100%; height: 100%; filter: drop-shadow(0 0 5px rgba(255,207,92,.9)); }
.tcell.cam .tc-spot { display: flex; }
.tut-cap { text-align: center; color: var(--muted); font-size: 13px; font-weight: 600; min-height: 18px; margin: 4px 0 0; padding-bottom: 16px; border-bottom: 1px solid rgba(255,255,255,.07); }
/* min-height fits the longest rule set (mechanic tabs have one extra line) → constant modal height */
/* .tut-sheet prefix beats the generic ".sheet ul { margin:0 }" so this spacing actually applies */
.tut-sheet .tut-rules { padding-left: 18px; line-height: 1.55; font-size: 13.5px; color: #d7e0f2; margin: 28px 0 4px; }

/* Confetti */
#confetti { position: fixed; inset: 0; pointer-events: none; overflow: hidden; z-index: 30; }
.confetti-bit { position: absolute; top: -14px; width: 9px; height: 14px; border-radius: 2px; animation: fall linear forwards; }
@keyframes fall { to { transform: translateY(105vh) rotate(560deg); opacity: .85; } }

/* Landscape phones / short screens: keep board reachable.
   In the wrapped-row layout #board-wrap's height is indefinite, so the stage's
   `min(100%, …)` collapses — give the board row an explicit height budget instead
   (viewport minus hud + subbar + paddings/gaps). */
@media (max-height: 520px) and (orientation: landscape) {
  #app { max-width: none; flex-direction: row; flex-wrap: wrap; align-content: center; }
  #board-wrap { order: 2; flex: 1 1 60%; height: calc(100vh - 128px); height: calc(100dvh - 128px); }
  #hud { order: 1; flex: 1 1 100%; }
  #subbar { order: 3; flex: 1 1 100%; }
  #toolbar { order: 4; flex: 0 0 auto; flex-direction: column; justify-content: center; }
}

/* Splash / title screen */
#splash { background: radial-gradient(720px 520px at 50% 34%, #223257, #0c1322 72%); }
.splash-inner { text-align: center; max-width: 380px; padding: 20px; }
.logo { width: 132px; height: 132px; margin: 0 auto 6px; display: flex; align-items: center; justify-content: center; position: relative; }
.logo svg { width: 100%; height: 100%; filter: drop-shadow(0 0 22px rgba(255,207,92,.7)); animation: spin-slow 14s linear infinite; }
.logo::after { content: ""; position: absolute; inset: -26%; border-radius: 50%; background: radial-gradient(circle, rgba(255,207,92,.28), transparent 62%); animation: pulseGlow 2.6s ease-in-out infinite; }
@keyframes pulseGlow { 0%,100% { transform: scale(.92); opacity: .7; } 50% { transform: scale(1.08); opacity: 1; } }
.title { margin: 6px 0 0; font-size: 40px; font-weight: 900; letter-spacing: .14em; }
.subtitle { color: var(--gold); font-weight: 800; letter-spacing: .5em; font-size: 15px; margin-left: .5em; }
.tagline { color: var(--muted); margin: 14px 0 22px; font-size: 14px; visibility: hidden; }
.splash-btns { display: flex; gap: 10px; justify-content: center; }
.splash-btns button { border-radius: 12px; padding: 14px 26px; font-weight: 800; font-size: 16px; cursor: pointer; border: 1px solid var(--tile-b); background: #223049; color: #fff; }
.splash-links { display: flex; gap: 7px; justify-content: center; margin-top: 20px; flex-wrap: wrap; }
.splash-chip { display: inline-flex; align-items: center; gap: 6px; padding: 8px 11px; border-radius: 10px;
  background: #223049; border: 1px solid var(--tile-b); color: var(--muted); font-size: 12.5px; font-weight: 700;
  white-space: nowrap; text-decoration: none; cursor: pointer; transition: transform .1s, border-color .15s, color .15s, background .15s; }
.splash-chip:hover { color: #fff; border-color: var(--accent); background: #26344f; transform: translateY(-1px); }
.splash-chip .ico { width: 14px; height: 14px; display: block; flex: 0 0 auto; }

/* Stats view — compact, fits without scrolling */
/* Stats page is narrower than the shared card (which stays wide for the level grid) */
#stats .sel-card { width: min(620px, 96%); }
/* Two-up sections (Campaign | Endless, Records | Calendar) so the sheet stays short on desktop. */
.stat-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 0 22px; align-items: start; }
.stat-cols > div { min-width: 0; }
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 14px 0 4px; }
.stat-big { background: linear-gradient(180deg, #26344f, #1d2a41); border: 1px solid var(--tile-b); border-radius: 12px; padding: 8px 6px; text-align: center; }
.stat-big b { display: block; font-size: 21px; color: var(--gold); line-height: 1.1; }
.stat-big span { font-size: 11px; color: var(--muted); }
.stat-h { margin: 10px 0 2px; font-size: 13px; color: var(--accent); letter-spacing: .02em; }
.stat-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 4px 4px; border-bottom: 1px solid rgba(255,255,255,.06); font-size: 13px; }
.stat-row > span:last-child { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.stat-row .sub { color: var(--muted); font-weight: 600; font-size: 12px; }
/* Short phones: tighten the (now fixed-height) stats sheet so it fits without scrolling. */
@media (max-width: 600px) and (max-height: 760px) {
  .stat-h { margin: 6px 0 0; font-size: 12px; }
  .stat-row { padding: 2px 4px; font-size: 12px; }
  .stat-grid { margin: 10px 0 2px; gap: 6px; }
  .stat-big { padding: 5px 4px; }
  .stat-big b { font-size: 17px; }
  .hm { --hmc: clamp(8px, 2vw, 11px); }
}

/* ---- Mobile: full-screen the big content modals so nothing is cramped at the edges ---- */
@media (max-width: 600px) {
  .overlay { padding: 0; }
  .sel-card, .tut-sheet, #stats .sel-card {
    width: 100%; max-width: none; height: 100%; max-height: 100%;
    border: none; border-radius: 0; overflow-y: auto;
    /* comfortable side gutters (~20px), expanded to honour notch/rounded-corner safe areas */
    padding-top: 18px;
    padding-bottom: calc(20px + env(safe-area-inset-bottom));
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
  }
  /* full-screen tutorial: center the whole block vertically (no big empty gap under the button) */
  .tut-sheet { display: flex; flex-direction: column; justify-content: center; }
  /* tutorial tabs wrap to two rows (labels not truncated); tighter rows, more gap before the demo */
  .tut-tabs { flex-wrap: wrap; row-gap: 4px; margin-bottom: 20px; }
  .tut-tab { flex: 1 1 calc(50% - 3px); font-size: 13px; overflow: visible; text-overflow: clip; }
  /* chapter tabs: shrink to fit all in one row instead of overflowing + cropping the active tab */
  .chap-bar { gap: 6px; margin: 14px 0 12px; }
  .chap-tab { flex: 1 1 0; min-width: 0; padding: 8px 6px; }
  .chap-ico { font-size: 18px; }
  .chap-name { font-size: 12px; }
  .chap-meta { font-size: 10px; }
  /* endless variant tabs: icon-only so all five fit in one row */
  .lb-vtab span { display: none; }
  .lb-vtab { padding: 9px 4px; }
  /* one slim 4-up tile row (a 2×2 block eats too much height) and stacked sections */
  .stat-grid { gap: 6px; }
  .stat-big { padding: 6px 3px; }
  .stat-big b { font-size: 16px; }
  .stat-big span { font-size: 9.5px; }
  .stat-cols { grid-template-columns: 1fr; }
  /* bigger, easier-to-tap level chips: 5 per row; the grid scrolls inside the full-screen card */
  .lvl-grid { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
  .lvl-n { font-size: 20px; }
  .lvl-st { font-size: 11px; }
  .lvl-time { font-size: 10px; }

  /* ---- In-game view on mobile: tidy the crowded HUD + give the board edge breathing room ---- */
  #app {
    padding-top: max(16px, env(safe-area-inset-top));
    padding-bottom: calc(16px + env(safe-area-inset-bottom));
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
  }
  #hud-level { display: none; }              /* free header space — the mode is obvious while playing */
  .brand { font-size: 17px; }
  .hud-right { gap: 8px; }
  #board-stage { height: min(100%, 86vw, var(--stage-cap, 520px)); }   /* more gutter around the board */
}

/* Rooms that must stay dark (0) — visually distinct "keep dark" look */
.cell.room.zero { background: linear-gradient(180deg, #1a2133, #141a29); border-color: #38445f; border-style: dashed; }
.cell.room.zero .num { color: #7f8db0; }
.cell.room.zero.exact { border-style: solid; }

/* HUD score (endless) */
#hud-score { color: var(--green); font-size: 16px; font-weight: 800; }
#hud-score::before { content: "◆ "; color: var(--gold); }
.hidden { display: none !important; }

/* Splash mode cards */
.mode-cards { display: flex; flex-direction: column; gap: 10px; margin: 18px 0 6px; }
.mode-card { display: grid; grid-template-columns: 40px 1fr; grid-template-rows: auto auto; column-gap: 12px; align-items: center;
  text-align: left; background: linear-gradient(180deg, #223049, #1a2740); border: 1px solid var(--tile-b);
  border-radius: 14px; padding: 12px 16px; color: var(--text); cursor: pointer; transition: transform .1s, border-color .15s, box-shadow .15s; }
.mode-card:hover { transform: translateY(-2px); border-color: var(--accent); box-shadow: 0 8px 22px rgba(0,0,0,.4); }
.mode-card:active { transform: translateY(0); }
.mc-ico { grid-row: 1 / 3; display: flex; align-items: center; justify-content: center; font-size: 26px; }
.mc-title { font-weight: 800; font-size: 17px; }
/* min-height keeps the card height stable while the sub ships EMPTY in the HTML — boot fills it,
   so the pre-JS frame shows nothing instead of flashing placeholder text that's about to change */
.mc-sub { color: var(--muted); font-size: 12px; font-weight: 600; min-height: 15px; display: block; }
#mode-endless { border-color: #3a4a6f; }
#mode-endless:hover { border-color: var(--gold); box-shadow: 0 8px 22px rgba(255,207,92,.18); }
.mode-card.locked, .mode-card:disabled { opacity: .5; cursor: not-allowed; transform: none; box-shadow: none; }
.mode-card.locked:hover { transform: none; border-color: var(--tile-b); box-shadow: none; }

/* Win extras */
.win-extra { color: var(--gold); font-weight: 800; margin: -6px 0 16px; }
.win-score { font-size: 46px; font-weight: 900; color: var(--green); text-shadow: 0 0 18px rgba(86,217,138,.5); margin: 2px 0 8px; }

/* Leaderboard */
.lb-banner { background: #1c2a44; border: 1px solid var(--tile-b); border-radius: 12px; padding: 10px 14px; margin: 4px 0 14px; font-size: 14px; color: var(--text); }
.lb-banner.best { border-color: var(--gold); box-shadow: 0 0 16px rgba(255,207,92,.25); }
.lb-list { display: flex; flex-direction: column; gap: 8px; min-height: 60px; }
.lb-row { display: grid; grid-template-columns: 34px minmax(0,1fr) auto auto; align-items: center; gap: 10px;
  background: linear-gradient(180deg, #26344f, #1d2a41); border: 1px solid var(--tile-b); border-radius: 12px; padding: 10px 14px; }
.lb-row.you { border-color: var(--gold); box-shadow: 0 0 12px rgba(255,207,92,.25); }
.lb-row.empty { opacity: .45; }
.lb-row.empty .lb-who, .lb-row.empty .lb-score { color: var(--muted); }
.lb-rank { font-size: 16px; font-weight: 800; text-align: center; color: var(--muted); }
.lb-rank.r1 { color: var(--gold); }
.lb-rank.r2 { color: #cfd8ec; }
.lb-rank.r3 { color: #ff9f45; }
.lb-who { font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-score { font-size: 20px; font-weight: 900; color: var(--green); text-align: right; }
.lb-meta { color: var(--muted); font-size: 11px; font-weight: 600; text-align: right; }

/* Leaderboard scope tabs + name control */
/* Endless variant tabs — switch which mode's best runs are shown (New run starts the active one). */
#leaderboard .sel-card { width: min(560px, 96%); }
#leaderboard .sel-head { margin-bottom: 14px; }   /* air below the title, with or without the banner */
.lb-vtabs { display: flex; gap: 6px; margin: 4px 0 12px; }
.lb-vtab { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  background: #223049; border: 1px solid var(--tile-b); color: var(--muted); border-radius: 10px;
  padding: 8px 4px; font-weight: 700; font-size: 12px; cursor: pointer; white-space: nowrap; }
.lb-vtab .mico { flex: 0 0 auto; }
.lb-vtab:hover:not(:disabled):not(.active) { filter: brightness(1.15); }
.lb-vtab.active { color: #fff; border-color: var(--accent); background: linear-gradient(180deg, #2c4066, #223049); box-shadow: 0 0 0 1px var(--accent); }
.lb-vtab:disabled { opacity: .45; cursor: not-allowed; }
.lb-tabs { display: flex; gap: 8px; margin: 4px 0 12px; }
.lb-tab { flex: 1; background: #223049; border: 1px solid var(--tile-b); color: var(--muted);
  border-radius: 10px; padding: 9px 6px; font-weight: 800; font-size: 13px; cursor: pointer; }
.lb-tab:hover { filter: brightness(1.2); }
.lb-tab.active { color: #fff; border-color: var(--accent); background: linear-gradient(180deg, #2c4066, #223049); box-shadow: 0 0 0 1px var(--accent); }
.lb-name-row { display: flex; align-items: center; gap: 8px; margin-top: 14px; font-size: 13px; flex-wrap: wrap; }
.lb-name-row .sub { color: var(--muted); font-weight: 600; white-space: nowrap; }
.lb-name-row b { font-size: 14px; }
.lb-name-row select { flex: 1; min-width: 130px; background: #0e1626; border: 1px solid var(--tile-b); color: var(--text);
  border-radius: 9px; padding: 8px 10px; font-size: 13px; font-weight: 600; }
.lb-name-row input { flex: 1; min-width: 0; background: #0e1626; border: 1px solid var(--tile-b); color: var(--text);
  border-radius: 9px; padding: 9px 11px; font-size: 14px; font-weight: 700; }
.lb-name-row input:focus { outline: none; border-color: var(--accent); }
.lb-name-row button { background: #223049; border: 1px solid var(--tile-b); color: #fff; border-radius: 9px; padding: 9px 14px; font-weight: 800; cursor: pointer; }
.sheet .zeroword { color: #9fb0d6; font-weight: 700; }

/* Rearrange: a picked-up light + drop-target hint */
.cell.empty.cam.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent), 0 0 20px rgba(110,168,255,.65), inset 0 0 0 2px rgba(110,168,255,.5);
  animation: selPulse 1s ease-in-out infinite;
}
@keyframes selPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
.cell.empty.movable { border-style: dashed; border-color: var(--accent); background: rgba(110,168,255,.08); }
.cell.empty.movable::after { content: "＋"; position: absolute; color: rgba(110,168,255,.7); font-size: clamp(14px,4vmin,24px); font-weight: 800; }

/* Half-Lit: a fixed (locked) given light */
.cell.empty.cam.locked { border-color: #b98a2e; box-shadow: 0 0 8px rgba(255,207,92,.25), inset 0 0 0 2px rgba(185,138,46,.6); cursor: default; }
.cell.empty.cam.locked::after {
  content: "🔒"; position: absolute; right: 2px; bottom: 1px; font-size: clamp(8px, 2vmin, 12px);
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.6)); opacity: .9; pointer-events: none;
}
.cell.empty.cam.locked .spot svg { animation: none; }   /* givens don't spin — they read as fixed */

/* Per-mechanic affordances on placed lights (board carries a .mech-* class) */
.mech-rearrange .cell.empty.cam { cursor: grab; }
.mech-rearrange .cell.empty.cam::after {
  content: "✥"; position: absolute; right: 2px; top: 0; font-size: clamp(8px, 2.1vmin, 13px);
  color: var(--accent); text-shadow: 0 1px 2px rgba(0,0,0,.6); opacity: .85; pointer-events: none;
}
.mech-overload .cell.empty.cam::after {
  content: "−"; position: absolute; right: 3px; top: -1px; font-size: clamp(12px, 3vmin, 20px); font-weight: 900;
  color: var(--red); text-shadow: 0 1px 2px rgba(0,0,0,.6); line-height: 1; pointer-events: none;
}
/* Overload: a switched-off starting light — dashed "ghost" slot with a + hint (tap to switch back on) */
.mech-overload .cell.empty.ghost { border-style: dashed; border-color: #4a5c80; background: rgba(255,207,92,.05); }
.mech-overload .cell.empty.ghost::after {
  content: "+"; position: absolute; right: 3px; top: -1px; font-size: clamp(12px, 3vmin, 20px); font-weight: 900;
  color: rgba(255,207,92,.7); text-shadow: 0 1px 2px rgba(0,0,0,.6); line-height: 1; pointer-events: none;
}
/* the selected (picked-up) rearrange light: hide the move glyph, the ring says it all */
.mech-rearrange .cell.empty.cam.selected::after { content: ""; }

/* Glare: two lights that illegally see each other reuse the red "blind" ring; add a badge so the
   reason reads clearly (they're clashing, not merely wasted). cb mode still shows the ✕ cue. */
.mech-glare .cell.empty.cam.blind::after {
  content: "✴"; position: absolute; right: 2px; top: -1px; font-size: clamp(9px, 2.2vmin, 14px);
  color: var(--red); text-shadow: 0 1px 2px rgba(0,0,0,.6); pointer-events: none;
}

/* Chapter bar (level select) */
.chap-bar { display: flex; gap: 8px; margin: 18px 0 14px; padding: 4px 2px; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.chap-tab {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: linear-gradient(180deg, #223049, #1a2740); border: 1px solid var(--tile-b); border-radius: 12px;
  padding: 10px 8px; color: var(--text); cursor: pointer; transition: transform .1s, border-color .15s, box-shadow .15s;
}
.chap-tab:hover:not(.locked):not(.active) { transform: translateY(-2px); border-color: var(--accent); }
.chap-tab.active { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold), 0 0 14px rgba(255,207,92,.25); }
/* Locked chapters open in PREVIEW (teaching levels playable) — dimmed but still tappable. */
.chap-tab.locked { opacity: .6; }
.chap-tab:hover.locked:not(.active) { opacity: .85; border-color: var(--accent); }
.chap-ico { font-size: 18px; line-height: 1; }
.chap-name { font-weight: 800; font-size: 12px; }
.chap-meta { font-size: 10px; color: var(--muted); font-weight: 700; white-space: nowrap; }
.chap-tab.active .chap-meta { color: var(--gold); }

/* Settings sheet — grouped rows + iOS-style switches */
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 14px 2px; border-bottom: 1px solid rgba(255,255,255,.07); font-size: 15px; font-weight: 700; color: #e6ecf9; }
.set-row:first-of-type { padding-top: 6px; }
.set-lab { display: inline-flex; align-items: center; gap: 8px; }
.set-ico { width: 17px; height: 17px; flex: 0 0 auto; color: var(--accent); }
.set-ico.lg { width: 20px; height: 20px; }
.set-row .switch {
  flex: 0 0 auto; width: 52px; height: 30px; margin: 0; padding: 0; border-radius: 999px;
  background: #2b3a57; border: 1px solid var(--tile-b); position: relative; cursor: pointer;
  transition: background .18s ease, border-color .18s ease;
}
.set-row .switch::after {
  content: ""; position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%;
  background: #cfd8ec; box-shadow: 0 1px 3px rgba(0,0,0,.4); transition: transform .18s ease, background .18s ease;
}
.set-row .switch.on { background: var(--green); border-color: var(--green); }
.set-row .switch.on::after { transform: translateX(22px); background: #fff; }
.set-row .switch:hover { border-color: var(--accent); }
.set-row .switch.on:hover { border-color: var(--green); filter: brightness(1.05); }
.set-link { cursor: pointer; transition: color .12s; }
.set-link:hover { color: #fff; }
.set-link .chev { color: var(--muted); font-size: 22px; font-weight: 800; line-height: 1; }
#settings .sheet button.primary { margin-top: 20px; }

/* Colorblind assist — shape/symbol cues layered on the hue feedback.
   Active only when <body class="cb">; corner badges so hue-blind players can read
   exact (✓) vs over-lit (!) rooms and wasted (✕) lights without relying on green/red. */
.cb .cell.room.exact::after,
.cb .cell.room.over::after {
  position: absolute; top: 2px; left: 4px; line-height: 1; pointer-events: none;
  font-size: clamp(9px, 2.3vmin, 14px); font-weight: 900; text-shadow: 0 1px 2px rgba(0,0,0,.75);
}
.cb .cell.room.exact::after { content: "✓"; color: #c9ffe0; }
.cb .cell.room.over::after  { content: "!"; color: #ffdbe0; }
.cb .cell.empty.blind::before {
  content: "✕"; position: absolute; top: 1px; left: 4px; line-height: 1; pointer-events: none;
  font-size: clamp(9px, 2.3vmin, 14px); font-weight: 900; color: #ffdbe0; text-shadow: 0 1px 2px rgba(0,0,0,.75); z-index: 4;
}
.cb .sheet .g::after { content: " ✓"; } .cb .sheet .r::after { content: " ✕"; }

/* Level-select: resume button + current-level highlight */
.sel-head-right { display: flex; align-items: center; gap: 10px; }
.sel-close { width: 34px; height: 34px; border-radius: 9px; background: #223049; border: 1px solid var(--tile-b); color: var(--text); font-size: 15px; font-weight: 800; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.sel-close .ico { width: 17px; height: 17px; display: block; }
.sel-close:hover { filter: brightness(1.25); }
.lvl-chip.current { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent), 0 0 16px rgba(110,168,255,.45); }

/* ===== Today hub (daily home) ===== */
.today-status { margin: 4px 0 14px; }
/* Four daily cards, one per mechanic: solved / playable / locked (locked = tap to learn) */
.today-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.td-card { position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 14px 8px 12px; border-radius: 14px; cursor: pointer; text-align: center;
  background: linear-gradient(180deg, #26344f, #1d2a41); border: 1px solid var(--tile-b); color: var(--text); }
.td-card:hover { transform: translateY(-2px); border-color: var(--accent); }
.td-card.locked, .td-card:disabled { opacity: .55; cursor: not-allowed; transform: none; border-color: var(--tile-b); }
.td-card.done { border-color: rgba(86,217,138,.55); }
.td-name { display: inline-flex; align-items: center; gap: 6px; font-weight: 800; font-size: 14px; }
.td-stars { color: var(--gold); font-size: 16px; letter-spacing: 2px; }
.td-sub { color: var(--muted); font-size: 12px; font-weight: 700; }
.td-go { color: var(--accent); }
.td-perfect { text-align: center; color: var(--gold); font-weight: 800; font-size: 14px; margin-bottom: 10px; }

/* streak strip + this-week dots */
.today-streak { display: flex; align-items: center; justify-content: space-between; gap: 12px;
  background: linear-gradient(180deg, #26344f, #1d2a41); border: 1px solid var(--tile-b); border-radius: 14px; padding: 12px 16px; }
.streak-main { display: flex; flex-direction: column; }
.streak-num { font-size: 24px; font-weight: 900; color: var(--gold); line-height: 1.1; }
.today-streak .sub { color: var(--muted); font-size: 12px; font-weight: 600; }
.wk-row { display: flex; gap: 6px; }
.wk-dot { width: 14px; height: 14px; border-radius: 50%; background: #2c3a56; border: 1px solid var(--tile-b); }
.wk-dot.on { background: var(--gold); border-color: var(--gold); box-shadow: 0 0 8px rgba(255,207,92,.5); }
.wk-dot.today { outline: 2px solid var(--accent); outline-offset: 1px; }

/* recent dailies "today" tag */
.rec-today { color: var(--accent); font-weight: 800; font-size: 11px; }

/* online-only compare slot */
.today-compare { margin-top: 12px; background: #1c2a44; border: 1px solid var(--tile-b); border-radius: 12px; padding: 10px 14px; font-size: 14px; }
.cmp-pct b { color: var(--green); font-size: 17px; }
.cmp-pct .sub { color: var(--muted); font-weight: 600; }
/* Per-mechanic standing rows (Today hub) + the standing line inside the daily win card */
.cmp-row { display: flex; align-items: center; gap: 7px; padding: 3px 0; font-weight: 700; }
.cmp-row .cmp-name { min-width: 84px; }
.cmp-row .cmp-val b { color: var(--green); }
.cmp-row .sub, .cmp-row .cmp-val { color: var(--muted); font-weight: 600; }
.win-card .cmp-pct { margin-top: 10px; font-size: 14px; font-weight: 700; min-height: 20px; }

/* calendar heatmap — compact fixed cells, centered (GitHub-style), so the hub fits without scrolling */
.hm { --hmc: clamp(10px, 2.1vw, 13px); display: grid; grid-auto-flow: row;
  grid-template-columns: repeat(var(--weeks, 12), var(--hmc)); grid-auto-rows: var(--hmc);
  gap: 3px; justify-content: start; margin: 6px 0 18px; }
.hm-cell { width: var(--hmc); height: var(--hmc); border-radius: 3px; background: #223049; border: 1px solid #2a3a58; }
.hm-cell.future { background: transparent; border-color: transparent; }
.hm-cell.s1 { background: #3a5a44; border-color: #3a5a44; }
.hm-cell.s2 { background: #45996a; border-color: #45996a; }
.hm-cell.s3 { background: var(--green); border-color: var(--green); box-shadow: 0 0 6px rgba(86,217,138,.45); }
.hm-cell.hm-today { outline: 2px solid var(--gold); outline-offset: 1px; }
