/* SPADES FAMILY — shared stylesheet (rebuild after the 2026-10-02 audit).
 *
 * One file for Spades, Whiz Spades, Cutthroat Spades and 2-Player Spades
 * (decision D11, the shared kit). The master copy is kit/spades/; each game
 * carries a byte-identical copy (harness/spades-kit-sync.js checks it).
 *
 * Spec: briefs/spades-family-spec.md. Decisions: briefs/spades-family-decisions.md.
 *
 * THE SHARED DNA (brief §9–§11). Card faces, court art, backs, the gold
 * action, type, buttons, plates and focus states are the catalogue's (the
 * War / Go Fish / Snap / Hearts shell). What carries over from the Hearts
 * rebuild (Ronan 17:05): the stats in the middle of the table, suits in their
 * colours, sentence case, phone boxes with the name above the cards, your tag
 * beside your box, and the card-spacing rule (claude/rule-card-spacing.md).
 *
 * Seats: 0 You (bottom), 1 left, 2 top, 3 right. Three-player Cutthroat
 * uses 0, 1, 3; two-player uses 0 and 2. [data-seats] on .game hides the
 * rest.
 */

*,*::before,*::after{ box-sizing:border-box; }
html,body{
  margin:0; padding:0; height:100%; overflow:hidden;
  background:var(--table-deep);
  touch-action:manipulation; overscroll-behavior:none;
}
body{
  font-family:var(--font-ui);
  color:var(--text-primary);
  -webkit-text-size-adjust:100%;
  -webkit-tap-highlight-color:transparent;
  background:radial-gradient(ellipse at 50% 44%, var(--table-highlight) 0%, var(--table-bg) 55%, var(--table-deep) 100%) var(--table-deep);
}
button, select, input{ font:inherit; color:inherit; }
[hidden]{ display:none !important; }
button{ touch-action:manipulation; }

