/* ══════════════════════════════════════════════════════════════════════════════
   PIXEL HOOPS — THE CABINET, ON ITS OWN
   ══════════════════════════════════════════════════════════════════════════════
   Every rule the basketball cabinet's markup uses: the screen, the deck, the
   two thumbsticks, the sign-in gate, the 1v1 lobby and the tag-entry overlay.

   ══ WHY THIS FILE EXISTS ══
   SESSION FIVE §3.2 — *"pixel hoops needs its own page"* — was asked for and
   deliberately not built, and the reason given was this stylesheet:

     "Its cabinet is welded into arcade.html: the markup shares one 31KB <style>
      block with the whole arcade page… Copying the cabinet out means either
      duplicating the CSS and shipping a script that throws on every deleted
      element, or splitting that script into modules first. It is a refactor,
      not a copy."

   This is the split. These 83 rules came OUT of arcade.html's inline block and
   now live here, and BOTH pages load them — arcade.html for the cabinet it
   still carries behind its attract clip, and hoops.html for the real one.

   ⚠ THE POINT IS THAT THERE IS ONE COPY, NOT TWO. Pasting these rules into a
   second page would have worked on the day and then rotted: the arcade already
   has "a catalogue of pairs of numbers that were supposed to agree and quietly
   stopped", and a pair of stylesheets drifts the same way. Edit the cabinet
   here and both pages move together.

   ⚠ AND arcade.html STILL NEEDS THE CABINET MARKUP even though you cannot play
   it there. hoops.js grabs #game and calls getContext() at load — line 12, before
   anything is guarded — so removing the element would throw on the arcade page
   and take the attract clip with it. The modal is hidden there (it has no
   `.open`), it just has to exist.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ═══════════ GAME MODAL ═══════════ */
.gm{position:fixed;inset:0;z-index:200;display:none;background:rgba(4,6,5,.92);backdrop-filter:blur(6px);
  align-items:center;justify-content:center;padding:12px}
.gm.open{display:flex}
.gm-cab{width:100%;max-width:420px;border:2px solid #00ff00;border-radius:6px;overflow:hidden;
  background:var(--arc-panel);box-shadow:0 0 40px rgba(0,255,0,.28)}
