/* CRAZY EIGHTS — category stylesheet.
 *
 * Built to the Crazy Eights brief. Section numbers below are that brief's.
 *
 * THE CATEGORY (§4). Matching and shedding: one card in the middle that
 * everybody is playing against, and a suit that can change under your feet.
 * So the composition is built around a single dominant discard card with the
 * active suit read out beside it in words — not a four-card trick (that is
 * the trick-taking family), not a tableau (that is solitaire), not a meld
 * table (that is rummy). The violet felt is this category's own and is
 * deliberately lighter than Hearts' burgundy or the green trick-taking
 * table; it carried over from the supplied build, where it was a direct
 * request, and it is the one thing here that was already right.
 *
 * THE SHARED DNA (§5). Card faces, court illustrations, card backs, the gold
 * action token, typography, buttons, overlays and focus states are the
 * catalogue's and are referenced, not redefined.
 *
 * The composition is a five-row grid on #crazyEightsGame, so the instruction
 * band, the hand and the table each own their row and none can intersect
 * another — which is what §9 and §31 require, made structural rather than
 * checked after the fact.
 */

*,*::before,*::after{ box-sizing:border-box; }
html,body{
  margin:0; padding:0; height:100%; overflow:hidden;
  background:var(--table-deep);
}
body{
  font-family:var(--font-ui);
  color:var(--text-primary);
  -webkit-text-size-adjust:100%;
  -webkit-tap-highlight-color:transparent;
}

:root{
  /* --- Crazy Eights category environment (§4). Its own, and only this. --- */
  --table-bg:#5B3A96;
  --table-deep:#2E1B52;
  --table-highlight:#7A52BE;
  --felt-glow:rgba(190,150,255,.20);

  /* --- Shared product tokens (§5): same values as the rest of the
         catalogue, referenced rather than redefined. --- */
  --text-primary:#F6F7F4;
  --text-secondary:#D6CFE6;
  --text-muted:#B6ACC9;

  --action:#F0B84B;
  --action-text:#1A1F1D;

  --success:#62C58B;
  --danger:#E45B64;
  --active:#62C4FF;

  --card-bg:#FAFAF7;
  --card-black:#202322;
  /* #D84A52 on the card face is 4.0:1 — under the WCAG floor for normal
     text, in every game in the catalogue that shows a red card. Found by
     contrast-sweep.js on 2026-09-21, after Ronan reported the Cribbage
     captions from his phone. #CB343E is 4.9:1 and still plainly red. */
  --card-red:#CB343E;

  --line:rgba(255,255,255,.14);
  --line-soft:rgba(255,255,255,.08);
  /* Ronan, 2026-09-21, about Cribbage but true here too: "on mobile font
     hard to read too similar to felt". .22 is a tint, not a plate — over
     the light middle of the violet it composites to rgb(106,75,158) and
     --text-muted on that is 3.1:1. A plate has to make the ground a known
     quantity. Held by contrast-sweep.js. */
  --panel:rgba(0,0,0,.46);
  /* For the captions that sit straight on the felt, where no amount of
     lifting the ink is enough at 9-10px against #7A52BE. */
  --felt-plate:rgba(22,12,44,.58);

  --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 throughout, the catalogue's canonical
     proportion. Hands start at five cards and grow while a player is stuck,
     so the hand card is sized for comfort and the fan tightens instead. */
  --card-w:clamp(50px, min(6.8vw, 11.6dvh), 88px);
  --card-h:calc(var(--card-w) / 0.70);

  --back-w:clamp(16px, 1.9vw, 26px);
  --back-h:calc(var(--back-w) / 0.70);

  /* The stock and active-suit cells either side of the discard. Wide enough
     for the longest content each will ever hold ("Diamonds", a two-digit
     count) so neither can resize under its own text. */
  --side-cell:clamp(96px, 11vw, 132px);
  --opp-cell:clamp(92px, 11vw, 124px);

  /* §17.1/§18.1 recognition, §17.2/§18.2 travel, §19.3 draw. Declared once,
     here, and referenced everywhere else. */
  --dur-select:150ms;
  --dur-travel:220ms;
  --dur-draw:250ms;
}

