/*
 * Two things are being combined here.
 *
 * From the owner-supplied direction: a warm paper page, a real green felt with
 * seats arranged around it, an acid-lime accent, and surfaces with depth. The
 * austere grey of v0.1 satisfied every prohibition and had no life in it.
 *
 * From what this build already earned: nothing encodes meaning by colour alone
 * (suits carry a letter, the three verdict states carry a shape), uncertainty
 * notes sit at body contrast rather than being the faintest thing on screen, and
 * the type scale is in rem so it follows the reader's own font size.
 */

:root {
  color-scheme: light dark;

  --type-micro: 0.6875rem;
  --type-note: 0.75rem;
  --type-aux: 0.875rem;
  --type-body: 1rem;
  --type-head: 1.25rem;
  --type-head-lg: 1.75rem;
  --type-figure: 2.5rem;

  --space-1: 8px;
  --space-2: 16px;
  --space-3: 24px;

  --paper: #f3f5ef;
  --surface: #ffffff;
  --soft: #e9eee7;
  --line: #dce2da;
  --ink: #152019;
  --muted: #5b665d;

  --felt: #164d38;
  --felt-2: #237052;
  --night: #0e1712;
  --felt-rail: #34463d;
  --felt-line: #7ba06f;
  --acid: #c9fb62;
  --card-face: #ffffff;
  --player-warm: #e6a06f;
  --player-sun: #e7cb74;
  --player-cool: #8eb7c9;
  --player-sage: #9fbea4;
  --player-violet: #b5a1ce;
  /* The outline of a chosen thing. Flips with the theme. */
  --selected: #164d38;
  /* Ink drawn on top of a judgment fill. Follows the fill, not the surface. */
  --on-judgment: #ffffff;
  /* Secondary text on the felt. Measured 4.68:1 against the lightest stop
     (#237052); the previous #9dbfaa was 2.98:1 and carried the SPR basis,
     the action history and the pot label. */
  --on-felt: #eef4ee;
  --on-felt-muted: #d6e8dc;

  /* Dark enough to carry white body text. */
  --action-primary: #14452f;
  --judgment-match: #14452f;
  --judgment-conditional: #4a4550;
  --judgment-diverge: #8c2b16;

  --radius: 14px;
  --radius-sm: 10px;
  --shadow: 0 18px 50px rgba(26, 48, 35, .12);
  --shadow-sm: 0 2px 8px rgba(26, 48, 35, .08);

  --font-text: "Geist", system-ui, -apple-system, "Hiragino Sans", "Noto Sans JP", sans-serif;
  --font-figure: "Geist Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px));
  scroll-padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px));
}

main { max-width: 480px; margin: 0 auto; padding: var(--space-2); }

/* ------------------------------------------------------------------ chrome */

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-2); margin-bottom: 10px;
}
.topbar .date { font-size: var(--type-note); color: var(--muted); letter-spacing: .08em; }
.topbar h1 { margin: 0; font-size: var(--type-head-lg); letter-spacing: -.02em; font-weight: 800; }
.topbar .right { text-align: right; }

.home-link {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  color: var(--ink); font: inherit; font-size: var(--type-aux); font-weight: 600;
  padding: 8px 16px; min-height: 50px; cursor: pointer;
}
.home-link:hover { border-color: var(--ink); }

.streak {
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  padding: 7px 14px; font-size: var(--type-aux); font-weight: 600;
}
.streak b { font-family: var(--font-figure); font-size: var(--type-head); }

.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--space-2); margin-bottom: var(--space-2); box-shadow: var(--shadow-sm);
}
.panel > .label {
  font-size: var(--type-note); color: var(--muted); font-weight: 600;
  letter-spacing: .12em; display: block; margin-bottom: 6px;
}

.dominant { font-size: var(--type-head); font-weight: 800; line-height: 1.45; margin: 0; letter-spacing: -.01em; }
.basis { font-size: var(--type-aux); color: var(--ink); margin-top: var(--space-1); }

