:root{
  --bg:#D3DAD8; --scene:#C8D0CE; --ink:#1E292D; --muted:#56646A;
  --panel:rgba(238,242,240,.86); --line:rgba(30,41,45,.18); --grid:#5d6b70;
  --accent:#C07A2C; --on-accent:#1b1206; --key:#ffffff;
  --b:min(52px, calc((100vw - 60px) / 6.4));
  --pad-h:0px;
  --rcol:360px;
  box-sizing:border-box;
  padding-top:env(safe-area-inset-top,0px);
  padding-bottom:env(safe-area-inset-bottom,0px);
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --bg:#172026; --scene:#19232A; --ink:#E2E8E6; --muted:#93A2A6;
    --panel:rgba(26,36,43,.86); --line:rgba(226,232,230,.16); --grid:#8a9aa0;
    --accent:#E3A64F; --key:#24313A;
  }
}
:root[data-theme="dark"]{
  --bg:#172026; --scene:#19232A; --ink:#E2E8E6; --muted:#93A2A6;
  --panel:rgba(26,36,43,.86); --line:rgba(226,232,230,.16); --grid:#8a9aa0;
  --accent:#E3A64F; --key:#24313A;
}
*,*::before,*::after{box-sizing:inherit}
html{height:100%;scroll-padding-top:env(safe-area-inset-top,0px)}
body{margin:0;height:100%;overflow:hidden;background:var(--bg);color:var(--ink);
  font-family:"Bricolage Grotesque",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif}
#stage{position:fixed;top:0;left:0;right:0;bottom:var(--pad-h)}
#stage canvas{display:block;width:100%;height:100%;touch-action:none;cursor:grab}
#stage canvas:active{cursor:grabbing}

.hud{position:fixed;top:calc(env(safe-area-inset-top,0px) + 20px);left:24px;pointer-events:none;z-index:2}
.hud h1{margin:0;font-weight:800;font-size:clamp(2.2rem,5vw,3.6rem);letter-spacing:-.035em;line-height:.9;font-variation-settings:"opsz" 96}
/* Score leads; the other four stats sit in one row of label-over-value columns underneath. */
.score{display:flex;flex-direction:column;margin:14px 0 0}
.score span,.stats dt{color:var(--muted);font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em}
.score output{font-size:2.4rem;font-weight:800;letter-spacing:-.02em;line-height:1.05;font-variant-numeric:tabular-nums}
.stats{display:grid;grid-auto-flow:column;grid-template-rows:auto auto;justify-content:start;gap:1px 24px;margin:12px 0 0;font-variant-numeric:tabular-nums}
.stats dd{margin:0;font-weight:600;font-size:1.15rem}

/* "Well cleared!" over the middle of the well. Never takes clicks, and fades out by itself. */
.banner{position:fixed;left:50%;top:30%;z-index:3;margin:0;padding:12px 22px;border-radius:14px;pointer-events:none;
  background:var(--panel);border:1px solid var(--line);text-align:center;white-space:nowrap;opacity:0;transform:translate(-50%,-50%)}
.banner strong{display:block;font-size:clamp(1.6rem,4vw,2.4rem);font-weight:800;letter-spacing:-.025em;line-height:1.1}
.banner span{color:var(--accent);font-size:1.15rem;font-weight:800;font-variant-numeric:tabular-nums}
.banner.show{animation:banner 2.4s ease-out}
@keyframes banner{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.85)}
  12%{opacity:1;transform:translate(-50%,-50%) scale(1.04)}
  20%,75%{opacity:1;transform:translate(-50%,-50%) scale(1)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(1)}
}
@media (prefers-reduced-motion:reduce){
  @keyframes banner{0%,100%{opacity:0}12%,75%{opacity:1}}
}

.topbar{position:fixed;top:calc(env(safe-area-inset-top,0px) + 20px);right:24px;z-index:2}
.ghost-btn{font:inherit;font-weight:600;font-size:.95rem;padding:8px 14px;border-radius:9px;border:1px solid var(--line);background:var(--panel);color:var(--ink);cursor:pointer}

/* Upper right, under the pause button, the same width as the help panel below it. */
.next{position:fixed;right:24px;top:calc(env(safe-area-inset-top,0px) + 80px);width:var(--rcol);margin:0;z-index:2;pointer-events:none;
  background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:10px 12px 12px;text-align:center}
.next figcaption{font-size:1rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin-bottom:4px}
.next svg{display:block;width:240px;height:240px;margin:0 auto}
.next polygon{stroke:rgba(0,0,0,.35);stroke-width:.8;stroke-linejoin:round}
body.hide-next .next{display:none}
/* H key hides the HUD during play, on the start screen, and after game over; the pause screen still shows everything.
   The next-piece box stays, since it's switched on and off separately with N. */
body.hud-off:is([data-state="play"],[data-state="idle"],[data-state="over"]) :is(.hud,.topbar,.help,.left-col){visibility:hidden}
/* Before a game starts the box shows empty, keeping any piece left over from a reset hidden. */
body[data-state="idle"] .next svg{visibility:hidden}

