/* v0.60 (DEV-329): the Command Center look (DESIGN.md item 78, mockups in prototype/v13-command-center.html). A war-room
   tactical display: dark glass, a live grid, the only light is the threat. The board is flat and top-down, edge to edge
   (the tilted CSS 3D tabletop is gone for good). Humans are rounded squares, the AI octagons. */
:root{
  --void:#060A10;--grid:#16263A;--hu:#5CC8FF;--hu-tile:#0B2438;--ai:#F5A524;--ai-tile:#26180A;--agi:#B48CFF;--asi:#FF4D5E;
  --volt:#FFD84A;--fg:#E6EDF3;--dim:#B7C5D4;--muted:#7F93AA;--faint:#3A5272;--line:#1C2C42;--line2:#26405E;--green:#3DDC84;
  --glass:linear-gradient(180deg,rgba(16,27,42,.92),rgba(9,15,24,.92));--ink:#04121D;
  --display:"Chakra Petch",system-ui,sans-serif;
  --ui:-apple-system,BlinkMacSystemFont,"SF Pro Text",system-ui,"Segoe UI",Roboto,sans-serif;
  --mono:"SF Mono",ui-monospace,"IBM Plex Mono",Menlo,monospace;
  /* the play column: the whole screen on a phone (the board runs edge to edge), a column on a desktop */
  --colw:100vw;
}
*{box-sizing:border-box}
html{overflow-x:clip;background:var(--void)} /* fight sparks and knock-offs fly past the edge for a moment: never let the page scroll sideways */
html,body{margin:0;color:var(--fg);font-family:var(--ui);-webkit-tap-highlight-color:transparent;overscroll-behavior:none;-webkit-font-smoothing:antialiased}
body{min-height:100dvh;display:flex;flex-direction:column;overflow-x:clip;padding:env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
  background:radial-gradient(120% 60% at 50% 0%,rgba(92,200,255,.05),transparent 60%),
    linear-gradient(rgba(22,38,58,.28) 1px,transparent 1px) 0 0/24px 24px,
    linear-gradient(90deg,rgba(22,38,58,.28) 1px,transparent 1px) 0 0/24px 24px,var(--void);background-attachment:fixed}
button{font:inherit;color:inherit;cursor:pointer}
h1{font:700 28px/1.08 var(--display);margin:0;letter-spacing:1px}
#app{display:flex;flex-direction:column;width:100%}

/* ---------- the play screen, top to bottom: pills, the 🧠 meter, the board, the console, the buttons. Pieces below.
   The column runs through the home-bar strip (its padding keeps the buttons clear), so the pieces list starts at the
   screen's bottom edge instead of peeking into that strip (v0.63). ---------- */
.left{display:flex;flex-direction:column;height:calc(100svh - env(safe-area-inset-top));min-height:470px;padding-bottom:calc(6px + env(safe-area-inset-bottom));width:var(--colw);max-width:100%;margin:0 auto}
.hud{display:flex;align-items:center;gap:6px;padding:4px 10px 0;height:34px;flex:none}
.pill{height:28px;display:inline-flex;align-items:center;padding:0 10px;border:1px solid var(--line2);border-radius:7px;background:rgba(10,18,28,.85);font:600 12px var(--mono);letter-spacing:2px;color:var(--dim);white-space:nowrap}
.pill.on{background:var(--hu);border-color:var(--hu);color:var(--ink);box-shadow:0 0 18px rgba(92,200,255,.45)}
.pill.on.ai{background:var(--ai);border-color:var(--ai);box-shadow:0 0 18px rgba(245,165,36,.45)}
.pill.wait{color:var(--ai);border-color:rgba(245,165,36,.45)}
body.me-ai .pill.wait{color:var(--hu);border-color:rgba(92,200,255,.45)}
.pill.r{margin-left:auto}
/* v0.64 (DEV-338): 🔊 at the right end of the pills (after VS … BOT; live, where there is none, it still sits right) */
.pill.snd{margin-left:auto;width:36px;padding:0;justify-content:center;font:14px/1 var(--ui);letter-spacing:0;color:var(--fg);cursor:pointer;flex:none}
.pill.r ~ .snd{margin-left:0}
.dots i{font-style:normal;animation:blink 1.2s infinite}.dots i:nth-child(2){animation-delay:.2s}.dots i:nth-child(3){animation-delay:.4s}
@keyframes blink{0%,60%,100%{opacity:.2}30%{opacity:1}}

/* the 🧠 meter: one for the whole game (its number is public: it grows in the open). 2 … 7 amber, AGI and 9 violet, ASI red;
   the drain shows what is gone as a yellow hatch; held, fragile and stopped */