/* ------------------------------------------------------------- shell --- */

.game{
  position:relative;
  display:grid;
  grid-template-rows:auto minmax(0,1fr) auto auto auto;
  grid-template-areas:'header' 'table' 'instruction' 'hand' 'action';
  height:100dvh; max-height:100dvh; width:100%;
  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));
  gap:var(--space-2);
  background:
    radial-gradient(ellipse at 50% 34%, var(--table-highlight) 0%, var(--table-bg) 46%, var(--table-deep) 100%);
}

/* ------------------------------------------------------------ header --- */

.zone-header{
  grid-area:header;
  display:flex; align-items:center; gap:var(--space-3);
  flex-wrap:nowrap; min-width:0;
  padding-bottom:var(--space-1);
  border-bottom:1px solid var(--line-soft);
}
.wordmark .title{
  font-family:var(--font-display); font-weight:800;
  font-size:clamp(15px,1.9vw,23px); letter-spacing:.01em; white-space:nowrap;
}

.scoreboard{ display:flex; align-items:center; gap:var(--space-2); min-width:0; margin-left:auto; }
/* Anything that sits DIRECTLY on the violet gets a plate — see --felt-plate. */
.sb-caption, .hand-label, .pile-label, .pile-count, .opponent{
  background:var(--felt-plate); border-radius:4px;
}
.sb-caption, .hand-label, .pile-label, .pile-count{ padding:1px 5px; }
.sb-caption{
  font-family:var(--font-mono); font-size:12px; font-weight:600; letter-spacing:.1em;
  text-transform:uppercase; color:var(--text-secondary); white-space:nowrap;
}
.score-box{
  display:flex; align-items:baseline; gap:var(--space-1);
  padding:2px var(--space-2); border-radius:var(--radius);
  background:var(--panel); border:1px solid var(--line-soft);
  transition:border-color .16s ease, background .16s ease;
}
/* Never colour alone (§42): the acting seat also gets a weight change. */
/* The acting tint has to be a DARKER plate, not a lighter wash: at .14 it
   replaced the plate underneath and put the label back on the felt. */
.score-box.is-acting{ border-color:var(--active); background:rgba(18,40,72,.70); }
.score-box.is-acting .score-label{ color:var(--text-primary); font-weight:800; }
.score-label{ font-size:12px; font-weight:600; color:var(--text-primary); white-space:nowrap; }
.score-value{ font-family:var(--font-mono); font-weight:700; font-size:15px; }
.score-box.you .score-label{ color:#FFD27A; }   /* the gold, lifted to 7:1 on the plate */
.score-target{
  font-family:var(--font-mono); font-size:12px; font-weight:600; color:var(--text-secondary); white-space:nowrap;
  background:var(--felt-plate); border-radius:4px; padding:1px 5px;
}

.secondary-controls{ display:flex; align-items:center; gap:var(--space-2); }
.hand-label{
  font-family:var(--font-mono); font-size:12px; font-weight:600; color:var(--text-primary); white-space:nowrap;
}

/* Icon-only buttons carry a text label underneath — standing rule. */
.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);
}
.ctrl-btn.primary:hover:not(:disabled){ filter:brightness(1.07); }
.icon-btn{ display:flex; flex-direction:column; align-items:center; gap:1px; padding:var(--space-1) var(--space-2); line-height:1; }
.icon-glyph{ font-size:15px; }
.icon-label{ font-size:12px; font-weight:700; letter-spacing:.03em; text-transform:uppercase; color:var(--text-primary); }

/* ------------------------------------------------------------- table --- */