/* The counter and bar the reference leads with, in place of a page title. */
.progress { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.progress .count { font-family: var(--font-figure); font-size: var(--type-head-lg); font-weight: 800; letter-spacing: -.02em; }
.progress .of { font-family: var(--font-figure); font-size: var(--type-aux); color: var(--muted); }
.progress .bar { flex: 1; height: 6px; border-radius: 999px; background: var(--soft); overflow: hidden; }
.progress .bar span { display: block; height: 100%; background: var(--felt); border-radius: 999px; }

.slots { display: flex; gap: 6px; }
.slots div {
  flex: 1; text-align: center; padding: 10px 0; border-radius: var(--radius-sm);
  background: var(--soft); color: var(--muted); font-family: var(--font-figure); font-size: var(--type-aux);
}
.slots div.done { background: var(--felt); color: var(--on-felt); }

.cta {
  display: block; width: 100%; min-height: 56px; border-radius: var(--radius);
  background: var(--action-primary); color: var(--on-judgment);
  border: 0; font: inherit; font-size: var(--type-head); font-weight: 700;
  cursor: pointer; text-align: left; padding: 0 var(--space-2); margin-top: var(--space-2);
}
.cta:disabled { background: var(--soft); color: var(--muted); cursor: default; }
.cta .arrow { float: right; }

/* -------------------------------------------------------------- the felt */

.table {
  color: var(--on-felt); box-shadow: var(--shadow);
}

.compact-table {
  background: var(--night);
  border-radius: 24px; padding: 12px;
}

/*
 * The supplied table reference is translated into the drill's information:
 * one tall oval, six stable seat anchors, the pot and board on the felt, and the
 * learner highlighted at the near rail. Grid areas keep the DOM in action order
 * while providing the spatial table model a poker player already knows.
 */
.full-table {
  background: var(--night); border-radius: 28px; padding: 12px 8px;
  overflow: hidden;
}
.table-meta {
  display: flex; align-items: center; gap: 8px; padding: 0 8px 6px;
  font-family: var(--font-figure); font-size: var(--type-micro); font-weight: 700;
  letter-spacing: .13em; color: var(--on-felt-muted);
}

.full-table .felt {
  position: relative; isolation: isolate;
  display: grid; gap: 4px;
  min-height: clamp(368px, 99vw, 438px);
  grid-template-columns: minmax(0, 1fr) 104px minmax(0, 1fr);
  grid-template-rows: 66px 1fr 1fr 72px;
  grid-template-areas:
    ".    top    ."
    "left center right"
    "ll   center rr"
    ".    bottom .";
  padding: 6px 0 8px;
}
.full-table .felt::before,
.full-table .felt::after {
  content: ""; position: absolute; pointer-events: none; z-index: -1;
  border-radius: 49% / 45%;
}
.full-table .felt::before {
  inset: 24px 7px 28px;
  background: var(--felt-rail);
  box-shadow: 0 16px 28px rgba(0, 0, 0, .28);
}
.full-table .felt::after {
  inset: 34px 18px 38px;
  border: 2px solid rgba(123, 160, 111, .72);
  background:
    radial-gradient(circle at 50% 42%, rgba(43, 126, 86, .82), transparent 48%),
    linear-gradient(180deg, var(--felt-2), #12422f 72%, #0f3527);
  box-shadow: inset 0 0 46px rgba(3, 19, 12, .42);
}
.full-table .seat-top { grid-area: top; justify-self: center; align-self: start; }
.full-table .seat-left { grid-area: left; justify-self: start; align-self: center; transform: translateY(-42px); }
.full-table .seat-right { grid-area: right; justify-self: end; align-self: center; transform: translateY(-42px); }
.full-table .seat-ll { grid-area: ll; justify-self: start; align-self: center; transform: translateY(2px); }
.full-table .seat-rr { grid-area: rr; justify-self: end; align-self: center; transform: translateY(2px); }
.full-table .seat-bottom { grid-area: bottom; justify-self: center; align-self: end; }
.full-table .middle { grid-area: center; align-self: stretch; }

.seat {
  position: relative; z-index: 2;
  display: flex; align-items: center; gap: 6px;
  width: clamp(104px, 30vw, 126px); min-height: 58px;
  background: rgba(8, 22, 15, .94); border: 1px solid rgba(214, 232, 220, .28);
  border-radius: 12px; padding: 6px 7px; font-size: var(--type-micro);
  box-shadow: 0 8px 18px rgba(0, 0, 0, .26);
}
.seat-top,
.seat-bottom { width: clamp(136px, 41vw, 168px); }
.seat.hero {
  border-color: var(--acid); border-width: 2px; background: rgba(8, 22, 15, .98);
  box-shadow: 0 0 0 2px rgba(201, 251, 98, .14), 0 10px 22px rgba(0, 0, 0, .34);
}
.seat.folded { color: var(--on-felt-muted); background: rgba(8, 22, 15, .82); }
.player-token {
  flex: none; display: grid; place-items: center;
  inline-size: 34px; block-size: 34px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, .72);
  background: var(--player-sage); color: var(--night);
  font-family: var(--font-figure); font-size: .625rem; font-weight: 900;
  letter-spacing: -.04em;
}
.seat-left .player-token { background: var(--player-sun); }
.seat-right .player-token { background: var(--player-warm); }
.seat-ll .player-token { background: var(--player-violet); }
.seat-rr .player-token { background: var(--player-cool); }
.seat.hero .player-token { background: var(--acid); }
.seat.folded .player-token { filter: saturate(.25); }
.seat-copy { min-width: 0; line-height: 1.25; }
.seat-head { display: flex; align-items: center; gap: 4px; min-width: 0; }
.seat .pos {
  flex: none; color: var(--acid); font-family: var(--font-figure);
  font-size: .625rem; font-weight: 800; letter-spacing: .04em;
}
.seat .name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 800; letter-spacing: .01em;
}
.seat .stack {
  font-family: var(--font-figure); display: block; margin-top: 2px;
  color: var(--on-felt-muted); font-size: var(--type-micro);
}
.seat .act {
  position: absolute; inset-block-end: -13px; inset-inline-start: 50%; transform: translateX(-50%);
  max-width: calc(100% - 12px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 2px 8px; border-radius: 999px;
  color: var(--on-felt); font-size: .625rem; font-weight: 800; letter-spacing: .04em;
  background: #33443b; box-shadow: 0 3px 8px rgba(0, 0, 0, .22);
}
.seat.hero .act { background: var(--acid); color: var(--night); }
.dealer {
  position: absolute; inset-inline-end: -7px; inset-block-end: -8px;
  display: grid; place-items: center; inline-size: 24px; block-size: 24px;
  border: 2px solid rgba(10, 16, 12, .55); border-radius: 50%;
  background: var(--card-face); color: var(--night);
  font-family: var(--font-figure); font-size: .625rem; font-weight: 900;
}

.middle {
  position: relative; z-index: 1; min-width: 0;
  display: grid; grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto; align-items: center;
  gap: 10px; padding: 28px 0 16px; text-align: center;
}
.middle .pot-label { font-size: var(--type-micro); letter-spacing: .2em; color: var(--on-felt-muted); display: block; }
.middle .pot { font-family: var(--font-figure); font-size: var(--type-head-lg); font-weight: 800; display: block; }
.middle .spr {
  display: block; inline-size: 100%; font-family: var(--font-figure);
  font-size: var(--type-micro); color: var(--on-felt-muted); line-height: 1.25;
}

.cards { display: flex; gap: 5px; align-items: center; justify-content: center; margin-top: 6px; }
.board-stage {
  inline-size: max-content; min-width: 0; margin: 0; align-self: center; justify-self: center;
}
.card-slot {
  inline-size: 31px; block-size: 45px; border: 3px solid rgba(238, 244, 238, .82);
  border-radius: 6px;
  background: repeating-linear-gradient(45deg, rgba(214, 232, 220, .3) 0 5px, rgba(7, 21, 14, .65) 5px 10px);
  box-shadow: 0 3px 8px rgba(0, 0, 0, .22);
}
.card {
  background: var(--card-face); color: var(--ink); border-radius: 7px;
  min-width: 38px; padding: 6px 4px; text-align: center;
  font-family: var(--font-figure); box-shadow: var(--shadow-sm);
}
.card.hero { min-width: 44px; padding: 5px 4px; }
.card .rank { display: block; font-size: var(--type-head); font-weight: 800; line-height: 1.05; }
/* The project-authored silhouette plus its letter remains identifiable without colour. */
.card .suit {
  display: inline-flex; align-items: center; justify-content: center; gap: 1px;
  font-size: var(--type-micro); font-weight: 800; letter-spacing: .04em;
}
.suit-icon { inline-size: 12px; block-size: 12px; flex: none; color: currentColor; }
.suit-letter { line-height: 1; }
.card.red .rank, .card.red .suit { color: #b3200c; }

.hero-hand { display: grid; justify-items: center; gap: 2px; margin: 0; transform: translateY(30px); }
.hero-hand .cards { margin: 0; }
.hero-hand .label { font-size: var(--type-micro); font-weight: 700; letter-spacing: .16em; color: var(--on-felt-muted); }
.history { font-size: var(--type-micro); color: var(--on-felt-muted); margin: 4px 0 0; text-align: center; line-height: 1.55; }

.compact-felt {
  position: relative; min-height: 180px; margin: 4px 6px 10px;
  border: 8px solid var(--felt-rail); border-radius: 49% / 45%;
  background:
    radial-gradient(circle at 50% 45%, rgba(43, 126, 86, .76), transparent 52%),
    linear-gradient(180deg, var(--felt-2), #103a2a);
  box-shadow: inset 0 0 30px rgba(3, 19, 12, .38);
}
.compact-table .seat {
  position: absolute; display: block; z-index: 2;
  width: auto; min-width: 38px; min-height: 0;
  border-radius: 999px; padding: 2px 8px; text-align: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, .22); transform: none;
}
.compact-table .player-token,
.compact-table .seat .name,
.compact-table .seat .stack,
.compact-table .seat .act,
.compact-table .dealer { display: none; }
.compact-table .seat-copy,
.compact-table .seat-head { display: block; }
.compact-table .seat .pos { display: block; }
.compact-table .seat-top { inset-block-start: -14px; inset-inline-start: 50%; transform: translateX(-50%); }
.compact-table .seat-left { inset-block-start: 26%; inset-inline-start: -14px; }
.compact-table .seat-right { inset-block-start: 26%; inset-inline-end: -14px; }
.compact-table .seat-ll { inset-block-end: 24%; inset-inline-start: -14px; }
.compact-table .seat-rr { inset-block-end: 24%; inset-inline-end: -14px; }
.compact-table .seat-bottom { inset-block-end: -14px; inset-inline-start: 50%; transform: translateX(-50%); }
.compact-middle {
  position: absolute; inset: 0; z-index: 1;
  display: grid; place-content: center; justify-items: center;
  padding: 24px 36px; text-align: center;
}
.compact-cards { display: grid; justify-items: center; gap: 6px; min-width: 0; }
.compact-middle .cards { margin: 0; }
.compact-middle > span {
  margin-top: 4px; color: var(--on-felt-muted);
  font-family: var(--font-figure); font-size: var(--type-micro);
}
/* The compact table is a diagram with full Japanese alternatives directly
   below it. Keep the card/seat glyphs inside that diagram at text zoom; the
   same values remain exposed by the group's accessible names. */
.compact-table .card .rank { font-size: 20px; }
.compact-table .card .suit { font-size: 11px; }
.compact-table .seat .pos { font-size: 10px; }
.compact-table .compact-middle > span,
.compact-table .history { font-size: 11px; }

/* ------------------------------------------------- the answer, right below */

/*
 * The answer sits directly under the felt.
 *
 * v0.1 put a 340px reserved placeholder between them, so the learner had to
 * scroll past an empty box before a single action was reachable (measured: 344px).
 * The verdict takes this same region once the answer is in, so the table never
 * moves and the controls are never stranded off-screen.
 */
.answer { margin-top: 3px; }

.sizes {
  display: grid; grid-template-columns: 72px repeat(auto-fit, minmax(44px, 1fr));
  gap: 6px; align-items: stretch; margin-bottom: 4px;
}
.sizes .label { font-size: var(--type-note); color: var(--muted); font-weight: 600; }
.sizes button {
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  color: var(--ink); font: inherit; font-size: var(--type-aux); font-weight: 600;
  min-height: 50px; padding: 4px 3px; cursor: pointer;
}
.sizes button[aria-pressed="true"] { background: var(--felt); color: var(--on-felt); border-color: var(--felt); }
.sizes button .bb { font-family: var(--font-figure); font-size: var(--type-micro); display: block; font-weight: 400; }

.actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.actions button {
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface);
  color: var(--ink); font: inherit; font-weight: 700;
  min-height: 56px; padding: 6px 8px; cursor: pointer; text-align: left;
  line-height: 1.25; box-shadow: var(--shadow-sm);
}
.actions button:hover:not([aria-disabled="true"]) { border-color: var(--ink); }
.actions button[aria-disabled="true"] { color: var(--muted); background: var(--soft); box-shadow: none; cursor: default; }
/* The reason is text, not just a dimmed control. */
.actions button .why {
  display: block; margin-top: 2px; font-size: var(--type-micro);
  font-weight: 400; line-height: 1.2;
}

/* --------------------------------------------------------- the verdict band */

.band {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 4px solid var(--felt); border-radius: var(--radius);
  padding: var(--space-2); box-shadow: var(--shadow-sm);
}
.band > * + * { margin-top: var(--space-2); }

.contrast { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-2); }
.contrast .label { font-size: var(--type-note); color: var(--muted); display: block; font-weight: 600; }
.contrast .value { font-size: var(--type-head); font-weight: 800; }

