/* RUMMY FAMILY — shared stylesheet (rebuild after the 2026-10-03 audit).
 *
 * One file for Gin Rummy, Oklahoma Gin Rummy, Rummy 500 and Canasta Rummy
 * (decision D2, the shared kit). The master copy is kit/rummy/; each game
 * carries a byte-identical copy (kit/rummy/build.js --check).
 *
 * Decisions: briefs/rummy-family-decisions.md. Briefs: briefs/gin-rummy.md,
 * oklahoma-gin.md, rummy-500.md, canasta-rummy.md.
 *
 * THE SHARED DNA (category-colour-system.md): card faces, court art, backs,
 * the gold action, type, buttons, plates, focus states and overlays are the
 * catalogue's (the Hearts / Spades shell). The rummy family's identity is
 * the felt: C Heather (D12, Ronan 2026-10-03 06:56).
 *
 * Seats: You (0, bottom); 1 left, 2 top, 3 right. Gin and Oklahoma use 2;
 * Rummy 500 uses 2 (two players), 1 and 3 (three) or all three (four);
 * Canasta uses all three (partner Kit at 2).
 *
 * Desktop: the opponents along the top, the felt (their side · the piles ·
 * your side), the stats, then the instruction and buttons, then the hand.
 * Phones: each game's own order from its brief (see the phone section).
 */

*,*::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{
  /* --- Rummy-family felt (D12): C Heather, brightened to B2 (Ronan
     2026-10-03 07:53). The highlight is held a little under B2's so text
     on the open felt keeps 4.5:1 at the brightest point. --- */
  --table-bg:#665984;
  --table-deep:#4D4364;
  --table-highlight:#6A5D8A;
  --plate:rgba(22,16,36,.58);
  --plate-strong:rgba(22,16,36,.90);
  --result-bg:#2E2740;
  --zone:rgba(22,16,36,.26);
  --text-secondary:#EEEAF6;
  --text-muted:#E2DCEF;

  /* --- Side accents (gold is for actions only). --- */
  --our-team:#62C4FF;
  --their-team:#FFB98A;

  /* --- 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:#FF8A8A;
  --suit-blue-on-dark:#8CC2FF;
  --suit-green-on-dark:#7FE0A0;
  --card-blue:#2563B8;
  --card-green:#1E7A45;

  --line:rgba(255,255,255,.20);
  --line-soft:rgba(255,255,255,.11);
  --panel:rgba(0,0,0,.26);

  --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). Gin brief: your cards 76–86px at 1200×675,
     65–75 at 1050×591; stock and discard about the same; the opponent's
     backs 38–48 (32–42 on a laptop). The hand card follows the window's
     height and width; everything else is a share of it. */
  --hand-w:clamp(52px, min(6.9vw, 11.4dvh), 86px);
  --hand-w2:calc(var(--hand-w) * .80);            /* a hand in two rows */
  --pile-w:var(--hand-w);
  --meld-w:clamp(40px, calc(var(--hand-w) * .58), 50px);
  --meld-step:clamp(14px, calc(var(--meld-w) * .36), 18px);
  --mini-w:clamp(36px, calc(var(--hand-w) * .46), 40px);
  --back-w:clamp(30px, calc(var(--hand-w) * .39), 32px);
  --lift:14px;
  --group-gap:22px;                               /* Gin brief: 18–26px between melds */
  --min-strip:30px;                               /* each overlapped card shows at least this much */
  --max-step:.76;                                 /* …and at most this share of its width (cards stay connected) */
  --row-gap:clamp(6px, 1.6dvh, 18px);
  --seat-gap:clamp(12px, 2.4vw, 40px);

  --dur-travel:300ms;
  --dur-lift:120ms;
}
/* One opponent (Gin, Oklahoma, two-player Rummy 500): the opponent's
   hidden hand is drawn larger (Gin brief §12). */
.game[data-opponents='1']{ --back-w:clamp(32px, calc(var(--hand-w) * .52), 46px); }
/* Canasta brief §8/§15: four seats and two meld areas share 675px, so the
   hand card sits at 68–80px (gin's is 76–86) and the boxes are tighter. */
.game[data-game='canasta']{ --hand-w:clamp(52px, min(6.2vw, 10.4dvh), 78px); }
.game[data-game='canasta'] .plate{ padding:4px 12px 5px; row-gap:3px; }
@media (min-width:641px) and (min-height:621px){
  .game[data-game='canasta']{ row-gap:5px; --row-gap:8px; --lift:10px; }
  .game[data-game='canasta'] .zone-header{ padding-bottom:2px; }
}
/* Gin brief §7 (1200×675): the human area 250–290px and the status zone
   50–70px. Shorter desktops (1366×625) keep the felt's room instead. */
@media (min-width:641px) and (min-height:650px){
  .game[data-game='gin'] .hand-zone, .game[data-game='oklahoma'] .hand-zone{ padding-top:22px; }
  .table-stats{ min-height:55px; }
}
/* Gin brief §23: the hand 760–900px wide. */
.game[data-game='gin'] .hand, .game[data-game='oklahoma'] .hand{ max-width:900px; }

/* ------------------------------------------------------------- shell --- */
.game{
  position:relative;
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  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';
  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);
}
/* Coach off ("Just the table"): no tip row, so the cards get the room. */
.game[data-coach='off'] .tip{ display:none; }

/* ------------------------------------------------------------ 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:44px;
}
.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); }
/* Every score box the same size (Ronan 2026-10-02 21:39). Gin brief: the
   score 16–18px. */
.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; }
.score-side{ display:flex; align-items:baseline; justify-content:center; gap:7px; padding:3px 10px; border-radius:8px; background:var(--plate); border:1px solid var(--line-soft); }
.score-side .score-label{ font-family:var(--font-ui); font-size:13px; font-weight:700; color:var(--text-secondary); }
.score-side .score-val{ font-size:17px; font-weight:800; }
.score-side.is-us, .score-side.is-you{ border-color:color-mix(in srgb, var(--our-team) 55%, transparent); }
.score-side.is-us .score-label, .score-side.is-you .score-label{ color:var(--our-team); }
.score-side.is-them .score-label{ color:var(--their-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:16px; }
@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:12px; font-weight:700; letter-spacing:.03em; text-transform:uppercase; white-space:nowrap; }
.icon-label .lab-short{ display:none; }
.icon-glyph.is-off{ opacity:.4; filter:grayscale(1); }
#btnCoach[aria-pressed='true']{ border-color:color-mix(in srgb, var(--active) 60%, transparent); }

/* ------------------------------------------------------------- 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 minmax(0,1fr) auto;
  grid-template-areas:
    'seats seats  seats'
    'feed  feed   feed'
    'left  centre right'
    'stats stats  stats';
  column-gap:var(--seat-gap); row-gap:var(--row-gap);
  align-items:center;
}
.seats{ grid-area:seats; display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr); column-gap:var(--seat-gap); align-items:start; }
#seat-1{ grid-column:1; justify-self:center; }
#seat-2{ grid-column:2; justify-self:center; }
#seat-3{ grid-column:3; justify-self:center; }
.centre{ grid-area:centre; display:flex; flex-direction:column; align-items:center; gap:6px; align-self:center; min-width:0; }
.pane-left{ grid-area:left; }
.pane-right{ grid-area:right; }
.table-stats{ grid-area:stats; }
.feed-line{ grid-area:feed; text-align:center; }

/* ------------------------------------------------------------- seats --- */
/* One box per opponent (and Canasta's partner): name, role, the hidden hand
   with its count in words, the running total; under it, what they last did,
   in words, until their next move replaces it (pace rule). */