/* Controls and scoring share one tabbed panel in the lower right. Only the open tab scrolls,
   and only when the window is too short to fit it below the next-piece box. */
.help{position:fixed;right:24px;bottom:calc(env(safe-area-inset-bottom,0px) + 20px);z-index:2;width:var(--rcol);
  max-height:calc(100dvh - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px) - 410px);min-height:160px;
  display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:0 16px 14px;font-size:.88rem}
body.hide-next .help{max-height:calc(100dvh - env(safe-area-inset-top,0px) - env(safe-area-inset-bottom,0px) - 100px)}
.tabs{display:flex;gap:20px;margin:0 -16px 12px;padding:0 16px;border-bottom:1px solid var(--line)}
.tabs button{font:inherit;font-size:.78rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);
  background:none;border:0;border-bottom:2px solid transparent;margin-bottom:-1px;padding:12px 0 9px;cursor:pointer}
.tabs [aria-selected="true"]{color:var(--ink);border-bottom-color:var(--accent)}
.tab-panel{min-height:0;overflow-y:auto}
.help dl{display:grid;grid-template-columns:auto auto;gap:5px 14px;margin:0}
.help dt{color:var(--muted)}
.help dd{margin:0}
.keypads{display:flex;align-items:center;gap:10px}
.keypad{display:grid;grid-template-columns:repeat(3,auto);gap:3px}
.keypad kbd{min-width:1.9em}
.keypad .rot-key{border-color:var(--accent);color:var(--accent);font-weight:600}
.keypads .or{color:var(--muted);font-size:.8rem}
.keypad-note{margin:6px 0 10px;color:var(--muted);font-size:.8rem}
.help dd kbd + kbd{margin-left:2px}
/* Game panel and its own top-15 panel under the stats, sharing one width.
   When the window is short, only the top-15 list scrolls. */
.left-col{position:fixed;left:24px;top:calc(env(safe-area-inset-top,0px) + 222px);bottom:calc(env(safe-area-inset-bottom,0px) + 20px);
  z-index:2;width:max-content;display:flex;flex-direction:column;align-items:stretch;gap:16px;pointer-events:none}