.zone-table{ grid-area:table; min-height:0; display:flex; }
.table{
  position:relative; flex:1; min-height:0;
  display:grid;
  /* The centre row IS the game: stock, discard, active suit. Opponents sit
     above it and the suit chooser below it, so nothing ever overlaps the
     central reference (§9). */
  /* FIXED centre cells. Sized to content, the stock count narrowing from
     "31" to "9" and the suit name from "Diamonds" to "Spades" both dragged
     the discard sideways — measured at 5px across six plays, against §9's
     1px. The discard is the thing every player is looking at; it does not
     move because a number got shorter. */
  grid-template-columns:1fr var(--side-cell) auto var(--side-cell) 1fr;
  grid-template-rows:auto minmax(0,1fr) auto;
  grid-template-areas:
    'opps  opps    opps    opps  opps'
    '.     stock   discard suit  .'
    'log   log     log     log   log'
    'chooser chooser chooser chooser chooser';
  align-items:center; justify-items:center;
  gap:var(--space-3);
  padding:var(--space-2);
  border-radius:calc(var(--radius) * 1.6);
  border:1px solid var(--line-soft);
  background:
    radial-gradient(ellipse at 50% 45%, var(--felt-glow) 0%, transparent 62%);
}

/* ---- opponents (§8, §23) ---- */
.opponents{
  grid-area:opps; align-self:start;
  display:flex; justify-content:center; align-items:flex-start;
  gap:clamp(var(--space-3), 3vw, var(--space-6));
  width:100%;
}
.opponent{
  position:relative;
  display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:var(--space-1) var(--space-2);
  border-radius:var(--radius);
  border:1px solid transparent;
  /* FIXED, not min-width. The one-card badge is ~70px wide, so while it was
     in flow it pushed this box past its minimum, and a centred row of three
     then re-centred: every seat moved when any seat reached its last card.
     §32 says that treatment must not move the seat. */
  width:var(--opp-cell);
  transition:border-color .16s ease, background .16s ease;
}
.opponent.is-acting{ border-color:var(--active); background:rgba(18,40,72,.70); }
.opp-head{ display:flex; align-items:center; gap:var(--space-1); }
.opp-dot{
  width:7px; height:7px; border-radius:50%;
  background:transparent; border:1px solid var(--line);
}
.opponent.is-acting .opp-dot{ background:var(--active); border-color:var(--active); }
.opp-name{ font-size:13px; font-weight:700; white-space:nowrap; }
/* §23: explicit text, so the one-card state never depends on colour, and a
   badge rather than a size change so the seat cannot move (§32). */
/* Out of flow as well as fixed-width, so the badge cannot change the box it
   sits in even if its text changes. */
.opp-badge{
  display:none;
  position:absolute; left:50%; bottom:-7px; transform:translateX(-50%);
  font-family:var(--font-mono); font-size:12px; font-weight:700;
  letter-spacing:.04em; padding:1px 5px; border-radius:4px;
  /* No pale type: white on --danger is 3.6:1; this red is over 8:1. */
  background:#8E1922; color:#fff; white-space:nowrap;
}
.opponent.is-last-card .opp-badge[data-role='lastcard']{ display:inline-block; }
.opp-count{ display:flex; align-items:baseline; gap:3px; }
.opp-count-value{ font-family:var(--font-mono); font-weight:700; font-size:clamp(13px,1.3vw,15px); }
.opp-count-label{ font-size:12px; font-weight:600; color:var(--text-secondary); letter-spacing:.02em; }
.opp-backs{ display:flex; margin-top:2px; min-height:calc(var(--back-h) * 0.6); }
.opp-backs .card-back{ margin-left:calc(var(--back-w) * -0.62); }
.opp-backs .card-back:first-child{ margin-left:0; }

.card-back{
  width:var(--back-w); height:var(--back-h);
  border-radius:4px; 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:1px solid var(--back-white);
  box-shadow:0 2px 5px rgba(0,0,0,.4);
}