.seat{ position:relative; display:flex; flex-direction:column; align-items:center; gap:4px; min-width:0; }
.plate{
  position:relative;
  display:grid; align-items:center; justify-items:center;
  grid-template-columns:auto auto auto auto;
  grid-template-areas:'name role count total' 'pile pile pile pile';
  column-gap:8px; row-gap:5px; min-width:0;
  padding:6px 12px 7px; border-radius:var(--radius);
  background:var(--plate); border:1px solid var(--line-soft);
  white-space:nowrap;
}
.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{ grid-area:name; font-family:var(--font-display); font-weight:800; font-size:clamp(16px,1.5vw,19px); letter-spacing:.02em; }
.seat-role{ grid-area:role; font-family:var(--font-ui); font-size:12px; font-weight:800; letter-spacing:.03em; color:var(--our-team); }
.seat-role:empty{ display:none; }
.seat-count{ grid-area:count; font-family:var(--font-mono); font-weight:700; font-size:13px; color:var(--text-secondary); }
.seat-total{ grid-area:total; font-family:var(--font-mono); font-weight:800; font-size:16px; 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:12px; line-height:15px; letter-spacing:.03em;
  color:#0B2233; background:var(--active); padding:1px 5px; border-radius:4px;
}
.seat-tag.is-on{ visibility:visible; }
.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 hidden hand: up to 11 backs in a fan of fixed width, so the box never
   shifts as the count changes (the exact count is in words). */
.mini-pile{ grid-area:pile; position:relative; display:block; width:calc(var(--back-w) * 3.4); height:calc(var(--back-w) / .70); }
.mini-pile .card-back{ position:absolute; top:0; width:var(--back-w); height:100%; left:calc((var(--back-w) * 2.4) * var(--i, 0) / (var(--n, 2) - 1)); border-radius:4px; }
.seat-act{
  font-size:13px; font-weight:600; line-height:17px; height:17px; color:var(--text-secondary);
  max-width:min(34ch, 30vw); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-align:center;
}
.seat-act.is-fresh{ color:var(--text-primary); }
.game[data-opponents='1'] .seat-act{ max-width:46ch; }

/* ------------------------------------------------------------- panes --- */
/* Their side (left) and your side (right): melds as cards, Ruby's taken
   cards, or Oklahoma's condition card. Spacing shows the structure before
   any boxes do (Gin brief §27). */