.left-col > *{pointer-events:auto}
.side,.board{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:14px 16px}
.side{flex:none;min-width:240px}
.board{display:flex;flex-direction:column;flex:0 1 auto;min-height:110px;margin:0}
.board[hidden]{display:none}
.leaderboard ol{min-height:0;overflow-y:auto}
.side .card-actions{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.side .primary{grid-column:1/-1}
.side button{white-space:nowrap}
.side .primary{padding:9px 16px;font-size:.95rem}
.option-row{display:flex;align-items:center;justify-content:space-between;margin-top:12px;font-size:.92rem}
.option-row > span,.option-row > label{color:var(--muted)}
.range-row{display:flex;align-items:center;gap:8px}
.option-row input[type="range"]{width:96px;margin:0;accent-color:var(--accent);cursor:pointer}
.option-row small{font-size:.78rem}
.toggle{min-width:56px;padding:5px 10px;font-size:.88rem}
.toggle[aria-pressed="true"]{background:var(--accent);color:var(--on-accent);border-color:transparent}
.stepper{display:flex;align-items:center;gap:6px}
.stepper .ghost-btn{width:32px;height:30px;padding:0;font-size:1.05rem;line-height:1}
.stepper .ghost-btn:disabled,#gridReset:disabled{opacity:.4;cursor:default}
.stepper output{min-width:2.2ch;text-align:center;font-weight:600;font-variant-numeric:tabular-nums}
body.setting-up .left-col{display:none}
.scoring h3{margin:14px 0 8px;font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
.scoring dd{text-align:right;font-variant-numeric:tabular-nums}
kbd{display:inline-block;min-width:1.7em;padding:1px 6px;border:1px solid var(--line);border-bottom-width:2px;border-radius:5px;background:var(--key);font:inherit;font-size:.8rem;text-align:center}

.overlay{position:fixed;inset:0;display:grid;place-items:center;z-index:5;background:rgba(0,0,0,.18);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);padding:16px}
.overlay[hidden]{display:none}
/* First launch: leave the scene and the controls panel sharp. */
.card{background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:28px 30px;max-width:420px}
.card h2{margin:0 0 10px;font-size:1.75rem;font-weight:800;letter-spacing:-.025em;line-height:1.1}
.card p{margin:0 0 20px;color:var(--muted);line-height:1.5}
.card{max-height:calc(100dvh - 32px);overflow-y:auto}
/* The only thing that pops up when a game ends, and only for a top-15 score. */
.name-card{width:min(420px,100%)}
.name-card label{display:block;margin-bottom:10px;color:var(--muted);line-height:1.5}
.name-row{display:flex;gap:8px}
.name-row button{white-space:nowrap}
.name-row input{flex:1;min-width:0;font:inherit;font-size:1.1rem;padding:11px 14px;border-radius:9px;border:1px solid var(--line);background:var(--key);color:var(--ink)}
.name-row input:focus-visible{outline:3px solid var(--accent);outline-offset:1px}
.leaderboard h3{margin:0 0 6px;font-size:.72rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--muted)}
.leaderboard ol{margin:0;padding:0;list-style:none;counter-reset:lb;font-variant-numeric:tabular-nums}
.leaderboard li{counter-increment:lb;display:flex;gap:10px;align-items:baseline;padding:4px 8px;border-radius:7px;font-size:.92rem}
.leaderboard li::before{content:counter(lb);width:1.4em;color:var(--muted);font-size:.85rem;text-align:right}
.leaderboard li:nth-child(odd){background:var(--line)}
.leaderboard li.mine{background:var(--accent);color:var(--on-accent)}
.leaderboard li.mine::before{color:inherit}
.leaderboard li.empty{counter-increment:none;color:var(--muted);font-style:italic}
.leaderboard li.empty::before{content:none}
.lb-name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lb-score{font-weight:600}
.card-actions{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.setup{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(var(--pad-h) + env(safe-area-inset-bottom,0px) + 16px);z-index:4;
  width:max-content;max-width:calc(100vw - 32px);box-sizing:border-box;background:var(--panel);border:1px solid var(--line);border-radius:14px;
  padding:14px 16px;display:flex;flex-wrap:wrap;gap:12px 18px;align-items:center;justify-content:center}
.setup[hidden]{display:none}
.setup p{margin:0;color:var(--muted);font-size:.9rem;text-align:center}
.setup-actions{display:flex;gap:8px}
.setup .primary{padding:8px 16px;font-size:.95rem}
body.setting-up .help{display:none}
.primary{font:inherit;font-weight:600;font-size:1rem;padding:12px 22px;border-radius:10px;border:0;background:var(--accent);color:var(--on-accent);cursor:pointer}
button:focus-visible{outline:3px solid var(--ink);outline-offset:2px}

.pad{display:none;position:fixed;left:0;right:0;bottom:0;height:var(--pad-h);padding:12px 14px calc(env(safe-area-inset-bottom,0px) + 12px);
  justify-content:space-between;align-items:center;gap:12px;background:var(--panel);border-top:1px solid var(--line);z-index:3;
  user-select:none;-webkit-user-select:none;touch-action:manipulation}
.pad button{font:inherit;font-weight:600;font-size:.72rem;line-height:1.1;border:1px solid var(--line);background:var(--key);color:var(--ink);border-radius:10px;width:var(--b);height:var(--b);padding:0}
.dpad{display:grid;grid-template-columns:repeat(3,var(--b));grid-template-rows:repeat(3,var(--b));gap:4px}
.dpad button{font-size:1.15rem}
.dpad [data-act="up"]{grid-area:1/2}
.dpad [data-act="left"]{grid-area:2/1}
.dpad [data-act="right"]{grid-area:2/3}
.dpad [data-act="down"]{grid-area:3/2}
.dpad [data-act="upLeft"]{grid-area:1/1}
.dpad [data-act="upRight"]{grid-area:1/3}
.dpad [data-act="downLeft"]{grid-area:3/1}
.dpad [data-act="downRight"]{grid-area:3/3}
.rot{display:grid;grid-template-columns:repeat(3,var(--b));grid-template-rows:repeat(3,var(--b));gap:4px}
.pad .rotate{grid-column:1/-1;grid-row:span 2;width:auto;height:auto;font-size:.95rem}
.pad .drop{grid-column:1/-1;width:auto;background:var(--accent);color:var(--on-accent);font-size:.95rem}

@media (pointer:coarse){
  :root{--pad-h:calc(var(--b) * 3 + 8px + 24px + env(safe-area-inset-bottom,0px))}
  .pad{display:flex}
  .help{display:none}
  .setup{bottom:calc(var(--pad-h) + 12px)}
  .hud{left:16px;top:calc(env(safe-area-inset-top,0px) + 14px)}
  .hud h1{font-size:2rem}
  .score{margin-top:8px}
  .score output{font-size:1.7rem}
  .stats{gap:0 14px;margin-top:6px}
  .stats dd{font-size:1rem}
  .topbar{right:14px;top:calc(env(safe-area-inset-top,0px) + 14px)}
  .next{right:14px;top:calc(env(safe-area-inset-top,0px) + 64px);width:auto;padding:6px 8px 8px}
  .next figcaption{font-size:.68rem}
  .next svg{width:120px;height:120px}
  .left-col{left:16px;top:calc(env(safe-area-inset-top,0px) + 168px);bottom:calc(var(--pad-h) + 12px);gap:8px}
  .side,.board{width:220px;min-width:0;padding:10px 12px}
  .side .primary,.side .ghost-btn{padding:7px 10px;font-size:.85rem}
  /* Small screens: keep the scene clear while a piece is falling. */
  body[data-state="play"] .board{display:none}
}
