/* ============================================================================
   FLAGSTER — STYLES (responsive: mobile + desktop/Mac)
   ============================================================================ */
:root{
  --bg:#07240f; --bg2:#0b3d1e; --panel:#0f2f1c; --panel2:#123f27;
  --line:#1d5c38; --grass:#2f8f3f; --ink:#eafff0; --muted:#9fd3b0;
  --accent:#2ec77a; --accent2:#ffd23f; --danger:#ff5a5a; --blue:#3c82ff;
  --shadow:0 8px 30px rgba(0,0,0,.45);

  /* THE NOTCH, AS A VARIABLE. `env(safe-area-inset-*)` is the real source and
     these default to it, but a headless browser has no notch and resolves
     every one of them to 0 — so a test can never see whether the controls
     actually move out of the way. Reading them through variables lets
     `npm run touch` stand a real device's insets up in their place and MEASURE
     that the buttons cleared them, instead of taking the stylesheet's word. */
  --safe-t:env(safe-area-inset-top,0px);
  --safe-r:env(safe-area-inset-right,0px);
  --safe-b:env(safe-area-inset-bottom,0px);
  --safe-l:env(safe-area-inset-left,0px)}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;height:100%}
body{
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  background:radial-gradient(circle at 50% -10%,#0e4a26,#07240f 60%);
  color:var(--ink);overflow-x:hidden;
}
#app{min-height:100vh;min-height:100dvh}
.boot{display:grid;place-items:center;height:100vh;color:var(--muted)}
button{font-family:inherit;cursor:pointer}
h1,h2,h3,h4{margin:.2em 0}
.muted{color:var(--muted);font-size:.86rem}
.hidden{display:none !important}

/* ---------- buttons ---------- */
.btn{border:1px solid var(--line);background:var(--panel2);color:var(--ink);
  padding:12px 18px;border-radius:12px;font-size:1rem;font-weight:600;
  transition:transform .08s ease,background .15s;margin:5px 0;width:100%}
.btn:hover{background:#1a5233}
.btn:active{transform:scale(.97)}
.btn.primary{background:linear-gradient(180deg,#37d98a,#1fa863);border-color:#37d98a;color:#04240f}
.btn.primary:hover{filter:brightness(1.08)}
.btn.danger{background:#3a1418;border-color:#7a2a2a;color:#ffb3b3}
.btn.ghost{background:transparent}
.btn.big{font-size:1.12rem;padding:16px 20px}
.btn:disabled{opacity:.4;cursor:not-allowed}

/* ---------- screens ---------- */
/* THE NOTCH AND THE HOME INDICATOR (v3.118.0): the page is installable (`apple-mobile-web-app-capable`) with a TRANSLUCENT status bar and `viewport-fit=cover`, so on an iPhone
   the clock, the signal and the battery are drawn OVER the page and the first 50-odd px belong to them. The back button of every screen sat under them. */
.screen{max-width:1100px;margin:0 auto;padding:calc(16px + var(--safe-t)) calc(16px + var(--safe-r)) calc(60px + var(--safe-b)) calc(16px + var(--safe-l));min-height:100vh;min-height:100dvh}
.screen-head{display:flex;align-items:center;gap:12px;margin:6px 0 18px}
.screen-head h2{font-size:1.3rem}
.back-btn{background:var(--panel2);border:1px solid var(--line);color:var(--ink);
  padding:8px 14px;border-radius:10px;font-weight:600}
.controls-btn{position:fixed;right:calc(12px + var(--safe-r));bottom:calc(12px + var(--safe-b));z-index:40;
  background:rgba(15,47,28,.92);border:1px solid var(--accent);color:var(--accent2);
  padding:10px 14px;border-radius:24px;font-weight:700;box-shadow:var(--shadow)}

/* ---------- MAIN MENU ---------- */
.main-menu{display:flex;flex-direction:column;justify-content:center;gap:8px}
.brand{text-align:center;margin:14px 0 26px}
.brand-logo{display:flex;align-items:center;justify-content:center;gap:12px}
.brand-flag{font-size:2.6rem}
.brand-name{font-size:3rem;font-weight:900;letter-spacing:3px;
  background:linear-gradient(180deg,#fff,#8ff0b8);-webkit-background-clip:text;background-clip:text;color:transparent;
  text-shadow:0 3px 18px rgba(46,199,122,.35)}
.brand-demo{width:auto;min-width:160px;margin:10px 0 0}
.brand-tag{color:var(--accent2);letter-spacing:2px;text-transform:uppercase;font-size:.8rem;font-weight:700}
.hero3d{max-width:720px;width:100%;margin:0 auto 16px;border-radius:18px;overflow:hidden;
  border:1px solid var(--line);background:linear-gradient(180deg,#0e4a26,#0a3a1f);
  box-shadow:var(--shadow),inset 0 1px 0 rgba(255,255,255,.05)}
.hero3d-canvas{display:block;width:100%;height:190px}
@media (max-width:820px){ .hero3d-canvas{height:150px} }
@media (max-width:420px){ .hero3d-canvas{height:128px} }
.menu-tiles{display:grid;gap:14px;max-width:720px;width:100%;margin:0 auto}
.menu-tile{display:flex;flex-direction:column;align-items:flex-start;text-align:left;gap:4px;
  padding:22px;border-radius:18px;border:1px solid var(--line);color:var(--ink);
  background:linear-gradient(135deg,var(--panel2),var(--panel));box-shadow:var(--shadow);
  transition:transform .1s,border-color .15s}
.menu-tile:hover{transform:translateY(-3px);border-color:var(--accent)}
.menu-tile:active{transform:scale(.99)}
.menu-tile.world{background:linear-gradient(135deg,#12406b,#0b2540)}
.menu-tile.builder{background:linear-gradient(135deg,#1c5a34,#0e3520)}
.menu-tile.glory{background:linear-gradient(135deg,#6b4a12,#3a2a0b)}
.tile-icon{font-size:2.2rem}
.tile-title{font-size:1.5rem;font-weight:800}
.tile-sub{color:var(--muted);font-size:.9rem;font-weight:500}
.menu-foot{display:flex;align-items:center;justify-content:center;gap:14px;margin-top:24px;flex-wrap:wrap}
.platform-badge{color:var(--muted);font-size:.8rem;border:1px solid var(--line);padding:6px 12px;border-radius:20px}
.act-btn.pitch{background:linear-gradient(180deg,#2f6f8f,#1d4a61)}
.sit-val.urgent{color:#ff5252}
.version-badge{display:block;margin-top:6px;color:var(--muted);font-size:.72rem;letter-spacing:.08em;opacity:.7;font-variant-numeric:tabular-nums}

/* ---------- selection screens ---------- */
.sel-block{margin-bottom:18px}
.sel-block h3{margin-bottom:8px;color:var(--accent2)}
.team-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:10px}
.team-card{display:flex;flex-direction:column;align-items:center;gap:2px;padding:12px 8px;border-radius:14px;
  border:2px solid var(--line);background:var(--panel);color:var(--ink);position:relative;overflow:hidden}
.team-card::before{content:"";position:absolute;inset:0 0 auto 0;height:6px;background:var(--c1,#2ec77a)}
.team-card.selected{border-color:var(--accent2);box-shadow:0 0 0 2px var(--accent2) inset}
.tc-flag{font-size:1.9rem;margin-top:4px}
.tc-name{font-weight:700;font-size:.9rem;text-align:center;line-height:1.1}
.tc-ovr{font-size:.72rem;color:var(--accent2);font-weight:800}
.sel-actions{margin-top:20px;display:flex;justify-content:center}
.sel-actions .btn{max-width:340px}

/* ---------- jersey ---------- */
.jersey-block{max-width:760px;margin:0 auto}
.matchup-head{display:flex;align-items:center;justify-content:center;gap:16px;font-size:1.3rem;font-weight:800;margin:8px 0 18px}
.mh-vs{color:var(--accent2)}
.jersey-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.jersey-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:8px}
.jersey-swatch{display:flex;flex-direction:column;align-items:center;gap:6px;background:transparent;border:2px solid transparent;border-radius:12px;padding:6px}
.jersey-swatch.selected{border-color:var(--accent2)}
.js-shirt{width:52px;height:52px;border-radius:10px;border:3px solid;display:grid;place-items:center;position:relative}
.js-stripe{width:10px;height:100%;border-radius:2px}
.js-label{font-size:.75rem;color:var(--muted)}
.game-opts{margin:22px 0;display:flex;align-items:center;gap:10px;justify-content:center;flex-wrap:wrap}
.fld{background:var(--panel);border:1px solid var(--line);color:var(--ink);padding:10px 12px;border-radius:10px;font-size:1rem}
.big-input{width:100%;max-width:360px;font-size:1.2rem;text-align:center}

/* ================= GAME SCREEN ================= */
.game-screen{position:fixed;inset:0;background:#06180c;overflow:hidden}
.field-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
/* ---------------------------- BROADCAST HUD -------------------------------
   Three independent panels absolutely positioned against the game screen, so
   each keeps its own corner and none can push another around: the scorebug
   (top-left on desktop, a full-width slab on phones), the play clock (centre)
   and the situation stack (right). `.hud` itself is a transparent, click-
   through layer — the field beneath it has to stay draggable.               */
.hud{position:absolute;top:0;left:0;right:0;z-index:10;pointer-events:none;
  font-weight:800;font-variant-numeric:tabular-nums}
.hud > *{pointer-events:auto}

/* --- panel look, shared --- */
.sb,.pc,.sit{background:linear-gradient(180deg,rgba(12,22,34,.94),rgba(8,15,24,.92));
  border:1px solid rgba(255,255,255,.14);border-radius:12px;
  box-shadow:0 6px 22px rgba(0,0,0,.5)}

/* --- scorebug --- */
.sb{position:absolute;top:calc(10px + var(--safe-t));left:calc(12px + var(--safe-l));display:flex;align-items:stretch;gap:0;overflow:hidden}
.sb-team{display:flex;align-items:center;gap:8px;padding:8px 14px}
.sb-team.has-ball{background:rgba(255,210,63,.14)}
.sb-crest{width:30px;height:32px;display:block;flex:none}
.sb-abbr{font-size:.95rem;letter-spacing:1.5px;color:#dce9f5}
.sb-score{font-size:1.7rem;line-height:1;color:#fff}
.sb-home{flex-direction:row-reverse}
.sb-clock{padding:6px 16px;text-align:center;border-left:1px solid rgba(255,255,255,.14);
  border-right:1px solid rgba(255,255,255,.14);background:rgba(0,0,0,.32);
  display:flex;flex-direction:column;justify-content:center;min-width:104px}
.sb-time{font-size:1.32rem;line-height:1.1;color:#fff}
.sb-dd{font-size:.68rem;letter-spacing:1.2px;color:var(--accent2)}

/* --- portrait-only strip under the scorebug --- */
.sb-strip{display:none;position:absolute;top:calc(62px + var(--safe-t));left:calc(12px + var(--safe-l));right:calc(12px + var(--safe-r));
  justify-content:space-between;padding:5px 14px;border-radius:9px;
  background:rgba(8,15,24,.86);border:1px solid rgba(255,255,255,.12);
  font-size:.72rem;letter-spacing:1.1px}
.sb-strip em{font-style:normal;color:var(--muted)}
.sb-strip b{color:#fff}

/* --- play clock --- */
.pc{position:absolute;top:calc(10px + var(--safe-t));left:50%;transform:translateX(-50%);
  padding:6px 22px;text-align:center}
.pc.hidden{display:none}
.pc-label{font-size:.6rem;letter-spacing:2px;color:var(--muted)}
.pc-num{font-size:1.9rem;line-height:1.05;color:#fff}
.pc.hot .pc-num{color:#ff6b6b}

/* --- situation stack --- */
.sit{position:absolute;top:calc(10px + var(--safe-t));right:calc(12px + var(--safe-r));width:224px;padding:8px 12px 10px}
/* 34px of right padding (plus the panel's own 12) keeps every value clear of the
   toggle's 44px corner. */
.sit-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin-bottom:3px;padding-right:34px}
.sit-label{font-size:.58rem;letter-spacing:1.6px;color:var(--muted);line-height:1.25}
/* Never let "1ST & 20" break across two lines — the panel is a fixed block and
   a wrap shoves the field map down out of alignment with the stamina rows. */
.sit-val{font-size:.92rem;color:#fff;white-space:nowrap;flex:none}
.mini-map{display:block;width:100%;height:auto;margin:6px 0 8px;border-radius:5px;
  border:1px solid rgba(255,255,255,.16)}
.stam-head{display:block;margin-bottom:4px}
.stam-bar{height:7px;border-radius:4px;background:rgba(255,255,255,.13);overflow:hidden;margin-bottom:4px}
.stam-fill{height:100%;width:100%;background:#37d98a;transition:width .18s linear}
.stam-fill.mid{background:var(--accent2)}
.stam-fill.low{background:#ff6b6b}
/* The toggle. A 44px hit area (Apple's floor) pinned to the panel's top-right
   corner over a small glyph, so the panel does not grow a header row for it.
   Collapsed, the panel IS the button: everything else in it is hidden rather
   than removed, so `_syncUI` keeps writing to the same nodes and the mini-map's
   bitmap is still there when it opens. */
.sit-toggle{position:absolute;top:0;right:0;width:44px;height:44px;padding:0;border:0;
  background:none;color:var(--muted);font:inherit;font-size:.8rem;cursor:pointer;
  border-radius:0 12px 0 0;display:flex;align-items:center;justify-content:center;gap:5px}
.sit-toggle .ico{width:16px;height:16px;flex:none}
.sit-toggle:hover,.sit-toggle:focus-visible{color:#fff}
.sit.collapsed{width:auto;padding:0}
.sit.collapsed > :not(.sit-toggle){display:none}
.sit.collapsed .sit-toggle{position:static;display:flex;width:auto;min-width:44px;height:44px;
  padding:0 14px;border-radius:12px;font-size:.66rem;letter-spacing:1.6px;font-weight:800}

/* FULL SCREEN lives at the foot of the open panel (it is hidden with the rest of
   it when collapsed). 44px tall: a tablet is a touch device and this is a tap. */
.sit-full{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;
  min-height:44px;margin-top:8px;padding:0 10px;border-radius:9px;
  border:1px solid rgba(255,255,255,.2);background:rgba(255,255,255,.07);color:#eaf3fb;
  font:inherit;font-size:.66rem;font-weight:800;letter-spacing:1.6px;cursor:pointer}
.sit-full:hover,.sit-full:focus-visible{background:rgba(255,255,255,.14);color:#fff}
.sit-full .ico{width:16px;height:16px;flex:none}

/* Drawn icons (see `icon()` in ui.js). They size from the control's own type
   so a control keeps its measured box, and sit on the text baseline. */
.ico{display:inline-block;vertical-align:-.16em;flex:none}
.mini-btn .ico{width:1.3em;height:1.3em;vertical-align:middle}
.replay-btn .ico{width:1.4em;height:1.4em;vertical-align:-.32em;margin-right:2px}
.replay-btn.icon-only .ico{width:1em;height:1em;margin:0;vertical-align:middle}
.rp-btn .ico{width:1.55em;height:1.55em;vertical-align:middle}
.rp-tag-ico .ico{width:1.3em;height:1.3em;vertical-align:middle}
.rp-tag-ico{display:inline-flex}
.overlay-card h2 .ico{width:1em;height:1em;vertical-align:-.12em}

/* The pause button is a control, so it clears the insets as well — and the
   container is transparent to touch for the same reason the right-hand cluster
   is: its flex gap is not a button and must not eat a steer. */
.game-top-btns{position:absolute;top:auto;z-index:20;display:flex;gap:8px;pointer-events:none;
  align-items:center;bottom:calc(12px + var(--safe-b));left:calc(12px + var(--safe-l))}
.mini-btn{pointer-events:auto}
/* 48, not 40. This cluster is the one place on the game screen a control had
   never been measured — `npm run touch` grades `.act-btn` and nothing else, so
   the pause button sat 4px under Apple's 44pt floor unnoticed for its whole
   life. `npm run replay` measures this cluster, and it starts by measuring the
   button that was already here. 48 clears Material's 48dp as well as Apple's
   44pt, which the action cluster cannot afford — 172px of a 375px screen is
   already 46% of the width — and this corner can: there are two buttons in it
   and nothing else. */
.mini-btn{width:48px;height:48px;border-radius:10px;border:1px solid var(--line);background:rgba(15,47,28,.9);color:var(--ink);font-size:1.1rem}
/* THE DEAD-BALL CONTROL. It sits beside PAUSE rather than in the action
   cluster because it is not an action of the play: see the block in ui.js
   where it is built. A label, not a glyph — a replay is a thing you go looking
   for, and this is the only control on the screen that is worth reading. */
.replay-btn{width:auto;min-width:48px;padding:0 12px;font-size:.72rem;font-weight:800;
  letter-spacing:.6px;color:#ffe9a8;border-color:rgba(255,210,63,.45)}
/* ...except in attract mode, where it is the ONLY button in this corner and
   goes back to the square `.mini-btn` is by default. The glyph is set bigger
   than `.mini-btn`'s 1.1rem because ⟲ is drawn small inside its em box and
   would otherwise read as a smudge rather than an arrow. */
.replay-btn.icon-only{width:48px;padding:0;font-size:1.5rem;font-weight:400;
  letter-spacing:0;line-height:1}

/* The replay transport. Anchored bottom-RIGHT, in the corner the action
   cluster occupies during a live ball — which is empty for exactly as long as
   a replay is up, because those controls belong to a play that is not running.
   Not bottom-centre: the chase camera puts the carrier low and centre by
   construction (it is why `CAM.tall.latBias` exists), so centred is the one
   place guaranteed to be on top of the man the replay is of. And one row up
   from the bottom edge, so it clears the pause row on the other side and the
   demo badge between them.

   THE CONTAINER IS NOT A CONTROL — `pointer-events` is on the buttons alone,
   for the same reason the right-hand cluster is transparent: a flex gap that
   eats a touch is a dead zone with no label on it. */
.replay-bar{position:absolute;right:calc(14px + var(--safe-r));z-index:22;
  bottom:calc(66px + var(--safe-b));display:flex;align-items:center;gap:8px;
  flex-wrap:wrap;justify-content:flex-end;
  pointer-events:none;max-width:calc(100% - 28px - var(--safe-l) - var(--safe-r))}
.rp-tag{pointer-events:none;display:inline-flex;align-items:center;gap:6px;height:48px;
  padding:0 12px;border-radius:11px;background:rgba(4,18,10,.86);
  border:1px solid rgba(255,210,63,.5);color:#ffd23f;
  font-size:.74rem;font-weight:900;letter-spacing:1.2px;white-space:nowrap}
/* The END badge is empty for the whole of a running replay, and an empty flex
   child still takes a gap — which would read as a tag with a hole in it. */
.rp-tag-end:empty{display:none}
/* The end of a replay holds on its last frame rather than closing itself, so
   the bar has to SAY it ended — a still picture is otherwise indistinguishable
   from a frozen game, which is the thing the stall watchdog exists to catch. */
.rp-ended .rp-tag{background:rgba(28,10,4,.9);border-color:rgba(255,150,63,.6);color:#ff9c3f}
.rp-btn{pointer-events:auto;min-width:48px;height:48px;padding:0 10px;border-radius:11px;
  border:1px solid rgba(255,255,255,.18);
  background:linear-gradient(180deg,rgba(12,22,34,.9),rgba(8,15,24,.88));
  color:#eaf3fb;font-weight:800;font-size:.9rem;box-shadow:0 4px 14px rgba(0,0,0,.45)}
.rp-btn:active{transform:scale(.94)}
.rp-btn.rp-close{border-color:rgba(255,107,107,.55);color:#ffbcbc}

/* playcall */
.cut-fade{position:absolute;inset:0;z-index:25;background:#000;opacity:0;pointer-events:none}
.playcall{position:absolute;inset:0;z-index:30;background:rgba(4,18,10,.94);
  display:flex;align-items:flex-start;justify-content:center;padding:calc(14px + var(--safe-t)) calc(14px + var(--safe-r)) calc(14px + var(--safe-b)) calc(14px + var(--safe-l));overflow:auto}
/* `align-items:center` on a scrolling flex box CLIPS the top of content taller than the box and it cannot be scrolled to (on an iPhone SE in portrait the title and the first
   102 px of the sheet were out of reach, measured on v3.118.0). `margin:auto` on the child centres when there is room and starts at the top when there is not. */
.playcall-inner{width:100%;max-width:980px;margin:auto}
.playcall-title{text-align:center;font-size:1.2rem;font-weight:800;margin-bottom:16px;color:var(--accent2)}
.play-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px}
.play-grid.def{grid-template-columns:repeat(4,1fr);max-width:640px;margin:0 auto}
.play-col{display:flex;flex-direction:column;gap:8px}
.play-col-h{text-align:center;font-size:.78rem;text-transform:uppercase;letter-spacing:1px;color:var(--muted);font-weight:800}
.play-card{display:flex;flex-direction:column;align-items:center;gap:6px;padding:14px 8px;border-radius:12px;
  border:1px solid var(--line);background:linear-gradient(180deg,var(--panel2),var(--panel));color:var(--ink)}
.play-card:hover{border-color:var(--accent);transform:translateY(-2px)}
.play-card.def{padding:20px 10px}
.play-icon{font-size:1.6rem}
.play-fig{display:block;line-height:0}.play-fig .pbk-fig{display:block;border-radius:3px}
@media (orientation:landscape) and (max-height:520px){ .play-card:not(.mine){padding:8px 6px;gap:4px}.play-fig .pbk-fig{width:46px;height:auto} }
/* The keycap emoji ("1" + U+FE0F + U+20E3) is a combining sequence, and a font
   without it draws the digit beside an empty box. A circled digit drawn here
   cannot fail that way. */
.play-digit{display:inline-flex;align-items:center;justify-content:center;width:2.1rem;height:2.1rem;
  border-radius:50%;border:2px solid var(--accent);color:var(--accent);font-size:1.15rem;font-weight:900}
.play-name{font-size:.82rem;font-weight:700;text-align:center;line-height:1.1}

/* touch controls */
.touch-controls{position:absolute;inset:0;z-index:15;pointer-events:none}
/* full-field swipe layer (below the action buttons) */
.swipe-pad{position:absolute;inset:0;pointer-events:auto;touch-action:none;z-index:1}
.float-base{position:absolute;width:120px;height:120px;border-radius:50%;
  background:rgba(255,255,255,.07);border:2px solid rgba(255,255,255,.16);
  transform:translate(-50%,-50%);pointer-events:none}
.float-knob{position:absolute;left:50%;top:50%;width:54px;height:54px;border-radius:50%;
  background:rgba(46,199,122,.85);box-shadow:0 4px 12px rgba(0,0,0,.4);transform:translate(-50%,-50%)}
/* The thumb controls are part of the broadcast overlay, not a separate toy
   palette. They used to be six solid blocks in six unrelated hues — blue,
   purple, brown, teal, green, violet — which read as louder than the game
   behind them. Same dark glass as the scorebug, with the role carried by the
   label colour and a thin left rule instead of a full-bleed fill. Tucked into
   the bottom-right corner so the ball carrier, who sits low-centre under the
   chase cam, isn't behind a button. */
/* THE GAPS BETWEEN THE BUTTONS ARE NOT BUTTONS, AND THEY WERE NOT THE FIELD
   EITHER. `pointer-events:auto` on the CONTAINER makes the whole column eat
   touches — the 8px flex gaps, the ragged edge where a row wraps short, the
   strip above SNAP — and none of it has a handler. Measured across five phone
   sizes, 7-10% of the entire screen hit `.right-cluster` and did nothing: a
   thumb landing there neither pressed a button nor steered the player, on a
   layer sitting directly over the swipe pad. The container is transparent to
   touch now and only the BUTTONS take it, so every gap falls through to the
   field beneath. (`npm run touch` hit-tests the whole screen on a grid.)

   And the insets are real estate the phone has already spent. `viewport-fit=
   cover` is set in index.html, so the layout runs under the notch and the home
   indicator unless it is told not to; without these the sprint button, SWITCH
   and PULL sat in the bottom inset on every iPhone tested, and in landscape the
   whole right-hand column sat 45px inside the notch. */
.right-cluster{position:absolute;display:flex;flex-direction:column;
  right:calc(14px + var(--safe-r));
  bottom:calc(16px + var(--safe-b));
  align-items:flex-end;gap:8px;pointer-events:none;z-index:3}
.act-btn{pointer-events:auto}
.btn-cluster{display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end;max-width:184px}
.act-btn{min-width:54px;height:46px;border-radius:11px;padding:0 11px;
  border:1px solid rgba(255,255,255,.16);border-left:3px solid rgba(255,255,255,.30);
  background:linear-gradient(180deg,rgba(12,22,34,.88),rgba(8,15,24,.86));
  color:#eaf3fb;font-weight:800;font-size:.82rem;letter-spacing:.5px;
  box-shadow:0 4px 14px rgba(0,0,0,.45);backdrop-filter:blur(3px)}
.act-btn:active{transform:scale(.94)}
.act-btn.snap{border-left-color:#37d98a;color:#8ff0bd;min-width:118px;height:50px;font-size:1rem}
.act-btn.r1{border-left-color:#5b9bff}
.act-btn.r2{border-left-color:#c07bff}
.act-btn.r3{border-left-color:#ffb84d}
.act-btn.r4{border-left-color:#4fd6c0}
.act-btn.juke{border-left-color:#ffd23f}
.act-btn.sprint{border-radius:50%;min-width:46px;width:46px;padding:0;font-size:1.05rem;
  border-left-width:1px;border-color:rgba(255,255,255,.22)}
.act-btn.sprint.on{background:linear-gradient(180deg,#ffd23f,#e0a800);color:#22201a;
  border-color:#ffd23f}
.act-btn.sw{border-left-color:#5b9bff}
.act-btn.pull{border-left-color:#ff6b6b}

/* ---------- receiver badges (field3d.js owns the layer; the controller owns the tap) ----------
   Takes NO touch: a press that starts on a badge is a press on the swipe pad, and
   the controller decides what it is. The tap target is a 52px-radius circle round
   the badge centre, computed in script, not this 34px icon. Colours are the old
   r1-r4 buttons', so a receiver is the same colour it always was. */
.recv-layer{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:6}
.recv-ico{position:absolute;left:0;top:0;width:0;height:0;will-change:transform}
.recv-badge{--c:#5b9bff;position:absolute;left:-17px;top:-17px;width:34px;height:34px;box-sizing:border-box;
  border-radius:50%;display:grid;place-items:center;font:900 1rem/1 system-ui,sans-serif;color:#0b1420;
  background:#fff;border:3px solid var(--c);
  box-shadow:0 3px 10px rgba(0,0,0,.5),0 0 0 2px rgba(0,0,0,.28);animation:recv-pulse 1.5s ease-out infinite}
.recv-badge::after{content:"";position:absolute;left:50%;bottom:-11px;transform:translateX(-50%);
  border:6px solid transparent;border-top:8px solid var(--c);border-bottom:0}
.recv-badge[data-slot=WR2]{--c:#c07bff}
.recv-badge[data-slot=RB]{--c:#ffb84d}
.recv-badge[data-slot=C]{--c:#4fd6c0}
.recv-ico.is-edge .recv-badge::after{display:none}
.recv-ico.is-locked .recv-badge{background:var(--c);color:#fff;transform:scale(1.25);animation:none}
@keyframes recv-pulse{0%{box-shadow:0 3px 10px rgba(0,0,0,.5),0 0 0 2px rgba(0,0,0,.28),0 0 0 0 rgba(255,255,255,.55)}
  100%{box-shadow:0 3px 10px rgba(0,0,0,.5),0 0 0 2px rgba(0,0,0,.28),0 0 0 14px rgba(255,255,255,0)}}
@media (prefers-reduced-motion:reduce){.recv-badge{animation:none}}

.game-banner{position:absolute;top:44%;left:0;right:0;text-align:center;z-index:12;font-size:2rem;font-weight:900}

/* ---------- result screens ---------- */
.result-screen{display:grid;place-items:center;min-height:100vh;min-height:100dvh}
.result-card{background:var(--panel);border:1px solid var(--line);border-radius:20px;padding:30px 26px;text-align:center;max-width:460px;width:92%;box-shadow:var(--shadow)}
.result-emoji{font-size:3.4rem}
.result-card h1{font-size:2rem}
.result-score{font-size:1.5rem;font-weight:800;color:var(--accent2);margin:8px 0 16px}
.result-stats{text-align:left;margin:16px 0}
.stat-line{display:flex;justify-content:space-between;padding:7px 0;border-bottom:1px solid var(--line)}
.result-actions{display:flex;flex-direction:column;gap:8px;margin-top:18px}
.result-screen.champ .result-card{border-color:var(--accent2);box-shadow:0 0 40px rgba(255,210,63,.3)}

/* ---------- overlay (controls/pause) ---------- */
.overlay{position:fixed;inset:0;z-index:100;background:rgba(4,14,8,.86);display:grid;place-items:center;padding:calc(16px + var(--safe-t)) calc(16px + var(--safe-r)) calc(16px + var(--safe-b)) calc(16px + var(--safe-l))}
.overlay-card{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:24px;max-width:640px;width:100%;box-shadow:var(--shadow);max-height:90vh;overflow:auto}
.overlay-card h2{text-align:center;margin-bottom:14px}
.ctrl-cols{display:grid;grid-template-columns:1fr 1fr;gap:20px}
.ctrl-cols h3{color:var(--accent2);font-size:1rem;margin-bottom:6px}
.ctrl-table{width:100%;border-collapse:collapse}
.ctrl-table td{padding:6px 4px;border-bottom:1px solid var(--line);font-size:.86rem}
.ctrl-act{color:var(--muted)}
.ctrl-key{text-align:right;font-weight:700}
.overlay-card .btn{margin-top:16px}

/* ---------- franchise / hub ---------- */
.menu-sub,.hub-screen,.list-screen,.create-screen,.trade-screen,.playoff-screen{max-width:920px}
.resume-card{text-align:center;background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:26px;max-width:440px;margin:20px auto}
.coach-avatar{border-radius:50%;box-shadow:var(--shadow);margin:0 auto;display:block}
.hub-top{display:flex;align-items:center;gap:14px;background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:16px;margin-bottom:16px}
.hub-team{font-size:1.2rem;font-weight:800}
.hub-actions{display:grid;gap:10px;max-width:520px}
.hub-actions .btn{width:100%}

/* create coach */
.create-grid{display:grid;grid-template-columns:280px 1fr;gap:22px}
.create-center{max-width:640px;margin:0 auto}
.create-screen.center{text-align:center}
.avatar-box{display:grid;place-items:center;margin-bottom:12px}
.create-left label{display:block;margin:12px 0 4px;color:var(--muted);font-size:.85rem;font-weight:700}
.swatch-row{display:flex;gap:8px;flex-wrap:wrap}
.swatch{width:38px;height:38px;border-radius:10px;border:3px solid transparent}
.swatch.on{border-color:var(--accent2)}

/* standings */
.standings{background:var(--panel);border:1px solid var(--line);border-radius:14px;overflow:hidden}
.st-row{display:grid;grid-template-columns:52px 1fr 34px 34px 44px 44px;align-items:center;padding:9px 12px;border-bottom:1px solid var(--line);font-size:.9rem}
.st-head{color:var(--muted);font-weight:800;font-size:.78rem;text-transform:uppercase}
.st-row.mine{background:rgba(46,199,122,.14)}
.st-row.playoff .st-rank{color:var(--accent2);font-weight:800}
.st-team{font-weight:600}

/* roster */
.roster-list{display:grid;gap:6px}
.roster-row,.trade-player{display:grid;grid-template-columns:48px 1fr 42px;align-items:center;gap:8px;
  background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:10px 12px}
.rr-pos{font-weight:800;color:var(--muted);font-size:.8rem}
.rr-name{font-weight:600}
.rr-ovr{text-align:center;font-weight:800;border-radius:8px;padding:3px 0;background:var(--panel2)}
.rr-ovr.ovr-good{background:#2b6b45;color:#bfffd7}
.rr-ovr.ovr-elite{background:var(--accent2);color:#222}

/* trades */
.trade-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.trade-col{display:grid;gap:6px;max-height:52vh;overflow:auto;padding-right:4px}
.trade-player{cursor:pointer;text-align:left;color:var(--ink)}
.trade-player.on{border-color:var(--accent2);box-shadow:0 0 0 1px var(--accent2) inset}
.trade-partner{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.trade-partner h4{margin:0}
.trade-footer{margin-top:16px;text-align:center}
.trade-summary{margin-bottom:10px;font-weight:700}

/* bracket */
.bracket{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:16px;margin-bottom:16px;overflow:auto}
.bk-col h4{color:var(--accent2);font-size:.85rem;margin:10px 0 6px}
.bk-match{background:var(--panel2);border:1px solid var(--line);border-radius:10px;padding:8px;margin-bottom:8px;display:flex;flex-direction:column;gap:4px}
.bk-team{font-weight:700;font-size:.85rem;padding:3px 6px;border-radius:6px}
.bk-team.mine{background:rgba(46,199,122,.2)}
.bk-team.won{color:var(--accent2)}
.bk-team.tbd{color:var(--muted);opacity:.6}
.bk-score{font-size:.72rem;color:var(--muted)}
.bk-champ{margin-top:8px;font-weight:800;color:var(--accent2)}

/* ---------- Road to Glory ---------- */
.rtg-badge{width:60px;height:60px;border-radius:16px;background:linear-gradient(135deg,#6b4a12,#3a2a0b);
  display:grid;place-items:center;font-size:1.9rem;border:1px solid var(--accent2)}
.rtg-badge.big{width:92px;height:92px;font-size:3rem;margin:0 auto}
.pos-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px}
.pos-card{display:flex;flex-direction:column;align-items:center;gap:4px;padding:18px 10px;border-radius:14px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink)}
.pos-card:hover{border-color:var(--accent)}
.pos-card.selected{border-color:var(--accent2)}
.pos-ico{font-size:2rem}
.pos-name{font-weight:700;text-align:center}
.pos-side{font-size:.72rem;color:var(--accent2);text-transform:uppercase;letter-spacing:1px}
.pos-note{font-size:.68rem;color:var(--muted);text-align:center}
.arch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}
.arch-card{padding:18px;border-radius:14px;border:1px solid var(--line);background:var(--panel);color:var(--ink);text-align:left}
.arch-card:hover{border-color:var(--accent)}
.arch-card.selected{border-color:var(--accent2)}
.arch-name{display:block;font-weight:800;font-size:1.1rem;margin-bottom:4px}
.arch-boost{color:var(--accent2);font-size:.8rem;font-weight:700}
.ovr-meter{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:16px;margin:14px 0}
.ovr-num{font-size:1.4rem;font-weight:900;color:var(--accent2);text-align:center;margin-bottom:8px}
.ovr-bar{height:14px;border-radius:8px;background:var(--panel2);overflow:hidden}
.ovr-fill{height:100%;background:linear-gradient(90deg,#37d98a,#ffd23f)}
.xp-row{display:flex;align-items:center;gap:8px;margin-top:10px}
.xp-bar{flex:1;height:8px;border-radius:6px;background:var(--panel2);overflow:hidden}
.xp-fill{height:100%;background:var(--blue)}
.challenge-card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:14px;margin-bottom:14px}
.challenge-card h4{color:var(--accent2);margin-bottom:8px}
.challenge-list,.challenge-results{display:grid;gap:6px}
.challenge-row{display:flex;justify-content:space-between;padding:7px 10px;border-radius:8px;background:var(--panel2);font-size:.9rem}
.challenge-row.done{background:rgba(46,199,122,.18)}
.challenge-row.miss{opacity:.6}
.chal-xp{color:var(--accent2)}
.xp-gain{font-size:1.2rem;font-weight:800;color:var(--blue);margin:12px 0}
.levelup{font-size:1.3rem;font-weight:900;color:var(--accent2);margin:8px 0;animation:pop .5s}
@keyframes pop{0%{transform:scale(.6);opacity:0}100%{transform:scale(1);opacity:1}}
.player-card{background:var(--panel);border:1px solid var(--line);border-radius:16px;padding:20px;max-width:520px;margin:0 auto}
.pc-head{display:flex;align-items:center;gap:14px;margin-bottom:16px}
.pc-ovr{margin-left:auto;font-size:2.4rem;font-weight:900;color:var(--accent2)}
.attr-row{display:grid;grid-template-columns:100px 1fr 32px;align-items:center;gap:10px;margin:8px 0}
.attr-bar{height:10px;border-radius:6px;background:var(--panel2);overflow:hidden}
.attr-fill{height:100%;background:linear-gradient(90deg,#37d98a,#ffd23f)}
.pc-career{margin-top:16px}

/* ---------- responsive ---------- */
@media (max-width:820px){
  .brand-name{font-size:2.4rem}
  .create-grid{grid-template-columns:1fr}
  .jersey-grid{grid-template-columns:1fr}
  .play-grid{grid-template-columns:repeat(3,1fr);gap:7px}
  .play-col{gap:6px}
  .play-name{font-size:.72rem}
  .ctrl-cols{grid-template-columns:1fr}
  .trade-grid{grid-template-columns:1fr}
  .bracket{grid-template-columns:1fr}
}
/* On a machine with a keyboard the thumb buttons are redundant — every one of
   them has a key — so they come off the field entirely rather than sitting
   there at reduced opacity as a permanent control legend. The swipe layer
   stays: slash-to-direct works with a mouse. */
body:not(.is-touch) .right-cluster{display:none}
/* Narrow screens: the scorebug becomes a full-width slab with a stats strip
   beneath it, and the two side panels are dropped. There is no room on a phone
   for a play clock and a field map without covering the play itself, and the
   same numbers already live in the slab and the strip. */
@media (max-width:620px){
  .sb{left:calc(8px + var(--safe-l));right:calc(8px + var(--safe-r));top:calc(8px + var(--safe-t));justify-content:space-between}
  .sb-team{padding:7px 10px;gap:7px}
  .sb-crest{width:26px;height:28px}
  .sb-abbr{font-size:.85rem;letter-spacing:1.2px}
  .sb-score{font-size:1.5rem}
  .sb-clock{min-width:88px;padding:5px 10px}
  .sb-time{font-size:1.16rem}
  .sb-dd{font-size:.62rem}
  .sb-strip{display:flex;top:calc(60px + var(--safe-t));left:calc(8px + var(--safe-l));right:calc(8px + var(--safe-r))}
  .pc,.sit{display:none}
}
/* A NARROW PHONE, AND THE BAR IS ONE ROW OR IT IS NOTHING — BUT IT IS THE
   WORD THAT PAYS FOR IT, NOT THE BUTTONS. This block used to drop the
   transport to Apple's 44 under Material's 48dp, on the arithmetic that "six
   controls plus a tag is 380px at 48dp" against 369 of usable width. The bar
   has never built six: `save` and `export` are feature-detected and the full
   set is FIVE buttons plus the tag, measured at 332x44 by `npm run replay`.
   So 48dp costs 20px, not 48, and there is somewhere cheaper to find it than
   the touch targets — the tag's own WORD, which the ⟲ glyph beside it already
   implies. Buttons hold 48 at every width now; the word goes below 380px,
   where 48dp genuinely would not fit. `END` stays at every width: see the
   block in ui.js where the three spans are built. */
/* A LANDSCAPE PHONE IS SHORT, AND THE CARRIER IS IN THE MIDDLE OF IT. There is
   no `latBias` in landscape — the chase camera puts him dead centre and the
   probe measures him there — so a transport one row up from the bottom edge
   stands on the man the replay is of: 26% of him, measured. Dropped to the
   bottom edge it clears him, and the pause button it would otherwise share a
   line with is 280px away on the other side of a wide screen. Height, not
   width, is what makes this screen small. */
@media (max-height:500px){
  .replay-bar{bottom:calc(12px + var(--safe-b))}
}
@media (max-width:400px){
  .replay-bar{gap:6px}
  .rp-tag{padding:0 8px;font-size:.66rem;letter-spacing:.8px}
}
/* 392, NOT 380, AND THE GAP IS THE REASON. With the word shown the bar is
   353px, and a 381px screen has 353px to give — an exact fit, decided by font
   metrics, in a band no device in `replaycheck` covers. Hiding the word from
   392 down instead puts the untested band on the side with 55px of slack
   (298px of bar) rather than the side with none, and leaves the two widths
   that ARE measured either side of it: 360 with the word gone at 298x48, and
   393 with it shown at 353x48. A rule is only as good as the width somebody
   measured it at. */
@media (max-width:392px){
  .rp-tag-word{display:none}
}
@media (max-width:420px){
  .play-grid{grid-template-columns:repeat(2,1fr)}
  .team-grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr))}
  .act-btn{min-width:50px;height:44px;font-size:.76rem;padding:0 9px}
  .act-btn.sprint{width:44px;min-width:44px}
  .btn-cluster{max-width:172px}
}

/* ---- contested flag-pull meter ---- */
.grab-wrap{position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);z-index:16;
  pointer-events:none;text-align:center;width:min(240px,60vw)}
.grab-label{font-weight:900;font-size:.9rem;letter-spacing:1px;color:#ffe14d;
  text-shadow:0 2px 6px rgba(0,0,0,.85);margin-bottom:4px}
.grab-bar{height:10px;border-radius:6px;background:rgba(0,0,0,.55);
  border:1px solid rgba(255,255,255,.35);overflow:hidden}
.grab-fill{height:100%;width:0;background:linear-gradient(90deg,#37d98a,#ffd23f);transition:width .06s linear}
.grab-wrap.danger .grab-fill{background:linear-gradient(90deg,#ffd23f,#ff5a5a)}
.grab-wrap.danger .grab-label{color:#ff8a8a}

/* ---- CPU-vs-CPU demo badge ---- */
/* Bottom-centre, clear of the scorebug it used to sit on top of. */
.demo-badge{position:absolute;bottom:14px;left:50%;transform:translateX(-50%);z-index:40;
  display:flex;align-items:center;gap:10px;background:rgba(4,18,10,.85);
  border:1px solid var(--accent);border-radius:20px;padding:6px 8px 6px 14px;
  font-weight:800;letter-spacing:1px;color:var(--accent2);font-size:.82rem;white-space:nowrap}
.demo-exit{background:var(--panel2);border:1px solid var(--line);color:var(--ink);
  border-radius:14px;padding:4px 12px;font-weight:700;cursor:pointer}
@media (max-width:620px){ .demo-badge{font-size:.72rem} }

/* A LANDSCAPE PHONE IS WIDE AND SHORT, and the situation panels were only
   dropped by a `max-width:620px` query — a portrait breakpoint that no
   landscape phone ever reaches, because they are 850-950px across. So on every
   landscape handset the button stack sat on top of `.sit`, covering 34-47% of
   it. What makes the screen small here is the HEIGHT, so that is what this
   asks about. Tablets and desktops are taller and keep their panels. */
@media (orientation:landscape) and (max-height:520px){
  .pc,.sit{display:none}
}

/* ===== PLAYBOOK (Phase 2): the list, the editor, My Plays ===== */
.menu-tile.playbook{background:linear-gradient(135deg,#3b2a63,#1f1638)}
.pbk-screen{max-width:1100px;padding-bottom:calc(var(--safe-b) + 72px)}
.pbk-head{display:flex;align-items:center;gap:12px;margin-bottom:10px}
.pbk-title{margin:0;font-size:1.5rem}
.pbk-btn{min-height:44px;min-width:44px;padding:8px 14px;font-weight:700;touch-action:manipulation;width:auto;margin:0}
.pbk-row>.pbk-btn{flex:1 1 84px}.pbk-row>.pbk-step,.pbk-n{flex:0 0 auto}
.pbk-head .pbk-btn{flex:none}
.pbk-btn.on,.pbk-chip.on{border-color:var(--accent2);box-shadow:0 0 0 2px var(--accent2) inset}
.pbk-btn.danger{border-color:#8a2f2f;color:#ffb3b3}
.pbk-btn[disabled]{opacity:.45}
.pbk-note,.pbk-hint{font-size:.85rem;margin:6px 0}
.pbk-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:8px 0}
.pbk-actions{margin-top:12px}
.pbk-status{min-height:1.3em;font-size:.9rem;margin:6px 0;color:var(--muted)}
.pbk-status.bad{color:#ffb3b3}.pbk-status.good{color:var(--accent)}
.pbk-file{position:fixed;left:-9999px;top:0;width:1px;height:1px;opacity:0}
.pbk-import .pbk-row{margin-bottom:0}
.pbk-backup{border:1px solid #2f9e5a;background:#0f3a22;border-radius:10px;padding:10px 12px;margin:8px 0}.pbk-backup-t{font-weight:700;margin-bottom:2px}
.pbk-warn{border:1px solid #b8860b;background:#3a2c07;color:#ffe6a3;border-radius:10px;padding:10px 12px;margin:8px 0;font-size:.9rem}
.pbk-cards,.pbk-sec,.pbk-starters{grid-template-columns:minmax(0,1fr)}
.pbk-cards{display:grid;gap:8px;margin-top:6px}
.pbk-card{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:8px 8px 8px 10px;min-height:64px}
.pbk-card.bad{border-color:#8a5a1f;border-left:3px solid #d99a3a}
.pbk-card-main{flex:1;min-width:0}
.pbk-card-name{font-weight:800;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pbk-card-line{display:flex;align-items:center;gap:6px;min-width:0}
.pbk-card-sub{font-size:.8rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pbk-card-note{font-size:.8rem;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pbk-card-copy{font-size:.78rem;line-height:1.3;font-weight:700;color:var(--accent2,#ffd23f);margin:1px 0 2px}
.pbk-num{flex:none;min-width:28px;text-align:center;font-size:.72rem;font-weight:800;border-radius:999px;padding:2px 7px;background:var(--accent2);color:#04240f}
.pbk-why{color:#ffd9a0;font-size:.82rem;overflow-wrap:anywhere}
.pbk-prow{padding-right:4px}
.pbk-open{flex:1;min-width:0;display:flex;align-items:center;gap:10px;min-height:48px;background:none;border:0;color:inherit;font:inherit;text-align:left;padding:0;margin:0;cursor:pointer;touch-action:manipulation}
.pbk-open.static{cursor:default}
.pbk-more{flex:none;width:44px;padding:0;display:flex;align-items:center;justify-content:center;font-size:1.3rem}
.pbk-star,.pbk-arrow{flex:none;width:44px;padding:0;display:flex;align-items:center;justify-content:center;font-size:1.25rem}
.pbk-star.on{color:#ffd34d;border-color:#8a6d1a}
.pbk-gdsec{display:grid;gap:8px;grid-template-columns:minmax(0,1fr);margin-top:8px;padding:8px 0 4px;border-bottom:1px solid var(--line)}
.pbk-gd-h{display:flex;align-items:baseline;gap:4px;flex-wrap:wrap;font-size:.8rem}
.pbk-gdrow{border-color:#8a6d1a}
.pbk-pos{flex:none;min-width:18px;text-align:center;font-weight:800;font-size:.9rem;color:#ffd34d}
.pbk-gdrow .pbk-arrow{padding:0}
@media (max-width:420px){.pbk-gdrow .pbk-card-thumb{display:none}}   /* a narrow phone: the position, the name and three 44 px buttons; the picture is on the play's own row */
.pbk-starter .pbk-add{flex:none;min-width:76px;padding:8px 10px}
.pbk-add.done{border-color:var(--accent);color:var(--accent)}
.pbk-count{margin:12px 0 2px}
.pbk-sec{display:grid;gap:8px}
.pbk-sec-h{display:flex;align-items:center;gap:6px;margin-top:4px}
.pbk-sec-t{flex:1;display:flex;align-items:center;gap:6px;justify-content:flex-start;text-align:left;min-height:48px;background:none;border-color:transparent}
.pbk-sec-n{font-weight:800;text-transform:uppercase;letter-spacing:.8px;font-size:.78rem;color:var(--muted)}
.pbk-chev{display:inline-flex;font-size:1.1rem}
.pbk-starters{display:grid;gap:8px;margin-top:14px}
.pbk-starters-h{width:100%}
.pbk-kind-h{margin-top:6px;padding:2px 4px 0;display:flex;align-items:baseline;gap:4px}
.pbk-toast{position:fixed;left:12px;right:12px;bottom:calc(var(--safe-b) + 72px);z-index:40;display:flex;align-items:center;gap:10px;background:#0f3a22;border:1px solid #2f9e5a;border-radius:12px;padding:6px 6px 6px 14px;box-shadow:0 6px 24px rgba(0,0,0,.45);max-width:560px;margin:0 auto}
.pbk-toast-t{flex:1;min-width:0;font-size:.92rem;overflow-wrap:anywhere}
.pbk-sheet-back{position:fixed;inset:0;z-index:50;background:rgba(0,0,0,.55);display:flex;align-items:flex-end;justify-content:center}
.pbk-sheet{width:100%;max-width:560px;max-height:85vh;max-height:85dvh;overflow:auto;background:var(--panel);border:1px solid var(--line);border-bottom:0;border-radius:16px 16px 0 0;padding:10px 12px calc(var(--safe-b) + 14px);display:grid;gap:6px;outline:0}
.pbk-sheet-t{font-weight:800;padding:6px 4px 8px;overflow-wrap:anywhere}
.pbk-sheet-row{display:flex;align-items:center;justify-content:space-between;gap:10px;width:100%;min-height:56px;text-align:left}
.pbk-sheet-row.on{border-color:var(--accent2)}
.pbk-sheet-cancel{justify-content:center;margin-top:4px}
.pbk-sheet-field{padding:2px 0}
.pbk-empty{padding:20px;text-align:center}.pbk-empty.small{padding:8px 4px;text-align:left;font-size:.85rem}.pbk-card-thumb{flex:none}
.pbk-thumb,.pbk-card-thumb svg{display:block;border-radius:6px}
.pbk-body{display:flex;gap:14px;align-items:flex-start;flex-wrap:wrap}
.pbk-fieldwrap{flex:1 1 320px;min-width:260px;position:relative}
.pbk-field{display:block;width:100%;height:auto;max-height:calc(100vh - 230px);min-height:280px;aspect-ratio:30/42;touch-action:none;user-select:none;-webkit-user-select:none;border-radius:10px;border:1px solid var(--line);background:#1b6b34}
.pbk-animrow{display:flex;flex-direction:column;gap:6px;margin-top:8px}.pbk-defrow{margin:0;gap:6px}.pbk-deflabel{flex:0 0 100%;font-size:.82rem}.pbk-defrow>.pbk-defchip{flex:1 1 56px;min-height:44px}.pbk-animate{min-height:48px;width:100%;display:flex;align-items:center;justify-content:center;gap:8px;font-size:1.05rem}.pbk-animate .ico{width:1.2em;height:1.2em}.pbk-animnote.warn{color:#ffe6a3}.pbk-field.pbk-animating .pbk-token{opacity:.28}.pbk-field.pbk-animating{cursor:default}
.pbk-axis{text-align:center;font-size:.78rem;margin-top:4px}
.pbk-side{flex:1 1 300px;min-width:260px;display:grid;gap:10px}
.pbk-card2{border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:10px}
.pbk-lab{font-size:.74rem;text-transform:uppercase;letter-spacing:1px;color:var(--muted);font-weight:800;margin:2px 0 4px;display:block}
.pbk-name{width:100%;min-height:44px;box-sizing:border-box;border-radius:10px;border:1px solid var(--line);background:var(--bg);color:var(--ink);padding:8px 12px;font-size:1rem}
.pbk-plays{margin-top:6px}.pbk-derived{font-weight:800;color:var(--accent2)}
.pbk-chips{display:flex;flex-wrap:wrap;gap:8px}
.pbk-chip{display:flex;flex-direction:column;align-items:flex-start;min-height:48px;min-width:64px;padding:6px 10px;border-radius:10px;border:1px solid var(--line);background:var(--panel2);color:var(--ink);touch-action:manipulation}
.pbk-chip-n{font-weight:800}.pbk-chip-r{font-size:.7rem}
.pbk-dot{display:inline-block;width:10px;height:10px;border-radius:50%;margin-bottom:2px}
.pbk-step{min-width:44px;font-size:1.3rem;padding:4px 10px}
.pbk-nudge{display:grid;grid-template-columns:repeat(3,48px);grid-template-areas:". up ." "left . right" ". down .";gap:4px}
.pbk-n{min-width:48px;min-height:48px;padding:0}
.pbk-n.up{grid-area:up}.pbk-n.left{grid-area:left}.pbk-n.right{grid-area:right}.pbk-n.down{grid-area:down}
.pbk-select{min-height:44px;border-radius:10px;border:1px solid var(--line);background:var(--bg);color:var(--ink);padding:6px 10px;font-size:1rem}
.pbk-action{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:6px 0}
.pbk-action-n{font-weight:700}.pbk-at{display:inline-flex;align-items:center;gap:6px}
.pbk-err{color:#ffb3b3;font-size:.86rem;margin:3px 0;overflow-wrap:anywhere}
.pbk-warnline{color:#ffe6a3;font-size:.82rem;margin:3px 0;overflow-wrap:anywhere}
.pbk-spacer{flex:1}
.pbk-toolbar{margin-bottom:8px}.pbk-toolrow{margin:6px 0 0}
.pbk-chips{gap:6px}.pbk-chip{min-width:58px;padding:4px 8px}
.pbk-focus,.pbk-zoomv{font-size:.82rem}
.play-card.mine{gap:4px}.play-thumb{display:block;line-height:0}.play-kind{font-size:.7rem}
.play-col.my-plays .play-col-h{color:var(--accent2)}
/* The call sheet's arranged My Plays (v3.119.0): a number badge, sub-headers for Unfiled and folders, and the Game Day list as a strip above the stock columns. */
.play-card.mine{position:relative}
.play-num{position:absolute;top:4px;left:6px;font-size:.7rem;font-weight:800;color:var(--accent2);line-height:1}
.play-sub{margin-top:4px;padding:2px 4px;font-size:.7rem;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:var(--muted);border-bottom:1px solid var(--line);overflow-wrap:anywhere}
.play-gameday{margin:0 0 12px}
.play-gameday .play-col-h{color:var(--accent2);margin-bottom:6px}
.play-gd-row{display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:8px}
.play-gd-row .play-card.mine{padding:12px 6px}
@media (orientation:landscape) and (max-height:520px){ .pbk-field{max-height:none;min-height:0;height:calc(100vh - 150px)} }
.trade-msg{margin:12px auto 0;max-width:520px;padding:10px 12px;border-radius:10px;font-weight:700;text-align:center;border:1px solid var(--line)}
.trade-msg.good{background:#0f3a22;border-color:#2f9e5a;color:#c9f7da}
.trade-msg.bad{background:#3a1212;border-color:#8a2f2f;color:#ffb3b3}

/* ROAD TO GLORY: the bench feed — a sentence a down while his unit is off the field. Under the scoreboard (.hud is 10), over the field. */
.rtg-feed{position:absolute;inset:0;z-index:9;background:linear-gradient(180deg,#071a0e,#0c2a17);overflow-y:auto;padding:calc(var(--rtg-hud,118px) + var(--safe-t) + 8px) 14px calc(var(--safe-b,0px) + 20px)}
.rtg-bench{text-align:center;margin:0 auto 12px;max-width:640px}
.rtg-bench-t{font-weight:800;font-size:1.05rem}
.rtg-list{display:grid;gap:8px;max-width:640px;margin:0 auto}
.rtg-card{border:1px solid var(--line);border-radius:12px;background:var(--panel);padding:10px 12px}
.rtg-card.score{border-color:#2f9e5a;background:#0f3a22}
.rtg-card.turn{border-color:#8a2f2f;background:#2a1010}
.rtg-hd{font-size:.74rem;text-transform:uppercase;letter-spacing:.6px}
.rtg-tx{font-weight:700;margin:4px 0;line-height:1.35}
.rtg-st{font-size:.85rem}
.rtg-note{font-size:.85rem;margin:8px 0;text-align:center}
.trade-value{font-size:.85rem;margin-bottom:10px}

/* ---------- Road to Glory: design your player's look and choose a number (v3.121.0) ----------
   The preview stays at the top while the options scroll under it, so a choice is seen as it is made. Every control is 44px or more. */
.rtg-look .create-center{text-align:left}
.rtg-pv-wrap{position:sticky;top:0;z-index:5;margin:0 -4px 10px;padding:6px 4px 6px;background:var(--bg);border-bottom:1px solid rgba(29,92,56,.5)}
.rtg-pv{position:relative;width:100%;height:min(34vh,260px);min-height:180px;border:1px solid var(--line);border-radius:14px;
  background:radial-gradient(circle at 50% 30%,#1d6a3a,#0b3d1e 70%);overflow:hidden;touch-action:pan-y;cursor:grab}
.rtg-pv canvas{display:block;width:100%;height:100%}
.rtg-pv-none{display:grid;place-items:center;height:100%;padding:16px;text-align:center}
.rtg-pv-hint{text-align:center;margin-top:2px}
.rtg-look h4{margin:14px 0 6px;font-size:.95rem;color:var(--muted);font-weight:600}
.rtg-chips{display:flex;flex-wrap:wrap;gap:8px}
.rtg-chip{min-height:44px;padding:8px 14px;border-radius:12px;border:1px solid var(--line);background:var(--panel2);color:var(--ink);font-size:.98rem;font-weight:600}
.rtg-chip.on{background:linear-gradient(180deg,#37d98a,#1fa863);border-color:#37d98a;color:#04240f}
.rtg-swatch{width:44px;height:44px;border-radius:50%;border:2px solid var(--line);padding:0}
.rtg-swatch.on{border-color:var(--accent2);box-shadow:0 0 0 3px rgba(255,210,63,.45)}
.rtg-num-row{display:flex;gap:8px;align-items:center}
.rtg-num-row .rtg-step{width:56px;min-height:48px;margin:0;font-size:1.4rem;padding:0}
.rtg-num-in{flex:1;min-width:0;min-height:48px;text-align:center;font-size:1.5rem;font-weight:700}
.rtg-num-msg{min-height:1.4em;margin-top:6px;font-size:.95rem}
.rtg-num-msg.good{color:var(--accent)}
.rtg-num-msg.bad{color:#ffb3b3}
.rtg-look .sel-actions{margin-top:22px}
/* A phone on its side has no height to spare: a preview pinned above the options would fill half the screen and sit over the thing a thumb is
   reaching for. Put it BESIDE them instead (v3.121.0; `npm run rtglook` found a tap landing on the preview on the 852x393 viewport). */
@media (max-height:520px){
  .rtg-look .create-center{display:grid;grid-template-columns:minmax(220px,40%) 1fr;column-gap:18px;align-items:start;max-width:none}
  .rtg-look .create-center>*{grid-column:2}
  .rtg-look .rtg-pv-wrap{grid-column:1;grid-row:1 / span 6;top:calc(8px + var(--safe-t));margin:0;padding:0;background:none;border:0}
  .rtg-pv{height:min(60vh,230px);min-height:0}
}

/* ---------- Road to Glory: the list of careers (v3.122.0) ----------
   Each row is two buttons: the career (its number, its name and its team, told apart at a glance) and Delete. Both are 44px or more. */
.rtg-careers{display:flex;flex-direction:column;gap:10px;margin:6px 0 14px}
.rtg-career{display:flex;gap:8px;align-items:stretch}
.rtg-career-open{flex:1;min-width:0;display:flex;align-items:center;gap:12px;text-align:left;min-height:64px;padding:10px 12px;border-radius:14px;
  border:1px solid var(--line);background:var(--panel2);color:var(--ink)}
.rtg-career-open:active{transform:scale(.98)}
.rtg-career-num{flex:0 0 auto;min-width:54px;text-align:center;font-size:1.5rem;font-weight:800;color:var(--accent2)}
.rtg-career-main{display:flex;flex-direction:column;min-width:0;gap:1px}
.rtg-career-name{font-size:1.05rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rtg-career-main .muted{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rtg-career-del{flex:0 0 auto;min-width:72px;min-height:64px;border-radius:14px;border:1px solid #7a2a2a;background:#3a1418;color:#ffb3b3;font-weight:700}
.rtg-toast{position:sticky;bottom:calc(12px + var(--safe-b));display:flex;gap:12px;align-items:center;justify-content:space-between;margin:14px 0 0;padding:10px 14px;
  border-radius:14px;background:#0b2a17;border:1px solid var(--accent);box-shadow:var(--shadow);z-index:6}
.rtg-toast span{min-width:0;overflow:hidden;text-overflow:ellipsis}
.rtg-toast-undo{flex:0 0 auto;min-width:72px;min-height:44px;border-radius:12px;border:1px solid var(--accent2);background:transparent;color:var(--accent2);font-weight:800}
.pbk-sim{display:flex;flex-direction:column;gap:8px}.pbk-sim .pbk-row{align-items:center;gap:6px}.pbk-simsize{flex:1 1 56px;min-height:44px}.pbk-simsize.on{outline:2px solid var(--accent, #7ee0a1)}.pbk-simgo{min-height:48px;width:100%}.pbk-simbar{width:100%;height:10px}.pbk-sim .warn{color:#ffe6a3}.pbk-sim[data-state=stale] .pbk-simrows{opacity:.55}.pbk-simrows{display:flex;flex-direction:column;gap:8px}.pbk-simrow{border:1px solid var(--line);border-radius:10px;padding:8px;display:flex;flex-direction:column;gap:4px;min-width:0}.pbk-simhead{display:flex;justify-content:space-between;align-items:baseline;gap:8px;flex-wrap:wrap}.pbk-simcall{font-weight:800}.pbk-simyd{font-variant-numeric:tabular-nums}.pbk-simsub{display:flex;flex-direction:column;gap:1px;font-size:.82rem}.pbk-simwatch{min-height:44px;align-self:flex-start}.pbk-field.pbk-replaying .pbk-def{display:none}