/* ---- stock (§19, §22) ---- */
.stock{
  grid-area:stock; width:100%;
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1);
}
.pile-label{
  font-family:var(--font-mono); font-size:12px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--text-secondary);
}
.stock-stack{
  position:relative; width:var(--card-w); height:var(--card-h);
  border-radius:8px;
  display:flex; align-items:center; justify-content:center;
}
.stock-stack .card-back{ width:100%; height:100%; border-radius:8px; }
.stock.is-available{ cursor:pointer; }
[data-coach="on"] .stock.is-available .stock-stack{ box-shadow:0 0 0 2px var(--action), 0 8px 18px rgba(0,0,0,.4); }   /* Coach's (2026-10-10) */
/* §22: an empty stock must not look like it can still be drawn from. */
.stock.is-empty .stock-stack{ opacity:.28; }
.stock.is-empty .stock-stack .card-back{ filter:grayscale(1); }
/* Tabular figures: a proportional "1" is narrower than a "3", which is the
   same class of wobble at a smaller scale. */
.pile-count{
  font-family:var(--font-mono); font-size:13px; font-weight:700;
  font-variant-numeric:tabular-nums;
}

/* ---- discard: the dominant element (§11, §30) ---- */
.discard{
  grid-area:discard;
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1);
}
.discard-slot{
  width:calc(var(--card-w) * 1.28); height:calc(var(--card-w) * 1.28 / 0.70);
  display:flex; align-items:center; justify-content:center;
  border-radius:10px;
}
.discard-slot .card{ width:100%; height:100%; }

/* ---- active suit (§12) ---- */
.active-suit{
  grid-area:suit;
  display:flex; flex-direction:column; align-items:center; gap:1px;
  padding:var(--space-2) var(--space-3);
  border-radius:var(--radius);
  background:var(--panel); border:1px solid var(--line);
  width:100%;
}
.as-caption{
  font-family:var(--font-mono); font-size:12px; font-weight:600; letter-spacing:.06em;
  text-transform:uppercase; color:var(--text-secondary); text-align:center;
}
.as-symbol{ font-size:clamp(24px,3.2vw,38px); line-height:1.05; }
.as-symbol.is-red{ color:var(--card-red); }
.as-symbol.is-black{ color:var(--text-primary); }
/* The NAME is what makes this readable without colour (§12, §42). */
.as-name{ font-size:clamp(13px,1.2vw,15px); font-weight:700; letter-spacing:.02em; }
.as-note{
  font-family:var(--font-mono); font-size:12px; font-weight:600; color:var(--action);
  letter-spacing:.02em; margin-top:1px; text-align:center;
}

/* ---- suit chooser (§16) ----
   On the table, under the centre row. The hand stays fully visible, which
   is the whole point: you cannot choose a suit sensibly without reading
   your own cards. */
/* ---- §27A: what the opponents did since your turn ----------------------
   Three seats act between the player's turns and the discard pile only ever
   shows the last of them. This accumulates, and is cleared by the player's
   own next move — never by an opponent's, never by a clock. The plate is the
   same one every caption on this felt now uses (V16): #B6ACC9 on the light
   middle of the violet is 2.6:1 without it. */
.turn-log{
  grid-area:log; justify-self:center;
  display:flex; flex-direction:column; align-items:stretch; gap:2px;
  min-width:172px; max-width:min(94%, 340px);
  padding:var(--space-2) var(--space-3);
  border-radius:var(--radius);
  background:var(--felt-plate);
  border:1px solid var(--line);
}
.turn-log[hidden]{ display:none; }
.tl-caption{
  font-family:var(--font-mono); font-size:12px; font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--text-secondary);
  padding-bottom:2px; border-bottom:1px solid var(--line-soft);
}
.tl-list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:1px; }
.tl-row{
  display:flex; align-items:baseline; gap:var(--space-2);
  font-size:13px; font-weight:600; line-height:1.35;
}
.tl-who{
  font-family:var(--font-mono); font-weight:700; font-size:13px;
  letter-spacing:.03em; text-transform:uppercase;
  color:var(--text-primary); min-width:52px;
}
.tl-what{ color:var(--text-primary); }
/* The suit colour is never the only cue — the suit is spelled out too.
   On the dark plate the card-face red is 2.6:1; a light red keeps the
   colour and passes 7:1 (no pale type, 2026-10-04). */
