/* frontend/shutbox.css — Shut the Box's board, rebuilt to the owner's variant C (old-games overhaul 2c item 6,
   2026-10-11, from the mock page shutbox-redesign-preview.html: "I think we'll go with this one for PC (c?) and B
   on phones").

   PC (≥ 1000 px, BoardFit's BP): your nine tiles in ONE ROW (the wooden box's flaps), online the rivals as a strip
   of cards OVER it (each card: name + status, their nine, their roll in a reserved slot), and a band UNDER it:
   your seat card · the dice tray + message · the action slot (the 1 die / 2 dice row reserved, the key under it).
   ⭐ It FILLS THE HEIGHT: the box is wider than a 16:9 window, so its width sets BoardFit's scale and the height
   left over used to sit empty under it. BoardFit (`fill: true`) hands that spare height in as `--bf-fill`, a
   measured number: the tile row takes up to 20 px of it (owner at 1920: "the boxes seem stretched" when it took
   more), each gap between the sections up to 48, and the rest centres the board. 0 at the measured box.
   Phone (both modes): variant B's column, a viewport-tall column: the rivals as full-width ROWS (name · their
   nine · score, or their dice while they roll), your 3×3 fitted to the free height (shutbox.js sbxFitPhone, the
   Ur recipe), the dice tray (dice centred, no "= 7" line), one key row with the 1 die / 2 dice toggle beside it.

   Its own file for the same reason as yahtzee.css / liars-dice.css / ur.css: it loads AFTER style.css under a NEW
   prefix (`sbx-*`), so style.css's old `.stbr-shell` / `.stbr-board` / `.stbr-rail` / `.stbr-seat` / action-slot
   rules match nothing any more. ✅ Pruned from style.css at .809 (2026-10-13).
   ⭐ KEPT on purpose: the screen chrome `.stbr-root` + `.stbr-content` (chat.css hangs the online reservation on
   `.stbr-content`, style.css resets `.bf-fit .stbr-root`, flashWin / shakeCard / the bet popup's blur name them),
   and the shipped PIECES: `.stbr-tile` (open / selected / shut), `.stbr-seat-tile` (a rival's mini tile), the
   `.stbr-dc-toggle` / `.stbr-dc-opt` toggle (its unlock glow included), the race board's `.pigr-btn-roll` key.
   Where a piece needs another size here it is set under `.sbx-board`, and every size it took from vw is restated.

   ⛔ The BoardFit traps (docs/ui-components.md § "PC fit"): no vh inside the fit target (`.sbx-board`; the phone
   column's dvh is on the SCREEN, outside it), no position: fixed / sticky anywhere, every row that can be empty
   (the dice before a roll, the "= 7", the toggle row, a rival's dice, the message) is a fixed box, and every text
   row has a fixed line box (a lazily loaded font weight must not move the box). */

/* ── Chrome ─────────────────────────────────────────────────────────────────────────────────────── */
/* The Arcade cabinet caps the shell for the phone column; a fitted PC board is 1180 wide, so the cap lifts there
   (BoardFit centres the board in this parent either way). */
.bf-fit .sbx-shell { max-width: none; }

/* The online idle bar FLOATS (shutbox_mp.js passes barClass 'mp-timeout-float', 2026-10-11 .797): a pill centred
   at the top of the content box, a SIBLING of the fit target (never scaled). On PC it sits over the rivals'
   strip, on a phone over the first rival row under the topbar; never over a tile, the dice or the key. Without
   the anchor the nearest positioned ancestor is the page and the bar lands on the topbar. */
#stb-mp-content { position: relative; }
#stb-mp-timeout-bar.mp-timeout-float { left: 50%; right: auto; transform: translateX(-50%); width: max-content; max-width: calc(100% - 24px); }

