/* HEARTS — stylesheet (rebuild after the 2026-10-02 audit).
 *
 * Spec: briefs/hearts-spec.md. Decisions: briefs/hearts-decisions.md.
 *
 * THE SHARED DNA. Card faces, court art, backs, the gold action, typography,
 * buttons, plates, focus states, radii and spacing are the catalogue's
 * (War / Go Fish / Snap shell). Hearts' identity is its own felt (one of three
 * Harbour blue, chosen by Ronan), the trick in a cross between
 * four seat plates, and the hand fanned along the bottom.
 *
 * Category tokens keep their names: --table-bg, --table-deep, --table-highlight.
 */

*,*::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;
}
button, select, input{ font:inherit; color:inherit; }
[hidden]{ display:none !important; }
button{ touch-action:manipulation; }

:root{
  /* --- Hearts felt: "Harbour blue" (Ronan 2026-10-02). L* 36.6; nearest
     other felt is solitaire #26384A at 16.9 dE (floor 12). --- */
  --table-bg:#2F5A7A;
  --table-deep:#1E3D55;
  --table-highlight:#3B6E92;
  --plate:rgba(6,18,30,.62);
  --plate-strong:rgba(6,18,30,.88);
  --text-secondary:#E0ECF4;
  --text-muted:#BFD3E2;

  /* --- 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 colours for text on the dark plates (contrast ≥ 4.5:1 on --plate). */
  --suit-red-on-dark:#FF8A8A;
  --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 every fixed row (--v-fixed) and the table (--table-share of what is
     left); the trick cards are a fixed share of the hand card. */
  /* fixed rows: header, state, instruction, tip, lift, gaps, Jade's and
     your plates; the rest is shared by the hand (1/0.7) and the trick
     (1.85 trick heights) = 3.86 hand widths. */
  --v-fixed:362px;
  --hand-k:4.06;
  --hand-w:clamp(56px, min(7.4vw, calc((100dvh - var(--v-fixed)) / 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.40);
  --back-h:calc(var(--back-w) / 0.70);
  --lift:14px;
  --gap:clamp(8px, 1.1vw, 14px);
  /* Spacing grows with the space available (Ronan 14:54): between trick
     cards, between the trick and the plates, and between the rows. */
  --trick-gap:clamp(10px, 1.5vw, 22px);
  /* Across the cross the gap can be wider than down it: width is cheap,
     height is not (brief §27: the trick area at least 260×190). */
  --trick-gap-x:clamp(10px, 2vw, 30px);
  --seat-gap:clamp(16px, 3.6vw, 64px);
  --row-gap:clamp(8px, 2dvh, 26px);

  /* Movement only. The reading holds live in the controller (pace A). */
  --dur-travel:300ms;
  --dur-collect:360ms;
  --dur-lift:120ms;
}

/* ------------------------------------------------------------- shell --- */
/* Every element is a direct child of the grid, so phones can put the
   buttons under the hand and desktops beside the instruction. */
.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 §21: on large monitors the composition is capped around 1200px
     and centred; the felt itself (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);
}
body{ background:radial-gradient(ellipse at 50% 44%, var(--table-highlight) 0%, var(--table-bg) 55%, var(--table-deep) 100%) var(--table-deep); }

/* ------------------------------------------------------------ header --- */
.zone-header{
  grid-area:header;
  display:flex; align-items:center; justify-content:space-between;
  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-primary); white-space:nowrap; background:var(--plate-strong); padding:2px 6px; border-radius:4px; }
.hand-pill:empty{ display:none; }
.header-controls{ display:flex; align-items:center; gap:var(--space-2); }

.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; }

/* ------------------------------------------------------------- table --- */
/* Three columns: Theo | the centre | Finn. Jade above the centre, You below.
   The trick sits in the centre as a cross of four slots, each nearest its
   player, so the four cards read as "who played what" (U-01). */
.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; }

.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] [total] [+hand] [tag]. Fixed shape — the
   tag's room is always reserved, so a plate never changes size (no
   movement). */
.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;
}
.seat-name{ font-family:var(--font-display); font-weight:800; font-size:clamp(15px,1.5vw,19px); letter-spacing:.02em; }
.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-hand{ font-family:var(--font-mono); font-weight:700; font-size:13px; color:var(--text-secondary); min-width:3ch; }
.seat-hand .qs{ color:var(--text-primary); margin-left:4px; }
.seat-hand:empty::before{ content:'\00a0'; }
/* The tag sits on the plate's top edge, outside its box, so the plate never
   changes size when it appears (no movement). */