.tl-card.is-red{ color:#FFA8AF; font-weight:700; }
.tl-card.is-black{ color:var(--text-primary); font-weight:700; }

.suit-chooser{
  grid-area:chooser; align-self:end;
  display:flex; flex-direction:column; align-items:center; gap:var(--space-1);
  padding:var(--space-2) var(--space-3);
  border-radius:var(--radius);
  background:rgba(0,0,0,.42);
  border:1px solid var(--action);
  box-shadow:0 10px 26px rgba(0,0,0,.4);
}
.suit-chooser[hidden]{ display:none; }
.sc-title{
  font-family:var(--font-mono); font-size:12px; font-weight:700; letter-spacing:.06em;
  text-transform:uppercase; color:#FFD27A;
}
.sc-grid{ display:flex; gap:var(--space-2); }
.suit-option{
  display:flex; flex-direction:column; align-items:center; gap:1px;
  min-width:64px; min-height:48px;
  padding:var(--space-1) var(--space-2);
  border-radius:var(--radius); cursor:pointer;
  background:var(--card-bg); border:1px solid var(--line);
  transition:transform .14s ease, box-shadow .14s ease;
}
.suit-option:hover{ transform:translateY(-2px); box-shadow:0 6px 14px rgba(0,0,0,.4); }
.suit-option:focus-visible{ outline:2px solid var(--active); outline-offset:2px; }
.so-symbol{ font-size:20px; line-height:1; }
.so-name{ font-size:12px; font-weight:700; letter-spacing:0; color:var(--card-black); }
.suit-option.is-red .so-symbol{ color:var(--card-red); }
.suit-option.is-black .so-symbol{ color:var(--card-black); }

/* ------------------------------------------------------- instruction --- */

.zone-instruction{ grid-area:instruction; display:flex; justify-content:center; }
.instruction{
  font-family:var(--font-mono); font-weight:700;
  font-size:clamp(13px,1.4vw,15px); letter-spacing:.08em;
  color:var(--text-primary); text-align:center;
  padding:var(--space-1) var(--space-3);
  border-radius:var(--radius);
  background:var(--panel); border:1px solid var(--line-soft);
  min-height:26px; display:flex; align-items:center; justify-content:center;
}
/* §14: the illegal-play warning is the SAME line in the alarm colour. One
   instruction at a time, never two stacked. */
.instruction.is-warning{
  color:#FFC9CD; border-color:rgba(228,91,100,.5); background:rgba(228,91,100,.17);
}

/* -------------------------------------------------------------- hand --- */

.zone-hand{ grid-area:hand; display:flex; justify-content:center; align-items:flex-end; min-width:0; }
.player-hand{
  display:flex; justify-content:center; align-items:flex-end;
  gap:var(--space-1);
  /* §10: the cards recompose inside the box; the BOX does not move. A
     content-width row would walk its own left edge inward as cards leave. */
  width:100%; max-width:100%;
  min-height:calc(var(--card-h) + 14px);
  padding-top:12px;                 /* headroom for the selected card's lift */
  flex-wrap:nowrap;
}
/* Q2 (Ronan, 2026-10-08): the fan's spacing is set per card by the
   controller (fitHand) so a big hand never leaves the screen. On a phone,
   once a card would show less than 30px, the hand becomes two rows; the
   second row sits half a card over the first, every rank and suit corner
   still clear. */
.player-hand.is-two-rows{ flex-wrap:wrap; align-content:flex-end; }
.player-hand .hand-row-break{ flex-basis:100%; height:0; }
.player-hand.is-two-rows .is-row-2{ margin-top:calc(var(--card-h) * -0.5); }
.crazy-eights-player-card{ cursor:pointer; flex:none; }

/* ------------------------------------------------------------ action --- */

.zone-action{
  grid-area:action;
  display:flex; align-items:center; justify-content:center; gap:var(--space-3);
  flex-wrap:wrap;
}
.secondary-play{ display:flex; gap:var(--space-2); }

/* -------------------------------------------------------------- card --- */

.card{
  position:relative;
  width:var(--card-w); height:var(--card-h);
  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;
  outline:2px solid transparent; outline-offset:0;
  transition:transform var(--dur-select) ease, box-shadow var(--dur-select) ease,
             outline-color var(--dur-select) ease, filter var(--dur-select) ease;
}
.card.red{ color:var(--card-red); }
.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:1; text-align:center;
  font-size:clamp(9px, calc(var(--card-w) * 0.20), 15px); line-height:1.06;
}
.card-corner-top{ top:4px; left:4px; }
.card-corner-bottom{ right:4px; bottom:4px; 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:calc(var(--card-w) * 0.52); opacity:.9;
}