.gm-bar{display:flex;align-items:center;justify-content:space-between;padding:11px 13px;
  border-bottom:1px solid rgba(255,255,255,.1);background:linear-gradient(180deg,#1c1d1c,#131413)}
.gm-bar .nm{font:10px 'Press Start 2P',monospace;color:#00ff00;text-shadow:0 0 8px rgba(0,255,0,.5)}
.gm-bar .tools{display:flex;gap:8px}
.gm-icon{width:30px;height:30px;border:1px solid rgba(255,255,255,.2);background:var(--arc-bg);color:var(--arc-mut);
  cursor:pointer;border-radius:3px;font-size:13px;display:flex;align-items:center;justify-content:center}
.gm-icon:hover{border-color:#00ff00;color:#00ff00}
.gm-screen{position:relative;aspect-ratio:4/3;background:#000;overflow:hidden;touch-action:none;user-select:none;-webkit-user-select:none}
/* 🔴 THE CANVAS HAS TO BE STRETCHED TO THE SCREEN, and this rule nearly did not
   make it into this file. The extraction that built hoops-cab.css classified
   every rule by the CLASS NAMES in its selector — and this one is an ID. So it
   stayed behind in arcade.html, where the cabinet kept working, while hoops.html
   got a 320x240 canvas sitting in the top-left of a 420x315 screen with the rest
   black: *"game isnt filling the module. half the game screen is black."*
   ⚠ A SPLIT THAT FILTERS ON SELECTORS HAS TO LOOK AT ALL OF THEM — classes, ids,
   elements and attributes. The other 83 rules were class-based and came across
   clean, which is exactly why one ID selector was easy to miss.
   `width/height:100%` rather than the canvas's own 320x240 attributes: the buffer
   stays a fixed pixel grid and the browser scales it, which is what keeps the art
   crisp at any cabinet size — hence the pixelated rendering hints. */
#game{display:block;width:100%;height:100%;image-rendering:pixelated;image-rendering:crisp-edges}
/* THE RIVAL'S SCORE, over the glass. Pointer-transparent because it sits on top
   of the court and the court is where every tap and drag in this game goes —
   a scoreboard that eats a shot is worse than no scoreboard. Top-left, clear of
   the engine's own HUD, which draws its score top-right. */
.duel-board{position:absolute;left:6px;top:6px;z-index:6;pointer-events:none;
  background:rgba(6,8,6,.78);border:1px solid rgba(255,210,61,.3);padding:5px 7px;
  max-width:52%;border-radius:2px}
.duel-board:empty{display:none}
/* ── name gate + 1v1 lobby (overlay the screen, same footprint as the game) ── */
.gate{position:absolute;inset:0;z-index:12;display:none;align-items:center;justify-content:center;
  padding:18px;background:radial-gradient(120% 90% at 50% 22%,#04170a,#030504)}
.gate.show{display:flex}
.gate-in{width:100%;max-width:300px;display:flex;flex-direction:column;align-items:center;gap:10px;text-align:center}
.gate-t{font:11px 'Press Start 2P',monospace;color:#00ff00;text-shadow:0 0 12px rgba(0,255,0,.45);line-height:1.7}
/* box-sizing was missing here, so width:100% plus 24px of padding pushed the
   field past its own container — that was the broken-looking text box. */
.gate-name{width:100%;box-sizing:border-box;padding:12px;background:#08090a;
  border:1px solid rgba(0,255,0,.35);color:#fff;font:14px 'JetBrains Mono',monospace;
  font-weight:700;letter-spacing:.1em;text-align:center;text-transform:uppercase;border-radius:3px}
.gate-name::placeholder{color:#3a4a3d;letter-spacing:.1em}
.gate-name:focus{outline:none;border-color:#00ff00;box-shadow:0 0 12px rgba(0,255,0,.28)}
.gate-err{font:8px 'Press Start 2P',monospace;color:#ff4d4d;line-height:1.6;min-height:10px}
/* the room code is an identifier now, not a thing to copy and text somebody */
.room-id{font:9px 'JetBrains Mono',monospace;letter-spacing:.18em;color:var(--arc-dim);text-transform:uppercase}
.room-id span{color:var(--arc-amber);font-weight:700}
.gate-ini-l{font:7px 'Press Start 2P',monospace;color:var(--arc-dim);letter-spacing:.12em;margin-top:2px}
.share-hint{font:9px/1.6 'Karla',sans-serif;color:var(--arc-mut);max-width:270px}
.seats{width:100%;display:flex;flex-direction:column;gap:6px;margin-top:4px}
.seat{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:9px 11px;
  background:#0c0d0c;border:1px solid rgba(255,255,255,.12);border-radius:3px;
  font:9px 'Press Start 2P',monospace;color:#fff}
.seat.rdy{border-color:#00ff00}
.seat .st{font-size:8px;color:var(--arc-dim)}
.seat.rdy .st{color:#00ff00}
.seat.empty{color:var(--arc-dim);border-style:dashed}
/* ── control deck: sticks sit UNDER the screen so nothing covers the court ── */
.gm-deck{display:none;align-items:center;justify-content:space-between;gap:10px;
  padding:12px 14px 14px;background:linear-gradient(180deg,#141513,#0d0e0c);
  border-top:1px solid rgba(0,255,0,.22);touch-action:none;user-select:none;-webkit-user-select:none}
.gm-deck.on{display:flex}
.pad-col{display:flex;flex-direction:column;align-items:center;gap:6px}
.pad{position:relative;width:82px;height:82px;border-radius:50%;background:radial-gradient(circle at 50% 40%,#1b1d1a,#0a0b0a);
  border:2px solid rgba(0,255,0,.45);box-shadow:inset 0 0 14px rgba(0,0,0,.8);touch-action:none;cursor:pointer}
.pad.shoot{border-color:rgba(255,210,61,.5)}
.pad.live{border-color:#00ff00;box-shadow:inset 0 0 14px rgba(0,0,0,.8),0 0 12px rgba(0,255,0,.4)}
.pad.shoot.live{border-color:var(--arc-amber);box-shadow:inset 0 0 14px rgba(0,0,0,.8),0 0 12px rgba(255,210,61,.45)}
.pad.shoot.green{border-color:#00ff00;box-shadow:inset 0 0 14px rgba(0,0,0,.8),0 0 18px rgba(0,255,0,.85)}
.pad .knob{position:absolute;left:50%;top:50%;width:34px;height:34px;margin:-17px 0 0 -17px;border-radius:50%;
  background:#d8ddd6;border:2px solid #050605;pointer-events:none;transition:background .1s}
.pad.live .knob{background:#00ff00}
.pad.shoot.live .knob{background:var(--arc-amber)}
.pad.shoot.green .knob{background:#00ff00}
.pad-lbl{font:8px 'Press Start 2P',monospace;color:var(--arc-mut);text-align:center;line-height:1.7}
.pad-lbl em{display:block;font:7px 'JetBrains Mono',monospace;font-style:normal;letter-spacing:.1em;color:var(--arc-dim);margin-top:3px}
.deck-mid{display:flex;flex-direction:column;align-items:stretch;gap:7px;flex:1;max-width:112px}
.deck-btn{padding:11px 4px;border:none;border-radius:3px;cursor:pointer;
  font:9px 'Press Start 2P',monospace;letter-spacing:.02em;
  clip-path:polygon(7px 0,100% 0,100% calc(100% - 7px),calc(100% - 7px) 100%,0 100%,0 7px)}
.deck-btn.green{background:#00a83c;color:#04140a}
.deck-btn.green.steal{background:#c9302c;color:#fff}
.deck-btn.amber{background:#6a5218;color:rgba(255,255,255,.45)}
.deck-btn.amber.ready{background:var(--arc-amber);color:#1a1405}
.dunk-meter{height:6px;background:#050605;border:1px solid rgba(255,255,255,.14);overflow:hidden}
.dunk-meter i{display:block;height:100%;width:100%;background:var(--arc-amber);transition:width .12s linear}
@media (max-width:400px){
  .pad{width:72px;height:72px}
  .pad .knob{width:30px;height:30px;margin:-15px 0 0 -15px}
  .deck-btn{font-size:8px;padding:10px 3px}
}
/* initials entry overlay */
.entry-wrap{position:absolute;inset:0;z-index:8;display:none;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:22px;background:radial-gradient(120% 90% at 50% 30%,rgba(0,40,0,.55),rgba(4,8,5,.94))}
.entry-wrap.show{display:flex}
.entry-wrap .big{font:13px 'Press Start 2P',monospace;color:var(--arc-amber);text-shadow:0 0 14px rgba(255,210,61,.4);line-height:1.7}
.entry-wrap .fscore{margin:14px 0 2px;font:26px 'JetBrains Mono',monospace;font-weight:800;color:#fff}
.entry-wrap .fmeta{font:8px 'JetBrains Mono',monospace;letter-spacing:.14em;color:var(--arc-dim);text-transform:uppercase}
.entry{margin-top:18px;display:flex;flex-direction:column;align-items:center;gap:12px}
.entry .lbl{font:8px 'Press Start 2P',monospace;color:var(--arc-amber)}
.ini-row{display:flex;gap:10px}
.ini-box{width:46px;height:56px;background:#0a0a0b;border:2px solid rgba(0,255,0,.5);border-radius:4px;
  text-align:center;font:20px 'Press Start 2P',monospace;color:#00ff00;text-transform:uppercase}
.ini-box:focus{outline:none;border-color:#00ff00;box-shadow:0 0 12px rgba(0,255,0,.4)}
.entry .nmfield{width:200px;padding:10px;background:#0a0a0b;border:1px solid rgba(255,255,255,.18);border-radius:4px;
  text-align:center;font-size:13px;color:#fff;font-family:'Karla',sans-serif}
.entry .nmfield:focus{outline:none;border-color:rgba(0,255,0,.5)}
.entry .row2{display:flex;gap:10px;margin-top:4px}
.btn-sm{padding:11px 18px;font:800 11px 'JetBrains Mono',monospace;letter-spacing:.06em;text-transform:uppercase;cursor:pointer;border-radius:3px}
.btn-sm.g{background:#00ff00;color:#000;border:none}
.btn-sm.o{background:transparent;border:1px solid rgba(255,255,255,.25);color:var(--arc-mut)}
.gm-note{padding:10px 13px;text-align:center;font:8px 'JetBrains Mono',monospace;letter-spacing:.12em;color:var(--arc-dim);text-transform:uppercase;border-top:1px solid rgba(255,255,255,.1)}
/* ══════════ THE WAITING LIST ══════════ lifted from the boxing cabinet so both
   games' lobbies look and behave identically. */
.wait-k{font:6.5px 'JetBrains Mono',monospace;letter-spacing:.14em;color:var(--arc-dim);
  text-transform:uppercase;margin-bottom:5px}
.wait-list{width:100%;display:flex;flex-direction:column;gap:5px;max-height:104px;
  overflow-y:auto;margin-bottom:8px}
.wrow{display:flex;align-items:center;gap:8px;padding:8px 10px;background:#0c0d0c;
  border:1px solid rgba(255,255,255,.13);cursor:pointer;text-align:left;
  clip-path:polygon(6px 0,100% 0,100% calc(100% - 6px),calc(100% - 6px) 100%,0 100%,0 6px)}
.wrow:hover{border-color:#00ff00;background:#0f1a10}
.wrow .ini{font:8px 'Press Start 2P',monospace;color:#00ff00;flex:none}
.wrow .nm{flex:1;min-width:0;font:11px 'JetBrains Mono',monospace;color:#fff;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.wrow .wt{font:7px 'JetBrains Mono',monospace;letter-spacing:.08em;color:var(--arc-dim);flex:none;text-transform:uppercase}
.wrow .gtag{font:6.5px 'Press Start 2P',monospace;color:var(--arc-dim);flex:none;
  border:1px solid rgba(255,255,255,.18);padding:3px 4px}
.wrow.other{border-style:dashed}
.wrow.other .gtag{color:var(--arc-amber);border-color:rgba(255,210,61,.5)}
.wait-none{padding:11px 10px;border:1px dashed rgba(255,255,255,.18);
  font:9px/1.5 'Karla',sans-serif;color:var(--arc-mut)}
/* ── OVERLAYS: CENTRED WHEN THEY FIT, SCROLLABLE WHEN THEY DON'T ──
   Never clipped. align-items:center on an overflowing flex parent cuts the top
   off and makes it unreachable; auto block margins on the child do the same
   centring while leaving both ends scrollable. */
.gate,.ov,.entry-wrap{overflow-y:auto;overscroll-behavior:contain}
.gate{align-items:flex-start}
.gate-in{margin-top:auto;margin-bottom:auto}
