/* Shared styles. Themes set CSS variables on <html data-theme>. Game pages (body.game) are
   a fixed, non-scrolling 100dvh grid: header / roster / stage / touch pad. The stage is a
   size container so boards are sized with cq units to fit both width and height. */
:root{color-scheme:dark;--bg:#0b0d12;--panel:#12151c;--panel2:#1a1e27;--border:#262b35;--border2:#3a4150;--text:#e6e6e6;--muted:#9aa3b2;--accent:#2563eb;--accent-h:#1d4fd8;--accent-text:#fff;--good:#4ade80;--bad:#f87171;--link:#8ab4ff;
  --sat:env(safe-area-inset-top,0px);--sar:env(safe-area-inset-right,0px);--sab:env(safe-area-inset-bottom,0px);--sal:env(safe-area-inset-left,0px)}
:root[data-theme=neon]{--bg:#05010b;--panel:#0d0618;--panel2:#170b2b;--border:#2a1650;--border2:#4a2a80;--text:#f6edff;--muted:#b9a0dc;--accent:#c400f0;--accent-h:#a100c8;--link:#5ff3ff}
:root[data-theme=gameboy]{--bg:#0f380f;--panel:#245224;--panel2:#306230;--border:#4b7a2a;--border2:#8bac0f;--text:#e2f7a6;--muted:#a8c64a;--accent:#9bbc0f;--accent-h:#8bac0f;--accent-text:#0f380f;--good:#c4e85a;--bad:#f0d070;--link:#c4e85a}
*{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%}
body{margin:0;min-height:100vh;min-height:100dvh;background:var(--bg);color:var(--text);font:15px/1.4 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;display:flex;flex-direction:column;align-items:center;
  padding:var(--sat) var(--sar) var(--sab) var(--sal);-webkit-tap-highlight-color:transparent}
header{width:100%;max-width:1040px;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:12px 16px;flex-wrap:wrap}
header a{color:var(--link);text-decoration:none;font-size:14px}
header .actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
h1{font-size:18px;margin:0;font-weight:650;display:flex;align-items:center;gap:8px}
h1 a.home{color:var(--text);font-size:18px}
.code{font:600 16px/1 ui-monospace,Menlo,monospace;letter-spacing:.14em;background:var(--panel2);border:1px solid var(--border2);border-radius:6px;padding:4px 8px}
canvas{display:block}
.side{display:flex;flex-direction:column;gap:10px;width:130px;flex:none}
.box{background:var(--panel);border:1px solid var(--border);border-radius:8px;padding:10px 12px;min-width:0}
.box h3{margin:0 0 4px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.box .v{font-size:22px;font-weight:650;font-variant-numeric:tabular-nums;white-space:nowrap}
.box .wins{font-size:12px;letter-spacing:.2em;color:var(--good);min-height:0}
.box .wins:empty{display:none}
.next canvas{width:100%;height:clamp(80px,100cqh - 470px,230px)}
@container (max-height:760px){.side .keys{display:none}.next canvas{height:clamp(80px,100cqh - 300px,230px)}}
.hold canvas{width:100%;height:52px}
.keys{font-size:12px;color:var(--muted);line-height:1.7}
kbd{display:inline-block;min-width:20px;padding:0 5px;border:1px solid var(--border2);border-bottom-width:2px;border-radius:5px;background:var(--panel2);color:var(--text);font:12px/20px ui-monospace,Menlo,monospace;text-align:center}
.name{font-weight:650;color:var(--text)}
button{margin-top:16px;padding:10px 20px;border-radius:10px;border:0;background:var(--accent);color:var(--accent-text);font-weight:600;font-size:15px;cursor:pointer;font-family:inherit;touch-action:manipulation}
button:hover{background:var(--accent-h)}
button:disabled{background:var(--panel2);color:var(--muted);cursor:default}
button.small{margin:0;padding:7px 12px;font-size:13px}
button.ghost{background:var(--panel2);border:1px solid var(--border2);color:var(--text)}
button.ghost:hover{background:var(--panel)}
button.icon{margin:0;padding:0;width:36px;height:36px;border-radius:9px;background:var(--panel2);border:1px solid var(--border2);color:var(--text);font-size:17px;line-height:1}
button.big{display:block;width:100%;min-height:56px;font-size:20px;border-radius:14px}
input{padding:10px 12px;border-radius:10px;border:1px solid var(--border2);background:var(--panel);color:var(--text);font:600 16px ui-monospace,Menlo,monospace;letter-spacing:.14em;text-transform:uppercase;width:150px;text-align:center}
input.text{font:600 18px system-ui,sans-serif;letter-spacing:0;text-transform:none;width:100%;text-align:left;min-height:52px}
.err{color:var(--bad);min-height:1.4em;margin-top:8px}
.hint{color:var(--muted);font-size:13px}

/* ---------- overlay panels ---------- */
.overlay{position:fixed;inset:0;display:grid;place-items:center;background:rgba(6,8,12,.72);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);z-index:10;padding:calc(12px + var(--sat)) calc(12px + var(--sar)) calc(12px + var(--sab)) calc(12px + var(--sal));overflow:auto}
.overlay[hidden]{display:none}
.panel{background:var(--panel);border:1px solid var(--border2);border-radius:16px;padding:24px 26px;width:min(440px,100%);text-align:center;box-shadow:0 20px 60px rgba(0,0,0,.5)}
.panel h2{margin:0 0 8px;font-size:22px}
.panel .bignum{font-size:72px;font-weight:700;line-height:1;margin:6px 0;font-variant-numeric:tabular-nums}
.panel p{margin:6px 0;color:var(--text);opacity:.88}
.panel .hint{margin-top:14px}
.panel .row{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-top:12px}
.panel .row button{margin:0;flex:1 1 0}
.roomcode{font:700 clamp(34px,11vw,52px)/1 ui-monospace,Menlo,monospace;letter-spacing:.16em;margin:10px 0 4px;color:var(--text);user-select:all;-webkit-user-select:all}
.roomcode[hidden]{display:none}
.namebox{display:flex;flex-direction:column;gap:10px;margin-top:12px}
.namebox button{margin:0}
.only-touch{display:none}
html.show-pad .only-touch{display:inline}
html.show-pad .only-keys{display:none}

/* ---------- settings sheet ---------- */
.sheet-wrap{position:fixed;inset:0;z-index:30;background:rgba(0,0,0,.55);display:flex;align-items:flex-end;justify-content:center}
.sheet{background:var(--panel);border:1px solid var(--border2);border-radius:18px 18px 0 0;padding:18px 18px calc(18px + var(--sab));width:min(480px,100%);display:flex;flex-direction:column;gap:8px}
@media (min-height:600px) and (min-width:600px){.sheet-wrap{align-items:center}.sheet{border-radius:18px}}
.sheet h2{margin:0 0 4px;font-size:19px}
.sheet label{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-top:6px}
.seg{display:flex;gap:6px}
.seg button{margin:0;flex:1;min-height:44px;background:var(--panel2);color:var(--text);border:1px solid var(--border2)}
.seg button.on{background:var(--accent);color:var(--accent-text);border-color:var(--accent)}
.sheet .done{margin-top:12px;min-height:48px}

/* ---------- landing / menus ---------- */
main.landing{width:min(560px,100%);padding:8px 16px 32px;text-align:center}
main.landing p{color:var(--muted)}
.card{background:var(--panel);border:1px solid var(--border);border-radius:16px;padding:18px;margin-top:16px;text-align:left}
.card h2{margin:0 0 6px;font-size:17px}
.card .row{display:flex;gap:8px;align-items:center;margin-top:12px;flex-wrap:wrap}
.card .row button{margin:0}
.card .row input{flex:1;min-width:120px;min-height:48px}
.card button.big{margin-top:12px}
.offline-note{background:var(--panel2);border:1px solid var(--border2);border-radius:12px;padding:12px 14px;color:var(--text)}
.modes{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:12px}
.mode{display:flex;flex-direction:column;gap:2px;text-align:left;padding:14px;border-radius:14px;background:var(--panel2);border:1px solid var(--border2);color:var(--text);text-decoration:none;min-height:72px;margin:0;font-weight:500}
.mode:hover{border-color:var(--accent)}
.mode b{font-size:16px}
.mode small{color:var(--muted);font-size:12px}
.mode .pb{color:var(--good);font-size:12px;font-variant-numeric:tabular-nums}
.modes .wide{grid-column:1 / -1}
.cpu-levels{margin-top:6px}

/* ---------- game pages ---------- */
html:has(body.game){height:100%;overflow:hidden;overscroll-behavior:none}
body.game{position:fixed;inset:0;min-height:0;overflow:hidden;overscroll-behavior:none;touch-action:manipulation;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;
  display:grid;align-items:stretch;grid-template-columns:minmax(0,1fr) minmax(0,1fr);grid-template-rows:auto auto minmax(0,1fr) auto;
  grid-template-areas:"hdr hdr" "roster roster" "stage stage" "padl padr"}
body.game > header{grid-area:hdr;max-width:none;padding:8px 14px;flex-wrap:nowrap}
body.game h1{min-width:0;flex:1 1 auto}
body.game header .actions{flex-wrap:nowrap;flex:none}
.code.mode-name{font:600 14px/1 system-ui,sans-serif;letter-spacing:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
body.game .roster{grid-area:roster}
.stage{grid-area:stage;min-height:0;min-width:0;container-type:size;display:flex;justify-content:center;align-items:flex-start;gap:28px;padding:8px 16px;position:relative}
.player{display:flex;gap:12px;align-items:flex-start;min-width:0}
.well{position:relative;flex:none;aspect-ratio:1/2;height:min(520px,100cqh - 16px,100cqw - 344px);container-type:inline-size;touch-action:none}
.stage.solo .well{height:min(620px,100cqh - 16px,(100cqw - 174px) * 2)}
.well canvas.board{position:absolute;inset:0;width:100%;height:100%;border-radius:8px;box-shadow:0 0 0 1px var(--border)}
.fx{position:absolute;inset:0;pointer-events:none;overflow:hidden;border-radius:8px}
.callout{position:absolute;left:0;right:0;top:calc(34% + var(--i) * 12cqw);text-align:center;font:900 11cqw/1 system-ui,sans-serif;letter-spacing:.04em;color:#fff;text-shadow:0 2px 0 rgba(0,0,0,.5),0 0 18px var(--accent);animation:callout 1.3s ease-out forwards}
:root[data-theme=gameboy] .callout{color:#0f380f;text-shadow:none}
@keyframes callout{0%{opacity:0;transform:scale(.6)}15%{opacity:1;transform:scale(1.08)}30%{transform:scale(1)}100%{opacity:0;transform:translateY(-14cqw)}}
.react-float{position:absolute;bottom:8%;font-size:max(28px,26cqw);line-height:1;transform:translateX(-50%);animation:floatup 2.2s ease-out forwards}
@keyframes floatup{0%{opacity:0;transform:translate(-50%,20%) scale(.5)}15%{opacity:1;transform:translate(-50%,0) scale(1.1)}100%{opacity:0;transform:translate(-50%,-260%) scale(1)}}
.reacts{display:flex;gap:6px;flex-wrap:wrap}
.reacts button{margin:0;width:44px;height:44px;padding:0;font-size:22px;border-radius:12px;background:var(--panel2);border:1px solid var(--border2)}
.reacts button:disabled{opacity:.45}
.netbanner{position:fixed;left:50%;top:calc(10px + var(--sat));transform:translateX(-50%);z-index:20;background:var(--bad);color:#1a0505;font-weight:700;padding:8px 16px;border-radius:999px;box-shadow:0 6px 20px rgba(0,0,0,.4)}
.netbanner[hidden]{display:none}
.rotate-hint{display:none}

.roster{width:100%;display:flex;gap:8px;padding:0 14px 6px;flex-wrap:wrap;align-items:center;font-size:13px;color:var(--muted)}
.slot{background:var(--panel);border:1px solid var(--border);border-radius:8px;padding:5px 10px;min-width:0;max-width:46%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.slot.ready{border-color:var(--good)}
.slot.off{opacity:.55}
.slot .tag{font-size:11px;text-transform:uppercase;letter-spacing:.06em;margin-left:6px;color:var(--muted)}
.status{margin-left:auto}
.status.bad{color:var(--bad)}

/* touch pad: clusters are direct grid items of body.game */
.pad{display:contents}
.cluster{display:none;gap:8px;padding:6px 12px 8px;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
html.show-pad .cluster{display:grid}
.cl-l{grid-area:padl;grid-template-columns:1fr 1fr;grid-template-rows:56px 64px;grid-template-areas:"hold hold" "left right"}
.cl-r{grid-area:padr;grid-template-columns:1fr 1fr;grid-template-rows:56px 64px;grid-template-areas:"hard rotate" "soft rotate"}
.edge{grid-template-columns:repeat(2,minmax(56px,1fr));grid-template-rows:repeat(3,56px);grid-template-areas:"hold rotate" "left right" "soft hard"}
.edge.p1{grid-area:padl}.edge.p2{grid-area:padr}
.pbtn{margin:0;padding:0;min-width:56px;min-height:56px;font-size:26px;font-weight:700;border-radius:14px;background:var(--panel2);border:1px solid var(--border2);color:var(--text);touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
.pbtn[data-a=hold]{font-size:17px}
.pbtn:hover{background:var(--panel2)}
.pbtn.down{background:var(--accent);color:var(--accent-text);transform:scale(.96)}

/* ---------- compact portrait (phones) ---------- */
@media (max-width:720px) and (orientation:portrait){
  body.game > header{padding:6px 12px;gap:6px}
  body.game h1{font-size:16px}
  body.game .hide-narrow{display:none}
  body.game[data-phase=playing] .roster{display:none}
  .roster .spectators{display:none}
  .stage{--mini-w:clamp(64px,21vw,104px);--strip-h:52px;display:grid;grid-template-columns:minmax(0,1fr) var(--mini-w);grid-template-rows:var(--strip-h) minmax(0,1fr);gap:8px 10px;padding:6px 12px;align-items:start;justify-items:center}
  .stage.solo{grid-template-columns:minmax(0,1fr)}
  .stage .me{display:contents}
  .me .side{grid-column:1;grid-row:1;flex-direction:row;width:100%;height:var(--strip-h);gap:6px}
  .me .side .box{flex:1 1 0;padding:4px 7px;display:flex;flex-direction:column;justify-content:center}
  .me .side .box h3{font-size:9px;margin:0 0 2px}
  .me .side .box .v{font-size:16px}
  .me .side .box .wins{font-size:9px;letter-spacing:.1em}
  .me .side .next{flex:2.3 1 0;order:5}
  .me .side .hold{order:1}.me .side .title{order:2;flex:1.4 1 0}.me .side .lines{order:3}.me .side .extra{order:4}
  .me .side canvas{height:26px}
  .me .side .keys{display:none}
  .me .well{grid-column:1;grid-row:2;height:min(100cqh - var(--strip-h) - 20px,(100cqw - var(--mini-w) - 34px) * 2)}
  .stage.solo .me .well{height:min(100cqh - var(--strip-h) - 20px,(100cqw - 24px) * 2)}
  .stage .opp{grid-column:2;grid-row:1 / 3;flex-direction:column;gap:6px;width:var(--mini-w);align-self:start}
  .opp .well{height:auto;width:100%}
  .opp .side{width:100%;gap:6px}
  .opp .side .box:not(.title){display:none}
  .opp .side .box{padding:4px 6px}
  .opp .side .box h3{font-size:9px}
  .opp .side .box .v{font-size:13px}
  .opp .reacts{display:grid;grid-template-columns:1fr 1fr;gap:4px}
  .opp .reacts button{width:auto;height:40px;font-size:19px}
  /* local 2P held upright: two equal columns, pads below */
  .stage.split{grid-template-columns:1fr 1fr;grid-template-rows:minmax(0,1fr);gap:8px;padding:6px 8px}
  .stage.split .player{display:flex;flex-direction:column;gap:6px;width:100%;align-items:center;grid-row:1}
  .stage.split .p1{grid-column:1}.stage.split .p2{grid-column:2}
  .split .well{height:min(100cqh - 60px,(50cqw - 16px) * 2)}
  .split .side{flex-direction:row;width:100%;gap:4px}
  .split .side .box{flex:1;padding:3px 6px}
  .split .side .box:not(.title):not(.lines){display:none}
  .split .side .box h3{font-size:9px}.split .side .box .v{font-size:14px}
  .edge{grid-template-rows:repeat(3,52px);padding:4px 8px 6px;gap:6px}
  .rotate-hint{display:block;position:absolute;left:50%;top:6px;transform:translateX(-50%);z-index:2;background:var(--panel2);border:1px solid var(--border2);border-radius:999px;padding:4px 12px;font-size:12px;color:var(--muted);white-space:nowrap}
}

/* ---------- compact landscape (phones on their side) ---------- */
@media (max-height:520px) and (orientation:landscape){
  body.game{grid-template-columns:auto minmax(0,1fr) auto;grid-template-rows:auto minmax(0,1fr);grid-template-areas:"hdr hdr hdr" "padl stage padr"}
  body.game > header{padding:4px 12px;gap:6px}
  body.game h1{font-size:15px}
  body.game .hide-narrow{display:none}
  body.game .roster{display:none}
  .stage{gap:10px;padding:4px 8px;align-items:center}
  .side{width:86px;gap:6px}
  .side .box{padding:5px 8px}
  .side .box h3{font-size:9px;margin-bottom:2px}
  .side .box .v{font-size:15px}
  .side .keys{display:none}
  .next canvas{height:max(50px,100cqh - 260px)}
  .stage.solo .next canvas{height:max(50px,100cqh - 300px)}
  .hold canvas{height:30px}
  .me{flex-direction:row-reverse}
  .well{height:min(100cqh - 8px,(100cqw - 300px) * 2)}
  .stage.solo .well{height:min(100cqh - 8px,(100cqw - 110px) * 2)}
  .opp{flex-direction:column;gap:6px;width:min(108px,(100cqh - 175px) / 2)}
  .opp .well{width:100%;height:auto}
  .opp .side{width:100%}
  .opp .side .box:not(.title){display:none}
  .opp .reacts{display:grid;grid-template-columns:1fr 1fr;gap:4px}
  .opp .reacts button{width:auto;height:36px;font-size:18px}
  .cluster{align-self:center;padding:6px calc(8px + var(--sal)) 6px 8px}
  .cl-r,.edge.p2{padding:6px 8px 6px calc(8px + var(--sar))}
  .cl-l,.cl-r{grid-template-columns:64px 64px;grid-template-rows:64px 72px}
  .edge{grid-template-columns:60px 60px;grid-template-rows:repeat(3,60px);gap:6px}
  .stage.split{gap:8px}
  .split .p1{flex-direction:row-reverse}
  .split .well{height:min(100cqh - 8px,(50cqw - 100px) * 2)}
  .split .side{width:76px}
}

/* ---------- multiplayer room (room.html: body.room) ----------
   Stage: [oppL] [me] [oppR]. room.js puts opponent mini-boards into oppL/oppR, sets
   data-opp (none | right | split | col | strip) and sizes minis via --mw / --cols. */
.overlay{place-items:safe center}
body.room{grid-template-areas:"hdr hdr" "hud hud" "stage stage" "padl padr"}
.hud{grid-area:hud;display:flex;gap:8px;align-items:center;padding:0 14px 6px;flex-wrap:wrap;font-size:13px;color:var(--muted);min-width:0}
.hud .seg button{min-height:32px;padding:4px 10px;font-size:13px;white-space:nowrap}
.hud .status{margin-left:auto}
.hud .reacts{flex-wrap:nowrap}
.hud .reacts button{width:34px;height:34px;font-size:17px;border-radius:9px}
.race{display:flex;gap:12px;align-items:center;min-width:0;overflow:hidden;flex:1 1 auto}
.race #raceClock{font-variant-numeric:tabular-nums;font-size:18px;color:var(--text);flex:none}
#lb{display:flex;gap:12px;list-style:none;margin:0;padding:0;overflow:hidden;white-space:nowrap;min-width:0}
#lb li{display:flex;align-items:center;gap:2px}
#lb li b{color:var(--text);font-variant-numeric:tabular-nums;margin-left:4px}
#lb li.me{color:var(--text)}
#lb li.out{opacity:.5}
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:var(--pc,#888);margin-right:5px;flex:none}
.muted{color:var(--muted);font-weight:400}
button.linkish{background:none;border:0;padding:0;margin:0;color:var(--link);font:inherit;cursor:pointer}

.stage.multi{--opp-total:0px;justify-content:center;gap:16px}
.stage.multi[data-opp=right]{--opp-total:42cqw}
.stage.multi[data-opp=split]{--opp-total:54cqw}
.stage.multi .opps{flex:0 0 auto;min-width:0;align-self:stretch;display:grid;grid-template-columns:repeat(var(--cols,1),var(--mw,80px));gap:6px;align-content:center;justify-content:center}
.stage.multi[data-opp=none] .opps,.stage.multi[data-opp=right] #oppL{display:none}
.stage.multi .me{gap:22px}
.stage.multi .me .well{height:min(680px,100cqh - 16px,(100cqw - 190px - var(--opp-total)) * 2)}

.mini{width:var(--mw,80px);display:flex;flex-direction:column;gap:2px;cursor:pointer;min-width:0;--pc:#888}
.mwell{position:relative;width:100%;aspect-ratio:1/2;border-radius:5px;overflow:hidden;box-shadow:0 0 0 1px var(--border);container-type:inline-size;transition:box-shadow .15s}
.mwell canvas{position:absolute;inset:0;width:100%;height:100%}
.mfx{position:absolute;inset:0;pointer-events:none;overflow:hidden}
.mname{display:flex;gap:4px;font-size:11px;line-height:14px;white-space:nowrap;overflow:hidden;color:var(--text);border-top:2px solid var(--pc);padding-top:1px}
.mname .nm{overflow:hidden;text-overflow:ellipsis;flex:1;min-width:0}
.mstat{color:var(--good);font-variant-numeric:tabular-nums;flex:none}
.mini.target .mwell{box-shadow:0 0 0 2px var(--accent),0 0 14px var(--accent)}
.mini.threat .mwell{box-shadow:0 0 0 2px var(--bad),0 0 14px var(--bad)}
.mini.target.threat .mwell{box-shadow:0 0 0 2px var(--accent),0 0 0 4px var(--bad),0 0 14px var(--bad)}
.mini.threat .mname::before{content:'⚔';color:var(--bad)}
.mini.focus .mwell{box-shadow:0 0 0 2px var(--good)}
.mini.out .mwell canvas{opacity:.35;filter:grayscale(1)}
.mini.off{opacity:.55}
.mini.hit .mwell{animation:hit .35s}
@keyframes hit{25%{transform:translateX(-3px)}75%{transform:translateX(3px)}}
.mko{position:absolute;inset:0;display:grid;place-content:center;text-align:center;font:700 13cqw/1.15 system-ui,sans-serif;color:#fff;text-shadow:0 1px 2px #000}
.mko b{display:block;font-size:24cqw;color:var(--bad)}
.mcall{position:absolute;left:0;right:0;top:calc(28% + var(--i) * 18cqw);text-align:center;font:900 15cqw/1 system-ui,sans-serif;color:#fff;text-shadow:0 1px 0 #000,0 0 8px var(--pc);animation:callout 1.3s ease-out forwards;white-space:nowrap}
.mreact{position:absolute;left:50%;bottom:10%;font-size:max(18px,40cqw);line-height:1;animation:floatup 2s ease-out forwards}
.callout.small{font-size:8cqw}

/* incoming garbage, per sender: a column just outside the left edge of your well */
.incoming{position:absolute;right:calc(100% + 3px);bottom:0;width:14px;display:flex;flex-direction:column-reverse;gap:1px;pointer-events:none}
.seg-in{height:calc(var(--n) * 10cqw);min-height:10px;background:var(--pc);border-radius:3px;position:relative;opacity:.9}
.seg-in span{position:absolute;left:50%;bottom:2px;transform:translateX(-50%);writing-mode:vertical-rl;rotate:180deg;font:700 10px/1 system-ui,sans-serif;color:#000;white-space:nowrap;overflow:hidden;max-height:calc(100% - 4px)}

/* lobby / results panel */
.panel.lobby{width:min(980px,100%);text-align:left;display:grid;grid-template-columns:minmax(0,320px) minmax(0,1fr);gap:26px;padding:22px}
.panel.lobby:has(.invite[hidden]){grid-template-columns:minmax(0,1fr);width:min(620px,100%)}
.invite{display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center}
.qr{width:min(300px,100%);aspect-ratio:1;background:#fff;border-radius:14px;padding:4px}
.qr svg{display:block;width:100%;height:100%}
.invite .roomcode{margin:4px 0 0}
.invite .row{display:flex;gap:8px;width:100%}
.invite .row button{flex:1;margin:0}
.invite .url{word-break:break-all;margin:0}
.info h3{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:16px 0 6px;font-weight:650}
.info > h3:first-child,.info > div:first-child > h3:first-child{margin-top:0}
.plist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.plist li{display:flex;align-items:center;gap:6px;background:var(--panel2);border:1px solid var(--border);border-left:4px solid var(--pc);border-radius:8px;padding:5px 8px;min-height:40px}
.plist .nm{font-weight:650;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.plist .dot{display:none}
.badge{font-size:10px;font-weight:700;letter-spacing:.06em;padding:2px 5px;border-radius:4px;background:var(--border2);color:var(--text);flex:none}
.badge.host{background:#b45309;color:#fff}
.sp{flex:1}
.rd{font-size:12px;color:var(--muted);white-space:nowrap}
.rd.ok{color:var(--good);font-weight:650}
.rd.off{color:var(--bad)}
.ping{font-size:11px;color:var(--good);font-variant-numeric:tabular-nums;white-space:nowrap}
.ping.meh{color:#facc15}.ping.bad{color:var(--bad)}
button.x{margin:0;padding:0;width:30px;height:30px;border-radius:8px;background:transparent;border:1px solid var(--border2);color:var(--muted);font-size:13px;flex:none}
button.x:hover{color:var(--bad);border-color:var(--bad);background:transparent}
.watchers{margin-top:8px;font-size:13px;color:var(--muted);display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.watchers .w{display:inline-flex;gap:4px;align-items:center;color:var(--text)}
.settings{display:grid;grid-template-columns:auto minmax(0,1fr);gap:6px 12px;align-items:center}
.settings label{font-size:12px;color:var(--muted);margin:0;text-transform:none;letter-spacing:0}
.settings .seg button{min-height:36px;font-size:13px;padding:4px 6px}
.seg button:disabled{opacity:.55}
.seg button.on:disabled{background:var(--accent);color:var(--accent-text);opacity:.85}
.seg.level{align-items:center;max-width:180px}
.seg.level b{min-width:40px;text-align:center;font-size:18px}
.lobby .strat button{min-height:40px;font-size:13px;padding:4px 6px;white-space:nowrap}
.go{display:flex;gap:8px;margin-top:16px;position:sticky;bottom:-22px;padding:10px 0 12px;background:linear-gradient(transparent,var(--panel) 30%);z-index:1}
.go button{margin:0;flex:1}
.table{width:100%;border-collapse:collapse;font-size:14px;font-variant-numeric:tabular-nums}
.table th{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);text-align:left;font-weight:600;padding:3px 6px}
.table td{padding:5px 6px;border-top:1px solid var(--border);white-space:nowrap}
.table td:nth-child(2){white-space:normal}
.table tr.me td{background:rgba(37,99,235,.16)}
.table tr.champ td{color:var(--good);font-weight:700}
.toast{position:fixed;left:50%;bottom:calc(24px + var(--sab));transform:translateX(-50%);z-index:40;background:var(--panel2);border:1px solid var(--border2);color:var(--text);padding:10px 16px;border-radius:12px;box-shadow:0 10px 30px rgba(0,0,0,.45);max-width:90vw}
@media (max-width:760px){
  .panel.lobby{grid-template-columns:minmax(0,1fr);padding:16px;gap:12px}
  .qr{width:min(250px,64vw)}
  .invite .roomcode{font-size:clamp(30px,10vw,44px)}
  .settings{gap:6px 8px}
  .settings .seg button{font-size:12px;padding:3px 4px;min-height:34px}
}
body.room.watching .cluster{display:none!important}
.watchnote{color:var(--muted);font-size:12px}

@media (max-width:720px) and (orientation:portrait){
  body.room .hud{padding:0 10px 4px;gap:6px;flex-wrap:nowrap;overflow:hidden}
  body.room .hud .seg button{padding:3px 6px;font-size:12px;min-height:30px}
  body.room .hud .strat{flex:1 1 auto;min-width:0}
  body.room .hud .reacts{display:none}
  body.room[data-phase=playing] .hud .status{display:none}
  body.room .race #raceClock{font-size:16px}
  .stage.multi{--opp-h:104px}
  .stage.multi .opps{display:none}
  .stage.multi[data-opp=none]{grid-template-columns:minmax(0,1fr)}
  .stage.multi[data-opp=none] .me .well{height:min(100cqh - var(--strip-h) - 20px,(100cqw - 24px) * 2)}
  .stage.multi[data-opp=col] #oppL{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;grid-column:2;grid-row:1 / 3;width:var(--mini-w);gap:8px;align-self:stretch}
  .stage.multi[data-opp=col] .me .well{height:min(100cqh - var(--strip-h) - 20px,(100cqw - var(--mini-w) - 34px) * 2)}
  .stage.multi[data-opp=strip]{grid-template-columns:minmax(0,1fr);grid-template-rows:var(--opp-h) var(--strip-h) minmax(0,1fr)}
  .stage.multi[data-opp=strip] #oppL{display:flex;grid-column:1;grid-row:1;width:100%;height:var(--opp-h);gap:6px;justify-content:center;align-items:flex-start}
  .stage.multi[data-opp=strip] .me .side{grid-row:2}
  .stage.multi[data-opp=strip] .me .well{grid-row:3;height:min(100cqh - var(--strip-h) - var(--opp-h) - 28px,(100cqw - 24px) * 2)}
  .stage.multi .mname{font-size:10px;line-height:12px}
  .incoming{right:auto;left:0;width:9cqw}
  body.room[data-mode=sprint] .me .side .title,body.room[data-mode=ultra] .me .side .lines{display:none}
  body.room .me .side .extra{flex:1.7 1 0}
  .seg-in span{font-size:9px}
}
@media (max-height:520px) and (orientation:landscape){
  body.room{grid-template-rows:auto auto minmax(0,1fr);grid-template-areas:"hdr hdr hdr" "padl hud padr" "padl stage padr"}
  body.room .hud{padding:0 6px 2px;gap:6px;flex-wrap:nowrap;overflow:hidden}
  body.room .hud .seg button{padding:2px 6px;font-size:12px;min-height:28px}
  body.room .hud .reacts{display:none}
  body.room[data-phase=lobby] .hud,body.room[data-phase=over] .hud{display:none}
  .qr{width:min(220px,100%,58vh)}
  .panel.lobby{grid-template-columns:minmax(0,250px) minmax(0,1fr);gap:18px;padding:16px}
  .invite .roomcode{font-size:34px}
  .settings .seg button{min-height:32px;font-size:12px}
  .stage.multi{gap:8px}
  .stage.multi .me .well{height:min(100cqh - 8px,(100cqw - 104px - var(--opp-total)) * 2)}
  .stage.multi .mname{font-size:10px;line-height:12px}
}
.card h3.sub{font-size:12px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin:16px 0 0;font-weight:650}
.card .err:empty{min-height:0;margin:0}

/* local 2P held upright (play.html, .stage.split): 2x2 stats (score, lines, next, hold)
   above each board, everything centred vertically, the rotate hint in the flow below. */
@media (max-width:720px) and (orientation:portrait){
  .stage.split{grid-template-rows:auto auto;align-content:center;row-gap:10px}
  .stage.split .player{gap:8px}
  .split .side{display:grid;grid-template-columns:1fr 1fr;grid-auto-rows:auto;order:-1;gap:4px;width:100%}
  .split .side .box:not(.title):not(.lines){display:none}
  .stage.split .side .box.next,.stage.split .side .box.hold{display:block}
  .split .side .box{padding:3px 6px}
  .split .side .next canvas,.split .side .hold canvas{height:24px}
  .split .side .box.extra,.split .side .box.keys{display:none}
  .split .well{height:min(100cqh - 130px,(50cqw - 16px) * 2)}
  .stage.split .rotate-hint{position:static;transform:none;grid-column:1 / -1;grid-row:2;justify-self:center}
}