.pane{
  align-self:stretch; min-width:0; min-height:0;
  display:flex; flex-direction:column; gap:5px;
  padding:6px 10px 8px; border-radius:var(--radius);
  background:var(--zone); border:1px solid var(--line-soft);
  overflow:hidden;
}
.pane-left{ justify-self:end; width:min(100%, 470px); }
.pane-right{ justify-self:start; width:min(100%, 470px); }
.pane[data-kind='taken'], .pane[data-kind='condition']{ align-self:center; width:auto; max-width:min(100%, 320px); }
.pane-head{ display:flex; align-items:center; gap:8px; min-width:0; }
.pane-head .pane-sub{ margin-left:auto; }
.pane-title{ font-size:13px; font-weight:800; color:var(--text-primary); white-space:nowrap; }
.pane-sub{ font-family:var(--font-mono); font-size:12px; font-weight:700; color:var(--text-muted); white-space:nowrap; }
.pane-chips{ display:flex; flex-wrap:nowrap; gap:4px; min-width:0; overflow:hidden; }
.chip{ display:inline-flex; align-items:center; gap:4px; font-size:13px; font-weight:700; line-height:18px; padding:0 7px; border-radius:9px; background:var(--plate); border:1px solid var(--line-soft); color:var(--text-secondary); white-space:nowrap; }
.chip.is-good{ border-color:color-mix(in srgb, var(--success) 60%, transparent); color:#BDF0D0; }
.chip.is-warn{ border-color:#FFD27A; color:#FFE3A8; }
.chip.is-bad{ border-color:var(--danger); color:#FFC2C6; }
.chip.is-ice{ border-color:#9FD3FF; color:#CFE9FF; }
.pane-body{ min-height:0; display:flex; flex-direction:column; gap:4px; }
.pane-empty{ margin:0; font-size:13px; color:var(--text-muted); }
.pane-line, .condition-line{ margin:0; font-size:13px; line-height:1.35; color:var(--text-secondary); }
.condition-line strong{ color:var(--text-primary); }

.meld-list{ display:flex; flex-wrap:wrap; align-content:flex-start; gap:6px 14px; }
.meld{ display:flex; flex-direction:column; gap:2px; min-width:0; border-radius:8px; }
.meld-head{ display:flex; gap:6px; align-items:baseline; font-size:12px; line-height:15px; white-space:nowrap; }
.meld-label{ font-weight:700; color:var(--text-secondary); }
.meld-note{ font-family:var(--font-mono); font-weight:700; color:var(--text-muted); }
.meld-cards{ display:flex; }
.card.meld-card{ width:var(--meld-w); }
.card.meld-card + .card.meld-card{ margin-left:calc(var(--meld-step) - var(--meld-w)); }
.meld.is-target{ cursor:pointer; outline:2px dashed var(--active); outline-offset:3px; }
.meld.is-target:focus-visible{ outline-style:solid; }
.meld.is-fresh .meld-cards{ filter:drop-shadow(0 0 6px rgba(255,255,255,.55)); }
/* A canasta (seven or more): squared up, the count in the label, a ring that
   says natural (red) or mixed (white). */
.meld.is-canasta .card.meld-card + .card.meld-card{ margin-left:calc(5px - var(--meld-w)); }
.meld.is-canasta .meld-cards{ border-radius:7px; }
.meld-cards{ position:relative; }
/* Press and hold to arrange: no native image drag, no text selection, no browser panning on the cards. */
#hand .hand-card{ -webkit-user-select:none; user-select:none; -webkit-user-drag:none; touch-action:none; }
#hand .hand-card img, #hand .hand-card svg{ -webkit-user-drag:none; pointer-events:none; }
.meld-count{ display:none; }
/* Stacked (a crowded phone box): one rank card per meld, its count on the foot. */
.pane.is-stacked .meld-cards .card:not(.is-face){ display:none; }
.pane.is-stacked .meld-cards .card.is-face{ margin-left:0 !important; }
.pane.is-stacked .meld-count{ display:block; position:absolute; right:-3px; bottom:-3px; z-index:2; min-width:20px; padding:0 3px; border-radius:6px; background:var(--plate-strong); color:var(--text-primary); font:700 12px/16px var(--font-ui, inherit); text-align:center; }
.meld.is-canasta.is-natural .meld-cards{ box-shadow:0 0 0 2px var(--suit-red-on-dark); }
.meld.is-canasta.is-mixed .meld-cards{ box-shadow:0 0 0 2px var(--text-primary); }
.taken-cards{ display:flex; flex-wrap:wrap; gap:4px; }
.condition-card{ display:flex; justify-content:center; flex:none; }
.pane[data-kind='condition'] .pane-body{ flex-direction:row; align-items:center; gap:10px; }
.pane[data-kind='condition'] .condition-line{ max-width:20ch; }
.condition-card .card.meld-card{ width:calc(var(--meld-w) * 1.2); }

/* ------------------------------------------------------------- piles --- */
.piles{ display:flex; align-items:flex-start; justify-content:center; gap:clamp(14px, 2vw, 26px); }
.pile{ position:relative; width:var(--pile-w); height:calc(var(--pile-w) / .70 + 20px); border-radius:8px; outline:none; }
.pile .pile-card{ position:absolute; left:0; top:0; width:var(--pile-w); height:calc(var(--pile-w) / .70); }
.pile .card-back.pile-card{ border-radius:8px; border-width:2px; }
.pile .pile-under{ transform:rotate(-4deg) translate(-3px, 1px); filter:brightness(.92); }
.pile-empty{
  position:absolute; left:0; top:0; width:var(--pile-w); height:calc(var(--pile-w) / .70);
  display:flex; align-items:center; justify-content:center; text-align:center;
  border:2px dashed var(--line); border-radius:8px; font-size:12px; font-weight:700; color:var(--text-muted);
}
.pile-label{
  position:absolute; left:-14px; right:-14px; bottom:0; height:17px; line-height:17px;
  text-align:center; white-space:nowrap; font-size:12px; font-weight:700; color:var(--text-secondary);
}
.pile-count{ font-family:var(--font-mono); font-weight:800; color:var(--text-primary); }
.pile.is-active{ cursor:pointer; }
.pile.is-active .pile-card:last-of-type, .pile.is-active .pile-top{ box-shadow:0 0 0 3px var(--active), 0 8px 18px rgba(0,0,0,.45); }
.pile.is-active:focus-visible{ outline:3px solid var(--active); outline-offset:3px; }
.pile.is-frozen .pile-top{ box-shadow:0 0 0 3px #9FD3FF, 0 8px 18px rgba(0,0,0,.45); }
.pile.is-closed{ opacity:.7; }
/* Rummy 500: the whole discard pile spread out, oldest first; the fan keeps
   inside its share of the table whatever its length. */
.pile.discard.is-fan{ width:auto; min-width:var(--pile-w); --fan-max:min(380px, 27vw); }
.fan{ display:flex; height:calc(var(--pile-w) / .70); }
.fan .fan-card{ position:relative; flex:none; width:var(--pile-w); height:calc(var(--pile-w) / .70); }
.fan .fan-card + .fan-card{ margin-left:calc(clamp(14px, (var(--fan-max) - var(--pile-w)) / max(var(--fan-n) - 1, 1), 30px) - var(--pile-w)); }
.fan .fan-card.is-chosen{ transform:translateY(-8px); box-shadow:0 0 0 3px var(--action), 0 10px 20px rgba(0,0,0,.45); z-index:2; }
.fan .fan-card.is-swept{ transform:translateY(-8px); box-shadow:0 0 0 2px color-mix(in srgb, var(--action) 60%, transparent); }
.pile.is-active .fan-card{ cursor:pointer; }
.pile-info{ display:flex; flex-wrap:wrap; justify-content:center; gap:4px; max-width:min(100%, 380px); }
.pile-info:empty{ display:none; }

/* ------------------------------------------------- panels on the felt --- */
/* A big moment held before any result, Rummy 500's pile picker, and the
   hand and game results: on the felt in the piles' place, never a modal. */
.felt-panel{
  grid-row:3; grid-column:1 / -1; justify-self:center; align-self:center; z-index:5;
  width:max-content; max-width:min(94%, 640px); min-width:min(90%, 280px);
  padding:12px 18px; 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;
}
.felt-panel.result{ grid-row:1 / -1; align-self:center; }
.felt-panel h2{ margin:0 0 4px; font-family:var(--font-display); font-weight:800; font-size:clamp(20px,2.2vw,26px); color:var(--action); }
.felt-panel .panel-line{ margin:0 0 6px; font-size:14px; line-height:1.35; color:var(--text-secondary); }
.felt-panel .panel-line strong{ color:var(--text-primary); }
.moment{ cursor:pointer; }
.moment[data-kind='gin'] h2, .moment[data-kind='canasta'] h2{ font-size:clamp(26px,3vw,34px); }
.moment-melds{ justify-content:center; margin-top:6px; }
.moment-cards, .picker-cards{ display:flex; justify-content:center; gap:6px; margin-top:6px; flex-wrap:wrap; }
.moment-skip{ margin:6px 0 0; font-size:12px; color:var(--text-muted); }
.picker-cards .meld-card{ cursor:pointer; }
.picker-cards .meld-card.is-chosen{ transform:translateY(-6px); box-shadow:0 0 0 3px var(--action), 0 10px 20px rgba(0,0,0,.45); }
.picker-cards .meld-card.is-swept{ transform:translateY(-6px); box-shadow:0 0 0 2px color-mix(in srgb, var(--action) 60%, transparent); }
.game.has-felt-panel .centre, .game.has-felt-panel .pane{ visibility:hidden; }
/* Between hands the result takes the room the hand had (the hand is not
   needed until the next deal). */
.game.has-result .hand-zone, .game.has-result .tip{ display:none; }
.game.has-felt-panel .felt-panel.moment ~ .table-stats{ visibility:visible; }

.result .result-sub{ margin:0 0 8px; font-size:14px; font-weight:600; color:var(--text-secondary); }
.result-side{ margin:0 0 8px; text-align:left; }
.result-side-head{ font-size:13px; font-weight:800; margin:0 0 3px; }
.result-side .meld-list{ gap:4px 14px; }
.result-side .card.mini{ width:var(--mini-w); }
.result-side .card.mini + .card.mini{ margin-left:calc(16px - var(--mini-w)); }
.result table{ border-collapse:collapse; margin:0 auto; font-family:var(--font-mono); font-size:14px; }
.result th{ font-family:var(--font-ui); font-size:12px; font-weight:700; color:var(--text-muted); padding:2px 9px; text-align:right; }
.result th:first-child, .result td:first-child{ text-align:left; }
.result td{ padding:3px 9px; 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, .result th.is-you{ 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:13px; line-height:1.4; color:var(--text-secondary); text-align:left; max-width:44ch; }
.result .result-notes li{ margin-top:3px; }
.result .result-next{ margin:8px 0 0; font-size:14px; font-weight:700; color:var(--text-primary); }

/* The choice bar: Rummy 500's player count, Canasta's "Partner, may I go
   out?", the up-card's Take / Pass; in the instruction's place. */
.choice-bar{ grid-area:ins; display:flex; align-items:center; justify-content:center; gap:10px; height:48px; width:100%; max-width:640px; justify-self:center; }
.game[data-choices='yes'] .instruction{ display:none; }
.choice-btn{ min-height:44px; padding:6px 16px; white-space:nowrap; }
.choice-btn.is-primary{ background:var(--action); color:var(--action-text); border-color:var(--action); font-weight:800; }
.choice-bar .ctrl-btn[aria-pressed='true']{ border-color:var(--action); box-shadow:0 0 0 2px var(--action); }

/* ------------------------------------------------- state / instruction --- */
.table-stats{
  justify-self:center; width:min(100%, 640px); justify-content:center;   /* briefs: status zone 50–75px (min-height at ≥650 high) */
  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, .feed-line{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; width:100%; }
.feed-line{ max-width:640px; justify-self:center; }
.state-line{ font-size:14px; font-weight:600; line-height:18px; color:var(--text-secondary); }
.contract-line{ font-size:14px; font-weight:600; line-height:18px; color:var(--text-secondary); }
.contract-line:empty{ display:none; }
.feed-line{ display:none; font-size:13px; font-weight:600; line-height:17px; color:var(--text-primary); }
.state-line .sep, .contract-line .sep{ opacity:.55; margin:0 .45em; }
.state-line .hot, .contract-line .hot{ color:var(--text-primary); font-weight:800; }
.contract-line .is-good{ color:#9BE8B8; font-weight:700; }
.contract-line .is-warn, .state-line .is-warn{ color:#FFD27A; font-weight:700; }
.contract-line .is-bad, .state-line .is-bad{ color:#FFB4B4; font-weight:700; }
.contract-line .is-ice, .state-line .is-ice{ color:#BFE3FF; 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); }
/* Suit symbols on a gold surface (Take, the primary choice buttons, flag tags): ink for gold, not for the felt.
   A white club on the gold Take button was 1.67:1 (contrast sweep, 2026-10-16). */
.ctrl-btn.primary .sym-S, .ctrl-btn.primary .sym-C, .choice-btn.is-primary .sym-S, .choice-btn.is-primary .sym-C, .seat-tag.is-flag .sym-S, .seat-tag.is-flag .sym-C{ color:var(--action-text); }
.ctrl-btn.primary .sym-H, .ctrl-btn.primary .sym-D, .choice-btn.is-primary .sym-H, .choice-btn.is-primary .sym-D, .seat-tag.is-flag .sym-H, .seat-tag.is-flag .sym-D{ color:#8E1B28; }
.game[data-four-colour='true'] .ctrl-btn.primary .sym-D, .game[data-four-colour='true'] .choice-btn.is-primary .sym-D, .game[data-four-colour='true'] .seat-tag.is-flag .sym-D{ color:#123F8C; }
.game[data-four-colour='true'] .ctrl-btn.primary .sym-C, .game[data-four-colour='true'] .choice-btn.is-primary .sym-C, .game[data-four-colour='true'] .seat-tag.is-flag .sym-C{ color:#1B5E2A; }
.cardname{ white-space:nowrap; }

.instruction{
  grid-area:ins;
  font-family:var(--font-ui); font-weight:700;
  font-size:clamp(15px,1.5vw,18px);
  text-align:center; height:48px; width:100%; max-width:640px; justify-self:center; 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:44px; padding:6px 12px; font-size:13px; white-space:nowrap; }
.action{ grid-area:act; justify-self:start; display:flex; align-items:center; }
#btnAction{ min-width:150px; white-space:nowrap; }
.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); }
.tip-text{ display:block; }

/* --------------------------------------------------------------- hand --- */
/* Groups sit apart (melds, near-melds with Coach, the rest); the cards in a
   group overlap. The label under each group says what it is; under the
   loose cards it is the deadwood (always shown: it is your own count). */
.hand-zone{ grid-area:hand; min-width:0; }
.hand{ display:flex; flex-direction:column; align-items:center; gap:2px; width:100%; max-width:950px; margin:0 auto; padding-top:var(--lift); }
/* A two-row hand: the second row tucks over the foot of the first, as cards
   held in two rows do; every corner index stays in view. The first row's
   labels would sit under it, so they give way. */
.hand[data-rows='2']{ gap:0; }
.hand[data-rows='2'] .hrow + .hrow{ margin-top:calc(var(--hand-w2) / .70 * -.44 - 21px); position:relative; z-index:1; }
.hand[data-rows='2'] .hrow:first-child .hgroup-label{ visibility:hidden; }
.hrow{ display:flex; justify-content:center; align-items:flex-start; gap:var(--group-gap); max-width:100%; }
.hgroup{ display:flex; flex-direction:column; align-items:flex-start; min-width:0; }
.hgroup-cards{ display:flex; padding-bottom:4px; border-bottom:3px solid transparent; }
.hgroup.is-meld .hgroup-cards{ border-bottom-color:color-mix(in srgb, var(--success) 75%, transparent); }
.hgroup.is-near .hgroup-cards{ border-bottom:3px dashed color-mix(in srgb, var(--text-muted) 80%, transparent); }
/* The label may run into the gap after its group, never further (checked);
   it never widens the group. */
.hgroup-label{ display:flex; gap:6px; align-items:baseline; height:17px; line-height:17px; font-size:12px; white-space:nowrap; width:0; min-width:100%; overflow:visible; padding-left:2px; }
.hgroup:last-child .hgroup-label{ justify-content:flex-end; padding-left:0; padding-right:2px; }  /* the last label runs left, not off the edge */
.hg-text{ font-weight:700; color:var(--text-secondary); }
.hgroup.is-meld .hg-text{ color:#BDF0D0; }
.hgroup.is-loose .hg-text{ color:var(--text-primary); font-weight:800; font-size:13px; }
.hg-note{ font-family:var(--font-mono); font-weight:700; color:var(--text-muted); }
.hand .hand-card{ width:var(--hand-w); cursor:pointer; transition:transform var(--dur-lift) ease, box-shadow var(--dur-lift) ease, filter .12s ease; }
.hand[data-rows='2'] .hand-card{ width:var(--hand-w2); }
.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-picked{ transform:translateY(calc(var(--lift) * -.6)); box-shadow:0 0 0 3px var(--active), 0 10px 20px rgba(0,0,0,.45); }
.hand .card.is-new{ box-shadow:0 0 0 3px var(--text-primary), 0 8px 18px rgba(0,0,0,.45); }
/* A card you just drew or took: a white ring and a bar along its top edge,
   which shows however tightly the hand is overlapped. */
.hand .card.is-new::after{ content:''; position:absolute; left:0; right:0; top:0; height:5px; z-index:3; background:var(--active); }
.hand .card.is-target{ box-shadow:0 0 0 2px var(--active), 0 5px 12px rgba(0,0,0,.42); }
.hand .card.is-required{ box-shadow:0 0 0 3px var(--action), 0 5px 12px rgba(0,0,0,.42); }
.hand .card.is-required::after{ content:'Must use'; position:absolute; left:3px; bottom:22px; z-index:3; font:800 12px/14px var(--font-ui); padding:0 4px; border-radius:4px; background:var(--action); color:var(--action-text); white-space:nowrap; }
.hand .card.is-dim{ filter:brightness(.62) saturate(.6); }
.hand .card.kb-focus, .hand .card:focus-visible{ outline:3px solid var(--active); outline-offset:2px; }
.game[data-large-cards='true'] .hand .card .card-corner{ font-size:clamp(16px, calc(var(--hand-w) * .26), 28px); }
.hand.is-crowded .card .card-corner{ letter-spacing:-.04em; }
.hand.is-crowded .card .card-corner-top{ left:3px; top:4px; }

/* -------------------------------------------------------------- card --- */
.card{
  position:relative; flex:none; display:block;
  width:var(--hand-w); aspect-ratio:.70; height:auto; 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;
  container-type:inline-size;
}
.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(12px, 20cqi, 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; inset:0; display:flex; align-items:center; justify-content:center; font-size:max(14px, calc(46cqi - 8px)); opacity:1; }   /* full strength: a red suit at .9 was 4.26:1 (2026-10-16) */
/* Small cards (melds, Ruby's taken cards): the corner index only, at a
   size that still reads; no centre pip, no court figure, no bottom corner. */
.card.mini, .card.meld-card{ border-radius:6px; }
.card.mini .card-corner, .card.meld-card .card-corner{ font-size:clamp(12px, 30cqi, 16px); top:3px; left:4px; }
.card.mini .card-corner-bottom, .card.meld-card .card-corner-bottom,
.card.mini .court-figure, .card.mini .card-centre-suit{ display:none; }
.card.meld-card .card-centre-suit{ top:30%; font-size:clamp(14px, 40cqi, 22px); }
.card.meld-card .court-figure{ top:62%; width:64%; height:46%; }
.card.mini{ width:var(--mini-w); }
.card.pile-card, .card.fan-card{ width:var(--pile-w); }
.condition-card .card-corner-bottom{ display:block; }
/* Sizes of the small cards (after .card, so they win). */
.meld-cards .card.meld-card, .moment .card.meld-card, .picker-cards .card.meld-card{ width:var(--meld-w); }
.condition-card .card.meld-card{ width:calc(var(--meld-w) * 1.2); }
.taken-cards .card.mini, .result-side .card.mini{ width:var(--mini-w); }
.moment-cards .card.meld-card, .picker-cards .card.meld-card{ width:calc(var(--meld-w) * 1.25); }
/* Joker: the word down the corner, the art in the middle. */
.card.joker{ color:#5B2A86; }
.card.joker .joker-corner{ font-size:clamp(12px, 15cqi, 16px); letter-spacing:0; line-height:1.0; font-weight:800; }
.card.joker svg{ position:absolute; z-index:1; left:50%; top:54%; transform:translate(-50%,-50%); width:62%; height:auto; }
.card.mini.joker svg{ display:none; }

.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; inset:0; z-index:40;
  display:none; align-items:center; justify-content:center;
  background:rgba(14,10,22,.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%, 340px); margin:0 auto var(--space-2); }
/* Start: Coach chosen every time (Ronan 2026-10-03), the remembered choice
   marked; each button says what it means. */
.coach-choice{ display:flex; flex-direction:column; align-items:center; gap:var(--space-2); margin:0 0 var(--space-3); }
.coach-choice .ctrl-btn{ margin:0; display:flex; flex-direction:column; align-items:center; line-height:1.25; padding:9px 16px; }
.coach-choice .btn-sub{ display:block; font-size:12.5px; font-weight:600; opacity:.85; }
.coach-choice .ctrl-btn.is-remembered:not(.primary){ border-color:var(--active); }
.start-rules, .resume-context, .start-link{ margin:0 0 var(--space-3); font-size:13px; color:var(--text-secondary); }
.mode-row{ display:flex; gap:var(--space-2); justify-content:center; margin:0 0 var(--space-3); flex-wrap:wrap; }
.mode-row .ctrl-btn{ min-height:48px; min-width:96px; 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:13px; 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:12px; color:var(--text-muted); }
.stat-val{ font-family:var(--font-mono); font-weight:800; font-size:16px; }

/* Short desktops (1050×591, 900×506): the felt gives way first, then the
   opponents' boxes, then the cards (brief responsive priority). */
@media (min-width:641px) and (max-height:620px){
  :root{ --row-gap:5px; --lift:12px; --meld-w:38px; --meld-step:13px; }
  .game[data-opponents='1']{ --back-w:clamp(32px, calc(var(--hand-w) * .46), 40px); }
  .game{ row-gap:6px; }
  .plate{ padding:4px 10px 5px; row-gap:3px; }
  .instruction{ height:44px; }
  .choice-bar{ height:44px; }
}
@media (min-width:641px) and (min-height:501px) and (max-height:540px){
  /* Briefs' responsive priority: the opponents' card backs give way before
     your cards; the count stays in words. */
  .mini-pile{ display:none; }
  .plate{ grid-template-areas:'name role count total'; }
  .result .result-sub{ margin-bottom:4px; } .felt-panel.result{ padding:8px 14px; } .felt-panel h2{ font-size:20px; }
  .result-side{ margin-bottom:4px; } .result-side .card.mini{ width:30px; } .result td{ padding:2px 9px; }
  :root{ --hand-w:clamp(52px, min(6.9vw, 10.8dvh), 86px); --hand-w2:calc(var(--hand-w) * .74); --meld-w:34px; --meld-step:12px; }
  .game[data-opponents='1']{ --back-w:24px; }
  .seat-act{ display:none; }
  .game .feed-line{ display:block; }
  .game[data-coach='on'] .tip:empty{ display:none; }
  .game .hand-card .card-centre-suit{ display:none; }
  /* Canasta at 900×506: the two state lines share one line, so both meld
     boxes keep their melds on screen. */
  .game[data-game='canasta']{ row-gap:3px; --meld-w:32px; --meld-step:11px; }
  .game[data-game='r500']{ row-gap:3px; }
  .game[data-game='canasta'] .table-stats{ flex-direction:row; justify-content:center; flex-wrap:wrap; gap:0; padding-top:2px; padding-bottom:2px; }
  .game[data-game='canasta'] .contract-line:not(:empty)::before{ content:'·'; opacity:.55; margin:0 .35em; }
  .game[data-game='canasta'] .state-line, .game[data-game='canasta'] .contract-line{ width:auto; flex:0 0 auto; }
}

/* ===================================================== phones, upright ===
   Each game recomposed in its brief's order (not a shrunk desktop):
     Gin, Oklahoma:  opponent → piles → (taken / condition) → instruction →
                     state → hand (deadwood under it) → buttons
     Rummy 500:      state → instruction → piles → hand → melds → buttons
     Canasta:        state → instruction → piles → Our Melds → hand → buttons,
                     Their Melds one line, opened with a tap
   The table's pieces join the page grid so each can be placed. */
@media (max-width:640px) and (min-height:501px), (max-width:900px) and (min-height:901px) and (orientation:portrait){
  :root{
    --hand-w:clamp(46px, min(15vw, 9.6dvh), 64px);
    --meld-w:clamp(34px, calc(var(--hand-w) * .66), 40px); --meld-step:13px;
    --mini-w:clamp(30px, calc(var(--hand-w) * .56), 36px); --back-w:12px; --hand-w2:var(--hand-w);
    --lift:10px; --group-gap:8px; --min-strip:26px; --row-gap:5px;
    --pile-w:max(44px, min(16vw, 9dvh));
  }
  .game[data-opponents='1']{ --back-w:14px; }
  .game{
    grid-template-columns:minmax(0,1fr) minmax(0,.62fr);
    grid-template-rows:auto auto auto minmax(0,1fr) auto auto auto auto auto auto;
    grid-template-areas:
      'header header' 'seats seats' 'feed feed' 'centre centre' 'left right'
      'ins ins' 'stats stats' 'tip tip' 'hand hand' 'sec act';
    padding-left:max(6px, env(safe-area-inset-left)); padding-right:max(6px, env(safe-area-inset-right));
    padding-top:max(5px, env(safe-area-inset-top)); padding-bottom:max(5px, env(safe-area-inset-bottom));
    row-gap:4px; column-gap:6px;
  }
  /* Gin and Oklahoma: what Ruby has taken sits beside her box. */
  .game[data-game='gin'], .game[data-game='oklahoma']{
    grid-template-rows:auto auto auto minmax(0,1fr) auto auto auto auto auto;
    grid-template-areas:
      'header header' 'left seats' 'feed feed' 'centre centre'
      'ins ins' 'stats stats' 'tip tip' 'hand hand' 'sec act';
  }
  .game[data-game='gin'] .seats, .game[data-game='oklahoma'] .seats{ justify-content:stretch; }
  .game[data-opponents='1'] .seat, .game[data-opponents='1'] .plate{ width:100%; }
  .taken-cards{ flex-wrap:nowrap; gap:0; }
  .taken-cards .card.mini + .card.mini{ margin-left:calc(20px - var(--mini-w)); }
  .game[data-opponents='1'] .plate{ grid-template-columns:auto auto; grid-template-areas:'name count' 'pile total'; }
  .game[data-game='gin'] .pane-left, .game[data-game='oklahoma'] .pane-left{ align-self:stretch; }
  /* Oklahoma: the hand's condition first (brief §83), on one line. */
  .game[data-game='oklahoma']{
    grid-template-rows:auto auto auto auto minmax(0,1fr) auto auto auto auto auto;
    grid-template-areas:
      'header header' 'right right' 'left seats' 'feed feed' 'centre centre'
      'ins ins' 'stats stats' 'tip tip' 'hand hand' 'sec act';
  }
  .game[data-game='oklahoma'] .pane[data-kind='condition'] .pane-body{ flex-direction:row; }
  .game[data-game='oklahoma'] .condition-line{ max-width:none; font-size:13px; }
  .game[data-game='oklahoma'] .condition-line + .condition-line::before{ content:'· '; opacity:.6; }
  .game[data-game='oklahoma'] .condition-card .card.meld-card{ width:var(--mini-w); }
  .game[data-game='r500']{
    grid-template-rows:auto auto auto auto auto auto minmax(0,1fr) auto auto auto;
    grid-template-areas:
      'header header' 'seats seats' 'feed feed' 'stats stats' 'ins ins' 'tip tip'
      'centre centre' 'hand hand' 'left right' 'sec act';
  }
  /* Canasta: both sides' melds always shown, each on its own row under the
     piles (Ronan 2026-10-03: no tap to see their melds). */
  .game[data-game='canasta']{
    grid-template-rows:auto auto auto auto auto auto minmax(0,1fr) auto auto auto auto;
    grid-template-areas:
      'header header' 'seats seats' 'feed feed' 'stats stats' 'ins ins' 'tip tip'
      'centre centre' 'left left' 'right right' 'hand hand' 'sec act';
  }
  .zone-table{ display:contents; }
  .feed-line{ display:block; font-size:13px; line-height:17px; max-width:none; }
  .table-stats{ width:100%; padding:2px 6px; gap:0; min-height:0; }
  .state-line, .contract-line{ font-size:13px; line-height:17px; }
  .state-line .sep, .contract-line .sep{ margin:0 .3em; }

  .hand-pill, .wordmark{ display:none; }
  .zone-header{ min-height:44px; gap:6px; padding-bottom:2px; }
  .scorebar{ gap:4px; }
  .score-side{ flex-direction:column; align-items:center; gap:0; padding:1px 7px; line-height:1.15; }
  .score-side .score-label{ font-size:12px; }
  .score-side .score-val{ font-size:15px; }
  .score-label .lab-long{ display:none; } .score-label .lab-short{ display:inline; }
  .icon-label .lab-long{ display:none; } .icon-label .lab-short{ display:inline; }
  .scorebar[data-count='3'], .scorebar[data-count='4']{ display:none; }
  .icon-btn{ min-width:44px; padding:2px 3px; }
  .icon-label{ font-size:12px; letter-spacing:0; text-transform:none; }
  .header-controls{ gap:3px; }

  /* Opponents: one compact line each. Their moves are in the feed line. */
  .seats{ grid-template-columns:repeat(3, minmax(0,auto)); justify-content:center; column-gap:6px; }
  .game[data-opponents='1'] .seats{ grid-template-columns:auto; }
  #seat-1, #seat-2, #seat-3{ grid-column:auto; }
  .seat-act{ display:none; }
  .plate{ grid-template-columns:auto auto; grid-template-areas:'name total' 'pile count'; padding:3px 8px 3px 10px; column-gap:6px; row-gap:1px; }
  .seat-name{ font-size:14px; }
  .seat-role{ display:none; }
  .seat-count{ font-size:12px; }
  .seat-total{ font-size:14px; }
  .seat-tag{ font-size:12px; padding:0 3px; right:4px; }

  .centre{ gap:8px; flex-direction:row; justify-content:center; align-items:center; }
  .pile-info{ flex-direction:column; align-items:flex-start; max-width:100px; min-width:0; }
  .pile-info .chip{ white-space:normal; line-height:15px; padding:1px 6px; }
  .centre{ min-width:0; max-width:100%; }
  /* Phones: the meld's cards say what it is; the heading line gives way. */
  .game[data-game='r500'] .meld-head, .game[data-game='canasta'] .meld-head{ display:none; }
  .game[data-game='r500'], .game[data-game='canasta']{ --pile-w:max(44px, min(15vw, 7.4dvh)); }
  .pile{ height:calc(var(--pile-w) / .70 + 18px); }
  .pile.discard.is-fan{ --fan-max:calc(100vw - 40px - var(--pile-w)); }
  .piles{ gap:16px; }
  .pile-info:empty{ display:none; }

  .pane{ padding:3px 7px 4px; gap:3px; }
  .pane-left, .pane-right{ justify-self:stretch; width:auto; }
  .pane[data-kind='taken'], .pane[data-kind='condition']{ align-self:stretch; max-width:none; }
  .pane[data-kind='taken']{ flex-direction:row; align-items:center; gap:8px; }
  .pane[data-kind='taken'] .pane-body{ flex-direction:row; }
  .pane[data-kind='taken'] .pane-title{ white-space:normal; max-width:8ch; line-height:15px; }
  .pane[data-kind='taken'] .pane-empty{ font-size:12px; line-height:15px; }
  .pane[data-kind='condition']{ flex-direction:row; align-items:center; gap:8px; }
  .pane[data-kind='condition'] .pane-head{ display:none; }
  .pane[data-kind='condition'] .pane-body{ flex-direction:row; align-items:center; gap:8px; }
  .condition-card .card.meld-card{ width:var(--meld-w); }
  .pane-title{ font-size:12px; }
  .meld-list{ gap:2px 8px; }
  .meld-head{ font-size:12px; line-height:14px; }
  .game[data-game='r500'] .pane, .game[data-game='canasta'] .pane{ --meld-w:32px; --meld-step:11px; }
  .game[data-game='r500'] .pane{ --meld-lines:2; }
  /* Felt panels take the felt's rows in each game's order, so they never
     cover the instruction or the buttons. Between hands the hand's row is
     free, so the result has room. */
  .game .felt-panel.felt-panel{ grid-column:1 / -1; grid-row:2 / 5; align-self:center; justify-self:stretch; width:auto; min-width:0; max-width:none; margin:0 2px; padding:10px 12px; }
  .game[data-game='oklahoma'] .felt-panel.felt-panel{ grid-row:2 / 6; }
  .game[data-game='r500'] .felt-panel.felt-panel{ grid-row:7 / 10; }
  .game[data-game='canasta'] .felt-panel.felt-panel{ grid-row:7 / 11; }
  .game .felt-panel.result.result{ align-self:stretch; overflow:hidden; display:flex; flex-direction:column; justify-content:center; }
  .felt-panel h2{ font-size:19px; }
  .felt-panel .panel-line{ font-size:13px; margin-bottom:4px; }
  .result table{ font-size:13px; } .result td, .result th{ padding:2px 5px; }

  .instruction{ width:100%; height:44px; font-size:15px; padding:2px var(--space-2); }
  .choice-bar{ width:100%; height:44px; gap:8px; }
  .secondary{ justify-self:stretch; gap:5px; }
  .secondary .ctrl-btn{ flex:1 1 auto; min-height:44px; min-width:44px; padding:4px 2px; font-size:12px; letter-spacing:-.01em; }
  .action{ justify-self:end; }
  .action{ justify-self:stretch; }
  #btnAction{ width:100%; min-width:0; min-height:44px; padding:4px 8px; }
  .tip{ font-size:13px; 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; }
  .hand{ padding-top:var(--lift); gap:0; }

  .hgroup-label{ height:16px; line-height:16px; }
  .hand .card .card-centre-suit{ display:none; }
  .hand .card .court-figure{ top:58%; width:70%; height:52%; }
  .keys-item{ display:none; }
}
/* Phones under 700 high: a ten- or eleven-card hand stays on one row
   (Canasta brief §19: one overlapped row while practical), every corner
   index still showing. */
@media (max-width:640px) and (min-height:501px) and (max-height:699px){
  :root{ --min-strip:19px; --group-gap:6px; --hand-w:clamp(48px, min(16.5vw, 9.4dvh), 60px); }
}
/* Short phones (the site's iPhone SE box, 345×504 … 620 high): the two
   stats lines share one line, and the melds' headings sit on the box edge. */
@media (max-width:640px) and (min-height:501px) and (max-height:620px){
  :root{ --hand-w:clamp(46px, min(16.5vw, 9.4dvh), 56px); }
  .game{ row-gap:2px; }
  .tip{ height:30px; min-height:30px; line-height:15px; }
  :root{ --lift:8px; }
  .zone-header{ padding-bottom:2px; }
  .feed-line{ line-height:15px; }
  .hgroup-cards{ padding-bottom:2px; border-bottom-width:2px; }
  .hgroup.is-near .hgroup-cards{ border-bottom-width:2px; }
  .table-stats{ flex-direction:row; justify-content:center; flex-wrap:wrap; gap:0; }
  .state-line, .contract-line{ width:auto; flex:0 0 auto; max-width:100%; }
  .contract-line:not(:empty)::before{ content:'·'; opacity:.55; margin:0 .35em; }
  .pane[data-kind='melds']{ position:relative; margin-top:7px; padding-top:9px; overflow:visible; }
  .pane[data-kind='melds'] .pane-head{ position:absolute; left:8px; top:-8px; padding:0 5px; border-radius:4px; background:var(--table-bg); line-height:16px; }
  .pane[data-kind='melds'] .pane-sub, .pane[data-kind='melds'] .pane-chips{ display:none; }
  /* The opponents' boxes on one line; their card backs give way (briefs'
     responsive priority), the count stays in words. */
  .mini-pile{ display:none; }
  .game .plate{ grid-template-columns:auto auto auto; grid-template-areas:'name count total'; }
  .game[data-opponents='1'] .plate{ grid-template-columns:auto auto auto; grid-template-areas:'name count total'; }
  .result-side{ display:flex; align-items:center; gap:6px; margin-bottom:4px; }
  .result-side-head{ flex:none; width:5ch; margin:0; font-size:12px; }
  .result-side .meld-head{ display:none; }
  .result-side .meld-list{ gap:2px 8px; }
  .result-side .card.mini{ width:28px; } .result-side .card.mini + .card.mini{ margin-left:calc(13px - 28px); }
  .felt-panel h2{ font-size:17px; } .result .result-sub{ font-size:12px; margin-bottom:4px; }
  .game[data-game='r500'] .pane, .game[data-game='canasta'] .pane{ --meld-w:30px; --meld-step:10px; }
  .meld-list{ gap:2px 6px; }
  /* The pile's name and count sit on the card's foot instead of under it. */
  .pile{ height:calc(var(--pile-w) / .70); }
  .pile-label{ left:2px; right:2px; bottom:3px; height:16px; line-height:16px; border-radius:4px; background:var(--plate-strong); font-size:12px; z-index:3; }
  .pile.discard.is-fan .pile-label{ left:auto; right:2px; padding:0 5px; }
  /* On the card's foot there is room for the count only; the stock is the
     face-down pile and the discard the face-up one (names stay for screen readers). */
  .pile-label .pile-name{ position:absolute; left:0; top:0; opacity:0; pointer-events:none; white-space:nowrap; }
  .tip{ height:32px; min-height:32px; }
}
/* Phones under 700 high */
@media (max-width:640px) and (min-height:501px) and (max-height:699px){
  /* Canasta: Their melds beside the piles, the pile's notes under them, so
     both sides' melds stay on screen with no tap (Ronan 2026-10-03). */
  .game[data-game='canasta']{
    grid-template-columns:auto minmax(0,1fr) minmax(0,37.5%);
    grid-template-rows:auto auto auto auto auto auto minmax(0,1fr) auto auto auto auto;
    grid-template-areas:
      'header header header' 'seats seats seats' 'feed feed feed' 'stats stats stats' 'ins ins ins' 'tip tip tip'
      'piles left left' 'piles info info' 'right right right' 'hand hand hand' 'sec sec act';
  }
  .game[data-game='canasta'] .centre{ display:contents; }
  .game[data-game='canasta'] .piles{ grid-area:piles; align-self:center; gap:8px; }
  .game[data-game='canasta'] .pile-info{ grid-area:info; flex-direction:row; flex-wrap:wrap; justify-content:flex-start; align-items:center; max-width:none; gap:3px; }
  .game[data-game='canasta'] .pane-left{ align-self:end; --meld-w:26px; --meld-step:9px; }
  .game[data-game='canasta'] .pane{ --meld-lines:1; --meld-stack:1; }
  .game[data-game='canasta'] .pane-left .meld.is-canasta .card.meld-card + .card.meld-card{ margin-left:calc(4px - var(--meld-w)); }
}
/* The SE box (504 high): the melds' headings sit at the left of each box,
   saving the edge's height. */
@media (max-width:640px) and (min-height:501px) and (max-height:540px){
  .game{ row-gap:1px; }
  /* Gin and Oklahoma: the taken cards and the hand's condition card a size smaller. */
  .game[data-game='gin'], .game[data-game='oklahoma']{ --mini-w:26px; }
  .game[data-game='oklahoma'] .pane{ padding-top:2px; padding-bottom:2px; }
  .game[data-game='canasta'] .pane[data-kind='melds']{ flex-direction:row; align-items:center; gap:6px; margin-top:0; padding:3px 6px; }
  .game[data-game='canasta'] .pane[data-kind='melds'] .pane-head{ position:static; flex:none; padding:0; background:none; }
  .game[data-game='canasta'] .pane[data-kind='melds'] .pane-title{ display:block; width:5ch; white-space:normal; line-height:15px; }
}
/* The narrowest phones (the site's SE and Android boxes): the two scores
   share one box, so the five header buttons keep their 44px. */
@media (max-width:350px) and (min-height:501px), (max-width:400px) and (min-height:501px) and (orientation:portrait){
  .zone-header{ gap:4px; } .header-controls{ gap:2px; }
  .scorebar{ display:flex; flex-direction:column; gap:0; padding:1px 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:13px; }
  .icon-btn{ min-width:44px; padding:2px 1px; }
  .seats{ column-gap:3px; }
  .plate{ padding:2px 5px 2px 7px; column-gap:4px; }
  .seat-name{ font-size:13px; }
  .seat-total{ font-size:13px; }
  .count-word{ display:none; }
  .scorebar{ padding:1px 3px; } .score-side{ gap:3px; } .score-side .score-val{ font-size:13px; }
  .header-controls{ gap:1px; }
  .game{ padding-left:4px; padding-right:4px; }
}
/* Tablets upright: the desktop pieces at a larger size. */
@media (min-width:641px) and (max-width:900px) and (min-height:901px) and (orientation:portrait){
  :root{ --hand-w:clamp(56px, 10vw, 84px); --hand-w2:calc(var(--hand-w) * .8); --pile-w:calc(var(--hand-w) * .9); --meld-w:44px; --meld-step:16px; --mini-w:38px; --back-w:20px; --group-gap:16px; }
  .wordmark{ display:flex; }
  .seat-name{ font-size:17px; }
  .seat-role{ display:inline; }
  .instruction{ font-size:16px; }
  .keys-item{ display:list-item; }
}

/* =================================================== phones, sideways === */
@media (max-height:500px){
  :root{ --hand-w:clamp(38px, min(6.2vw, 16dvh), 62px); --hand-w2:calc(var(--hand-w) * .86); --pile-w:max(44px, calc(var(--hand-w) * .78)); --meld-w:34px; --meld-step:12px; --mini-w:30px; --back-w:11px; --lift:8px; --group-gap:10px; --min-strip:24px; --row-gap:3px; --seat-gap:10px; }
  .game[data-opponents='1']{ --back-w:13px; }
  .game{
    grid-template-columns:minmax(0,1fr) clamp(190px, 28vw, 270px);
    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:4px;
    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:40px; }
  .hand-pill{ display:none; }
  .icon-label .lab-long{ display:none; } .icon-label .lab-short{ display:inline; }
  .scorebar[data-count='3'], .scorebar[data-count='4']{ display:none; }
  .seat-act{ display:none; }
  .feed-line{ display:block; font-size:12px; line-height:15px; }
  .plate{ grid-template-columns:auto auto auto auto; grid-template-areas:'name pile count total'; padding:2px 8px 2px 10px; column-gap:6px; }
  .seat-name{ font-size:13px; } .seat-total{ font-size:13px; } .seat-count{ font-size:12px; } .seat-role{ display:none; }
  .pane{ padding:3px 6px; gap:2px; }
  .pane-head{ display:none; }
  .pane-chips{ display:none; }
  .meld-head{ display:none; }
  .meld-list{ gap:3px 8px; }
  .pane{ --meld-w:30px; --meld-step:10px; }
  .pile.discard.is-fan{ --fan-max:22vw; }
  .pile{ height:calc(var(--pile-w) / .70 + 16px); }
  .pile-info{ display:none; }
  .table-stats{ padding:1px 8px; gap:0; min-height:0; }
  .state-line, .contract-line{ font-size:12px; line-height:15px; }
  .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:4px; } .secondary .ctrl-btn{ flex:1 1 0; min-height:44px; padding:4px 3px; font-size:12px; }
  .felt-panel{ padding:6px 12px; } .felt-panel h2{ font-size:17px; } .felt-panel .panel-line{ font-size:12px; margin-bottom:2px; }
  .result table{ font-size:12px; } .result td, .result th{ padding:1px 5px; }
  .result .result-notes, .result-side{ display:none; }
  .hgroup-label{ height:15px; line-height:15px; }
  .hand .card .card-centre-suit{ display:none; }
}

/* ------------------------------------------------- brief text floors --- */
/* Nothing below 12px; what a player reads while deciding 13px or more. */
@media (min-width:380px){
  html .game .state-line, html .game .contract-line, html .game .feed-line, html .game .seat-count, html .game .score-side .score-val{ font-size:max(13px, 1em); }
}

/* ---------------------------------------------------- reduced motion --- */
/* Movement shortened, never removed; the lifted card keeps its lift. */
@media (prefers-reduced-motion: reduce){
  :root{ --dur-travel: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-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 that sits on the felt goes on the dark plate. ---- */
.hand-pill, .pile-label .pile-name, .pile-count, .seat-act, .seat-role, .score-side .score-label{ background:var(--plate-strong); border-radius:4px; padding:0 4px; }
.hand-pill, .pile-label .pile-name, .seat-act{ color:var(--text-primary); }
.coach-choice .btn-sub{ opacity:1; }
.overlay-panel p.sub, .start-rules, .resume-context, .start-link, .pane-empty{ font-weight:600; }
.pane-empty{ color:var(--text-secondary); }
/* the plate is drawn without padding (a shadow of the same colour), so the labels keep their width and the hand groups as before */
.hgroup-label .hg-text{ background:var(--plate-strong); box-shadow:0 0 0 3px var(--plate-strong); border-radius:2px; padding:0; color:var(--text-primary); }
.condition-line{ font-weight:600; }
#feedLine, .pane-head .pane-title{ color:var(--text-primary); }
@media (max-width:679px){ #feedLine, .pane-head .pane-title{ background:var(--plate-strong); border-radius:4px; padding-left:4px; padding-right:4px; } }
/* R4 decision (Ronan 13:46): the start panel a shade darker so its subtitle and rules line reach 7:1 */
#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)); }

/* Canasta on the larger phone frames (376+ wide, 621–699 high: the site's Pro Max
   box, 400x686): the desktop Canasta card size (6.2vw) was overriding the phone
   size, so the hand fell to 52px and the piles to 51px. Brief §109 (54–64px at
   390–430) and §41 (stock/discard 58–70px), Ronan's "Move them" (2026-10-14). */
@media (min-width:376px) and (max-width:640px) and (min-height:621px) and (max-height:699px){
  .game[data-game='canasta']{ --hand-w:clamp(54px, min(16.5vw, 9.4dvh), 60px); --pile-w:max(58px, min(15vw, 8.6dvh)); }
}