/* ── The board root ─────────────────────────────────────────────────────────────────────────────── */
.sbx-board {
  position: relative; isolation: isolate; box-sizing: border-box;
  font-family: var(--pgr-font, 'Outfit', system-ui, sans-serif); color: var(--pgr-txt, #e9e8e4);
  /* The spare height BoardFit hands in (0 everywhere else): ≤ 20 px to the tile row, ≤ 48 to each gap. */
  --sbx-row: min(calc(var(--bf-fill, 0px) * .45), 20px);
  --sbx-gap: min(calc((var(--bf-fill, 0px) - var(--sbx-row)) / 2), 48px);
}
.sbx-board.sbx-solo { --sbx-gap: min(calc(var(--bf-fill, 0px) - var(--sbx-row)), 48px); }   /* one gap solo */
.sbx-board *, .sbx-board *::before, .sbx-board *::after { box-sizing: border-box; }

/* Your tiles: the box, its head ONE fixed line, the shipped `.stbr-tile` sized here. */
.sbx-box {
  position: relative; display: flex; flex-direction: column; gap: 10px; min-width: 0;
  padding: 14px 16px 16px; border-radius: 18px;
  background: var(--pgr-panel, rgba(255,255,255,.04)); border: 1px solid var(--pgr-line, rgba(255,255,255,.075));
}
.sbx-box.is-turn { box-shadow: inset 0 0 0 1.5px var(--pgr-sel, #1D9E75); }
.sbx-boxhead {
  flex: none; height: 20px; line-height: 20px; display: flex; justify-content: space-between; gap: 10px;
  font-size: 13px; font-weight: 600; letter-spacing: .06em; color: var(--pgr-dim, #83858b); white-space: nowrap;
}
.sbx-bh-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }
.sbx-bh-r { flex: none; letter-spacing: 0; }
.sbx-bh-r b { color: var(--pgr-txt, #e9e8e4); font-size: 17px; font-weight: 800; }
.sbx-bh-r i, .sbx-score i { font-style: normal; opacity: .7; }
.sbx-bh-face { font-size: 16px; letter-spacing: 0; }
.sbx-bh-face .face-wrap { font-size: 16px; margin-left: 0; }
.sbx-board .sbx-tile { width: auto; height: auto; min-width: 0; border-radius: 14px; font-size: 60px; }
.sbx-board .sbx-tile.selected { transform: translateY(-4px); }

/* Your seat card (PC): the pal face, the name (a `.yz-clip`: marquee.js scrolls it if it overflows), a note (or,
   solo, the pal's line in its place), the running score over par / of 55. Locked rows. */
.sbx-seat {
  position: relative; display: flex; align-items: center; gap: 12px; min-width: 0;
  padding: 0 16px 0 12px; border-radius: 16px;
  background: var(--pgr-panel, rgba(255,255,255,.04)); border: 1px solid var(--pgr-line, rgba(255,255,255,.075));
}
.sbx-seat.is-turn { box-shadow: inset 0 0 0 1.5px var(--pgr-sel, #1D9E75), 0 10px 26px -14px var(--pgr-sel, #1D9E75); }
.sbx-av {
  flex: none; width: 46px; height: 46px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
  background: var(--pgr-seat, rgba(255,255,255,.025)); border: 1px solid var(--pgr-line, rgba(255,255,255,.075));
}
.sbx-av .face-wrap { font-size: 26px; margin-left: 0; }
.sbx-meta { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sbx-name { display: block; height: 22px; line-height: 22px; font-size: 18px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--pgr-sel, #1D9E75); }
.sbx-note { display: block; height: 17px; line-height: 17px; font-size: 13px; color: var(--pgr-dim, #83858b); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The pal's line (solo, game.js's `.commentary`) takes the note's line box while it is up, never a row of its own. */
.sbx-board .sbx-say {
  position: absolute; left: 0; right: 0; top: 22px; height: 17px; line-height: 17px; min-height: 0; margin: 0;
  font-size: 13px; text-align: left; color: var(--pgr-txt, #e9e8e4); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sbx-meta:has(.sbx-say.commentary-in:not(:empty)) .sbx-note { visibility: hidden; }
.sbx-score { flex: none; display: flex; flex-direction: column; align-items: flex-end; }
.sbx-score b { height: 36px; line-height: 36px; font-size: 34px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--pgr-txt, #e9e8e4); }
.sbx-score i { height: 15px; line-height: 15px; font-size: 12px; color: var(--pgr-dim, #83858b); }

/* A rival: name + status on one fixed line, nine mini tiles (the shipped `.stbr-seat-tile`), their roll in a
   RESERVED slot. The border carries the player's vanity colour (--pid-bd, PlayerIdentity); a turn wins over it. */
.sbx-rival {
  position: relative; min-width: 0; display: flex; flex-direction: column; gap: 8px;
  padding: 10px 14px; border-radius: 14px;
  background: var(--pgr-panel, rgba(255,255,255,.04));
  border: 1px solid var(--pid-bd, var(--pgr-panelBdC, var(--pgr-line, rgba(255,255,255,.075))));
  transition: border-color .2s, box-shadow .2s, opacity .2s;
}
.sbx-rival.is-turn { border-color: var(--pgr-sel, #1D9E75); box-shadow: inset 0 0 0 1px var(--pgr-sel, #1D9E75), 0 10px 26px -14px var(--pgr-sel, #1D9E75); }
.sbx-rival.done { opacity: .7; }
.sbx-rhead { flex: none; height: 20px; display: flex; align-items: center; gap: 8px; min-width: 0; }
.sbx-rname { display: block; flex: 1 1 auto; min-width: 0; height: 20px; line-height: 20px; font-size: 16px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sbx-rstat { flex: none; height: 20px; line-height: 20px; font-size: 14px; color: var(--pgr-dim, #83858b); white-space: nowrap; }
.sbx-rstat b { color: var(--pgr-txt, #e9e8e4); }
.sbx-rbody { flex: none; display: flex; align-items: center; gap: 10px; min-width: 0; }
.sbx-strip { display: flex; gap: 4px; flex: none; }
.sbx-board .sbx-mini { flex: none; width: 28px; min-width: 0; height: 34px; aspect-ratio: auto; font-size: 15px; border-radius: 6px; }
.sbx-rdice { flex: none; display: flex; gap: 4px; align-items: center; width: 52px; height: 26px; }
.sbx-rdice .dr-die, .sbx-rdice .dr-wrap { flex: none; }

/* The dice tray: the dice in a FIXED-width slot (two dice wide, so one die never re-packs the message) + the
   reserved "= 7" line (PC), then the message. Your roll, or while someone else holds a roll, THEIRS. */
.sbx-tray {
  min-width: 0; display: flex; align-items: center; gap: 16px; padding: 12px 18px; border-radius: 16px;
  background: radial-gradient(120% 140% at 50% 0%, color-mix(in srgb, var(--pgr-sel, #1D9E75) 9%, var(--pgr-panel, #1b1d22)) 0%, var(--pgr-panel, #17191d) 70%);
  border: 1px solid var(--pgr-line, rgba(255,255,255,.075));
}
.sbx-dicecol { flex: none; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.sbx-dice { --die: 66px; display: flex; justify-content: center; align-items: center; gap: 10px; width: calc(var(--die) * 2 + 10px); height: var(--die); }
.sbx-dice .dr-die, .sbx-dice .dr-wrap { flex: none; }
.sbx-dice .sbx-ghost { display: block; opacity: .26; }
.sbx-dcap { display: block; height: 18px; line-height: 18px; font-size: 15px; font-weight: 800; color: var(--pgr-sel, #1D9E75); font-variant-numeric: tabular-nums; }
/* The message: TWO reserved lines (the bust line and "3 players are still going" are the longest). */
.sbx-msg {
  flex: 1 1 auto; min-width: 0; height: 42px; line-height: 21px; font-size: 16px; color: var(--pgr-dim, #83858b);
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}

/* The action slot: the toggle row RESERVED in every state (hidden, never removed, when it is not your roll), the
   ONE key under it: Roll → Shut tiles → dimmed while it is not your turn → 📊 Results / 🎲 New bet. */
.sbx-act { min-width: 0; display: flex; flex-direction: column; justify-content: flex-end; gap: 8px; }
.sbx-dcrow { flex: none; height: 40px; display: flex; align-items: center; justify-content: center; gap: 10px; }
.sbx-dcrow.off { visibility: hidden; }
/* HintArrow's target (the toggle itself clips its children: overflow hidden). */
.sbx-dcwrap { position: relative; display: inline-flex; }
.sbx-dclab { font-size: 13px; font-weight: 600; color: var(--pgr-dim, #83858b); }
.sbx-board .sbx-dc .stbr-dc-opt { height: 40px; font-size: 14px; padding: 0 16px; }
.sbx-board .sbx-key { flex: none; width: 100%; height: 62px; font-size: 19px; padding: 0 12px; white-space: nowrap; }
.sbx-board .sbx-key.sbx-shut { border-color: var(--pgr-sel, #1D9E75); }

/* ── PC: one design box (BoardFit 1180 × the registry h), the board grows into --bf-fill ─────────── */
@media (min-width: 1000px) {
  /* A 24 px margin each side, 8 over the board and 16 under it: BoardFit reads it as padding beside / below the
     board, so the board never touches the window's edge (×1.04 at 1280, the mock's number) and, filled to the
     height, its key stays clear of the chat bar's ▾ tab (19 px over the bar). One value in both layout schemes:
     the shell tokens are the phone column's. */
  .sbx-shell { padding: 8px 24px 16px; }
  .sbx-board {
    width: 1180px; display: flex; flex-direction: column; justify-content: center; gap: calc(14px + var(--sbx-gap));
    --pgr-vh: 6.37px;   /* the .762 rule, belt and braces: nothing in here reads vh at all */
  }
  .sbx-rivals { flex: none; height: 92px; display: grid; grid-template-columns: repeat(var(--n, 3), minmax(0, 380px)); justify-content: center; gap: 14px; }
  .sbx-rival { height: 92px; }
  .sbx-box { flex: none; }
  .sbx-bh-ph, .sbx-bh-r { display: none; }
  .sbx-tiles { display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); gap: 12px; height: calc(130px + var(--sbx-row)); }
  .sbx-solo .sbx-tiles { height: calc(150px + var(--sbx-row)); }
  .sbx-board .sbx-tile { font-size: 62px; }
  .sbx-band { flex: none; height: 140px; display: flex; align-items: stretch; gap: 14px; }
  .sbx-seat { flex: 0 0 290px; }
  .sbx-tray { flex: 1 1 auto; }
  .sbx-act { flex: 0 0 300px; }
}

/* ── Phone: a viewport-tall column; your 3×3 takes the free height ────────────────────────────────
   The screen is the column (min-height 100dvh, border-box, so chat.css's reservation — solo's padding on the
   SCREEN, online's on `.stbr-content` — is INSIDE it, not added). No fixed / sticky: the key row is just the
   column's last row. */
@media (max-width: 999.98px) {
  #shutbox-game-screen, #stb-mp-game-screen { display: flex; flex-direction: column; min-height: 100dvh; box-sizing: border-box; }
  /* The column owns its own `display: flex` rather than leaning on style.css's general `.stbr-root` rule, which
     did not parse at all until .804 (the comment above it named the tokens as "--pgr-shell" + "*" + "/tile"; that
     star-slash ENDED the comment early, and the rest of it plus the rule were dropped as one bad selector).
     `min-height: 0` here also overrides that rule's 100vh, which would otherwise stretch the column. */
  #shutbox-game-screen > .stbr-root, #stb-mp-game-screen > .stbr-root { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
  #shutbox-content, #stb-mp-content { flex: 1 1 auto; min-height: 0; padding-top: 8px; padding-left: 12px; padding-right: 12px; }
  .sbx-shell { flex: 1 1 auto; min-height: 0; }
  .sbx-board { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 8px; width: 100%; }
  .sbx-band { display: contents; }
  .sbx-seat, .sbx-bh-pc { display: none; }

  .sbx-box { flex: 1 1 0; min-height: 0; padding: 8px 10px 10px; gap: 6px; border-radius: 16px; }
  .sbx-boxhead { font-size: 12px; letter-spacing: .02em; }
  .sbx-bh-r b { font-size: 16px; }
  .sbx-gridslot { flex: 1 1 0; min-height: 0; display: flex; align-items: center; justify-content: center; }
  .sbx-tiles { --tile: 80px; display: grid; grid-template-columns: repeat(3, var(--tile)); grid-template-rows: repeat(3, var(--tile)); gap: 8px; }
  .sbx-board .sbx-tile { font-size: calc(var(--tile) * .5); border-radius: 12px; }

  /* The tray is the dice's height + its padding (both fixed), so the dice sit centred (owner: "center the dice …
     touching the top of the card with space underneath"). No "= 7" line on a phone: the message says the total. */
  .sbx-tray { flex: none; padding: 7px 12px; gap: 12px; border-radius: 14px; }
  .sbx-dice { gap: 8px; width: calc(var(--die) * 2 + 8px); }
  .sbx-dcap { display: none; }
  .sbx-msg { height: 36px; line-height: 18px; font-size: 13.5px; }

  .sbx-act { flex: none; height: 54px; flex-direction: row; align-items: stretch; gap: 8px; }
  .sbx-dcrow { height: auto; align-items: stretch; }
  .sbx-dcrow.off, .sbx-dclab { display: none; }
  .sbx-dcwrap { display: flex; }
  .sbx-board .sbx-dc { display: inline-flex; }
  .sbx-board .sbx-dc .stbr-dc-opt { height: 100%; padding: 0 10px; font-size: 13px; }
  .sbx-board .sbx-key { flex: 1 1 0; width: auto; height: 54px; font-size: 17px; }

  /* The rivals as full-width ROWS: name · their nine · the score, or their dice while they hold a roll. */
  .sbx-rivals { flex: none; display: flex; flex-direction: column; gap: 5px; }
  .sbx-rival { height: 32px; padding: 0 8px; flex-direction: row; align-items: center; gap: 8px; border-radius: 10px; }
  .sbx-rivals:empty { display: none; }
  .sbx-rhead, .sbx-rbody { display: contents; }
  .sbx-rname { flex: 0 0 84px; height: 18px; line-height: 18px; font-size: 13px; order: 1; }
  .sbx-strip { flex: 1 1 0; min-width: 0; display: grid; grid-template-columns: repeat(9, minmax(0, 1fr)); gap: 2px; order: 2; }
  .sbx-board .sbx-mini { width: auto; height: 20px; font-size: 11px; border-radius: 4px; }
  .sbx-rstat, .sbx-rdice { flex: 0 0 56px; order: 3; height: 20px; }
  .sbx-rstat { line-height: 20px; font-size: 13px; text-align: right; overflow: hidden; }
  .sbx-rdice { width: 56px; gap: 3px; justify-content: flex-end; }
  .sbx-left { display: none; }
  /* ONE right-hand slot: the score, or their dice while they hold a roll (the row never re-packs). */
  .sbx-rival:not(.has-roll) .sbx-rdice, .sbx-rival.has-roll .sbx-rstat { display: none; }
  .sbx-board .speech-bubble { font-size: 13px; padding: 6px 10px; }
}