.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:16px; letter-spacing:.02em;
  color:#0B2233; background:var(--active); padding:1px 5px; border-radius:4px;
}
.seat-tag.is-on{ visibility:visible; }
/* Your tag sits beside your box, so it never reaches up into the stats. */
.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-pass{ background:var(--text-primary); color:#1A1F1D; }
.seat.is-turn .plate{ border-color:var(--active); box-shadow:0 0 0 2px var(--active); }
.seat.is-target .plate{ border-color:var(--action); box-shadow:0 0 0 2px var(--action); }
.mini-pile{ display:none; position:relative; width:13px; height:18px; }
.mini-pile .card-back{ position:absolute; left:0; top:0; width:13px; height:100%; border-radius:2px; border-width:1px; }

/* The opponents' face-down hands: a small overlapping row of backs. */
.backs{ display:flex; height:var(--back-h); }
.backs .card-back{ width:var(--back-w); height:var(--back-h); margin-left:calc(var(--back-w) * -0.72); }
.backs .card-back:first-child{ margin-left:0; }
.seat-left .backs, .seat-right .backs{ height:var(--back-h); }

/* ------------------------------------------------------------- trick --- */
.trick{
  position:relative;
  /* No card overlaps another (Ronan 14:43): three card widths and two card
     heights, with gaps. */
  width:calc(var(--trick-w) * 3 + var(--trick-gap-x) * 2);
  height:calc(var(--trick-h) * 2 + var(--trick-gap));
}
.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%); }
.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:calc(var(--trick-w) * 0.52); }
/* The winning card, after the trick is complete: lifted and ringed in gold
   (a shape cue, with the seat's tag saying TAKES IT in words). */
.slot.is-winner .card{ box-shadow:0 0 0 3px var(--action), 0 10px 22px rgba(0,0,0,.45); }
/* Stacking: the bottom card sits over the top one, so every card's top-left
   rank corner is always visible (the winner is marked by its ring and the
   words on its seat, never by being lifted over a neighbour). */
.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; }
/* "LAST TRICK" peek caption and the led suit, inside the cross's empty
   corner so it never covers a card. */
.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:12px; line-height:1.3; letter-spacing:.03em;
  color:var(--text-primary); background:var(--plate-strong); border-radius:4px; padding:1px 3px; white-space:normal;
}
.trick-caption:empty{ display:none; }

/* Pass direction: an arrow from the centre towards the receiver. */
.pass-arrow{
  display:none; position:absolute; left:50%; top:50%;
  font-size:clamp(34px, 4vw, 52px); line-height:1; color:var(--action);
  transform:translate(-50%,-50%); text-shadow:0 2px 8px rgba(0,0,0,.5);
}
.game[data-phase='passing'] .pass-arrow{ display:block; }
.pass-arrow[data-dir='left']::before{ content:'\2190'; }
.pass-arrow[data-dir='right']::before{ content:'\2192'; }
.pass-arrow[data-dir='across']::before{ content:'\2191'; }

/* Hand and game results on the felt, in place of the trick. */
.result{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  z-index:5; min-width:min(92vw, 330px);
  padding:12px 16px; border-radius:calc(var(--radius) * 1.3);
  background:#10263A; border:1px solid var(--line);
  box-shadow:0 18px 40px rgba(0,0,0,.45);
  text-align:center;
}
.result[hidden]{ display:none; }
.result h2{ margin:0 0 2px; font-family:var(--font-display); font-weight:800; font-size:clamp(19px,2.2vw,26px); color:var(--action); }
.result .result-sub{ margin:0 0 8px; font-family:var(--font-mono); font-size:13px; font-weight:700; letter-spacing:.03em; color:var(--text-primary); }
.result table{ border-collapse:collapse; margin:0 auto; font-family:var(--font-mono); font-size:14px; }
.result th{ font-size:13px; font-weight:700; letter-spacing:.04em; color:var(--text-secondary); 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.name{ font-family:var(--font-ui); font-weight:700; }
.result tr.is-you td{ color:#FFE7B3; }
.result tr.is-mark td{ background:rgba(240,184,75,.12); }
.result .result-notes{ margin:8px 0 0; padding:0; list-style:none; font-size:13px; font-weight:600; line-height:1.4; color:var(--text-primary); text-align:left; max-width:34ch; }
.result .result-notes li{ margin-top:3px; }
.result .result-facts{ margin:8px 0 0; font-family:var(--font-mono); font-size:13px; font-weight:700; letter-spacing:.02em; color:var(--text-primary); }
.result .result-next{ margin:8px 0 0; font-family:var(--font-mono); font-size:13px; font-weight:700; letter-spacing:.03em; color:var(--text-primary); }

/* ------------------------------------------------- state / instruction --- */
/* The stats, in the middle of the table under the trick (Ronan 16:10):
   two lines, sentence case, suits in their colours, Hearts broken in red.
   Both lines always hold their room, so nothing moves. */
.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-strong); border:1px solid var(--line-soft);
  font-family:var(--font-ui); text-align:center;
}
.state-line, .pass-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-primary); }
.pass-line{ font-size:13px; font-weight:600; line-height:16px; color:var(--text-primary); }
.state-line .sep, .pass-line .sep{ color:var(--text-muted); margin:0 .45em; }
.state-line .hot{ color:var(--text-primary); font-weight:700; }
.state-line .is-broken{ color:var(--suit-red-on-dark); 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; }
#btnAction .suit-red{ color:#9B1C26; }
.tip{ grid-area:tip; font-size:13px; font-weight:600; color:var(--text-primary); 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-strong); }