/* §13: legal cards are emphasised WITHOUT obscuring the face. Illegal cards
   stay visible and muted — never hidden (template §19). */
[data-coach="on"] .card.is-legal{ box-shadow:0 5px 12px rgba(0,0,0,.42), 0 0 0 2px var(--action); }   /* the "play this" ring is Coach's (2026-10-10) */
[data-coach="on"] .card.is-legal:hover{ transform:translateY(-6px); }
[data-coach="on"] .card.is-illegal{ filter:grayscale(.62) brightness(.68); cursor:not-allowed; }   /* the greying is Coach's too in Crazy Eights (Ronan 2026-10-11 07:21): matching is the decision */
.card.is-selected{
  transform:translateY(-14px);
  outline-color:var(--active);
  box-shadow:0 12px 22px rgba(0,0,0,.5), 0 0 0 2px var(--active);
}
.discard-card{ box-shadow:0 8px 20px rgba(0,0,0,.5), inset 0 0 0 1px rgba(0,0,0,.08); }

/* ------------------------------------------------------------ Coach --- */
/* Q9/Q16-Q20 (Ronan, 2026-10-08). The label says "Coach on" / "Coach off",
   as in the rummy games; a fixed width so the header never moves when it
   changes. */
.coach-btn{ min-width:84px; }
.coach-btn.is-on{ border-color:var(--action); }
.hand-label-row{ display:none; }
.zone-instruction{ flex-wrap:wrap; align-items:center; gap:var(--space-2); }
.coach-tip{
  display:flex; align-items:baseline; gap:var(--space-2);
  font-size:13px; font-weight:600; line-height:1.3; color:var(--text-primary);
  padding:3px var(--space-3); border-radius:var(--radius);
  background:var(--felt-plate); border:1px solid rgba(240,184,75,.55);
  max-width:100%;
}
.coach-tip[hidden]{ display:none; }
.ct-value{ font-family:var(--font-mono); font-weight:700; color:#FFD27A; white-space:nowrap; }
.ct-text:empty{ display:none; }
/* Coach's pick in the suit chooser: a gold ring and a tag on the corner,
   over nothing but the option's own edge. */
.suit-option{ position:relative; }
.suit-option.is-coach-pick{ box-shadow:0 0 0 3px var(--action), 0 6px 14px rgba(0,0,0,.4); }
.suit-option.is-coach-pick::after{
  content:'MOST'; position:absolute; top:-9px; right:-6px;
  font-family:var(--font-mono); font-size:12px; font-weight:700; line-height:1;
  padding:2px 4px; border-radius:4px; background:#1A1F1D; color:#FFD27A;
}
.start-choices{ display:flex; gap:var(--space-2); justify-content:center; flex-wrap:wrap; }
.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:var(--space-3) 0 0; }

/* ----------------------------------------------------------- overlays --- */