.mark { display: flex; gap: 10px; align-items: flex-start; }
/* Shape carries the state; colour is only the second cue. */
.verdict-icon { flex: none; inline-size: 26px; block-size: 26px; color: currentColor; }
.mark.match { color: var(--judgment-match); }
.mark.conditional { color: var(--judgment-conditional); }
.mark.diverge { color: var(--judgment-diverge); }
.mark .words { font-weight: 800; }
.mark .condition { display: block; font-weight: 400; font-size: var(--type-aux); color: var(--ink); margin-top: 3px; }

.premises { border-top: 1px solid var(--line); }
.premises div {
  display: grid; grid-template-columns: 92px 1fr; gap: var(--space-1);
  padding: 8px 0; border-bottom: 1px solid var(--line);
}
.premises dt { font-size: var(--type-aux); font-weight: 700; }
.premises dd { margin: 0; font-size: var(--type-aux); }

.numbers { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-1); }
.numbers > div { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; }
.numbers .label { font-size: var(--type-note); color: var(--muted); display: block; font-weight: 600; }
.numbers .value { font-family: var(--font-figure); font-size: var(--type-head); font-weight: 800; }
/* Same contrast as the number it qualifies. */
.numbers .qualifier { font-size: var(--type-aux); color: var(--ink); display: block; }
.numbers .derivation { font-family: var(--font-figure); font-size: var(--type-aux); color: var(--ink); display: block; }