/* --------------------------------------------------------------- hand --- */
.hand-zone{ grid-area:hand; min-width:0; padding-top:var(--lift); }
/* Brief §32: 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; }
.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); }
/* Lifted (the card you are about to play, or chosen to pass): up, and a
   gold outline. Never colour alone: the lift is the shape cue. */
.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); }
/* Cards just received: their own short reveal (U-03), then nothing. */
.hand .card.is-received{ 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 .from-tag{
  position:absolute; z-index:3; left:50%; bottom:6px; transform:translateX(-50%);
  font-family:var(--font-mono); font-weight:800; font-size:12px; letter-spacing:.02em; white-space:nowrap;
  color:var(--action-text); background:var(--action); padding:1px 4px; border-radius:3px;
}
/* A lifted card keeps its place in the fan's stacking order, so it never
   covers the next card's rank corner (card-spacing rule). */
.hand .card.kb-focus{ outline:3px solid var(--active); outline-offset:2px; }
.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) * 0.26), 28px); }

/* -------------------------------------------------------------- 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;
  /* Each card is its own stacking context, so a court figure or a corner can
     never paint over the next card in the fan (Ronan 14:43). */
  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:calc(var(--hand-w) * 0.52); opacity:.9; }
/* H5: a card too small for its centre pip to clear the corner indexes reads
   by its corners alone (as the short phones already did). */