.overlay{
  position:absolute; inset:0; z-index:40;
  display:none; align-items:center; justify-content:center;
  background:rgba(12,6,26,.76); backdrop-filter:blur(3px);
  padding:var(--space-4);
}
.overlay.open{ display:flex; }
.overlay-panel{
  width:min(92vw, 460px); max-height:86dvh; overflow-y:auto;
  padding:var(--space-5);
  border-radius:calc(var(--radius) * 1.6);
  background:linear-gradient(180deg, #26144A, #1A0E33);
  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(19px,2.4vw,24px); 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);
}
.result-table{ width:100%; border-collapse:collapse; margin-bottom:var(--space-3); font-size:13px; }
.result-table th{
  font-family:var(--font-mono); font-size:13px; letter-spacing:.04em; text-transform:uppercase;
  color:var(--text-secondary); font-weight:700; padding:var(--space-1) var(--space-2);
  border-bottom:1px solid var(--line); text-align:left;
}
.result-table td{ font-weight:600; padding:var(--space-1) var(--space-2); border-bottom:1px solid var(--line-soft); text-align:left; }
.result-reason{ font-size:13px; font-weight:600; color:var(--text-primary); margin:0 0 var(--space-4); line-height:1.5; }
.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:13px; 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:last-child{ border-bottom:none; }

/* The footer copy is in the markup for search engines and is not part of the
   table. Two earlier attempts were both wrong: left in flow it sat one pixel
   below a 100dvh grid and put the page into vertical scroll, and squeezed to
   1px with overflow hidden it reported 1407px of clipped text to the
   containment check — which was right to complain, because a check that
   ignores hidden overflow cannot tell a caption from a lost sentence.
   display:none is what the rest of the catalogue does. */
footer{ display:none; }

/* ------------------------------------------------------------ mobile --- */

@media (max-width:640px){
  :root{
    --card-w:clamp(42px, min(12vw, 9.4dvh), 64px);
    --back-w:clamp(13px, 3.6vw, 20px);
    --side-cell:clamp(74px, 22vw, 104px);
    --opp-cell:clamp(80px, 26vw, 104px);
  }
  .game{ gap:var(--space-1); }
  .zone-header{ flex-wrap:wrap; gap:var(--space-2); }
  .wordmark .title{ font-size:15px; }
  .scoreboard{ order:3; width:100%; margin-left:0; justify-content:space-between; gap:var(--space-1); }
  .sb-caption, .score-target{ display:none; }
  /* Q17: the hand number moves to the score row; Coach takes its place. */
  #handLabel{ display:none; }
  /* "Coach on" is wider than "Coach": tighter header buttons keep the title,
     Rules, Coach and New on one row at 330. */
  .zone-header .icon-btn{ padding:var(--space-1) 6px; }
  .zone-header .secondary-controls{ gap:6px; }
  .coach-btn{ min-width:78px; }
  .hand-label-row{ display:inline-block; }
  .coach-tip{ font-size:13px; padding:2px var(--space-2); }
  .score-box{ padding:1px var(--space-1); }
  .score-label{ font-size:12px; }
  .score-value{ font-size:14px; }
  .table{
    /* Portrait: the centre row stays a row — stock, discard and active suit
       read left to right — but the columns give the discard the room. */
    grid-template-columns:var(--side-cell) minmax(0,auto) var(--side-cell);
    grid-template-areas:
      'opps    opps    opps'
      'stock   discard suit'
      'log     log     log'
      'chooser chooser chooser';
    gap:var(--space-2);
  }
  .opponents{ gap:var(--space-2); }
  .opponent{ padding:2px var(--space-1); }
  .opp-backs{ display:none; }   /* the count is the information; the fan is decoration */
  .active-suit{ padding:var(--space-1) var(--space-2); }
  .as-symbol{ font-size:24px; }
  .discard-slot{ width:calc(var(--card-w) * 1.2); height:calc(var(--card-w) * 1.2 / 0.70); }
  .suit-option{ min-width:48px; min-height:46px; }
  /* Fanned cards cannot each be 44px wide; what must stay tappable is each
     neighbour's exposed index (template §39). */
  .player-hand{ gap:0; }
  .instruction{ font-size:13px; letter-spacing:.03em; padding:2px var(--space-2); }
  .zone-action{ gap:var(--space-2); }
  .ctrl-btn{ padding:var(--space-2); }
  /* Q3: 44px touch targets for the play actions. */
  .zone-action .ctrl-btn{ min-height:44px; }
  .ctrl-btn.primary{ padding:var(--space-2) var(--space-4); }
  /* §27A on a phone: the same record, tighter. */
  .turn-log{ min-width:0; max-width:97%; padding:var(--space-1) var(--space-2); }
  .tl-row{ font-size:13px; }
  .tl-who{ min-width:50px; font-size:13px; }
}