.meter{margin:6px 10px 0;padding:7px 12px 6px;border:1px solid var(--line);border-radius:12px;background:var(--glass);flex:none}
.mt{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font:600 12px var(--mono);letter-spacing:2px;color:var(--dim);white-space:nowrap}
.mt .v{font:700 17px var(--display);color:var(--ai);letter-spacing:0;margin-left:5px}
.mt .nx{color:var(--ai);font-size:11px;letter-spacing:1.5px;overflow:hidden;text-overflow:ellipsis;min-width:0}
.bars{display:grid;grid-template-columns:repeat(9,1fr);gap:4px;margin-top:6px}
.bars i{height:9px;border-radius:2px;border:1px solid rgba(245,165,36,.35)}
.bars i.agi{border-color:rgba(180,140,255,.55);background:repeating-linear-gradient(90deg,rgba(180,140,255,.28) 0 2px,transparent 2px 5px)}
.bars i.asi{border-color:rgba(255,77,94,.6);background:repeating-linear-gradient(90deg,rgba(255,77,94,.3) 0 2px,transparent 2px 5px)}
.bars i.f{background:var(--ai);border-color:var(--ai);box-shadow:0 0 8px rgba(245,165,36,.5)}
.bars i.f.agi{background:var(--agi);border-color:var(--agi);box-shadow:0 0 8px rgba(180,140,255,.55)}
.bars i.f.asi{background:var(--asi);border-color:var(--asi);box-shadow:0 0 10px rgba(255,77,94,.7)}
.bars i.dr{background:repeating-linear-gradient(135deg,rgba(255,216,74,.35) 0 2px,transparent 2px 5px);border-color:rgba(255,216,74,.45);box-shadow:none}
.bars i.off{background:#1A2333;border-color:#25324A;box-shadow:none}
.lbls{display:grid;grid-template-columns:repeat(9,1fr);gap:4px;margin-top:3px;font:500 10px var(--mono);color:var(--muted);text-align:center}
.lbls .agi{color:var(--agi)}.lbls .asi{color:var(--asi)}
.meter.agi .mt .v,.meter.agi .mt .nx{color:var(--agi)}
.meter.asi{border-color:rgba(255,77,94,.55);box-shadow:0 0 22px rgba(255,77,94,.25)}
.meter.asi .mt .v,.meter.asi .mt .nx{color:var(--asi)}
.meter.drain{border-color:rgba(255,216,74,.5)}
.meter.drain .mt .v,.meter.drain .mt .nx{color:var(--volt)}
.meter.stopped .mt,.meter.stopped .mt .v,.meter.stopped .mt .nx{color:var(--muted)}
.meter.stopped .mt .v{text-decoration:line-through}
.meter.frag .mt .v,.meter.frag .mt .nx{color:var(--asi)}

/* the board: flat, top-down, edge to edge, no gaps. Its squares are as wide as the column allows and up to 1.087 times as tall
   (48.75 x 53 px on a 390 px iPhone); on a short screen (Safari's bars, an iPhone SE) it gives up height first, so the
   console and the buttons always fit. .boardwrap is a size container: a piece's size follows its square's (cq units). */
.boardwrap{position:relative;flex:0 1 calc(var(--colw) / 8 * 1.087 * 8);min-height:200px;container-type:size;margin-top:8px}
.board{position:relative;display:grid;grid-template-columns:repeat(8,minmax(0,1fr));grid-template-rows:repeat(8,minmax(0,1fr));height:100%;background:#09111B;user-select:none;-webkit-user-select:none;touch-action:pan-y;-webkit-touch-callout:none}
/* v0.36 (DEV-294): on a phone the board is most of the screen, so a vertical swipe on it scrolls the page (to the rules).
   pan-y lets it; a touch that starts on a square you can drag from right now is held by the board's touchmove listener
   (bindPointer), not by touch-action on the squares */
.sq{position:relative;border:0;border-radius:0;padding:0;margin:0;min-width:0;min-height:0;color:var(--fg);box-shadow:inset 0 0 0 .5px var(--grid);background:linear-gradient(180deg,rgba(14,24,36,.9),rgba(9,16,26,.9));
  font-size:min(12.5cqw,11.6cqh)} /* 1em: the square's own size (its width, or a little less than its height on a short board) */
/* blocked: a grey hatch (red means only an attack or a fight) */
.sq.block{background:repeating-linear-gradient(135deg,rgba(138,155,176,.30) 0 3px,rgba(10,14,20,.95) 3px 9px);box-shadow:inset 0 0 0 1px rgba(138,155,176,.28);cursor:default}
.rk{position:absolute;left:1px;top:0;font:600 8px/1 var(--mono);color:#5A7596;z-index:6;text-shadow:0 0 2px #000,0 0 3px #000;pointer-events:none}
.files{display:grid;grid-template-columns:repeat(8,1fr);height:13px;flex:none;font:500 9px/13px var(--mono);color:var(--faint);text-align:center}
/* pieces fill the square, 3px in from each edge: humans a rounded square with the rank bottom-right, the AI an octagon with
   its rank under the face, a ? while hidden. .pz is the piece's place on its square, .blk the piece itself (what the fight
   animations move) */
.pz{position:absolute;inset:3px;z-index:2;pointer-events:none}
.blk{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-weight:700}
.blk.h{border:2px solid var(--hu);border-radius:.19em;background:linear-gradient(180deg,#103250,var(--hu-tile));box-shadow:0 0 10px rgba(92,200,255,.22),inset 0 0 10px rgba(92,200,255,.10)}
.blk.h.hid{background:linear-gradient(180deg,#0E2A44,#0A2034)}
.blk.a{isolation:isolate;filter:drop-shadow(0 0 5px rgba(245,165,36,.32))}
.blk.a::before,.blk.a::after{content:"";position:absolute;z-index:-1}
.blk.a::before{inset:0;background:var(--ai);clip-path:polygon(.25em 0,calc(100% - .25em) 0,100% .25em,100% calc(100% - .25em),calc(100% - .25em) 100%,.25em 100%,0 calc(100% - .25em),0 .25em)}
.blk.a::after{inset:2px;background:linear-gradient(180deg,#352210,var(--ai-tile));clip-path:polygon(.23em 0,calc(100% - .23em) 0,100% .23em,100% calc(100% - .23em),calc(100% - .23em) 100%,.23em 100%,0 calc(100% - .23em),0 .23em)}
.blk .ic{font-size:.52em;line-height:1}
.blk .ic.up{transform:translateY(-.1em)}
.blk.a .ic.up{transform:translateY(-.13em)}
.blk .n{position:absolute;font:700 .29em/1 var(--mono)}
.blk.h .n{right:.14em;bottom:.1em;color:var(--hu)}
.blk.a .n{left:0;right:0;bottom:.14em;text-align:center;color:var(--ai)}
.blk .q{font:700 .5em/1 var(--display)}
.blk.a .q{color:var(--ai)}.blk.h .q{color:var(--hu)}
/* ↺ a piece that switched sides at a trap (v0.28), shown only where its face is: in its old army's colour */
.trn{position:absolute;left:-.3em;top:-.3em;width:1.55em;height:1.55em;border-radius:50%;font:700 .2em/1.55em var(--ui);text-align:center;color:var(--ink);font-style:normal;z-index:3;pointer-events:none}
.sq.clash::after{content:"";position:absolute;inset:1px;border:2px solid var(--asi);border-radius:9px;box-shadow:0 0 14px rgba(255,77,94,.7);z-index:5;pointer-events:none}
.trn.h{background:var(--hu)}.trn.ai{background:var(--ai)}
/* ↑ a piece that took power from the datacenter (+1, once) */
.bst{position:absolute;right:.04em;top:0;font:800 .23em var(--mono);color:var(--volt);font-style:normal;text-shadow:0 1px 2px #000;pointer-events:none;z-index:3}
.blk.a .bst{right:.8em;top:.15em}
/* where a picked piece can go: pulsing cyan dots; an attack: a red ring; a 🧬 copy: green */
.sq.can{background:linear-gradient(180deg,rgba(92,200,255,.12),rgba(92,200,255,.05))}
.sq.can:not(.fight)::after{content:"";position:absolute;left:50%;top:50%;width:13px;height:13px;border-radius:50%;transform:translate(-50%,-50%);background:rgba(92,200,255,.6);box-shadow:0 0 12px rgba(92,200,255,.9);animation:pulse 1.4s ease-in-out infinite;z-index:3;pointer-events:none}
.sq.can.fight::after{content:"";position:absolute;inset:1px;border:2px solid var(--asi);border-radius:9px;box-shadow:0 0 14px rgba(255,77,94,.65),inset 0 0 12px rgba(255,77,94,.3);z-index:3;animation:pulse 1.4s ease-in-out infinite;pointer-events:none}
.sq.copy::after{content:"";position:absolute;inset:1px;border:2px solid var(--green);border-radius:9px;box-shadow:0 0 12px rgba(61,220,132,.6);z-index:3;animation:pulse 1.4s ease-in-out infinite;pointer-events:none}
@keyframes pulse{50%{opacity:.55}}
/* the picked piece: a white ring on the piece */
.sq.sel .blk.h{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,.18),0 0 18px rgba(92,200,255,.8)}
.sq.sel .blk.a::before{background:#fff}
.sq.sel .blk.a{filter:drop-shadow(0 0 9px rgba(245,165,36,.85))}
/* where a drag lands if you let go now (v0.33, DEV-291): a steady white ring, over the lit squares' pulse */
.sq.over::before{content:"";position:absolute;inset:-1px;border:3px solid #fff;border-radius:8px;box-shadow:0 0 18px rgba(255,255,255,.6),inset 0 0 10px rgba(255,255,255,.25);z-index:5;pointer-events:none}
.sq.over::after{animation:none!important;opacity:1}
.sq.over.swap .pz::after{content:"⇄";position:absolute;right:-7px;bottom:-9px;width:18px;height:18px;border-radius:50%;background:#fff;color:var(--ink);font:800 12px/18px var(--ui);text-align:center;z-index:6}
/* the opponent's last move, loud: corner brackets in their colour round the square it went to and a glow on its piece
   (still a ? if hidden), a dashed square where it came from. Your own last move: a faint white ring */
.lm{position:absolute;inset:1px;z-index:4;pointer-events:none;--c:var(--ai);filter:drop-shadow(0 0 4px var(--c));
  background:linear-gradient(var(--c),var(--c)) 0 0/12px 3px no-repeat,linear-gradient(var(--c),var(--c)) 0 0/3px 12px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 0/12px 3px no-repeat,linear-gradient(var(--c),var(--c)) 100% 0/3px 12px no-repeat,
    linear-gradient(var(--c),var(--c)) 0 100%/12px 3px no-repeat,linear-gradient(var(--c),var(--c)) 0 100%/3px 12px no-repeat,
    linear-gradient(var(--c),var(--c)) 100% 100%/12px 3px no-repeat,linear-gradient(var(--c),var(--c)) 100% 100%/3px 12px no-repeat}
.lm.h{--c:var(--hu)}
.sq.opt{background:radial-gradient(circle,rgba(245,165,36,.16),rgba(9,16,26,.9) 75%)}
.sq.opt.oph{background:radial-gradient(circle,rgba(92,200,255,.16),rgba(9,16,26,.9) 75%)}
.sq.opt .blk.a{filter:drop-shadow(0 0 10px rgba(245,165,36,.95))}
.sq.opt .blk.h{box-shadow:0 0 18px rgba(92,200,255,.9),inset 0 0 10px rgba(92,200,255,.2)}
.lmf{position:absolute;inset:9px;z-index:1;border:1.5px dashed var(--ai);border-radius:7px;opacity:.6;pointer-events:none}
.lmf.h{border-color:var(--hu)}
.sq.last{box-shadow:inset 0 0 0 2px rgba(255,255,255,.3)}
/* a face-up enemy piece (a 📡 shows it): a cyan glow */
.sq.spot .blk.a{filter:drop-shadow(0 0 10px rgba(92,200,255,.9))}
.sq.spot .blk.h{box-shadow:0 0 14px rgba(245,165,36,.8)}
.sq.asi .blk.a::before{background:var(--asi)}
.sq.asi .blk.a{filter:drop-shadow(0 0 10px rgba(255,77,94,.9))}
/* the last square at the end of the game */
.sq.final::before{content:"";position:absolute;inset:-2px;border:3px solid var(--hu);border-radius:9px;box-shadow:0 0 24px rgba(92,200,255,.9);z-index:5;pointer-events:none}
.sq.final.fai::before{border-color:var(--ai);box-shadow:0 0 24px rgba(245,165,36,.9)}
/* 🏢 the humans' datacenter: a square they place in setup, not a piece. Dim; lit once the 🧠 is a 10 (the CTO drains it there);
   pulsing while the CTO stands on it and drains the 🧠 (v0.38, DEV-295); dark once the drain has started and nobody is draining */
.sq.dc{box-shadow:inset 0 0 0 1px rgba(92,200,255,.55)}
.dci{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;font-size:.4em;opacity:.6;pointer-events:none}
.dci b{font:700 8px var(--mono);letter-spacing:1.5px;color:var(--hu)}
.dcm{position:absolute;right:2px;top:1px;font-size:10px;line-height:1;z-index:4;pointer-events:none}
.sq.dc.live{background:radial-gradient(circle,rgba(255,216,74,.22),rgba(42,34,8,.7));box-shadow:inset 0 0 0 1.5px rgba(255,216,74,.7)}
.sq.dc.live .dci{opacity:1;filter:drop-shadow(0 0 6px #ffd84a);animation:bolt 1.2s ease-in-out infinite}.sq.dc.live .dci b{color:var(--volt)}
.sq.dc.drain{background:radial-gradient(circle,rgba(255,216,74,.35),rgba(42,34,8,.8));z-index:1;box-shadow:inset 0 0 0 2px rgba(255,216,74,.4)}
.dcp{position:absolute;inset:0;box-shadow:inset 0 0 0 3px var(--volt),0 0 16px rgba(255,216,74,.6);opacity:0;animation:drainpulse 1.1s ease-in-out infinite;will-change:opacity;pointer-events:none}
.sq.dc.drain .dci,.sq.dc.drain .dcm{opacity:1;filter:drop-shadow(0 0 6px #ffd84a);animation:bolt 1.1s ease-in-out infinite}.sq.dc.drain .dci b{color:var(--volt)}
/* v0.78: the lit 🏢's glow animates opacity only (the glow itself is drawn once), which the GPU runs on its own. v0.74's
   filter and box-shadow animations were repainted every frame, the 🏢 lit or draining, drag or no drag: 60 style
   recalcs a second, and on the iPhone a touch on a piece then often didn't start a drag (the user: "it should move like
   how it does in beginning of the game"). The pulse is its own span (.dcp), so .over's and .can's ::before / ::after
   still show on the draining 🏢 */
@keyframes drainpulse{50%{opacity:1}}
@keyframes bolt{0%,100%{opacity:.65}50%{opacity:1}}
body.dragging .sq.dc .dci,body.dragging .sq.dc .dcm,body.dragging .dcp{animation-play-state:paused}
.sq.dc.off .dci,.sq.dc.off .dcm{opacity:.2;filter:grayscale(1)}
.sq.dc.pick{box-shadow:inset 0 0 0 3px var(--hu),0 0 14px rgba(92,200,255,.6);z-index:1}
.sq.dc.pick .dci{opacity:1}
/* the moves: a piece shown face up for the first time flips over; one that switched sides flashes */
.pz.drag{opacity:.25;filter:grayscale(.4)}
/* v0.89: the touch log (triple-tap the round): at the bottom of the screen, clear of the board, never in the way of a touch */
#ksdiag{position:fixed;left:6px;right:6px;bottom:calc(env(safe-area-inset-bottom,0px) + 6px);max-height:38vh;overflow:hidden;margin:0;padding:6px 8px;border-radius:8px;background:rgba(0,0,0,.88);color:#9FF0C8;font:10px/1.35 ui-monospace,Menlo,monospace;white-space:pre-wrap;overflow-wrap:anywhere;pointer-events:none;z-index:60}
/* v0.86: the last 10 rounds (R91/100): the round pill turns red */
.pill.late{color:var(--asi);border-color:var(--asi)}
.blk.reveal{animation:flip .5s cubic-bezier(.3,1.4,.5,1)}
@keyframes flip{0%{transform:perspective(300px) rotateY(-90deg)}100%{transform:none}}
.sq.turned .blk{animation:turnflash .7s ease-out}
@keyframes turnflash{0%{filter:brightness(1)}30%{filter:brightness(2.2) saturate(2)}100%{filter:brightness(1)}}
/* while dragging, a copy of the piece follows the finger, drawn bigger and above it. It sits at the top left of the screen
   and is moved by a transform only (set each frame from the code; v0.33, DEV-291), so a drag does no layout work */
.floater{position:fixed;left:0;top:0;z-index:20;pointer-events:none;will-change:transform;filter:drop-shadow(0 12px 14px rgba(0,0,0,.75))}
/* the fight on the board: stand-ins in the fx layer (the board's own coordinates), sparks, the big hit's square flash */
.fx{position:absolute;inset:0;pointer-events:none;z-index:7}
.clone{position:absolute;pointer-events:none}.clone .blk{inset:3px}
.spk{position:absolute;width:6px;height:6px;margin:-3px;border-radius:2px;background:var(--asi);pointer-events:none}
/* v0.61 (DEV-332): the screen stays still. A big hit (7 and up) flashes the fight square only; the drain jolts the 🧠 meter */
.sqflash{position:absolute;pointer-events:none;border-radius:8px;background:radial-gradient(circle,rgba(255,77,94,.55),rgba(255,77,94,.12) 70%);box-shadow:0 0 22px 4px rgba(255,77,94,.75);animation:sqflash .75s ease-out forwards}
@keyframes sqflash{0%{opacity:0}15%{opacity:1}100%{opacity:0}}
.meter.jolt{animation:shake .4s}
@keyframes shake{0%,100%{transform:none}20%{transform:translate(-6px,2px)}40%{transform:translate(6px,-2px)}60%{transform:translate(-4px,0)}80%{transform:translate(4px,0)}}
/* after a fight the winner's number rises from the square and fades; never blocks a tap */
.float{position:fixed;z-index:9;pointer-events:none;transform:translate(-50%,-50%);font:700 40px/1 var(--display);white-space:nowrap;text-shadow:0 0 14px rgba(0,0,0,.6),0 2px 0 #000}
.float.h{color:var(--hu);text-shadow:0 0 14px rgba(92,200,255,.9),0 2px 0 #000}.float.ai{color:var(--ai);text-shadow:0 0 14px rgba(245,165,36,.9),0 2px 0 #000}.float.n{color:var(--fg)}
.float .x{color:var(--muted);font-size:.6em;margin:0 .15em}.float .b{color:var(--hu)}.float .a{color:var(--ai)}
/* alerts: level-ups and milestones over the board */
.toasts{position:absolute;left:0;right:0;top:30%;display:flex;flex-direction:column;align-items:center;gap:6px;pointer-events:none;z-index:8}
.toast{padding:10px 16px;border-radius:12px;background:rgba(8,12,20,.94);border:1px solid var(--line2);color:var(--fg);font:600 13px var(--ui);box-shadow:0 10px 30px rgba(0,0,0,.6);animation:tin .25s ease-out,tout .5s ease-in forwards;animation-delay:0s,var(--hold,1.6s);max-width:calc(100vw - 32px);text-align:center;text-wrap:balance}
.toast.big{font:700 15px var(--display);letter-spacing:1.5px;color:var(--asi);border-color:var(--asi);box-shadow:0 0 30px rgba(255,77,94,.5);--hold:3.2s}
.toast.big.agi{color:var(--agi);border-color:var(--agi);box-shadow:0 0 30px rgba(180,140,255,.45)}
.toast.drain{color:var(--volt);border-color:var(--volt);box-shadow:0 0 30px rgba(255,216,74,.4)}
.toast.drain:not(.big){font:600 13px var(--ui)}
@keyframes tin{from{opacity:0;transform:translateY(-12px) scale(.9)}to{opacity:1;transform:none}}
@keyframes tout{to{opacity:0;transform:translateY(-10px)}}

/* ---------- under the board: the console. The message and the last fight; during a fight, the ENGAGEMENT panel.
   Its height never depends on what it says (a longer message never moves the board under the finger), and it is the
   same between fights and during one, so the board never jumps.
   v0.61 (DEV-332): both fill it. It is a size container: the piece tiles grow with its height (--t, about 80 px on an
   iPhone 13, smaller on the SE so nothing scrolls). Two layouts: short (the SE, a desktop: one row) and tall (from 150 px
   of room: the pieces large, names under them). ---------- */
.console{margin:8px 10px 0;padding:10px 12px;border:1px solid var(--line);border-radius:14px;background:var(--glass);flex:1 0 var(--cons,136px);min-height:0;display:flex;flex-direction:column;overflow:hidden;
  container:cons/size;--msgh:calc(2 * 1.38 * 15px);--msgb:6px}
.msg{font:15px/1.38 var(--ui);color:var(--dim);margin-bottom:var(--msgb);height:var(--msgh);overflow:hidden;flex:none}
.msg b{color:var(--fg)}
.you{color:var(--hu);font-weight:600}.them{color:var(--ai);font-weight:600}
body.me-ai .you{color:var(--ai)}body.me-ai .them{color:var(--hu)}
.msg b.recon,body.me-ai .msg b.recon,.lvnote{color:var(--volt)}
/* the last fight, between fights: both pieces as tiles (the loser struck through), "R15 · Operative 7 tied Strongman 7",
   LOG ›; tap it: the log. Short: one row. Tall: LAST FIGHT · LOG ›, the tiles big with the numbers between, the line under */
.fline{--t:clamp(30px,calc(100cqh - var(--msgh) - var(--msgb) - 12px),56px);--tw:calc(var(--t) * .92);flex:1 1 0;min-height:0;width:100%;display:grid;grid-template-columns:var(--tw) minmax(0,1fr) var(--tw) auto;
  grid-template-areas:"fa fs fd go";align-items:center;gap:8px;padding:4px 10px;border:1px solid var(--grid);border-radius:12px;background:rgba(6,10,16,.55);color:var(--dim);text-align:left;font:inherit}
.fline .lf,.fline .cmp{display:none}
.fline .lf{grid-area:lf;font:600 10px var(--mono);letter-spacing:2px;color:var(--muted);justify-self:start}
.fline .go{grid-area:go;font:600 12px var(--mono);color:var(--dim);letter-spacing:1.5px;white-space:nowrap;justify-self:end}
.fline .fa{grid-area:fa}.fline .fd{grid-area:fd}
.fline .cmp{grid-area:cmp;font:700 28px/1 var(--display);color:var(--fg);text-align:center;white-space:nowrap}
.fline .fs{grid-area:fs;font:500 13px/1.3 var(--ui);color:var(--dim);text-align:center;min-width:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
.fline .fs b{font:700 1em var(--mono);color:var(--fg)}
.fline.none{display:flex;align-items:center;justify-content:center;border-style:dashed;border-color:var(--line);background:none}
.fline .nf{font:500 14px var(--ui);color:var(--muted);letter-spacing:.3px}
.ftl,.tile{position:relative;width:var(--tw);height:var(--t);font-size:var(--t);justify-self:center}
.ftl .pz,.tile .pz{inset:0}
.ftl.x .pz,.tile.lost .pz{opacity:.5}
.ftl.x::after,.tile.lost::after{content:"";position:absolute;left:-3px;right:-3px;top:50%;height:2px;background:var(--asi);transform:rotate(-38deg);box-shadow:0 0 6px var(--asi);z-index:3}
@container cons (min-height:150px){
  .fline{--t:clamp(44px,calc(100cqh - var(--msgh) - var(--msgb) - 66px),80px);grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);grid-template-rows:auto 1fr auto;
    grid-template-areas:"lf . go" "fa cmp fd" "fs fs fs";gap:4px 14px;padding:8px 12px 9px}
  .fline .lf,.fline .cmp{display:block}
  .fline .fs{font-size:15px;-webkit-line-clamp:1}
}
/* the engagement: a fight, big. The header (where, and FIGHT until the hidden one turns over), the two pieces, the verdict */
.console.eng{padding:9px 12px}
.eng-h{display:flex;justify-content:space-between;align-items:center;font:600 11px var(--mono);letter-spacing:2.5px;color:var(--muted);flex:none}
.eng-h .ft{color:var(--asi);display:flex;align-items:center;gap:6px}
.eng-h .ft::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--asi);box-shadow:0 0 8px var(--asi)}
.eng-row{--t:clamp(30px,calc(100cqh - 50px),64px);--tw:calc(var(--t) * .92);flex:1 1 0;min-height:0;display:grid;grid-template-columns:var(--tw) minmax(0,1fr) auto minmax(0,1fr) var(--tw);align-items:center;gap:7px;margin:3px 0}
.side{font:600 9px var(--mono);letter-spacing:1px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.who{font:600 15px/1.15 var(--ui);color:var(--fg);margin-top:2px;overflow-wrap:anywhere}
.vs{text-align:center;font:700 20px var(--display);color:var(--dim)}
.vs small{display:block;font:600 13px var(--mono);color:var(--fg);letter-spacing:1px;white-space:nowrap}
.r-side{text-align:right}
.verdict{display:flex;justify-content:space-between;align-items:center;gap:8px;border:1px solid rgba(92,200,255,.4);background:rgba(92,200,255,.07);border-radius:10px;padding:5px 12px;flex:none}
.verdict b{font:700 16px/1.15 var(--display);letter-spacing:1px;color:var(--hu);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.verdict span{font:11px var(--ui);color:var(--muted);text-align:right}
.verdict.l{border-color:rgba(245,165,36,.45);background:rgba(245,165,36,.07)}.verdict.l b{color:var(--ai)}
.verdict.t{border-color:rgba(230,237,243,.3);background:rgba(230,237,243,.05)}.verdict.t b{color:var(--fg)}
.verdict.wait{border-style:dashed;border-color:var(--line2);background:none}.verdict.wait b{color:var(--muted)}
@container cons (min-height:150px){
  .eng-row{--t:clamp(44px,calc(100cqh - 130px),84px);grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);grid-template-rows:auto auto auto;
    grid-template-areas:"sa vs sd" "ta vs td" "wa vs wd";justify-items:center;align-content:center;gap:4px 12px;margin:6px 0}
  .eng-row .ia,.eng-row .id{display:contents}
  .eng-row .ta{grid-area:ta}.eng-row .td{grid-area:td}
  .ia .side{grid-area:sa}.id .side{grid-area:sd}.ia .who{grid-area:wa}.id .who{grid-area:wd}
  .side{font-size:10px;max-width:100%}
  .who{font-size:18px;margin-top:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;overflow-wrap:normal}
  .vs{grid-area:vs;font-size:18px;color:var(--muted)}
  .vs small{font:700 26px/1.1 var(--display);letter-spacing:2px;margin-top:2px}
  .verdict{flex-direction:column;justify-content:center;gap:1px;padding:6px 12px 7px}
  .verdict b{font-size:22px;letter-spacing:.5px;max-width:100%}
  .verdict span{font-size:12px;text-align:center}
}
.console.end{flex:1 0 auto;container-type:normal} /* the end of a game: the console takes what it needs (the board gives way), so the last fight is never cut off */
.console.end .fline{--t:44px;flex:1 0 auto;min-height:60px}
/* a tall phone has room at the end too: the last fight in the tall layout (the end console is sized by its content, so it
   is no size container: a media query stands in for the container query) */
@media (min-height:741px) and (max-width:859px){
  .console.end .fline{--t:64px;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);grid-template-rows:auto 1fr auto;
    grid-template-areas:"lf . go" "fa cmp fd" "fs fs fs";gap:4px 14px;padding:8px 12px 9px}
  .console.end .fline .lf,.console.end .fline .cmp{display:block}
  .console.end .fline .fs{font-size:15px;-webkit-line-clamp:1}
}
/* the end: the banner lights up, blue for a win, red for a loss (the screen itself stays still) */
.console.end.won{animation:endwon 1.2s ease-out}
.console.end.lost{animation:endlost 1.2s ease-out}
@keyframes endwon{0%,100%{box-shadow:none}25%{box-shadow:0 0 0 2px var(--hu),0 0 36px rgba(92,200,255,.55)}}
@keyframes endlost{0%,100%{box-shadow:none}25%{box-shadow:0 0 0 2px var(--asi),0 0 36px rgba(255,77,94,.55)}}
/* the end of the game: the headline, how it ended, the last move and the round, then the last fight */
.msg.over{height:auto;max-height:none;display:flex;flex-direction:column;gap:3px;margin-bottom:8px}
.msg.over h1{font:700 24px/1.1 var(--display);letter-spacing:1px;color:var(--fg)}
.msg.over.win h1{color:var(--hu);text-shadow:0 0 20px rgba(92,200,255,.45)}
.msg.over.lose h1{color:var(--ai);text-shadow:0 0 20px rgba(245,165,36,.45)}
body.me-ai .msg.over.win h1{color:var(--ai);text-shadow:0 0 20px rgba(245,165,36,.45)}
body.me-ai .msg.over.lose h1{color:var(--hu);text-shadow:0 0 20px rgba(92,200,255,.45)}
.msg.over .eyebrow{font:500 11px/1.4 var(--mono);letter-spacing:.3px}

/* ---------- the buttons ---------- */
/* v0.64 (DEV-338): 🏠 first on every screen: 🏠 PIECES ↓ LOG in play, 🏠 START in setup, 🏠 PLAY AGAIN PIECES ↓ at the end */
.actions{display:grid;grid-template-columns:52px 1fr 1fr;gap:8px;padding:8px 10px 0;flex:none}
.actions.home{grid-template-columns:56px 1fr}
.actions.end{grid-template-columns:52px 1.4fr 1fr}
.actions button{white-space:nowrap;padding:0 6px;min-width:0}
.ghost,.primary{min-height:46px;border:1px solid var(--line2);border-radius:11px;background:rgba(10,18,28,.85);font:700 14px var(--display);letter-spacing:2px;color:var(--fg);display:flex;align-items:center;justify-content:center;gap:8px;padding:0 10px}
.ghost.sm{font-size:19px;letter-spacing:0;padding:0}
.primary{background:var(--hu);border-color:var(--hu);color:var(--ink);box-shadow:0 0 24px rgba(92,200,255,.35);font-size:15px}
body.me-ai .left .primary{background:var(--ai);border-color:var(--ai);box-shadow:0 0 24px rgba(245,165,36,.35)}
.ghost[aria-pressed="true"]{border-color:var(--green);color:var(--green);background:#0d2418}
.ghost:disabled,.primary:disabled{opacity:.45}
.ghost.danger{color:var(--asi);border-color:rgba(255,77,94,.45)}
@media (max-width:360px){.actions .ghost,.actions .primary{font-size:13px;letter-spacing:.5px}.actions .ghost.sm{font-size:17px}.actions{grid-template-columns:46px 1fr 1fr;gap:6px}.actions.end{grid-template-columns:46px 1.4fr 1fr}.actions.home{grid-template-columns:50px 1fr}}

/* ---------- setup: the lineup picker in the console's place (v0.64, DEV-338): the picked lineup's line, then a row of
   cards that scrolls sideways, each with a mini map of its three rows (front row on top), and a legend ---------- */
.setupbox{margin:8px 0 0;flex:1 0 auto;display:flex;flex-direction:column;gap:7px;min-height:0}
.setupbox .msg{margin:0 10px;padding:9px 12px;border:1px solid var(--line);border-radius:12px;background:#0A1019;font:14px/1.35 var(--ui);color:#C9D4E0;height:auto}
.luhd{display:flex;justify-content:space-between;align-items:baseline;padding:0 12px}
.luhd b{font:700 13px var(--display);letter-spacing:3px;color:var(--fg)}
.luhd span{font:12px var(--ui);color:#8C9BAD}
.lus{display:flex;gap:8px;overflow-x:auto;padding:0 10px 2px;scroll-padding:0 10px;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.lus::-webkit-scrollbar{display:none}
.lu{flex:none;width:128px;display:flex;flex-direction:column;gap:6px;padding:8px;margin:0;text-align:left;border-radius:12px;border:1px solid var(--grid);background:#0A1019;color:var(--fg);font:inherit;cursor:pointer}
.lu.on{border:1.5px solid var(--hu);background:var(--hu-tile);padding:7.5px}
body.me-ai .lu.on{border-color:var(--ai);background:var(--ai-tile)}
.lun{display:flex;justify-content:space-between;align-items:center;font:700 14px var(--display);letter-spacing:1px}
.lun b{font-size:13px;color:var(--hu)}body.me-ai .lun b{color:var(--ai)}
.lum{display:grid;grid-template-columns:repeat(8,12px);gap:2px}
.lum i,.lul i{display:block;width:12px;height:12px;border-radius:2px;font:700 8px/12px var(--mono);font-style:normal;text-align:center;color:var(--ink)}
.lum i.e{background:transparent}
.lum i.b,.lul i.b{background:var(--hu)}.lum i.m,.lul i.m{background:#2E6F96}.lum i.d,.lul i.d{background:#1E3A55}
.lum i.t,.lul i.t{background:#B07A1E}.lum i.f,.lul i.f{background:var(--green)}
body.me-ai .lum i.b,body.me-ai .lul i.b{background:var(--ai)}body.me-ai .lum i.m,body.me-ai .lul i.m{background:#99620F}body.me-ai .lum i.d,body.me-ai .lul i.d{background:#4A3212}
body.me-ai .lum i.t,body.me-ai .lul i.t{background:var(--agi)}
.luh{font:11px/1.3 var(--ui);color:#B7C4D3;min-height:29px}
.lul{display:flex;flex-wrap:wrap;gap:4px 10px;padding:0 12px;font:11px var(--ui);color:#9FB0C3}
.lul span{display:inline-flex;align-items:center;gap:4px}
.lul i{width:9px;height:9px}
/* setup never shows the 🧠 meter: it is 2 and says nothing until the game starts, and the lineup picker needs the room
   (v0.65; v0.64 dropped it on short screens only) */
.left.setup .meter{display:none}
/* a short screen (an iPhone SE, Safari's bars): the board keeps its height. Setup also drops the LINEUP heading and each
   card's hint (the line above names the picked lineup and gives its hint) */
@media (max-height:740px){
  .left.setup .luhd,.luh{display:none}
  .setupbox{gap:6px;margin-top:6px}.setupbox .msg{padding:7px 10px;font-size:13px}
  .lu{gap:5px;padding:7px}.lu.on{padding:6.5px}
}
@media (max-height:600px){.lul{display:none}}

/* ---------- below the board: the pieces left and the rules (PIECES ↓ scrolls here; DEV-294, DEV-334) ---------- */
.right{width:min(100%,560px);margin:0 auto}
.key{padding:18px 16px 32px;display:flex;flex-direction:column;gap:18px}
.ksec{display:flex;flex-direction:column;gap:12px}
.kh{display:flex;justify-content:space-between;align-items:baseline;gap:8px;padding-bottom:8px;border-bottom:1px solid var(--grid)}
.kh h2{margin:0;font:700 18px var(--display);letter-spacing:3px;text-transform:uppercase;white-space:nowrap}
.kh.b h2{color:var(--hu)}.kh.a h2{color:var(--ai)}
.kh .kc{font:500 13px var(--mono);color:#9FB0C3;white-space:nowrap}
.kh .kc b{font-size:16px;font-weight:700;color:var(--fg)}
/* a tile per kind: the piece in its owner's shape, the name, ×left /total; none left: dimmed and struck through in red */
.kg{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}
.kr{display:flex;flex-direction:column;align-items:center;gap:4px;min-width:0;padding:8px 2px;margin:0;border-radius:10px;background:#0A1019;border:1px solid var(--grid);color:var(--fg);font:inherit;cursor:pointer}
.kr.on{border-color:#C9D6E3;background:#111B28}
.kr .k{position:relative;width:52px;height:56px;font-size:52px;flex:none}
.kr .k .pz{inset:0}
.kr.gone{opacity:.4}
.ks{position:absolute;left:-2px;right:-2px;top:calc(50% - 1px);height:2.5px;border-radius:2px;background:var(--asi);transform:rotate(-40deg);z-index:4;pointer-events:none}
.kb{position:absolute;right:-9px;top:-7px;z-index:5;padding:1px 3px;border-radius:5px;background:var(--void);border:1px solid rgba(255,216,74,.5);font:700 9px/1.2 var(--mono);color:var(--volt);font-style:normal;white-space:nowrap;pointer-events:none} /* v0.29: AI fighters 5–6 take +1 at the 🏢, once */
.kn{max-width:100%;font:11px/1.2 var(--ui);color:var(--dim);text-align:center;min-height:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.kr .kc{font:700 15px var(--mono);color:var(--fg);white-space:nowrap}
.kr .kc i{font:500 11px var(--mono);font-style:normal;color:#8C9BAD}
.kr.gone .kc{color:#8C9BAD}
.ktip{margin:-4px 0 0;font:12px var(--ui);color:var(--muted)}
.kd{margin-top:-2px;padding:10px 12px;border:1px solid var(--line2);border-radius:10px;background:#0A1019;font:14px/1.45 var(--ui);color:var(--dim)}
.seen{display:flex;align-items:center;gap:6px;flex-wrap:wrap;font:13px var(--ui);color:var(--muted)}
.seen.trnd{gap:6px 10px;color:var(--dim)}
.seen.trnd b{font:700 13px var(--display);letter-spacing:2px;color:var(--fg)}
.seen.trnd span{display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap}
.seen .none{color:var(--muted)}
.pc{position:relative;display:inline-flex;align-items:center;gap:3px;height:22px;padding:0 6px;font:700 12px var(--mono);border:1.5px solid var(--hu);border-radius:6px;color:var(--hu);background:var(--hu-tile)}
.pc.ai{border-color:var(--ai);color:var(--ai);background:var(--ai-tile);border-radius:2px}
.pc .trn{position:static;width:13px;height:13px;font-size:9px;line-height:13px}
/* the rules, worded for your side (v0.64, DEV-338): YOU in your side's colour, WATCH OUT in red, BASICS */
.rcs{display:flex;flex-direction:column;gap:22px;margin-top:4px}
.rg{display:flex;flex-direction:column;gap:8px;--rgc:var(--fg)}
.rg.h{--rgc:var(--hu)}.rg.a{--rgc:var(--ai)}.rg.w{--rgc:var(--asi)}
.rgh{display:flex;justify-content:space-between;align-items:baseline;gap:8px;padding-bottom:8px;border-bottom:1px solid var(--grid)}
.rgh h2{margin:0;font:700 18px var(--display);letter-spacing:3px;text-transform:uppercase;color:var(--rgc);white-space:nowrap}
.rgh span{font:12px var(--ui);color:#8C9BAD;text-align:right}
.rc{display:grid;grid-template-columns:36px minmax(0,1fr);gap:12px;align-items:start;padding:10px 12px;border-radius:12px;background:#0A1019;border:1px solid var(--grid)}
.ri{width:36px;height:36px;border-radius:9px;background:#111B28;display:flex;align-items:center;justify-content:center;font-size:19px}
.rc h3{margin:0 0 2px;font:700 13px var(--display);letter-spacing:2px;text-transform:uppercase;color:var(--rgc)}
.rc p{margin:0;font:15px/1.35 var(--ui);color:#C9D4E0}
@media (max-width:380px){.kn{font-size:10.5px;letter-spacing:-.2px}}
@media (max-width:360px){.kg{gap:6px}.kr .k{width:46px;height:50px;font-size:46px}.kh h2{font-size:16px;letter-spacing:2px}}

/* ---------- full screens: the start screen, Play a friend, Stats, the account screens, Friends ---------- */
.overlay{position:fixed;inset:0;overflow:auto;z-index:5;padding:16px}
.card{width:100%;max-width:440px;margin:0 auto;display:flex;flex-direction:column;gap:10px;padding-bottom:12px}
.card p{margin:0;font:15px/1.45 var(--ui);color:var(--dim)}
.card p b{color:var(--fg)}
.eyebrow{font:600 11px/1.45 var(--mono);letter-spacing:2.5px;color:var(--muted);text-transform:uppercase}
.card p.eyebrow{font:600 11px/1.45 var(--mono);color:var(--muted)}
.card > .primary{min-height:54px;font-size:17px}
/* v0.68 (DEV-349): the start screen's hero, as the canvas boards "Home: hero" (390 × 844): the Watcher over a faded
   grid floor, KILL SWITCH, the rules for your side, then the buttons. It fits one iPhone screen with no My games. */
.overlay.home{overflow-x:hidden;background:radial-gradient(120% 60% at 50% 18%,#0E1826 0%,#060A10 70%)}
.overlay.home,html .overlay.home{padding-top:max(16px,env(safe-area-inset-top));padding-bottom:max(16px,env(safe-area-inset-bottom))} /* over the apps' app.css */
.home .card{position:relative;z-index:0;gap:0;padding-bottom:0}
.overlay.home{--hs:1} /* the hero's scale: fitHero() in main.js shrinks it on a short screen */
.home.noacct #acctslot:empty{display:none}
.home #acctslot,.home #acctslot:empty{display:block;min-height:36px}
.home .acctbar{min-height:36px;align-items:center}
.hero{position:relative;display:flex;flex-direction:column;align-items:center;margin-top:calc(18px * var(--hs))}
/* the background: decorative only, behind everything, never takes a tap. Mockup coordinates: x -200…590 (the screen's
   centre at 195), y 0 at 116 px above the Watcher's top. The pieces are faint (15–22 %) and a little blurred. */
.herobg{--w:min(100vw,790px);position:absolute;z-index:-1;top:-116px;left:50%;width:var(--w);height:460px;margin-left:calc(var(--w) / -2);overflow:hidden;pointer-events:none}
.herobg > div{position:absolute;top:0;left:50%;width:790px;height:460px;margin-left:-395px;transform:scale(var(--hs));transform-origin:395px 116px}
.herobg svg{position:absolute;inset:0;display:block}
.herobg i{position:absolute;display:block;background:var(--ai);filter:blur(.6px);font:700 13px var(--display);font-style:normal}
.herobg i.h{background:var(--hu);border-radius:8px}
.herobg i b{position:absolute;inset:2px;display:flex;align-items:center;justify-content:center;background:#0A1019;color:var(--ai)}
.herobg i.h b{border-radius:6px;color:var(--hu)}
.herobg i.a,.herobg i.a b{clip-path:polygon(30% 0,70% 0,100% 30%,100% 70%,70% 100%,30% 100%,0 70%,0 30%)}
@media (min-width:600px){.herobg{-webkit-mask-image:linear-gradient(90deg,transparent,#000 25%,#000 75%,transparent);mask-image:linear-gradient(90deg,transparent,#000 25%,#000 75%,transparent)}}
/* the Watcher (its red eye sweeps the visor, clipped to the visor, so its glow and trail never smear onto the helmet) */
.watcher{display:block;width:calc(104px * var(--hs));height:calc(104px * var(--hs));filter:drop-shadow(0 0 18px rgba(245,165,36,.6)) drop-shadow(0 0 40px rgba(245,165,36,.25))}
.watcher .eye{animation:sweep 5s ease-in-out infinite}
@keyframes sweep{0%,18%,100%{transform:translateX(0)}42%,60%{transform:translateX(-19px)}}
/* KILL SWITCH: outlined letters (no font load), the cap height of 46 px Chakra Petch */
.logo{display:flex;align-items:center;justify-content:center;height:max(30px,calc(46px * var(--hs)));margin-top:calc(30px * var(--hs));line-height:0;filter:drop-shadow(0 0 24px rgba(92,200,255,.25))}
.logo > svg{display:block;height:max(21px,calc(32px * var(--hs)));width:auto;max-width:100%}
/* the rules: a strip of three boxes for the side picked, › between them, in an amber-edged card */
.home .rules{display:grid;grid-template-columns:minmax(0,1fr) 12px minmax(0,1fr) 12px minmax(0,1fr);align-items:start;gap:0;margin-top:calc(34px * var(--hs));padding:12px 8px;border:1px solid #5A4416;border-radius:14px;background:linear-gradient(#141008,#0A0D12)}
.rb{display:flex;flex-direction:column;align-items:center;gap:5px;text-align:center;min-width:0}
.rb .k{width:34px;height:34px;font-size:34px}
.rb > b{font:700 13px/1.15 var(--display);letter-spacing:1.5px;white-space:nowrap}
.card .rb p{margin:0;font:12.5px/1.3 var(--ui);color:#C9D4E0}
.rb b.r-win{color:var(--green)}.rb b.r-grow{color:var(--agi)}.rb b.r-drain{color:var(--hu)}.rb b.r-warn{color:var(--asi)}
.chev{margin-top:10px;font:700 15px var(--ui);font-style:normal;color:var(--ai);text-align:center}
@media (max-width:359px){.rb > b{font-size:11.5px;letter-spacing:.5px}.card .rb p{font-size:11.5px}}
/* side, level, PLAY AS, then PLAY A FRIEND · JOIN CODE · STATS; JOIN CODE opens the code entry under that row */
.home .sides{margin-top:max(8px,calc(14px * var(--hs)))}
.home .sides button{min-height:46px;font-size:15px;letter-spacing:3px}
.home .seg.lv{margin-top:8px}
.home .seg.lv button{min-height:42px;font-size:14px;letter-spacing:3px}
.home #play{margin-top:max(8px,calc(12px * var(--hs)));border:0;background:linear-gradient(#8ED8FF,var(--hu));box-shadow:0 0 22px rgba(92,200,255,.35)}
.home #play.ai{background:linear-gradient(#FFC25C,var(--ai));box-shadow:0 0 22px rgba(245,165,36,.35)}
.home .introrow{margin-top:max(8px,calc(10px * var(--hs)));grid-template-columns:1.35fr 1fr .8fr}
.home .introrow .ghost{min-height:48px;font-size:13px;letter-spacing:1.5px;padding:0 6px;white-space:nowrap}
.home #joinopen[aria-expanded="true"]{border-color:var(--hu);color:var(--hu)}
.home .join{margin-top:10px}
.home .games{margin-top:14px}
@media (max-width:359px){.home .introrow .ghost{font-size:11.5px;letter-spacing:.5px;padding:0 4px}.home .sides button,.home .seg.lv button{letter-spacing:1.5px}}
/* a line with an icon: the friend lobby's "You play …" rows (and, as .home .rule above, the start screen's rules) */
.rules{display:flex;flex-direction:column;gap:9px;padding-top:4px}
.rule{display:grid;grid-template-columns:40px minmax(0,1fr);gap:12px;align-items:center;font:16px/1.3 var(--ui);color:#C9D4E0}
.rule b{color:var(--fg)}.rule b.win{color:var(--green)}.rule b.lose{color:var(--asi)}.rule b.agi{color:var(--agi)}
.k{position:relative;width:40px;height:40px;font-size:40px}
.k .pz{inset:0}
.seg{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:4px;padding:4px;border:1px solid var(--line);border-radius:13px;background:rgba(8,13,20,.8)}
.seg button{min-height:42px;border:1px solid transparent;border-radius:9px;background:none;font:700 14px var(--display);letter-spacing:2px;color:var(--muted);display:flex;align-items:center;justify-content:center;gap:8px;padding:0 4px;white-space:nowrap}
.seg button[aria-pressed="true"]{background:#18222F;border-color:#C9D6E3;color:var(--fg)}
.seg button[aria-pressed="true"].h{background:#0E2236;border-color:var(--hu);color:var(--hu);box-shadow:0 0 14px rgba(92,200,255,.25)}
.seg button[aria-pressed="true"].ai{background:#22170A;border-color:var(--ai);color:var(--ai);box-shadow:0 0 14px rgba(245,165,36,.25)}
.seg button[aria-pressed="true"].rnd{background:#1C1630;border-color:var(--agi);color:var(--agi);box-shadow:0 0 14px rgba(180,140,255,.25)}
.seg.lv button{min-height:36px;font-size:13px}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.introrow{display:grid;grid-template-columns:1.6fr 1fr;gap:8px}
.join{display:grid;grid-template-columns:minmax(0,1.6fr) 1fr 46px;gap:8px;margin:0}.join[hidden]{display:none}
.join input{min-width:0;height:46px;border:1px solid var(--line2);border-radius:11px;background:#070C13;color:var(--fg);font:700 18px var(--mono);letter-spacing:6px;text-transform:uppercase;padding:0 14px}
.join input::placeholder{color:var(--faint);letter-spacing:6px}
/* this phone's games (v0.30), and challenges (v0.52) */
.games{display:flex;flex-direction:column;gap:6px}.games[hidden]{display:none}
.game{display:flex;align-items:center;gap:12px;min-height:44px;padding:6px 12px;border:1px solid var(--line);border-radius:11px;background:var(--glass);font:14px var(--ui);color:var(--dim);text-align:left;width:100%}
.game .gc{font:700 15px var(--mono);letter-spacing:3px;color:var(--fg)}
.game .gs{flex:1;min-width:0}.game .gs b{color:var(--hu)}
.grow{display:flex;gap:6px}.grow>.game{flex:1;min-width:0}
.gx{flex:none;width:44px;min-height:44px;border:1px solid var(--line);border-radius:11px;background:var(--glass);color:var(--dim);font:16px var(--ui)}
.game.gq{flex-direction:column;align-items:stretch;gap:8px;padding:10px 12px;color:var(--fg)}
.game:not(.chal):not(.gq)::after{content:"›";margin-left:auto;color:var(--muted);font-size:16px}
.game.chal{flex-direction:column;align-items:stretch;gap:8px;border-color:rgba(245,165,36,.5);border-radius:12px;padding:10px 12px;background:linear-gradient(180deg,rgba(38,24,10,.75),rgba(16,12,8,.8))}
.ch-who{display:flex;align-items:center;gap:8px;font:15px var(--ui);min-width:0}.ch-who b{color:var(--fg)}.ch-who > span:last-child{min-width:0;overflow-wrap:anywhere}
.ch-sub{font:13px var(--ui);color:var(--muted)}
.chal .ghost{min-height:40px}
.badge{display:inline-block;padding:1px 7px;border-radius:9px;background:var(--ai);color:#1A1004;font:700 10px var(--mono);letter-spacing:1px;margin-left:6px;text-transform:uppercase}
/* Play a friend (v0.30): the code in four big cells, who plays which side, the dot for whether they're here */
.codebig{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:4px 0}
.codebig span{height:84px;border:1.5px solid var(--hu);border-radius:12px;background:var(--hu-tile);display:flex;align-items:center;justify-content:center;font:700 52px var(--display);color:var(--hu);text-shadow:0 0 18px rgba(92,200,255,.6);box-shadow:0 0 18px rgba(92,200,255,.18)}
.panel{border:1px solid var(--line);border-radius:14px;background:var(--glass);padding:12px;display:flex;flex-direction:column;gap:10px}
.nw{white-space:nowrap}
.dot{display:inline-block;width:8px;height:8px;border-radius:50%;background:#4A5A6E;margin-left:6px;vertical-align:1px}.dot.yes{background:var(--green);box-shadow:0 0 8px var(--green)}
.link{padding:8px 10px;border-radius:10px;background:#070C13;border:1px solid var(--line);font:10.5px var(--mono);color:var(--muted);word-break:break-all;max-height:64px;overflow:auto;user-select:all}
.card .lvnote{color:var(--volt)}
#lvwait{text-align:center;margin:6px 0}
/* the log, over the board */
.overlay.logov{z-index:30;background:rgba(3,6,10,.72);backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);display:flex;align-items:flex-start;justify-content:center;padding-top:calc(60px + env(safe-area-inset-top))}
.logov .card{max-width:420px;border:1px solid var(--line2);border-radius:16px;background:linear-gradient(180deg,#0F1A28,#0A111B);padding:14px;box-shadow:0 20px 60px rgba(0,0,0,.7);max-height:calc(100svh - 100px);margin:0}
.lgs{display:flex;flex-direction:column;overflow:auto;min-height:0;flex:1}
.lgs div{display:grid;grid-template-columns:40px 1fr;gap:8px;padding:8px 2px;border-top:1px solid var(--grid);font:14px/1.38 var(--ui);color:var(--dim)}
.lgs i{font:600 11px/20px var(--mono);font-style:normal;color:var(--muted)}
.lgs .mile{background:rgba(180,140,255,.07);border-radius:8px;border-top-color:transparent}
.lgs .mile span,.lgs .mile{color:var(--agi)}
pre{white-space:pre-wrap;padding:16px;font-size:13px}

/* v0.49 (DEV-315): the Stats screen (web/src/stats.js) */
.st-body{display:flex;flex-direction:column;gap:10px}
.st-empty{color:var(--muted)!important;text-align:center;padding:18px 6px}
.st-tiles{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:6px}
.st-tile{border:1px solid var(--line);border-radius:11px;background:var(--glass);padding:8px 10px;display:flex;flex-direction:column;gap:2px}
.st-tile b{font:700 24px/1.1 var(--display)}.st-tile span{font:600 10px var(--mono);letter-spacing:1.5px;color:var(--muted);text-transform:uppercase}
.st-tile.up b{color:var(--hu)}.st-tile.down b{color:var(--ai)}
.st-table{border:1px solid var(--line);border-radius:11px;overflow:hidden;background:rgba(8,13,20,.7)}
.st-row{display:grid;grid-template-columns:minmax(0,1fr) repeat(4,34px) 46px;align-items:center;min-height:30px;padding:0 10px;font:500 13px var(--mono);color:var(--dim);border-top:1px solid var(--grid);font-variant-numeric:tabular-nums}
.st-row > span:not(:first-child){text-align:right}.st-row > span:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.st-head{border-top:0;min-height:28px;font:600 10px var(--mono);letter-spacing:1.5px;color:var(--muted);text-transform:uppercase;background:rgba(22,38,58,.35)}.st-head > span:first-child{color:var(--fg)}
.st-row .h{color:var(--hu);font-family:var(--ui);font-weight:600}.st-row .ai{color:var(--ai);font-family:var(--ui);font-weight:600}
.st-row.zero{color:var(--faint)}.st-row.zero .h,.st-row.zero .ai{opacity:.6}
.st-ends{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.st-end{display:flex;justify-content:space-between;align-items:center;gap:6px;border:1px solid var(--line);border-radius:10px;padding:8px 10px;font:13px var(--ui);color:var(--dim)}.st-end b{font:700 16px var(--mono);color:var(--fg)}
.st-games{display:flex;flex-direction:column}
.st-game{display:grid;grid-template-columns:52px minmax(0,1fr) 48px 52px 40px;align-items:center;min-height:34px;border-top:1px solid var(--grid);font:13px var(--ui);color:var(--dim);white-space:nowrap}
.st-game .gd{font:500 12px var(--mono);color:var(--muted)}.st-game .gr{font:500 12px var(--mono);color:var(--muted);text-align:right}
.st-game > span:nth-child(2){overflow:hidden;text-overflow:ellipsis}
.st-game b{font:700 12px var(--display);letter-spacing:1px}
.st-game.won b{color:var(--hu)}.st-game.lost b{color:var(--ai)}.st-game.drawn b{color:var(--fg)}
.st-game .h{color:var(--hu)}.st-game .ai{color:var(--ai)}.st-game .gv{color:var(--muted)}
.st-confirm{border:1px solid rgba(255,77,94,.5);border-radius:13px;background:rgba(40,8,14,.55);padding:12px;display:flex;flex-direction:column;gap:10px}
.st-note,.acct-busy,.acct-note{color:var(--muted)!important;font-size:13px!important}
@media (max-width:359px){.st-row{grid-template-columns:minmax(0,1fr) repeat(4,28px) 40px;padding:0 8px;font-size:12px}.st-game{grid-template-columns:46px minmax(0,1fr) 42px 44px 34px;font-size:12px}.st-ends{grid-template-columns:1fr}}
/* v0.51 (DEV-317): the profile button on the start screen and the account screens (web/src/account-ui.js) */
#acctslot:empty{display:none}
.acctbar{display:flex;justify-content:flex-end;gap:8px;min-height:32px}
.acct{display:inline-flex;align-items:center;gap:6px;max-width:100%;min-width:0;height:32px;padding:0 12px;border-radius:16px;border:1px solid var(--line2);background:rgba(10,18,28,.85);font:700 12px var(--display);letter-spacing:1.5px;color:var(--fg)}
.acct.in{font:600 13px var(--ui);letter-spacing:0;padding-left:8px}.acct .av{font-size:17px;line-height:1}.acct .hd{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.acct.fr{flex:0 0 auto}
.acct-card h1{overflow-wrap:anywhere}
.sso-list{display:flex;flex-direction:column;gap:10px}
.sso{display:flex;align-items:center;justify-content:center;gap:10px;min-height:50px;border-radius:12px;font:600 17px var(--ui);letter-spacing:0}
.sso.apple{background:#fff;color:#000;border:0} /* Apple's guidelines: white on a dark background */
.sso.google{background:#131314;color:#E3E3E3;border:1px solid #8E918F} /* Google's dark button */
.sso:disabled{opacity:.5}
.sso-g{min-height:44px;display:flex;justify-content:center;color-scheme:normal}
.stub{display:flex;gap:8px;margin:0}.stub input{flex:1;min-width:0;min-height:46px;border-radius:11px;border:1px solid var(--line2);background:#070C13;color:var(--fg);font:600 15px var(--mono);padding:0 10px}.stub .ghost{flex:0 0 auto;padding:0 12px;font-size:13px}
.acct-err{color:var(--asi)!important;font-size:13px!important}.acct-err[hidden]{display:none}
.card p.acct-fine{color:var(--muted);font-size:12.5px;line-height:1.45}.acct-fine a{color:var(--hu)}
.hd-in{display:flex;align-items:center;gap:4px;min-height:46px;padding:0 14px;border-radius:11px;border:1px solid var(--line2);background:#070C13;font:500 17px var(--ui)}
.hd-in span{color:var(--muted)}.hd-in input{flex:1;min-width:0;border:0;background:transparent;color:var(--fg);font:inherit;padding:0;outline:none}
.hd-in input::placeholder{color:var(--faint)}
.hd-in:focus-within{border-color:var(--hu)}
.av-grid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:6px}
.av-grid button{height:48px;border-radius:10px;border:1px solid var(--line);background:rgba(8,13,20,.8);font-size:24px;line-height:1;padding:0}
.av-grid button[aria-pressed="true"]{border:2px solid var(--hu);background:var(--hu-tile);box-shadow:0 0 12px rgba(92,200,255,.35)}
.me{display:flex;align-items:center;gap:14px;min-width:0}.me h1{min-width:0}
.me-av{flex:0 0 auto;width:60px;height:60px;border:2px solid var(--hu);border-radius:14px;background:var(--hu-tile);display:flex;align-items:center;justify-content:center;font-size:32px;box-shadow:0 0 18px rgba(92,200,255,.3)}
.friends[data-view="friend"] .me-av{border-color:var(--ai);background:var(--ai-tile);box-shadow:0 0 18px rgba(245,165,36,.3)}
#st-acct{text-transform:none;letter-spacing:1px} /* a handle keeps its own case */
/* v0.52 (DEV-318): the Friends screens (web/src/friends.js) */
.fr-add{display:grid;grid-template-columns:1.6fr 1fr;gap:8px;margin:0}.fr-add .hd-in{min-width:0}
.fr-head{display:flex;justify-content:space-between;padding:0 12px}
.fr-list{display:flex;flex-direction:column;gap:6px}
.fr-row{display:grid;grid-template-columns:38px minmax(0,1fr) auto 14px;align-items:center;gap:10px;width:100%;min-height:50px;padding:0 12px;border:1px solid var(--line);border-radius:12px;background:var(--glass);color:var(--fg);font:600 15px var(--ui);text-align:left}
.fr-av{font-size:24px;line-height:1;text-align:center}
.fr-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.fr-rec{font:600 13px var(--mono);color:var(--muted);white-space:nowrap;font-variant-numeric:tabular-nums}.fr-rec .fr-w{color:var(--hu)}.fr-rec .fr-l{color:var(--ai)}
.fr-go{color:var(--muted);font-size:18px;line-height:1}
.seg.fr-sides button{flex-direction:column;gap:2px;min-height:48px;font-size:12px;letter-spacing:1.5px;line-height:1.1}.seg.fr-sides i{font-style:normal;font-size:16px;letter-spacing:0}
.me-friends{display:flex;flex-direction:column;gap:10px}.me-friends:empty{display:none}
#mg-chal:empty,#mg-more:empty{display:none}
@media (max-width:359px){.seg.fr-sides button{font-size:11px;letter-spacing:0}.fr-row{gap:8px;padding:0 10px}.codebig span{height:70px;font-size:42px}}

/* ---------- phones and desktops ---------- */
/* a short screen (Safari's bars, an iPhone SE): the meter drops its labels and the console tightens, so the board keeps
   as much height as it can and the buttons always fit */
@media (max-height:740px){
  .lbls{display:none}.meter{padding:6px 10px;margin-top:4px}.bars{margin-top:5px}.mt{font-size:11px}
  .hud{height:30px}.pill{height:26px;font-size:11px;padding:0 8px}.boardwrap{margin-top:6px}
  .console{padding:8px 10px;margin-top:6px;--cons:112px;--msgh:calc(2 * 1.38 * 14px);--msgb:4px}.msg{font-size:14px}
  .fline{padding:4px 8px;gap:8px}.eng-row{gap:6px}.verdict{padding:5px 10px}
  .actions{padding-top:6px}.ghost,.primary{min-height:42px}
  .msg.over h1{font-size:20px}
}
@media (max-height:600px){.console{--cons:96px;--msgh:calc(1.38 * 14px)}}
/* the shortest console (320 × 568): the fight drops its header line so the pieces keep their size */
@container cons (max-height:85px){.eng-h{display:none}.eng-row{--t:clamp(30px,calc(100cqh - 38px),64px)}}
/* the narrowest phones (iPhone SE 1st gen, 320 px): the pills and the meter's title tighten so each stays on one line */
@media (max-width:359px){.hud{gap:4px}.pill{padding:0 6px;letter-spacing:.5px}.mt{letter-spacing:.5px}.mt .lb{display:none}.mt .nx{letter-spacing:.5px}.fline .fs{font-size:12px}}
/* home-screen app (DEV-297): the pills drop a little from the status bar / Dynamic Island */
.standalone .hud{padding-top:10px}
@media (max-width:859px){
  /* iPhone Safari 26 floats its tab bar over the bottom of the page, and the viewport units don't leave room for it:
     lift the buttons above it (v0.28: START was under the bar at setup) */
  .ios-bar .left{padding-bottom:calc(6px + max(env(safe-area-inset-bottom), 76px))}
}
@media (min-width:860px){
  /* desktop: the same column, as wide as fits the window's height */
  :root{--colw:min(100vw - 40px,480px)}
  .left{padding:10px 0 16px}
  .hud,.actions{padding-left:0;padding-right:0}
  .meter,.console{margin-left:0;margin-right:0}
}
@media (prefers-reduced-motion:reduce){.watcher .eye,.blk.reveal,.sq.can::after,.sq.copy::after,.sq.dc.live .dci,.dcp,.sq.dc.drain .dci,.sq.dc.drain .dcm,.sq.turned .blk,.meter.jolt,.console.end.won,.console.end.lost,.toast{animation:none!important}}