.card{ container-type:inline-size; }
@container (max-width:60px){ .card-centre-suit{ 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; left:0; top:0; right:0; bottom:0; z-index:40;
  display:none; align-items:center; justify-content:center;
  background:rgba(4,12,20,.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, #24496A, #14304A);
  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-family:var(--font-mono); font-size:13px; font-weight:600; color:var(--text-primary); 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, .daily-context{ margin:0 0 var(--space-3); font-size:13px; font-weight:600; color:var(--text-primary); }
.start-choices{ display:flex; gap:var(--space-2); justify-content:center; flex-wrap:wrap; margin:0 0 var(--space-2); }
.start-choice{ min-height:48px; padding:var(--space-2) var(--space-4); font-size:15px; }
.start-choice.is-remembered{ background:var(--action); color:var(--action-text); border-color:var(--action); }
.start-note{ font-size:13px; font-weight:600; color:var(--text-primary); line-height:1.45; margin:0 auto var(--space-3); max-width:420px; }
.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; font-weight:600; line-height:1.55; color:var(--text-primary); 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 li[hidden]{ display:none; }
.rules-list .disclaimer{ font-size:13px; color:var(--text-secondary); }
.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:600; color:var(--text-secondary); }
.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-row[data-disabled='true']{ opacity:.45; }
.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; }
.preset-row{ display:flex; justify-content:center; gap:var(--space-2); flex-wrap:wrap; margin-bottom:var(--space-2); }
.preset-btn.is-active{ border-color:var(--action); box-shadow:0 0 0 1px var(--action); }
.rule-warning{ font-size:13px; font-weight:600; color:#FFE7B3; margin:var(--space-2) 0 0; }
.rule-warning[hidden]{ display:none; }
.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; font-weight:600; color:var(--text-secondary); }
.stat-val{ font-family:var(--font-mono); font-weight:800; font-size:16px; }
.panel-sub{ font-family:var(--font-display); font-size:16px; margin:var(--space-4) 0 var(--space-2); }
.daily-list{ font-family:var(--font-mono); font-size:13px; font-weight:600; color:var(--text-primary); }
.daily-row{ display:flex; justify-content:space-between; padding:3px 0; border-bottom:1px solid var(--line-soft); }

/* ---------------------------------------------------- phones, upright --- */
/* The hand is the priority (§22): every other row gives way first. Plates
   become one line with a mini pile; opponents' backs are hidden (the mini
   pile shows they hold cards); Hint / Last trick / Sort and the action go
   under the hand, in the thumb's reach. */
@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(10px, 3vw, 16px); --row-gap:clamp(8px, 2.6dvh, 26px); --v-fixed:362px; --hand-k:4.3; --hand-w:clamp(42px, min(15.2vw, calc((100dvh - var(--v-fixed)) / 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; }
  /* H7: the title gives its room to readable labels (Ronan 07:26). */
  .wordmark{ display:none; }
  .zone-header{ justify-content:center; }
  .icon-btn{ min-width:44px; padding:2px 3px; }
  .icon-label{ font-size:12px; letter-spacing:0; }
  .header-controls{ gap:4px; }
  .backs{ display:none; }
  .mini-pile{ display:block; }
  .plate{ padding:3px 7px; column-gap:6px; }
  .seat-name{ font-size:14px; }
  .seat-total{ font-size:14px; }
  .seat-hand{ font-size:12px; min-width:3ch; }
  .seat-tag{ font-size:12px; padding:0 3px; right:4px; }
  /* Opponents on phones (Ronan 16:10): the name on top, their cards under
     it with the score 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; }
  .seat-top .plate{ grid-template-columns:auto auto auto; grid-template-areas:'name name name' 'pile total hand'; }
  .seat-left .plate, .seat-right .plate{ grid-template-columns:auto auto; grid-template-areas:'name name' 'pile total' 'hand hand'; }
  .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-total, .seat-left .plate .seat-total, .seat-right .plate .seat-total{ grid-area:total; }
  .seat-top .plate .seat-hand, .seat-left .plate .seat-hand, .seat-right .plate .seat-hand{ grid-area:hand; }
  .seat-top .plate .seat-hand{ min-width:3.2ch; }
  /* The side plates' tag takes a reserved third row inside the plate, so it
     can never run off the screen edge or over a trick card. */
  .seat-left, .seat-right{ max-width:100%; }
  .seat-left .plate, .seat-right .plate{ max-width:100%; }
  /* Theo's and Finn's tag sits centred on the box's top edge, so it stays
     over the box and can never run off the screen. */
  .seat-left .plate .seat-tag, .seat-right .plate .seat-tag{ left:50%; right:auto; transform:translate(-50%, -62%); font-size:12px; letter-spacing:0; padding:0 3px; }
  .trick{ width:calc(var(--trick-w) * 3 + var(--trick-gap-x) * 2); height:calc(var(--trick-h) * 2 + var(--trick-gap)); }
  .instruction{ width:100%; height:44px; font-size:15px; letter-spacing:0; line-height:1.25; padding:2px var(--space-2); }
  .secondary{ justify-self:stretch; gap:6px; }
  .secondary .ctrl-btn{ flex:1 1 0; min-height: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; }
  .secondary .ctrl-btn{ min-width:44px; }
  /* Two lines always reserved, so a tip appearing never moves the hand. */
  .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; }
  .table-stats{ width:100%; padding:3px 6px; gap:0; }
  .state-line{ font-size:13px; line-height:16px; }
  .pass-line{ font-size:13px; line-height:16px; letter-spacing:0; }
  .pass-line .sep{ margin:0 .3em; }
  @media (max-width:350px){ .pass-line .sep{ margin:0 .3em; } .table-stats{ padding-left:3px; padding-right:3px; }
    .seat-left .plate .seat-tag, .seat-right .plate .seat-tag{ letter-spacing:-.05em; padding:0 2px; } }
  .keys-item{ display:none; }
  .hand .card .from-tag{ display:none; }
  .result table{ font-size:13px; }
  .result td, .result th{ padding:2px 5px; }
}
/* Tablets upright: the stacked arrangement with room for bigger cards. */
@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(--hand-k))), 96px); --trick-w:calc(var(--hand-w) * 1.1); --gap:14px; }
  .backs{ display:flex; }
  .mini-pile{ display:none; }
  .seat-name{ font-size:18px; } .seat-total{ font-size:17px; }
  /* Tablets show the real backs under each box, so the boxes go back to one
     line: name, score, this hand. */
  .seat-top .plate, .seat-left .plate, .seat-right .plate{ grid-auto-flow:column; grid-template-areas:none; grid-template-columns:none; padding:5px 10px; 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; }
}
/* Short phones (SE): tighter rows. */
@media (max-width:640px) and (min-height:501px) and (max-height:620px){
  :root{ --v-fixed:352px; --row-gap:6px; --hand-w:clamp(40px, min(15.2vw, calc((100dvh - var(--v-fixed)) / var(--hand-k))), 72px); }
  .table-stats{ padding:1px 6px; }
  .state-line{ line-height:15px; } .pass-line{ line-height:15px; }
  .game{ row-gap:6px; }
  .zone-header{ min-height:44px; }
  .instruction{ height:38px; font-size:14px; }
  /* Cards this small read by their corners; the centre pip would sit on them. */
  .hand .card .card-centre-suit, .trick .card .card-centre-suit{ display:none; }
}