.sizecheck { margin: 0; font-size: var(--type-aux); color: var(--ink); border-left: 3px solid var(--line); padding-left: 10px; }
.sizecheck.off { border-left-color: var(--judgment-diverge); font-weight: 700; }

.leak { font-size: var(--type-aux); }
.focus { background: var(--night); color: var(--on-felt); padding: var(--space-2); border-radius: var(--radius-sm); }
.focus .label { font-size: var(--type-note); color: var(--on-felt-muted); display: block; font-weight: 600; }
.focus p { margin: 4px 0 0; font-weight: 700; }
/* muted is for labels. The verification level of the teaching material is not
   a label, and it was the smallest, palest element in the band. */
.provenance { font-size: var(--type-aux); color: var(--ink); }

/* A control, not a caption: the items it names must be reachable. */
.tier2[data-collapsed] { display: none; }
.tier2-note {
  display: block; width: 100%; text-align: left;
  border: 1px dashed var(--line); border-radius: var(--radius-sm); background: var(--soft);
  padding: 12px; min-height: 50px;
  font: inherit; font-size: var(--type-aux); color: var(--ink);
  margin-top: var(--space-2); cursor: pointer;
}
.tier2-note:hover { border-color: var(--ink); }

/* ---------------------------------------------------------------- the chart */