:root{
  /* --- Spades-family felt (D2): one of three, chosen by Ronan from the
     preview. Defaults to A until then. L* 30–35, at least 12 dE from every
     other felt in the catalogue (Hearts' Harbour blue, Go Fish, solitaire). --- */
  --table-bg:#105C4E;
  --table-deep:#0A4238;
  --table-highlight:#1A6E5F;
  --plate:rgba(3,20,17,.62);
  --plate-strong:rgba(3,20,17,.90);
  --result-bg:#0A2E28;
  --text-secondary:#DDEFEA;
  --text-muted:#B5D3CB;

  /* --- Team accents (brief §8; audit U-07: gold is for actions only). --- */
  --our-team:#62C4FF;
  --their-team:#C9A8FF;

  /* --- Shared product tokens: the catalogue's values. --- */
  --text-primary:#F6F7F4;
  --action:#F0B84B;
  --action-text:#1A1F1D;
  --success:#62C58B;
  --danger:#E45B64;
  --active:#62C4FF;

  --card-bg:#FAFAF7;
  --card-black:#202322;
  --card-red:#CB343E;
  --suit-red-on-dark:#FF7B7B;
  --suit-blue-on-dark:#7DB8FF;
  --suit-green-on-dark:#6FD892;
  --card-blue:#2563B8;
  --card-green:#1E7A45;

  --line:rgba(255,255,255,.18);
  --line-soft:rgba(255,255,255,.10);
  --panel:rgba(0,0,0,.30);

  --space-1:4px;  --space-2:8px;  --space-3:12px;
  --space-4:16px; --space-5:24px; --space-6:32px;
  --radius:10px;

  --font-ui:'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-display:'Playfair Display',Georgia,serif;
  --font-mono:'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,monospace;

  --back-red:#A6142B;
  --back-white:#F7F1E6;

  /* CARD GEOMETRY (ratio 0.70). The hand card is sized from the height left
     after the fixed rows; the trick cards are a share of the hand card. */
  --v-fixed:356px;
  --hand-k:4.06;
  --hand-w:clamp(56px, min(7.4vw, calc((100dvh - var(--v-fixed) - var(--lift)) / var(--hand-k))), 100px);
  --hand-h:calc(var(--hand-w) / 0.70);
  --trick-w:calc(var(--hand-w) * 0.92);
  --trick-h:calc(var(--trick-w) / 0.70);
  --back-w:calc(var(--hand-w) * 0.46);
  --back-h:calc(var(--back-w) / 0.70);
  --back-step:0.26;
  --lift:12px;
  --gap:clamp(8px, 1.1vw, 14px);
  /* Spacing grows with the space available (card-spacing rule). */
  --trick-gap:clamp(10px, 1.5vw, 22px);
  --trick-gap-x:clamp(10px, 2vw, 30px);
  --seat-gap:clamp(16px, 3.6vw, 64px);
  --row-gap:clamp(8px, 1.75dvh, 26px);

  --dur-travel:300ms;
  --dur-collect:360ms;
  --dur-lift:120ms;
}
/* The three felts for Ronan's choice (D2). */
.game[data-felt='a'], :root[data-felt='a']{ --table-bg:#105C4E; --table-deep:#0A4238; --table-highlight:#1A6E5F; --plate:rgba(3,20,17,.62); --plate-strong:rgba(3,20,17,.90); --result-bg:#0A2E28; --text-secondary:#DDEFEA; --text-muted:#B5D3CB; }
.game[data-felt='b'], :root[data-felt='b']{ --table-bg:#385252; --table-deep:#263B3B; --table-highlight:#456363; --plate:rgba(10,18,18,.60); --plate-strong:rgba(10,18,18,.90); --result-bg:#1C2D2D; --text-secondary:#E3ECEC; --text-muted:#C0D0D0; }
.game[data-felt='c'], :root[data-felt='c']{ --table-bg:#3C5660; --table-deep:#293E46; --table-highlight:#4A6874; --plate:rgba(10,18,24,.60); --plate-strong:rgba(10,18,24,.90); --result-bg:#1D2F37; --text-secondary:#E2EBF0; --text-muted:#BFCFD8; }

/* ------------------------------------------------------------- shell --- */
.game{
  position:relative;
  display:grid;
  grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  grid-template-rows:auto minmax(0,1fr) auto auto auto;
  grid-template-areas:
    'header header header'
    'table  table  table'
    'sec    ins    act'
    'tip    tip    tip'
    'hand   hand   hand';
  /* Brief §13: the composition is capped around 1200px on large monitors;
     the felt (on body) still fills the window. */
  height:100dvh; max-height:100dvh; width:100%; max-width:1240px; margin:0 auto;
  padding:
    max(var(--space-2), env(safe-area-inset-top)) max(var(--space-3), env(safe-area-inset-right))
    max(var(--space-2), env(safe-area-inset-bottom)) max(var(--space-3), env(safe-area-inset-left));
  row-gap:8px; column-gap:var(--space-4);
}

/* ------------------------------------------------------------ header --- */
.zone-header{
  grid-area:header;
  display:flex; align-items:center; justify-content:space-between; gap:var(--space-3);
  padding-bottom:var(--space-1);
  border-bottom:1px solid var(--line-soft);
  min-height:40px;
}
.wordmark{ display:flex; align-items:baseline; gap:var(--space-3); min-width:0; }
.wordmark .title{ font-family:var(--font-display); font-weight:800; font-size:clamp(18px,2vw,24px); letter-spacing:.01em; white-space:nowrap; }
.hand-pill{ font-family:var(--font-mono); font-weight:700; font-size:12px; letter-spacing:.06em; color:var(--text-muted); white-space:nowrap; }
.header-controls{ display:flex; align-items:center; gap:var(--space-2); }
/* The score that matters (brief §19): your team against the opponents, or
   (Cutthroat) every player's total. */
.scorebar{ display:grid; grid-auto-flow:column; grid-auto-columns:1fr; flex:none; align-items:stretch; gap:var(--space-2); font-family:var(--font-mono); font-weight:700; white-space:nowrap; min-width:0; }  /* every score box the same size (Ronan 21:39) */
.score-side{ display:flex; align-items:baseline; gap:6px; padding:3px 9px; border-radius:8px; background:var(--plate); border:1px solid var(--line-soft); }
.score-side .score-label{ font-family:var(--font-ui); font-size:12px; font-weight:700; color:var(--text-secondary); }
.score-side .score-val{ font-size:16px; font-weight:800; }
.score-side.is-us{ border-color:color-mix(in srgb, var(--our-team) 55%, transparent); }
.score-side.is-us .score-label{ color:var(--our-team); }
.score-side.is-them .score-label{ color:var(--their-team); }
.score-side.is-you .score-label{ color:var(--our-team); }
.score-label .lab-short{ display:none; }
.scorebar[data-count='3'] .score-side, .scorebar[data-count='4'] .score-side{ flex-direction:column; align-items:center; gap:0; padding:1px 8px; line-height:1.15; }
.scorebar[data-count='3'] .score-side .score-val, .scorebar[data-count='4'] .score-side .score-val{ font-size:14px; }
@media (max-width:1150px){ .game[data-scores='3'] .hand-pill, .game[data-scores='4'] .hand-pill{ display:none; } }
@media (max-width:960px){ .game[data-scores='4'] .wordmark{ display:none; } }

.ctrl-btn{
  font-family:var(--font-ui); font-size:clamp(13px,1.2vw,15px); font-weight:700;
  color:var(--text-primary); background:var(--panel);
  border:1px solid var(--line); border-radius:var(--radius);
  padding:var(--space-2) var(--space-3); cursor:pointer;
  transition:border-color .16s ease, background .16s ease, filter .16s ease;
}
.ctrl-btn:hover:not(:disabled){ border-color:var(--action); }
.ctrl-btn:disabled{ opacity:.42; cursor:not-allowed; }
.ctrl-btn:focus-visible{ outline:2px solid var(--active); outline-offset:2px; }
.ctrl-btn.primary{ background:var(--action); color:var(--action-text); border-color:var(--action); font-weight:800; padding:var(--space-2) var(--space-5); min-height:48px; }
.ctrl-btn.primary:hover:not(:disabled){ filter:brightness(1.07); }
.ctrl-btn[aria-pressed='true']:not(.icon-btn){ border-color:var(--active); }
.icon-btn{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:1px; min-width:52px; min-height:44px; padding:3px 8px; }
.icon-glyph{ font-size:16px; line-height:1; }
.icon-label{ font-family:var(--font-mono); font-size:10px; font-weight:700; letter-spacing:.06em; text-transform:uppercase; white-space:nowrap; }
.icon-label .lab-short{ display:none; }
.icon-glyph.is-off{ opacity:.4; filter:grayscale(1); }

/* ------------------------------------------------------------- table --- */
.zone-table{
  grid-area:table; position:relative; min-height:0;
  display:grid;
  grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  grid-template-rows:auto auto auto auto;
  align-content:center;
  grid-template-areas:
    '.     top    .'
    'left  centre right'
    'stats stats  stats'
    '.     bottom .';
  column-gap:var(--seat-gap); row-gap:var(--row-gap);
  align-items:center;
}
.seat-top{ grid-area:top; }
.seat-left{ grid-area:left; justify-self:end; }
.seat-right{ grid-area:right; justify-self:start; }
.seat-bottom{ grid-area:bottom; }
.centre{ grid-area:centre; position:relative; align-self:center; justify-self:center; }

.game[data-seats='3'] .seat-top, .game[data-seats='2'] .seat-left, .game[data-seats='2'] .seat-right{ display:none; }
.game[data-seats='3'] .slot-top, .game[data-seats='2'] .slot-left, .game[data-seats='2'] .slot-right{ display:none; }

.seat{ display:flex; align-items:center; gap:6px; min-width:0; }
.seat-top, .seat-bottom{ flex-direction:column; justify-self:center; }
.seat-top{ flex-direction:row; align-items:center; }
.seat-left{ flex-direction:column; align-items:flex-end; }
.seat-right{ flex-direction:column; align-items:flex-start; }

/* One plate per player: [name] [role] [bid · won] [total] [tag]. */
.plate{
  position:relative;
  display:inline-grid; grid-auto-flow:column; align-items:center;
  column-gap:8px; min-width:0;
  padding:5px 10px; border-radius:var(--radius);
  background:var(--plate); border:1px solid var(--line-soft);
  white-space:nowrap;
}
/* Team marker: a small bar on the plate's left edge, never a coloured panel
   (brief §8). */
.plate::before{ content:''; position:absolute; left:3px; top:7px; bottom:7px; width:3px; border-radius:2px; background:transparent; }
.seat[data-team='us'] .plate::before{ background:var(--our-team); }
.seat[data-team='them'] .plate::before{ background:var(--their-team); }
.seat-name{ font-family:var(--font-display); font-weight:800; font-size:clamp(15px,1.5vw,19px); letter-spacing:.02em; }
.seat-role{ font-family:var(--font-ui); font-size:11px; font-weight:800; letter-spacing:.04em; color:var(--our-team); }
.seat-role:empty{ display:none; }
.seat-bid{ font-family:var(--font-mono); font-weight:700; font-size:13px; color:var(--text-secondary); min-width:8.5ch; }
.seat-bid .won{ color:var(--text-primary); font-weight:800; }
.seat-bid .nil{ display:inline-block; font-family:var(--font-ui); font-size:11px; font-weight:800; padding:0 5px; border-radius:4px; background:var(--text-primary); color:#1A1F1D; margin-right:4px; }
.seat-bid .nil.is-broken{ background:var(--danger); color:#fff; }
.seat-bid:empty::before{ content:'\00a0'; }
.seat-total{ font-family:var(--font-mono); font-weight:800; font-size:clamp(15px,1.4vw,18px); min-width:2.2ch; text-align:right; }
.seat-total:empty{ display:none; }
.seat-tag{
  position:absolute; right:8px; top:0; transform:translateY(-62%); z-index:4;
  display:inline-block; visibility:hidden; text-align:center; white-space:nowrap;
  font-family:var(--font-mono); font-weight:800; font-size:11px; line-height:15px; letter-spacing:.04em;
  color:#0B2233; background:var(--active); padding:1px 5px; border-radius:4px;
}
.seat-tag.is-on{ visibility:visible; }
.seat-bottom .plate .seat-tag{ top:50%; left:100%; right:auto; transform:translate(6px, -50%); }
.seat-tag.is-flag{ background:var(--action); color:var(--action-text); }
.seat-tag.is-bad{ background:var(--danger); color:#fff; }
.seat.is-turn .plate{ border-color:var(--active); box-shadow:0 0 0 2px var(--active); }
/* The fan keeps room for 13 cards, so the box never shifts as they play. */
.mini-pile{ display:none; position:relative; width:calc(13px + 12 * 1.6px); height:18px; }
.mini-pile .card-back{ position:absolute; left:0; top:0; width:13px; height:100%; border-radius:2px; border-width:1px; }

.backs{ display:flex; height:var(--back-h); width:calc(var(--back-w) * (1 + 12 * var(--back-step))); }
.seat-left .backs{ justify-content:flex-end; }
.backs .card-back{ width:var(--back-w); height:var(--back-h); margin-left:calc(var(--back-w) * (var(--back-step) * 12 / (var(--back-n, 13) - 1) - 1)); }
.backs .card-back:first-child{ margin-left:0; }
.seat{ position:relative; }
.backs-count{ position:absolute; font-family:var(--font-mono); font-size:12px; font-weight:700; letter-spacing:.04em; color:var(--text-secondary, #CFE3DC); white-space:nowrap; pointer-events:none; }
.seat-left .backs-count, .seat-right .backs-count{ top:calc(100% + 4px); }
.game.has-result .backs-count{ visibility:hidden; }
.seat-left .backs-count{ right:0; } .seat-right .backs-count{ left:0; }
.seat-top .backs-count{ left:calc(100% + 8px); top:50%; transform:translateY(-50%); }

/* ------------------------------------------------------------- trick --- */
.trick{
  position:relative;
  width:calc(var(--trick-w) * 3 + var(--trick-gap-x) * 2);
  height:calc(var(--trick-h) * 2 + var(--trick-gap));
}
/* Two players: the two cards one above the other. */
.game[data-seats='2'] .trick{ width:max(calc(var(--trick-w) * 3 + var(--trick-gap-x) * 2), 260px); }
/* Spades brief §34/§41/§47: the trick area is at least 260px wide on desktop. */
@media (min-width:901px) and (min-height:561px){ .trick{ width:max(calc(var(--trick-w) * 3 + var(--trick-gap-x) * 2), 260px); } }
.slot{ position:absolute; width:var(--trick-w); height:var(--trick-h); }
.slot-top{ left:50%; top:0; transform:translateX(-50%); }
.slot-bottom{ left:50%; bottom:0; transform:translateX(-50%); }
.slot-left{ left:0; top:50%; transform:translateY(-50%); }
.slot-right{ right:0; top:50%; transform:translateY(-50%); }
/* Three players: the two opponents' cards on the top row, yours below. */
.game[data-seats='3'] .slot-left, .game[data-seats='3'] .slot-right{ top:0; transform:none; }
.slot .card{ width:100%; height:100%; }
.slot .card .card-corner{ font-size:clamp(13px, calc(var(--trick-w) * 0.20), 22px); }
.slot .card .card-centre-suit{ font-size:min(calc(var(--trick-w) * 0.46), calc(var(--trick-w) - 34px)); }
.slot.is-winner .card{ box-shadow:0 0 0 3px var(--action), 0 10px 22px rgba(0,0,0,.45); }
.slot-top{ z-index:1; } .slot-left, .slot-right{ z-index:2; } .slot-bottom{ z-index:3; }
.slot.is-collecting .card{ transition:transform var(--dur-collect) cubic-bezier(.4,.1,.6,1), opacity var(--dur-collect) ease; }
.trick-caption{
  position:absolute; left:0; top:0; max-width:calc(var(--trick-w) * 0.9);
  font-family:var(--font-mono); font-weight:700; font-size:11px; line-height:1.3; letter-spacing:.05em;
  color:var(--text-secondary); white-space:normal;
}
.trick-caption:empty{ display:none; }
.game[data-seats='3'] .trick-caption{ top:auto; bottom:0; }

/* ------------------------------------------- panels in the trick's place --- */
/* Bidding, Blind Nil, the two-player draft and the results all sit on the
   felt where the trick goes, never in a modal. */
.centre-panel{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  z-index:5; width:max-content; max-width:min(92vw, 420px); min-width:min(88vw, 260px);
  padding:10px 14px; border-radius:calc(var(--radius) * 1.3);
  background:var(--result-bg); border:1px solid var(--line);
  box-shadow:0 18px 40px rgba(0,0,0,.45);
  text-align:center;
}
.centre-panel[hidden]{ display:none; }
.centre-panel h2{ margin:0 0 4px; font-family:var(--font-display); font-weight:800; font-size:clamp(18px,2vw,24px); color:var(--action); }
.centre-panel .panel-line{ margin:0 0 6px; font-size:13px; line-height:1.35; color:var(--text-secondary); }
.centre-panel .panel-line strong{ color:var(--text-primary); }

/* Bidding, Blind Nil and the draft: the words (and, in the draft, the card)
   fill exactly the trick's box, so they never cover a player's box or the
   stats; the controls are in the choice bar under the table. In two-player
   there are no side boxes, so the panel may be wider. The panel is a size
   container: when the box is short, the explanation gives way first. */
.bid-panel, .blind-panel, .draft-panel{
  left:0; top:0; right:0; bottom:0; transform:none; width:auto; min-width:0; max-width:none;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
  padding:6px 8px; overflow:hidden; container-type:size;
}
.bid-panel[hidden], .blind-panel[hidden], .draft-panel[hidden]{ display:none; }
.game[data-seats='2'] .draft-panel, .game[data-seats='2'] .blind-panel, .game[data-seats='2'] .bid-panel{ left:-40%; right:-40%; }
.centre-panel .panel-line{ margin:0; }
@container (max-height:150px){ .bid-panel .panel-line + .panel-line{ display:none; } .blind-panel .panel-line:first-of-type{ display:none; } }
@container (max-height:120px){ .bid-panel .panel-line{ display:none; } }
@container (max-height:110px){ .blind-panel h2{ display:none; } }
@container (max-height:100px){ .blind-panel .panel-line{ font-size:12px; line-height:1.15; } }
.draft-card{ display:flex; justify-content:center; }
.draft-card .card{ width:var(--trick-w); height:var(--trick-h); }
/* 2-Player brief §11/§62: the card you are deciding on is the largest thing on
   the table (about 105-120px on desktop, 90-105px on a phone). The panel is a
   size container, so the card takes what the box allows, never less than a
   trick card; on a wide box the words sit beside it. */
.draft-text{ display:flex; flex-direction:column; align-items:center; gap:4px; min-width:0; }
.draft-panel .draft-card .card{ width:clamp(var(--trick-w), calc((100cqh - 74px) * 0.70), 105px); height:auto; aspect-ratio:0.70; }
@container (max-height:170px){ .draft-panel .draft-card .card{ width:clamp(var(--trick-w), calc((100cqh - 4px) * 0.70), 105px); } }
/* A narrow box (a phone) keeps the card number and gives the rest to the card;
   the instruction under the table already states the consequence. */
@container (max-width:419px) and (min-height:171px){ .draft-panel .panel-line{ display:none; } .draft-panel .draft-card .card{ width:clamp(var(--trick-w), calc((100cqh - 38px) * 0.70), 105px); } }
@media (min-width:641px) and (min-height:501px){
  .game[data-seats='2'] .draft-panel{ flex-direction:row; gap:18px; }
  .game[data-seats='2'] .draft-panel .draft-text{ max-width:260px; align-items:flex-start; text-align:left; order:2; }
  .game[data-seats='2'] .draft-panel .draft-card{ order:1; }
  .game[data-seats='2'] .draft-panel .draft-card .card{ width:clamp(var(--trick-w), calc((100cqh - 16px) * 0.70), 118px); }
  .game[data-seats='2'] .draft-panel h2, .game[data-seats='2'] .draft-panel .panel-line{ display:block; }
}
@container (max-height:170px){ .draft-panel h2, .draft-panel .panel-line{ display:none; } }

/* The choice bar: the stepper and Nil, Whiz's two bids, Blind Nil, or the
   draft's Discard; in the instruction's place, the same height. */
.choice-bar{ grid-area:ins; display:flex; align-items:center; justify-content:center; gap:10px; height:48px; width:min(560px, 52vw); justify-self:center; }
.choice-bar[hidden]{ display:none; }
.game[data-choices='yes'] .instruction{ display:none; }
.bid-step{ width:44px; height:44px; border-radius:50%; font-size:22px; font-weight:800; line-height:1; padding:0; flex:none; }
.bid-value{ font-family:var(--font-mono); font-weight:800; font-size:30px; min-width:1.6ch; text-align:center; line-height:1; }
.bid-value.is-blank{ color:var(--text-muted); }
.bid-nil{ min-height:44px; min-width:72px; }
.choice-btn{ min-height:44px; padding:6px 16px; white-space:nowrap; }
.choice-bar .ctrl-btn[aria-pressed='true']{ border-color:var(--action); box-shadow:0 0 0 2px var(--action); }

/* Results on the felt (U-08, U-09). */
.result h2{ margin:0 0 2px; }
.result .result-sub{ margin:0 0 8px; font-size:13px; font-weight:600; color:var(--text-secondary); }
.result table{ border-collapse:collapse; margin:0 auto; font-family:var(--font-mono); font-size:13.5px; }
.result th{ font-family:var(--font-ui); font-size:11px; font-weight:700; color:var(--text-muted); padding:2px 8px; text-align:right; }
.result th:first-child, .result td:first-child{ text-align:left; }
.result td{ padding:3px 8px; text-align:right; font-weight:700; border-top:1px solid var(--line-soft); }
.result td.label{ font-family:var(--font-ui); font-weight:600; color:var(--text-secondary); }
.result tr.is-total td{ border-top:1px solid var(--line); font-weight:800; color:var(--text-primary); }
.result th.is-us{ color:var(--our-team); } .result th.is-them{ color:var(--their-team); }
.result td.neg{ color:#FFB4B4; }
.result .result-notes{ margin:8px auto 0; padding:0; list-style:none; font-size:12.5px; line-height:1.4; color:var(--text-secondary); text-align:left; max-width:36ch; }
.result .result-notes li{ margin-top:3px; }
.result .result-next{ margin:8px 0 0; font-size:13px; font-weight:700; color:var(--text-primary); }

/* ------------------------------------------------- state / instruction --- */
.table-stats{
  grid-area:stats; justify-self:center; width:min(100%, 640px);
  display:flex; flex-direction:column; align-items:center; gap:1px;
  padding:3px 14px; border-radius:var(--radius);
  background:var(--plate); border:1px solid var(--line-soft);
  font-family:var(--font-ui); text-align:center;
}
.state-line, .contract-line{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; width:100%; }
.state-line{ font-size:14px; font-weight:600; line-height:17px; color:var(--text-secondary); }
.contract-line{ font-size:13px; font-weight:500; line-height:16px; color:var(--text-secondary); }
.state-line .sep, .contract-line .sep{ opacity:.55; margin:0 .45em; }
.state-line .hot, .contract-line .hot{ color:var(--text-primary); font-weight:700; }
.state-line .is-broken{ color:var(--text-primary); font-weight:800; }
.contract-line .is-us{ color:var(--our-team); font-weight:700; }
.contract-line .is-warn{ color:#FFD27A; font-weight:700; }
.contract-line .is-bad{ color:#FFB4B4; font-weight:700; }
.sym{ font-weight:700; }
.sym-H, .sym-D{ color:var(--suit-red-on-dark); }
.sym-S, .sym-C{ color:var(--text-primary); }
.game[data-four-colour='true'] .sym-D{ color:var(--suit-blue-on-dark); }
.game[data-four-colour='true'] .sym-C{ color:var(--suit-green-on-dark); }
.instruction{
  grid-area:ins;
  font-family:var(--font-ui); font-weight:700;
  font-size:clamp(15px,1.5vw,18px); letter-spacing:0;
  text-align:center; height:48px; width:min(560px, 52vw); line-height:1.25;
  display:flex; align-items:center; justify-content:center;
  padding:var(--space-1) var(--space-4);
  border-radius:var(--radius); background:var(--plate); border:1px solid var(--line-soft);
}
.game[data-your-turn='yes'] .instruction{ border-color:var(--action); color:#FFE7B3; }
.instruction.is-reason{ border-color:var(--text-muted); color:var(--text-primary); }
.secondary{ grid-area:sec; display:flex; gap:var(--space-2); justify-self:end; align-items:center; }
.small-btn{ min-height:40px; padding:6px 12px; font-size:13px; }
.action{ grid-area:act; justify-self:start; display:flex; align-items:center; }
#btnAction{ min-width:150px; white-space:nowrap; }
#btnDiscard{ min-width:150px; }  /* 2-Player brief §12: the draft's two choices 140-180px wide */
#btnAction .suit-red{ color:#9B1C26; }
.tip{ grid-area:tip; font-size:13px; color:var(--text-secondary); min-height:18px; line-height:18px; text-align:center; padding:0 var(--space-2); justify-self:center; border-radius:4px; max-width:100%; }
.tip:not(:empty){ background:var(--plate); }

/* --------------------------------------------------------------- hand --- */
.hand-zone{ grid-area:hand; min-width:0; padding-top:var(--lift); }
/* Brief §21: the useful hand width at 1200×675 is 850–950px. */
.hand{ display:flex; justify-content:center; height:var(--hand-h); width:100%; max-width:950px; margin:0 auto; padding-top:var(--lift); box-sizing:content-box; }  /* the lift is reserved inside the hand (brief: the selected card stays inside the hand) */
.hand .card{ width:var(--hand-w); height:var(--hand-h); cursor:default; transition:transform var(--dur-lift) ease, box-shadow var(--dur-lift) ease, opacity .12s ease; }
.hand .card.is-legal{ cursor:pointer; }
.hand .card.is-illegal{ filter:brightness(.66) saturate(.55); }
.hand .card.is-lifted{ transform:translateY(calc(var(--lift) * -1)); box-shadow:0 0 0 3px var(--action), 0 12px 22px rgba(0,0,0,.45); }
.hand .card.is-new{ transform:translateY(calc(var(--lift) * -1)); box-shadow:0 0 0 3px var(--text-primary), 0 12px 22px rgba(0,0,0,.45); }
.hand .card.kb-focus{ outline:3px solid var(--active); outline-offset:2px; }
.hand .card:focus-visible{ outline:3px solid var(--active); outline-offset:2px; }
/* Blind Nil is asked before you see your cards (S-04): the hand is face down. */
.hand .hand-back{ width:var(--hand-w); height:var(--hand-h); border-radius:8px; }
.cardname{ white-space:nowrap; }
.game[data-large-cards='true'] .hand .card .card-corner{ font-size:clamp(16px, calc(var(--hand-w) * 0.26), 28px); }

/* A tightly fanned hand (17 cards, or 13 on a narrow phone): the corner
   index narrows so every rank reads (set by layoutHand). */
.hand.is-crowded .card .card-corner{ letter-spacing:-.04em; font-size:12px; }
.hand.is-crowded .card .card-corner-top{ left:3px; top:4px; transform:scaleX(.8); transform-origin:left top; }

/* -------------------------------------------------------------- card --- */
.card{
  position:relative; flex:none; display:block;
  width:var(--hand-w); height:var(--hand-h); padding:0; border:0;
  background:linear-gradient(155deg,#FFFFFF,var(--card-bg));
  border-radius:8px;
  box-shadow:0 5px 12px rgba(0,0,0,.42), inset 0 0 0 1px rgba(0,0,0,.07), inset 0 1px 0 rgba(255,255,255,.9);
  color:var(--card-black);
  font-family:var(--font-ui); font-weight:800;
  overflow:hidden; text-align:left;
  isolation:isolate;
}
.card.red{ color:var(--card-red); }
.game[data-four-colour='true'] .card.suit-D{ color:var(--card-blue); }
.game[data-four-colour='true'] .card.suit-C{ color:var(--card-green); }
.court-figure{ position:absolute; z-index:1; left:50%; top:50%; transform:translate(-50%,-50%); width:70%; height:60%; display:block; }
.card-corner{ position:absolute; z-index:2; text-align:center; font-size:clamp(13px, calc(var(--hand-w) * 0.20), 22px); line-height:1.06; }
.card-corner-top{ top:5px; left:5px; }
.card-corner-bottom{ right:5px; bottom:5px; transform:rotate(180deg); }
.corner-suit-upright{ display:inline-block; transform:rotate(180deg); }
.card-centre-suit{ position:absolute; left:0; top:0; right:0; bottom:0; display:flex; align-items:center; justify-content:center; font-size:min(calc(var(--hand-w) * 0.46), calc(var(--hand-w) - 34px)); opacity:.9; }

.card-back{
  border-radius:5px; flex:none;
  background:var(--back-red);
  background-image:
    repeating-linear-gradient(45deg, var(--back-white) 0, var(--back-white) 1px, transparent 1px, transparent 5px),
    repeating-linear-gradient(-45deg, var(--back-white) 0, var(--back-white) 1px, transparent 1px, transparent 5px);
  border:1.5px solid var(--back-white);
  box-shadow:0 2px 5px rgba(0,0,0,.4);
}

.flying{
  position:fixed; z-index:60; margin:0; pointer-events:none;
  transition-property:transform, opacity; transition-timing-function:cubic-bezier(.3,.7,.3,1);
  box-shadow:0 10px 24px rgba(0,0,0,.45);
}

/* ----------------------------------------------------------- overlays --- */
.overlay{
  position:absolute; left:0; top:0; right:0; bottom:0; z-index:40;
  display:none; align-items:center; justify-content:center;
  background:rgba(4,14,12,.70); backdrop-filter:blur(3px);
  padding:var(--space-4);
}
.overlay.open{ display:flex; }
.overlay-panel{
  width:min(92vw, 520px); max-height:calc(100dvh - 32px); overflow-y:auto;
  padding:var(--space-5);
  border-radius:calc(var(--radius) * 1.6);
  background:linear-gradient(180deg, var(--table-highlight), var(--table-deep));
  border:1px solid var(--line);
  box-shadow:0 26px 70px rgba(0,0,0,.6);
  text-align:center;
}
.overlay-panel h2{ font-family:var(--font-display); color:var(--action); margin:0 0 var(--space-2); font-size:clamp(22px,2.8vw,30px); letter-spacing:.02em; }
.overlay-panel p.sub{ font-size:14px; color:var(--text-secondary); margin:0 0 var(--space-4); }
.ctrl-btn.wide{ display:block; width:min(100%, 320px); margin:0 auto var(--space-2); }
.start-rules, .resume-context, .start-link{ margin:0 0 var(--space-3); font-size:13px; color:var(--text-secondary); }
.start-link a{ color:var(--our-team); font-weight:700; }
.mode-row{ display:flex; gap:var(--space-2); justify-content:center; margin:0 0 var(--space-3); }
.mode-row .ctrl-btn{ min-height:48px; min-width:130px; display:flex; flex-direction:column; align-items:center; justify-content:center; line-height:1.2; }
.mode-row .mode-sub{ font-size:12px; font-weight:600; color:var(--text-secondary); }
.mode-row .ctrl-btn[aria-pressed='true']{ border-color:var(--action); box-shadow:0 0 0 2px var(--action); }
.start-more{ display:flex; flex-wrap:wrap; justify-content:center; gap:var(--space-2); margin-top:var(--space-2); }
.start-more .ctrl-btn{ min-height:44px; }
.rules-panel{ text-align:left; }
.rules-panel h2, .rules-panel p.sub{ text-align:center; }
.rules-list{ list-style:none; margin:0 0 var(--space-4); padding:0; }
.rules-list li{ font-size:14px; line-height:1.55; color:var(--text-secondary); padding:var(--space-2) 0; border-bottom:1px solid var(--line-soft); }
.rules-list li strong{ color:var(--text-primary); }
.rules-list li:last-child{ border-bottom:none; }
.rules-list .disclaimer{ font-size:12.5px; color:var(--text-muted); }
.rules-panel > .ctrl-btn, .options-panel > .ctrl-btn{ display:block; margin:var(--space-3) auto 0; min-height:44px; }
.opt-list{ text-align:left; }
.opt-row{ display:flex; align-items:center; justify-content:space-between; gap:var(--space-3); padding:10px 0; border-bottom:1px solid var(--line-soft); min-height:48px; }
.opt-label{ display:flex; flex-direction:column; font-size:14px; font-weight:700; color:var(--text-primary); }
.opt-hint{ font-size:12px; font-weight:500; color:var(--text-muted); }
.opt-row input[type='checkbox']{ width:22px; height:22px; accent-color:var(--action); flex:none; }
.opt-row select{ background:var(--panel); border:1px solid var(--line); border-radius:8px; padding:6px 8px; max-width:55%; min-height:40px; }
.opt-row select option{ color:#1A1F1D; }
.opt-links, .panel-actions{ display:flex; justify-content:center; gap:var(--space-2); margin-top:var(--space-4); flex-wrap:wrap; }
.opt-links .ctrl-btn, .panel-actions .ctrl-btn{ min-height:44px; }
.stats-grid{ display:grid; grid-template-columns:1fr 1fr; gap:6px; text-align:left; }
.stat-cell{ display:flex; flex-direction:column; padding:6px 8px; border-radius:8px; background:var(--panel); }
.stat-label{ font-size:11.5px; color:var(--text-muted); }
.stat-val{ font-family:var(--font-mono); font-weight:800; font-size:16px; }

/* ---------------------------------------------------- phones, upright --- */
@media (max-width:640px) and (min-height:501px), (max-width:900px) and (min-height:901px) and (orientation:portrait){
  :root{ --trick-gap:clamp(8px, 2.6vw, 14px); --trick-gap-x:var(--trick-gap); --seat-gap:clamp(8px, 2.6vw, 16px); --row-gap:clamp(7px, 2.2dvh, 22px); --v-fixed:370px; --hand-k:4.3; --hand-w:clamp(48px, min(15.2vw, calc((100dvh - var(--v-fixed) - var(--lift)) / var(--hand-k))), 72px); --trick-w:calc(var(--hand-w) * 0.84); --gap:6px; --lift:10px; }
  .game{
    grid-template-columns:minmax(0,1fr) auto;
    grid-template-rows:auto minmax(0,1fr) auto auto auto auto;
    grid-template-areas:'header header' 'table table' 'ins ins' 'tip tip' 'hand hand' 'sec act';
    padding-left:max(6px, env(safe-area-inset-left)); padding-right:max(6px, env(safe-area-inset-right));
    row-gap:7px; column-gap:6px;
  }
  .hand-pill{ display:none; }
  /* The title gives way to the score on phones (the site names the game
     above the frame); the score is two short lines. */
  .wordmark{ display:none; }
  .scorebar{ gap:4px; }
  .score-side{ flex-direction:column; align-items:flex-start; gap:0; padding:1px 6px; line-height:1.15; }
  .score-side .score-label{ font-size:10.5px; }
  .score-label .lab-long{ display:none; } .score-label .lab-short{ display:inline; }
  .icon-label .lab-long{ display:none; } .icon-label .lab-short{ display:inline; }  /* 'Tips' / 'Sound' on every phone: the glyph shows on or off */
  /* Three or four separate scores don't fit beside the buttons: on phones
     each player's total is on their own box instead. */
  .scorebar[data-count='3'], .scorebar[data-count='4']{ display:none; }
  @media (max-width:350px){
    .icon-label .lab-long{ display:none; } .icon-label .lab-short{ display:inline; }
    .game .zone-header{ gap:5px; } .zone-header .header-controls{ gap:3px; }
    .zone-header .icon-btn{ padding:2px 1px; } .zone-header .icon-label{ letter-spacing:0; }
    .scorebar{ flex:none; }
    .seat-left .plate, .seat-right .plate{ padding:3px 5px 3px 8px; }
    .seat-left .seat-name, .seat-right .seat-name{ font-size:13px; }
    .scorebar{ display:flex; flex-direction:column; align-items:stretch; gap:0; padding:2px 5px; border-radius:8px; background:var(--plate); border:1px solid var(--line-soft); }
    .score-side{ flex-direction:row; align-items:baseline; justify-content:space-between; gap:5px; padding:0; border:0; background:none; }
    .score-side .score-val{ font-size:12.5px; }
    .score-side .score-label{ font-size:10px; }
  }

  .score-side .score-val{ font-size:14px; }
  .icon-btn{ min-width:44px; padding:2px 3px; }
  .icon-label{ font-size:9px; letter-spacing:.02em; }
  .header-controls{ gap:4px; }
  .backs{ display:none; } .backs-count{ display:none; }
  .mini-pile{ display:block; }
  .plate{ padding:3px 7px; column-gap:6px; }
  .seat-name{ font-size:14px; }
  .seat-bid{ font-size:11.5px; min-width:0; }
  .seat-total{ font-size:14px; }
  .seat-tag{ font-size:10px; padding:0 3px; right:4px; }
  /* Opponents and partner on phones (Hearts 16:10, Ronan 17:05): the name
     on top, the cards under it with the bid beside them; each box only as
     big as what is in it. */
  .seat-top .plate, .seat-left .plate, .seat-right .plate{ grid-auto-flow:row; justify-items:center; row-gap:2px; column-gap:6px; padding:4px 8px 4px 10px; }
  .seat-top .plate{ grid-template-columns:auto auto auto; grid-template-areas:'name name role' 'pile bid total'; }
  /* Theo-style side boxes, narrow: name, role, the card fan, then the bid
     and tricks won on two short lines. */
  .seat-left .plate, .seat-right .plate{ grid-template-columns:auto; grid-template-areas:'name' 'role' 'pile' 'bid' 'total'; row-gap:1px; }
  .seat-left .seat-bid, .seat-right .seat-bid{ display:flex; flex-direction:column; align-items:center; line-height:1.25; }
  .seat-left .seat-bid .bid-dot, .seat-right .seat-bid .bid-dot{ display:none; }
  .seat-top .plate .seat-name, .seat-left .plate .seat-name, .seat-right .plate .seat-name{ grid-area:name; line-height:1.1; }
  .plate .mini-pile{ grid-area:pile; }
  .seat-top .plate .seat-role, .seat-left .plate .seat-role, .seat-right .plate .seat-role{ grid-area:role; font-size:10px; }
  .seat-top .plate .seat-bid, .seat-left .plate .seat-bid, .seat-right .plate .seat-bid{ grid-area:bid; }
  .seat-top .plate .seat-total, .seat-left .plate .seat-total, .seat-right .plate .seat-total{ grid-area:total; }
  .seat-left, .seat-right{ max-width:100%; }
  .seat-left .plate, .seat-right .plate{ max-width:100%; }
  .seat-left .plate .seat-tag, .seat-right .plate .seat-tag{ left:50%; right:auto; transform:translate(-50%, -62%); font-size:9.5px; letter-spacing:0; padding:0 3px; }
  @media (max-width:340px){ .seat-left .plate .seat-tag, .seat-right .plate .seat-tag{ font-size:8.5px; letter-spacing:-.02em; } }
  .trick{ width:calc(var(--trick-w) * 3 + var(--trick-gap-x) * 2); height:calc(var(--trick-h) * 2 + var(--trick-gap)); }
  .game[data-seats='2'] .trick{ width:calc(var(--trick-w) * 3 + var(--trick-gap-x) * 2); }
  .centre-panel{ padding:8px 10px; }
  .result{ min-width:min(92vw, 230px); }
  .centre-panel h2{ font-size:17px; }
  .centre-panel .panel-line{ font-size:12px; margin-bottom:4px; }
  .centre-panel h2{ margin-bottom:2px; }
  .bid-row{ margin:2px 0 4px; }
  .instruction{ width:100%; height:44px; font-size:15px; line-height:1.25; padding:2px var(--space-2); }
  .choice-bar{ width:100%; height:44px; gap:8px; }
  .bid-value{ font-size:26px; }
  .secondary{ justify-self:stretch; gap:6px; }
  .secondary .ctrl-btn{ flex:1 1 0; min-height:44px; min-width:44px; padding:4px 4px; font-size:12px; white-space:nowrap; }
  .action{ justify-self:end; }
  #btnAction{ min-width:min(128px, 34vw); min-height:44px; padding:4px 12px; }
  .tip{ font-size:12px; line-height:16px; height:34px; min-height:34px; white-space:normal; display:flex; align-items:center; justify-content:center; overflow:hidden; }
  .tip:empty{ background:none; }
  .table-stats{ width:100%; padding:3px 6px; gap:0; }
  .state-line{ font-size:12px; line-height:16px; }
  .contract-line{ font-size:11.5px; line-height:15px; }
  .contract-line .sep, .state-line .sep{ margin:0 .3em; }
  @media (max-width:350px){ .contract-line, .state-line{ font-size:11px; letter-spacing:-.01em; } .table-stats{ padding-left:3px; padding-right:3px; } }
  .keys-item{ display:none; }
  .result table{ font-size:12.5px; }
  .result td, .result th{ padding:2px 5px; }
}
@media (min-width:641px) and (max-width:900px) and (min-height:901px) and (orientation:portrait){
  :root{ --hand-w:clamp(56px, min(12vw, calc((100dvh - var(--v-fixed) - var(--lift)) / var(--hand-k))), 96px); --trick-w:calc(var(--hand-w) * 1.1); --gap:14px; --back-step:0.16; }
  .wordmark{ display:flex; }
  .score-side{ flex-direction:row; align-items:baseline; gap:6px; padding:3px 9px; }
  .backs{ display:flex; } .backs-count{ display:block; }
  .mini-pile{ display:none; }
  .seat-name{ font-size:18px; }
  .seat-top .plate, .seat-left .plate, .seat-right .plate{ grid-auto-flow:column; grid-template-areas:none; grid-template-columns:none; padding:5px 10px 5px 12px; column-gap:8px; }
  .game .seat-top .plate > *, .game .seat-left .plate > *, .game .seat-right .plate > *{ grid-area:auto; }
  .instruction{ font-size:16px; }
  .keys-item{ display:list-item; }
}
@media (max-width:640px) and (min-height:501px) and (max-height:620px){
  :root{ --v-fixed:366px; --row-gap:6px; --lift:12px; --hand-w:clamp(37px, min(15.2vw, calc((100dvh - var(--v-fixed) - var(--lift)) / var(--hand-k))), 72px); --trick-w:calc(var(--hand-w) * 0.78); }
  .tip{ height:32px; min-height:32px; }
  .table-stats{ padding:1px 6px; }
  .state-line{ line-height:15px; } .contract-line{ line-height:14px; }
  .game{ row-gap:6px; }
  .zone-header{ min-height:44px; }
  .instruction{ height:44px; font-size:14px; }
  .hand .card .card-centre-suit, .trick .card .card-centre-suit{ display:none; }
}
/* Brief §74/§81: hand cards 48px or more at 320-375 wide. The site's iPhone SE box (504px tall) keeps 40px so nothing scrolls. */
@media (max-width:640px) and (min-height:560px) and (max-height:620px){ :root{ --hand-w:clamp(48px, min(15.2vw, calc((100dvh - var(--v-fixed) - var(--lift)) / var(--hand-k))), 72px); } }
@media (min-width:641px) and (min-height:501px) and (max-height:560px){
  :root{ --lift:12px; --hand-w:clamp(42px, min(7.4vw, calc((100dvh - var(--v-fixed) - var(--lift)) / var(--hand-k))), 100px); }
  .hand .card .card-centre-suit, .trick .card .card-centre-suit{ display:none; }
}

/* --------------------------------------------------- phones, sideways --- */
@media (max-height:500px){
  :root{ --v-fixed:96px; --hand-w:clamp(39px, min(6.4vw, calc((100dvh - var(--v-fixed) - var(--lift)) * 0.245)), 70px); --trick-w:calc(var(--hand-w) * 0.82); --gap:6px; --lift:8px; --trick-gap:8px; --trick-gap-x:8px; --seat-gap:12px; --row-gap:4px; }
  .game{
    grid-template-columns:minmax(0,1fr) clamp(190px, 28vw, 280px);
    grid-template-rows:auto minmax(0,1fr) auto auto auto auto;
    grid-template-areas:'header header' 'table .' 'table ins' 'table act' 'table sec' 'hand hand';
    column-gap:10px; row-gap:5px;
    padding-top:max(4px, env(safe-area-inset-top)); padding-bottom:max(4px, env(safe-area-inset-bottom));
  }
  .tip{ display:none; }
  .zone-header{ min-height:36px; }
  .icon-btn{ min-height:44px; min-width:44px; }
  .hand-pill{ display:none; }
  .scorebar[data-count='3'], .scorebar[data-count='4']{ display:none; }
  .backs{ display:none; } .backs-count{ display:none; }
  .mini-pile{ display:block; }
  .plate{ padding:2px 7px 2px 10px; column-gap:6px; }
  .seat-name{ font-size:13px; } .seat-total{ font-size:13px; } .seat-bid{ font-size:11px; min-width:0; }
  .seat-tag{ font-size:10px; }
  .zone-table{ row-gap:3px; }
  .table-stats{ padding:2px 8px; gap:0; }
  .state-line{ font-size:11.5px; line-height:15px; }
  .contract-line{ font-size:11px; line-height:14px; }
  .instruction{ width:100%; height:56px; font-size:13.5px; }
  .choice-bar{ width:100%; height:56px; gap:6px; }
  .action{ justify-self:stretch; } #btnAction{ width:100%; min-height:44px; }
  .secondary{ justify-self:stretch; gap:5px; } .secondary .ctrl-btn{ flex:1 1 0; min-height:44px; padding:4px 4px; font-size:12px; }
  .keys-item{ display:list-item; }
  .centre-panel{ padding:5px 10px; } .centre-panel h2{ font-size:16px; } .centre-panel .panel-line{ font-size:11.5px; margin-bottom:2px; }
  .result table{ font-size:11.5px; } .result td, .result th{ padding:1px 5px; }
  .result .result-notes{ display:none; }
  .card-centre-suit{ font-size:min(calc(var(--hand-w) * 0.42), calc(var(--hand-w) - 36px)); }
  .slot .card .card-centre-suit{ font-size:min(calc(var(--trick-w) * 0.40), calc(var(--trick-w) - 36px)); }
}

/* ---------------------------------------------------- reduced motion --- */
/* Movement shortened, never removed; the selected card keeps its lift
   (P-06) — only the motion goes. */
/* 2-Player brief §74: hand cards 58px or more at 1050x591. Two seats leave the
   middle of the table free, so the hand may take a larger share of the height. */
@media (min-width:641px) and (min-height:561px) and (orientation:landscape){
  .game[data-seats='2']{
    --hand-w:clamp(58px, min(7.4vw, calc((100dvh - var(--v-fixed) - var(--lift)) / 3.9)), 100px);
    --hand-h:calc(var(--hand-w) / 0.70);
    --trick-w:calc(var(--hand-w) * 0.86); --trick-h:calc(var(--trick-w) / 0.70);
    --back-w:calc(var(--hand-w) * 0.46); --back-h:calc(var(--back-w) / 0.70);
  }
}
/* ------------------------------------------------- brief text floors ---
   Every Spades brief: nothing in the game below 12px, and the text a player
   reads while deciding (instruction, the stats lines, bids, scores) 13px or
   more — on desktop and on phones from 380px wide (the briefs' 390 phone).
   Narrower phones keep the smaller sizes that let everything fit unscrolled. */
@media (min-width:641px) and (min-height:501px){
  html .game .icon-label{ font-size:12px; letter-spacing:.03em; }
  html .game .seat-role, html .game .seat-tag, html .game .seat-bid .nil, html .game .result th, html .game .stat-label{ font-size:12px; }
}
@media (min-width:380px) and (max-width:640px) and (min-height:501px){
  html .game .icon-label, html .game .icon-label .lab-long, html .game .icon-label .lab-short{ font-size:12px; letter-spacing:0; }
  html .game .icon-label .lab-long{ display:none; } html .game .icon-label .lab-short{ display:inline; }  /* 'Tips' / 'Sound': the glyph shows on or off */
  html .game .score-side .score-label{ font-size:12px; }
  html .game .seat-role, html .game .seat-tag, html .game .seat-bid .nil{ font-size:12px; }
  html .game .seat-bid{ font-size:13px; }
  html .game .seat .plate .seat-role{ font-size:12px; }
  html .game .seat .plate .seat-tag{ font-size:12px; }
  html .game .state-line, html .game .contract-line{ font-size:13px; line-height:16px; }
}
/* Tall phones (the briefs' 390x844): the room is there, so the trick cards
   reach the briefs' 58-70px and the main button its 48px. */
@media (max-width:640px) and (min-height:760px){
  :root{ --trick-w:calc(var(--hand-w) * 1.1); --lift:12px; }
  .game[data-seats='2']{ --trick-w:calc(var(--hand-w) * 1.16); --trick-h:calc(var(--trick-w) / 0.70); }
  .game[data-seats='2'] .draft-panel, .game[data-seats='2'] .blind-panel, .game[data-seats='2'] .bid-panel{ left:-20%; right:-20%; }
  html .game .secondary .ctrl-btn, html .game #btnAction{ min-height:48px; }
}
@media (prefers-reduced-motion: reduce){
  :root{ --dur-travel:1ms; --dur-collect:1ms; --dur-lift:1ms; }
  .card, .ctrl-btn, .flying{ transition-duration:1ms !important; animation-duration:1ms !important; }
}
.game[data-reduce-motion='true']{ --dur-travel:1ms; --dur-collect:1ms; --dur-lift:1ms; }
.game[data-reduce-motion='true'] .card, .game[data-reduce-motion='true'] .ctrl-btn{ transition-duration:1ms !important; animation-duration:1ms !important; }

/* ---- R4 (Ronan 2026-10-11): no pale type — under 16px at 7:1 against what is drawn behind it,
   semi-bold. Small print on the felt sits on the dark plate (it holds on all three felts). ---- */
.hand-pill, .backs-count{ background:var(--plate-strong); border-radius:4px; padding:0 4px; color:var(--text-primary); }
.overlay-panel p.sub, .start-rules, .resume-context, .start-link, .centre-panel .panel-line, .contract-line{ font-weight:600; }
.overlay-panel p.sub, .start-rules, .resume-context, .start-link{ color:var(--text-primary); }
.start-link a{ color:#A9DCFF; }
/* the header and score labels keep the 12px floor on phones too (measured to fit inside their
   buttons at 330); the start screen's subtitle and link reach 7:1 on its panel */
.icon-label, .score-side .score-label{ font-size:12px !important; }
.overlay-panel p.sub{ color:#FFFFFF; }
.start-link a{ color:#C9EAFF; }
/* R4 decisions (Ronan 13:46): (1) phones — seat-plate text at the 12px floor; the side seats' TURN tag
   sits just above its plate (measured clear at 330, 363 and the SE); (2) the start panel a shade
   darker so its subtitle and link reach 7:1 */
html body .seat-role, html body .seat-tag, html body .bid-b, html body .bid-w, html body .plate .nil{ font-size:12px !important; letter-spacing:0 !important; }
/* SF1 (Ronan 2026-10-16): the contract line is essential gameplay text — 13px at every size (fits every state at 330 with 43px spare) */
html body .contract-line{ font-size:13px !important; letter-spacing:0 !important; }
@media (max-width:679px){ html body .seat-left .plate .seat-tag, html body .seat-right .plate .seat-tag{ transform:translate(-50%, calc(-100% - 2px)) !important; } }
#startOverlay .overlay-panel{ background:linear-gradient(rgba(0,0,0,.25), rgba(0,0,0,.25)), linear-gradient(180deg, var(--table-highlight), var(--table-deep)); }

/* ---- R5b (Ronan 2026-10-11 15:16): Coach replaces Tips ---- */
.coach-choice{ display:flex; flex-direction:column; gap:var(--space-2, 8px); margin:0 0 var(--space-3, 12px); }
.coach-choice .ctrl-btn{ display:flex; flex-direction:column; align-items:center; gap:2px; line-height:1.2; }
.coach-choice .btn-sub{ display:block; font-size:12.5px; font-weight:600; opacity:1; text-transform:none; letter-spacing:0; }
.coach-choice .ctrl-btn.is-chosen{ box-shadow:0 0 0 2px var(--action, #F0B84B); }
/* phones: "Coach" over "on"/"off", inside the usual 44px button (measured at 330, 363, SE, sideways) */
.coach-two .cw, .coach-two .cs{ display:block; line-height:12px; }
@media (max-width:679px), (max-height:480px){
  html body #btnCoach{ gap:0 !important; padding-top:2px !important; padding-bottom:2px !important; }
  html body #btnCoach .icon-glyph{ font-size:13px !important; line-height:13px !important; }
  html body #btnCoach .icon-label{ line-height:12px !important; }
}
/* the phone header at 351-399px: with the readable 12px labels it ran 10px past the edge at 360/363
   (4-player games). Tighter button padding and gaps only — the same look, nothing moved or hidden. */
@media (min-width:351px) and (max-width:399px){
  .zone-header .header-controls{ gap:3px; }
  .zone-header .icon-btn{ padding-left:1px; padding-right:1px; }
  .zone-header .icon-label{ letter-spacing:0; }
}

/* ---- 400x686 band (Ronan 2026-10-16, SF3 "A"): the large phone frame (376-640 wide, 621-759 high) gets the
   brief's phone sizes — the selected card lifts 12px; centre cards 58-70px (two-seat table 68-82px); the
   two-seat Keep 48px high. Measured at 400x686 against every layout state. ---- */
@media (min-width:376px) and (max-width:640px) and (min-height:621px) and (max-height:759px){
  :root{ --lift:12px; --trick-w:calc(var(--hand-w) * 0.97); }
  .game[data-seats='2']{ --trick-w:68px; }
  .game[data-seats='2'] .draft-panel{ left:-20%; right:-20%; }  /* the draft panel hangs off the wider trick zone: same width as before (313px), on the screen */
  .game[data-seats='2'] #btnAction{ min-height:48px; }
}

/* ---- SF2 (Ronan 2026-10-16, "A"): at desktop heights 651-760 (the site's 1254x700 frame) the table's rows ran 4px
   past the felt, so your plate hung below the table edge. The rows close up to 8px there, the smallest the desktop scale uses (12.25px before). ---- */
@media (min-width:1050px) and (min-height:651px) and (max-height:760px){
  .zone-table{ row-gap:8px; }
}

/* ---- P2 (2026-10-16): at 330 the West tag ("TAKES IT", 63px) centred over its 49px plate ran off the left edge of the
   screen. On phones up to 350 wide the side tags line up with the plate's outer edge instead, so they stay on screen. ---- */
@media (max-width:350px){
  html body .seat-left .plate .seat-tag{ left:0 !important; right:auto !important; transform:translate(0, calc(-100% - 2px)) !important; }
  html body .seat-right .plate .seat-tag{ left:auto !important; right:0 !important; transform:translate(0, calc(-100% - 2px)) !important; }
}