/* Short desktop windows (900×506): the card floor comes down a little so
   the table, with its stats, still fits above the hand. */
@media (min-width:641px) and (min-height:501px) and (max-height:560px){
  :root{ --hand-w:clamp(44px, min(7.4vw, calc((100dvh - var(--v-fixed)) / var(--hand-k))), 100px); }
  .hand .card .card-centre-suit, .trick .card .card-centre-suit{ display:none; }
}

/* --------------------------------------------------- phones, sideways --- */
/* Height runs out first: the table on the left, the instruction and the
   buttons in a column on the right, the hand along the bottom. */
@media (max-height:500px){
  :root{ --v-fixed:96px; --hand-w:clamp(40px, min(6.6vw, calc((100dvh - var(--v-fixed)) * 0.26)), 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 tip' '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));
  }
  /* The tip / Coach line in its own slot above the instruction (H6, Ronan 07:26). */
  .tip{ align-self:end; justify-self:stretch; display:flex; align-items:center; justify-content:center; white-space:normal; line-height:16px; padding:3px 8px; }
  .tip:empty{ background:none; }
  .zone-header{ min-height:36px; }
  .icon-btn{ min-height:40px; min-width:44px; }
  .backs{ display:none; }
  .mini-pile{ display:block; }
  .plate{ padding:2px 7px; column-gap:6px; }
  .seat-name{ font-size:13px; } .seat-total{ font-size:13px; } .seat-hand{ font-size:12px; min-width:5ch; }
  .seat-tag{ font-size:12px; }
  .zone-table{ row-gap:3px; }
  .table-stats{ padding:2px 8px; gap:0; }
  .state-line{ font-size:13px; line-height:16px; }
  .pass-line{ font-size:13px; line-height:16px; }
  .instruction{ width:100%; height:56px; font-size:13.5px; letter-spacing:0; }
  .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:40px; padding:4px 4px; font-size:12px; }
  .keys-item{ display:list-item; }
  .result h2{ font-size:17px; } .result table{ font-size:13px; } .result td, .result th{ padding:1px 6px; }
  .result .result-notes{ display:none; }
  .card-centre-suit{ font-size:calc(var(--hand-w) * 0.42); }
  .slot .card .card-centre-suit{ font-size:calc(var(--trick-w) * 0.40); }
}

/* Phones: the start screen fits without scrolling (the Coach choice side by side). */
@media (max-width:640px){
  .overlay{ padding:8px; }
  .overlay-panel{ padding:14px 12px; width:100%; }
  .start-choice{ padding:8px 12px; font-size:14px; }
  .start-panel .sub{ margin-bottom:var(--space-3); }
}
@media (max-width:640px) and (max-height:620px){
  .start-panel h2{ margin-bottom:4px; }
  .start-note, .start-rules, .resume-context{ margin-bottom:8px; line-height:1.35; }
  .start-more{ margin-top:0; }
  .daily-context{ margin:6px 0 0; }
}

/* H4: on a touch screen every button is at least 44px, sideways too. */
@media (pointer:coarse){
  .icon-btn, .ctrl-btn, .secondary .ctrl-btn, .small-btn{ min-height:44px; }
}

/* H3: on phones and sideways the result covers the whole table in a solid
   panel, so nothing on the table is half-covered. */
@media (max-width:640px), (max-height:500px){
  .game[data-result='yes'] .centre{ position:static; }
  .game[data-result='yes'] .seat-tag{ visibility:hidden; }
  .result{ left:0; top:0; right:0; bottom:0; transform:none; min-width:0; width:auto; max-width:none;
    display:flex; flex-direction:column; align-items:center; justify-content:center; overflow:hidden;
    padding:8px 10px; border-radius:var(--radius); background:#10263A; box-shadow:none; }
  .result[hidden]{ display:none; }
}

/* ---------------------------------------------------- reduced motion --- */
/* Movement shortened, never removed; the reading holds are unchanged
   (pace A). The in-game switch (data-reduce-motion) does the same as the
   system setting (H-09). */
@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; }