.result-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-1);
  padding: 10px 0; border-bottom: 1px solid var(--line);
}
.result-row .name { font-weight: 700; font-size: var(--type-aux); }
.result-row .marks { display: flex; gap: 4px; }
.result-row .count { font-family: var(--font-figure); font-size: var(--type-aux); font-weight: 700; }
.cell {
  /* The mark's ink follows the surface it is drawn on. Hard-coded to --ink it
     measured 2.8:1 once the results moved onto the felt, which is below the 3:1
     WCAG 2.2 asks of a non-text mark — and these marks are the shape that keeps
     the three verdict states readable without colour. */
  --cell-ink: var(--ink);
  width: 22px; height: 22px; color: var(--cell-ink);
  display: grid; place-items: center;
}
.cell .verdict-icon { inline-size: 100%; block-size: 100%; }
.panel.lead .cell { --cell-ink: var(--on-felt); }

.legend { margin-top: var(--space-1); display: grid; gap: 6px; }
.legend div { display: flex; gap: var(--space-1); align-items: center; font-size: var(--type-note); }

/* ---------------------------------------------------------------- nav / a11y */

.tabbar {
  position: fixed; inset: auto 0 0 0; display: flex; justify-content: center; gap: 4px;
  background: rgba(243, 245, 239, .96); border-top: 1px solid var(--line);
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
  backdrop-filter: blur(8px);
}
.tabbar button {
  flex: 1; max-width: 96px; background: none; border: 0; border-radius: 999px;
  color: var(--muted); font: inherit; font-size: var(--type-note); font-weight: 600;
  padding: 10px 0 12px; min-height: 52px; cursor: pointer;
}
.tabbar button[aria-current="page"] { background: var(--acid); color: var(--night); font-weight: 800; }
/* An unavailable tab keeps its place in the reading order and says why. */
.tabbar button.unavailable { color: var(--muted); cursor: default; }
.tabbar button .pending { display: block; font-size: var(--type-micro); font-weight: 400; }