/* --------------------------------------------------- reduced motion --- */
/* §35: every duration here is SHORTENED, never removed. A removed
   transition stops transitionend firing, and a controller waiting on it
   deadlocks — the reason is recorded once in conventions §8. Stated in this
   game's own stylesheet rather than inherited only from the shared sheet. */
/* ---------------------------------------------- sideways and short --- */
/* Q15 (Ronan, 2026-10-08, "fix"). A phone held sideways leaves the table
   about 140px of height, and the stacked rows above (opponents, centre,
   record, chooser) need over 250px: they were drawn over one another. Here
   the table is ONE row — the opponents stacked on the left, then stock,
   discard and active suit, and on the right "Since your turn" or the suit
   chooser (never both at once: the record clears when the player moves). */
@media (min-width:641px) and (max-height:500px){
  .game{ gap:var(--space-1); }
  .zone-header{ padding-bottom:2px; }
  .table{
    grid-template-columns:auto var(--side-cell) auto var(--side-cell) minmax(0,1fr);
    grid-template-rows:minmax(0,1fr);
    grid-template-areas:'opps stock discard suit side';
    gap:var(--space-3); padding:var(--space-1) var(--space-2);
  }
  .opponents{ flex-direction:column; align-self:center; gap:var(--space-1); width:auto; }
  .opponent{ flex-direction:row; gap:var(--space-2); width:auto; min-width:118px; justify-content:space-between; padding:2px var(--space-2); }
  .opp-backs{ display:none; }
  .opp-badge{ position:static; transform:none; }
  .opponent.is-last-card .opp-count{ display:none; }
  .turn-log, .suit-chooser{ grid-area:side; align-self:center; justify-self:start; }
  .turn-log{ min-width:0; max-width:100%; }
  .discard-slot{ width:var(--card-w); height:var(--card-h); }
  .player-hand{ padding-top:10px; min-height:calc(var(--card-h) + 10px); }
}

/* Sideways with Coach in the header the row ran ~100px short and "game ends
   at 100" ran under "Hand 1": the same words, shorter. */
.st-short{ display:none; }
@media (min-width:641px) and (max-width:1000px){
  .st-long{ display:none; }
  .st-short{ display:inline; }
}
/* The iPhone SE frame (345x504, may scroll vertically: Q1): with the Coach
   line up, the table's rows were squeezed until the piles ran into the
   opponents. Below 540px tall the page grows past the frame instead and
   scrolls; nothing is drawn over anything. */
@media (max-width:640px) and (max-height:540px){
  html, body{ height:auto; overflow-y:auto; }
  .game{ height:auto; max-height:none; min-height:100dvh; }
  .table{ min-height:max-content; }
}

/* Q3 on a touch screen held sideways too: the play actions stay 44px. */
@media (pointer:coarse){
  .zone-action .ctrl-btn{ min-height:44px; }
}

@media (prefers-reduced-motion: reduce){
  :root{
    --dur-select:1ms;
    --dur-travel:1ms;
    --dur-draw:1ms;
  }
  .card, .suit-option, .ctrl-btn, .opponent, .score-box{
    transition-duration:1ms !important;
  }
}

/* R6a (2026-10-11): the Resume button and where the saved game was */
#btnResume{ display:block; width:min(100%, 320px); margin:0 auto var(--space-2); }
#btnResume[hidden], #resumeContext[hidden]{ display:none; }
.resume-context{ font-size:13px; font-weight:600; color:var(--text-primary); line-height:1.4; margin:0 0 var(--space-3); }