:focus-visible {
  outline: 3px solid var(--paper);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px var(--ink);
}

.sr-only,
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Motion explains a state change; nothing here is decorative. */
@keyframes bandIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes loadingPulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
.band > * { animation: bandIn 120ms ease-out both; }
.loading-mark { animation: loadingPulse 900ms ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .band > *, .loading-mark { animation: none; }
}

/* Short viewports, which is what page zoom produces. */
@media (max-height: 620px) {
  main { padding: var(--space-1) var(--space-2); }
  .topbar, .progress { margin-bottom: var(--space-1); }
  .table { padding: var(--space-1); }
  .full-table .felt { gap: 3px; }
  .card { min-width: 32px; padding: 4px 3px; }
  .card .rank { font-size: var(--type-aux); }
}

@media (max-width: 380px) {
  .full-table .felt {
    min-height: 345px;
    grid-template-rows: 62px 1fr 1fr 68px;
  }
  .full-table .seat-left,
  .full-table .seat-right { transform: translateY(-36px); }
  .full-table .seat-ll,
  .full-table .seat-rr { transform: translateY(6px); }
  .full-table .middle { gap: 6px; padding: 20px 0 10px; }
  .full-table .hero-hand { transform: translateY(18px); }
}

@media (max-width: 360px) {
  main { padding-inline: 10px; }
  .full-table { padding-inline: 5px; }
  .full-table .felt { grid-template-columns: minmax(0, 1fr) 92px minmax(0, 1fr); }
  .seat { width: clamp(98px, 30vw, 112px); padding-inline: 5px; gap: 4px; }
  .seat-top,
  .seat-bottom { width: clamp(128px, 43vw, 150px); }
  .player-token { inline-size: 30px; block-size: 30px; }
  .card-slot { inline-size: 27px; block-size: 41px; }
}

/* At high page zoom the spatial stage becomes a readable seat ledger. */
@media (max-width: 300px) {
  .sizes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sizes .label { grid-column: 1 / -1; }
  .full-table { overflow: visible; }
  .full-table .felt {
    display: flex; flex-direction: column; min-height: 0; gap: 8px;
    padding: 8px 0 4px;
  }
  .full-table .felt::before,
  .full-table .felt::after { display: none; }
  .full-table .seat,
  .full-table .seat-top,
  .full-table .seat-bottom {
    width: 100%; min-height: 58px; align-self: stretch; transform: none;
  }
  .full-table .seat.hero { order: -1; }
  .full-table .seat .act {
    position: static; flex: none; max-width: 42%; margin-left: auto;
    transform: none;
  }
  .full-table .middle {
    order: 1; display: grid; grid-template-rows: auto auto auto;
    gap: 16px; padding: 18px 4px; border-radius: 42% / 18%;
    background: linear-gradient(180deg, var(--felt-2), #103a2a);
  }
  .full-table .hero-hand { transform: none; }
  .full-table .cards { flex-wrap: wrap; max-width: 100%; }
  .full-table .board-stage { inline-size: 100%; }

  .compact-table { overflow: visible; padding-inline: 6px; }
  .compact-felt {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px; min-height: 0; margin-inline: 0; padding: 8px 5px;
    border-width: 4px; border-radius: 18px;
  }
  .compact-table .seat,
  .compact-table .seat-top,
  .compact-table .seat-bottom {
    position: static; inset: auto; width: 100%; min-width: 0;
    transform: none; padding-inline: 3px;
  }
  .compact-table .compact-middle {
    position: static; grid-column: 1 / -1;
    padding: 10px 2px 4px;
  }
  .compact-table .compact-cards { max-width: 100%; }
  .compact-table .compact-board { flex-wrap: wrap; max-width: 100%; }
}

@media (max-width: 160px) {
  main { padding-inline: 4px; }
  .compact-felt { grid-template-columns: 1fr; }
}

/*
 * Dark theme.
 *
 * The felt stays a felt — it is already dark, so it barely moves. What inverts
 * is the paper the page is printed on. Every ratio below was measured the same
 * way as the light values, and the same rule holds: colour is never the only cue.
 */
@media (prefers-color-scheme: dark) {
  :root {
    --paper: #101511;          /* page */
    --surface: #191f1b;        /* panels, cards, the verdict band */
    --soft: #232a25;           /* second surface */
    --line: #333d36;
    --ink: #eef2ec;            /* 14.6:1 on --paper */
    --muted: #a9b5ac;          /* 7.4:1 on --paper */

    --felt: #14432f;
    --felt-2: #1d5f45;
    --night: #0a100c;

    --action-primary: #c9fb62; /* the accent carries the primary action here */
    --judgment-match: #9fe08a;
    /* The match fill is a light green here, so the tick goes dark. White on it
       measured 1.5:1 — the same invisible mark, moved to the other theme. */
    --on-judgment: #0a100c;
    /* Card faces stay light in both themes; only the paper inverts. */
    --card-face: #f4f7f3;
    --selected: #9fe08a;
    --judgment-conditional: #c3bcd0;
    --judgment-diverge: #ff9d84;

    --shadow: 0 18px 50px rgba(0, 0, 0, .45);
    --shadow-sm: 0 2px 8px rgba(0, 0, 0, .35);
  }
  /* The primary action inverts with its surface. */
  .cta { color: var(--night); }
  .card { background: var(--card-face); color: #152019; }
  .card.red .rank, .card.red .suit { color: #a51d0b; }
  .tabbar { background: rgba(16, 21, 17, .96); }
  /* Selection is a state, not a place. Using the accent here put four of
     them on one screen, which is how an accent stops meaning anything. */
  .sizes button[aria-pressed="true"] { background: var(--felt-2); color: var(--on-felt); border-color: var(--felt-2); }
}

/*
 * The chart's hierarchy.
 *
 * It was six panels of one size stacked vertically — the shape design.visual
 * itself lists as rejected, and the shape the owner called 単調 in v0.1. Three
 * weights now: the result leads, the two notes sit as a pair, and the
 * housekeeping recedes into a utility block.
 */
.panel.lead {
  /* Top to bottom, like the table. The token text says the gradient shows the
     tilt of a surface; a diagonal wash means something else. */
  background: linear-gradient(180deg, var(--felt-2), var(--felt));
  color: var(--on-felt);
  box-shadow: var(--shadow);
}
.panel.lead .label,
.panel.lead .basis { color: var(--on-felt-muted); }

.pair { display: grid; gap: 12px; }
@media (min-width: 600px) { .pair { grid-template-columns: 1fr 1fr; } }
.panel.note { background: none; border: 1px solid var(--line); box-shadow: none; }

.panel.utility { background: var(--soft); box-shadow: none; }
.facts { display: grid; gap: 2px; margin: 8px 0 12px; }
.facts > div {
  display: flex; justify-content: space-between; gap: 12px;
  flex-wrap: wrap; min-width: 0;
  padding: 5px 0; border-block-end: 1px solid var(--line);
}
.facts dt { min-width: 0; color: var(--muted); font-size: var(--type-aux); }
.facts dd {
  min-width: 0; max-width: 100%; margin: 0; overflow-wrap: anywhere;
  font-family: var(--font-figure); font-size: var(--type-aux); color: var(--ink);
}

/* Tokens rather than inline colour, so design.visual's own rule holds. */
/*
 * A secondary action still has to look like a surface you can press.
 *
 * Measured against the page: the fill was 1.11:1 and the border 1.19:1, so the
 * only cue was the text floating on the paper — below the 3:1 that WCAG 2.2 asks
 * of a control's boundary. These are the recovery routes (read a record back,
 * keep the current type), so being hard to find is not a small cost.
 */
.cta.secondary {
  background: var(--soft); color: var(--ink);
  border: 1px solid var(--muted); cursor: pointer;
}
.cta.secondary:hover { border-color: var(--ink); }
.provenance.spaced { margin-block-start: 16px; }
.progress.inline { flex: 1; margin: 0; }
.lead-note { margin: 0; }

/*
 * The type chooser.
 *
 * Five identically filled slabs was the exact shape design.visual rejects, on
 * the one screen every learner sees first. Rows carry the same information with
 * one accent instead of five.
 */
.choices { display: grid; gap: 8px; margin-bottom: var(--space-2); }
.choice {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px var(--space-2); min-height: 56px; font: inherit; color: var(--ink);
}
.choice:hover { border-color: var(--ink); }
/* The felt is nearly the surface colour in dark (measured 1.49:1 on the border),
   so the current row lost its outline there. A token that flips with the theme,
   like everything else that has to stay visible in both. */
.choice.current { border-color: var(--selected); border-width: 2px; }
.choice .head { display: block; font-weight: 700; font-size: var(--type-aux); }
/* This sentence is the only thing a learner has to tell the five types apart.
   It was 12px in the label token — the weakest treatment on the screen whose
   entire purpose is this choice — while the rule says muted is for labels. */
.choice .blurb { display: block; font-size: var(--type-aux); color: var(--ink); line-height: 1.5; }
.choice .tag {
  display: inline-block; margin-left: 6px; padding: 0 7px; border-radius: 999px;
  background: var(--soft); color: var(--ink); font-size: var(--type-micro); font-weight: 700;
}
.choice .tag.now { background: var(--felt); color: var(--on-felt); }

/* The file input is clipped, so without this the focus ring lands on nothing
   and a keyboard user loses their place for one stop. */
.cta.secondary:focus-within { outline: 2px solid var(--felt); outline-offset: 2px; }
#import-result:focus { outline: 2px solid var(--felt); outline-offset: 3px; }
#import-result:empty { display: none; }
/* A near-black band butting straight into the next panel read as its heading. */
.focus { margin-bottom: var(--space-2); }

/* The one result line. Above whatever screen the outcome lands on. */
.notice {
  margin: 0 0 var(--space-2); padding: 12px var(--space-2);
  background: var(--soft); border-radius: var(--radius-sm);
  font-size: var(--type-aux); color: var(--ink);
}
.notice:focus { outline: 2px solid var(--felt); outline-offset: 2px; }

.offline-banner,
.loading-panel {
  margin: 0 0 var(--space-2); padding: var(--space-2);
  border: 1px solid var(--muted); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); font-size: var(--type-aux);
}
.loading-panel { min-height: 148px; display: grid; place-content: center; justify-items: center; gap: 12px; }
.loading-panel p { margin: 0; font-weight: 700; }
.loading-mark { inline-size: 34px; block-size: 34px; border: 8px solid var(--felt); border-radius: 50%; }

.answer-history { list-style: none; padding: 0; margin: 0; }
.answer-history li {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 10px 0; border-block-end: 1px solid var(--line);
}
.history-copy { display: grid; min-width: 0; font-size: var(--type-aux); }
.history-copy span { color: var(--ink); }
.history-withdraw {
  flex: none; min-height: 48px; padding: 8px 12px;
  border: 1px solid var(--muted); border-radius: 999px;
  background: var(--surface); color: var(--ink); font: inherit; font-size: var(--type-aux);
  cursor: pointer;
}

.record-nav {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
  margin: 0 0 var(--space-2); padding: 4px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--soft);
}
.record-nav button {
  min-height: 48px; border: 0; border-radius: 999px; background: transparent;
  color: var(--ink); font: inherit; font-size: var(--type-aux); font-weight: 700; cursor: pointer;
}
.record-nav button[aria-pressed="true"] { background: var(--surface); box-shadow: var(--shadow-sm); }
.growth-comparison {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px;
}
.growth-comparison > div { display: grid; gap: 4px; }
.growth-comparison > div:last-child { text-align: right; }
.growth-comparison span { font-size: var(--type-note); color: var(--on-felt-muted); }
.growth-comparison b { font-family: var(--font-figure); font-size: var(--type-head); }
.growth-row { display: grid; gap: 3px; padding: 10px 0; border-block-end: 1px solid var(--line); }
.growth-row > span { font-size: var(--type-aux); color: var(--ink); }

/* The legend folds away: it is reference, not a result, and it was occupying a
   third of the strongest surface on day thirty as much as on day one. */
.legend > summary { cursor: pointer; font-size: var(--type-aux); }
.legend > div { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
