/* dice — the shelf's shell (mahjong's, solitaire's and minesweeper's before
 * it: the glass, the bar, the menu sheet, the rows, the foot of settings)
 * around a score card and a tray of dice.
 *
 * TWO THEMES, LIGHT IS THE BASE: the palette on bare :root, dark as a token
 * swap in two guarded blocks (the media query for "system", the attribute for
 * a choice).
 *
 * THE ROOM IS THE TABLE (mahjong-v4's rule, the owner's "match the theme of
 * the game"): every screen sits on the table's cloth (Settings › Table, worn
 * as data-felt on <html>), and every panel is PAPER — the score pad's cream —
 * with dark ink in both themes, so the card you score on and the cards you
 * read are one material. Two token scopes do it: the ground takes the felt's
 * ink; the paper puts a dark ink back.
 *
 * GOLD MEANS YOU (wizard's rule): your row on a leaderboard, your best on a
 * card, the one button that is the next thing to do, the box you picked.
 *
 * BIG ON PURPOSE (mahjong-v8, the owner: "as large as possible … this helps
 * older users"): the card's boxes share the screen's height, up to 64 px a
 * row, and the dice are as wide as five fit.
 */

:root {
  --bg:       #f4ede0;
  --panel:    #ffffff;
  --glass:    rgba(255, 255, 255, .78);
  --glass-2:  rgba(255, 255, 255, .55);
  --line:     rgba(60, 60, 67, .16);
  --line-2:   rgba(60, 60, 67, .08);
  --ink:      #000000;
  --ink-2:    #3c3c43;
  --dim:      #8a8a8e;
  --dim-2:    #b0b0b6;
  --pill:     #efeff0;
  --good:     #1a9e4b;
  --warn:     #b8730a;
  --bad:      #e5322b;
  --link:     #007aff;
  --heart:    #e0596e;
  --gold:     #d9a520;
  --gold-lit: #ffd45c;
  --gold-ink: #1a1200;
  --shadow:   0 1px 2px rgba(0,0,0,.04), 0 6px 20px rgba(0,0,0,.05);

  /* The cloth. Wine is the default: a dice tray's velvet. */
  --felt-1:   #8c2a3b;
  --felt-2:   #5a1424;
  --felt-ink: #fdf3ef;
  --felt-dim: rgba(253, 243, 239, .66);
  --felt-line: rgba(255, 255, 255, .24);
  --felt-glass:   rgba(255, 255, 255, .14);
  --felt-glass-2: rgba(255, 255, 255, .09);
  --felt-link:    #ffd9cf;

  /* The paper: a score pad. */
  --paper-1:  #fffaf0;
  --paper-2:  #f3e9d2;
  --paper-rule: rgba(60, 90, 160, .14);
  --paper-shadow: inset 0 1px 0 rgba(255,255,255,.8), 0 0 0 .5px rgba(60,40,10,.25), 0 10px 24px rgba(0,0,0,.28);

  /* The dice (Settings › Dice). */
  --die-1:   #ffffff;
  --die-2:   #f1ead8;
  --die-3:   #d9ccad;
  --pip:     #1d1712;
  --pip-one: #b5182c;

  --r-card: 18px;
  --r-mid:  14px;
  --r-sm:   10px;

  --font: -apple-system, BlinkMacSystemFont, system-ui, "SF Pro Text", "Helvetica Neue", sans-serif;
  --font-num: ui-rounded, -apple-system, "SF Pro Rounded", system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #1a0a0e; --panel: #1c1c1e; --glass: rgba(28,28,30,.86); --glass-2: rgba(44,44,46,.75);
    --line: rgba(84,84,88,.5); --line-2: rgba(84,84,88,.28); --ink: #fff; --ink-2: #ebebf5; --dim: #8e8e93; --dim-2: #636366;
    --pill: #2c2c2e; --good: #30d158; --warn: #ffd60a; --bad: #ff453a; --link: #0a84ff; --gold: #e8c05a; --gold-lit: #ffd77a;
    --shadow: 0 1px 2px rgba(0,0,0,.5), 0 6px 20px rgba(0,0,0,.4);
    --felt-1: #571826; --felt-2: #2c0a12;
    --paper-1: #f3ecdc; --paper-2: #e2d6bb;
  }
}
:root[data-theme="dark"] {
  --bg: #1a0a0e; --panel: #1c1c1e; --glass: rgba(28,28,30,.86); --glass-2: rgba(44,44,46,.75);
  --line: rgba(84,84,88,.5); --line-2: rgba(84,84,88,.28); --ink: #fff; --ink-2: #ebebf5; --dim: #8e8e93; --dim-2: #636366;
  --pill: #2c2c2e; --good: #30d158; --warn: #ffd60a; --bad: #ff453a; --link: #0a84ff; --gold: #e8c05a; --gold-lit: #ffd77a;
  --shadow: 0 1px 2px rgba(0,0,0,.5), 0 6px 20px rgba(0,0,0,.4);
  --felt-1: #571826; --felt-2: #2c0a12;
  --paper-1: #f3ecdc; --paper-2: #e2d6bb;
}

/* THE TABLE'S CLOTH (Settings › Table). */
:root[data-felt="green"] { --felt-1: #2f7d4f; --felt-2: #1b5233; --felt-link: #d2f5df; }
@media (prefers-color-scheme: dark) { :root[data-felt="green"]:not([data-theme="light"]) { --felt-1: #1e5236; --felt-2: #0d2a1b; } }
:root[data-felt="green"][data-theme="dark"] { --felt-1: #1e5236; --felt-2: #0d2a1b; }
:root[data-felt="blue"] { --felt-1: #2f5f99; --felt-2: #183660; --felt-link: #d4e6ff; }
@media (prefers-color-scheme: dark) { :root[data-felt="blue"]:not([data-theme="light"]) { --felt-1: #1d3d66; --felt-2: #0b1c33; } }
:root[data-felt="blue"][data-theme="dark"] { --felt-1: #1d3d66; --felt-2: #0b1c33; }

/* THE DICE (Settings › Dice): ivory with black pips and a red one, casino
   red with white pips, or black with white. */
:root[data-dice="red"]   { --die-1: #e8404f; --die-2: #c41f30; --die-3: #8c0f1d; --pip: #fffaf2; --pip-one: #fffaf2; }
:root[data-dice="black"] { --die-1: #4a4a4f; --die-2: #26262a; --die-3: #111114; --pip: #fffaf2; --pip-one: #ffd45c; }

* { box-sizing: border-box; }
/* `[hidden]` MUST WIN (solitaire's lesson: any author `display` beats the UA's). */
[hidden] { display: none !important; }

/* NATIVE CONTROLS FOLLOW THE IN-APP CHOICE (IOS.md §11). */
:root { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

html, body {
  margin: 0;
  min-height: 100%;              /* the page scrolls; a sheet in play locks it (see "the shell") */
  font-family: var(--font);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}
/* On the ROOT, not the body: a short screen's body ends mid-screen, and a
   gradient painted on it stopped there in a seam (mahjong-v4). */
html { background: radial-gradient(140% 90vh at 50% 0, var(--felt-1), var(--felt-2)) no-repeat, var(--felt-2); }
body { background: transparent; }

/* No text selection, no long-press callout, no double-tap zoom — on EVERY
   element (IOS.md §27: touch-action is not inherited). */
*, *::before, *::after { touch-action: manipulation; }
body {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent;
}
input, textarea { -webkit-user-select: text; user-select: text; }

/* THE GLASS AT THE TOP (IOS.md §1): iOS 26 blurs a band under the status bar. */
:root { --glass-t: 20px; }

/* ── the shell ─────────────────────────────────────────────────────────────

   THE PAGE SCROLLS; A SHEET IN PLAY LOCKS IT (IOS.md §15, gems' shape). The
   home, the tables, the menu are in-flow content and the document is their
   one scroller. While a sheet is being played (and the menu is closed) app.js
   sets html.locked: the root is the viewport and nothing moves under a drag. */
html.locked, html.locked body { height: 100%; min-height: 0; overflow: hidden; overscroll-behavior: none; }
html.locked main { height: 100%; }

.view {
  padding: calc(8px + var(--glass-t) + env(safe-area-inset-top, 0px)) 16px calc(24px + env(safe-area-inset-bottom, 0px));
  max-width: 560px; margin: 0 auto;
}
.view[hidden] { display: none !important; }
/* WHILE THE MENU IS OPEN the screen under it is hidden and pinned, not unmounted. */
body:has(#sheet-menu:not([hidden])) main { visibility: hidden; position: fixed; inset: 0; height: auto; }

/* THE GROUND: every screen takes the felt's ink. */
.view, .sheet-body, .gate {
  --ink: var(--felt-ink); --ink-2: var(--felt-ink); --dim: var(--felt-dim); --dim-2: var(--felt-dim);
  --line: var(--felt-line); --line-2: var(--felt-line);
  --glass: var(--felt-glass); --glass-2: var(--felt-glass-2); --pill: var(--felt-glass); --link: var(--felt-link);
  color: var(--ink);
}

.view-head { padding: 12px 4px 18px; }
.view-head.bar { display: flex; align-items: center; gap: 10px; }
.bar-title { flex: 1; min-width: 0; }
.view-head h1 { margin: 0; font-size: 34px; font-weight: 700; letter-spacing: -.6px; }
.view-sub { margin: 4px 0 0; color: var(--dim); font-size: 15px; }

/* THE PAPER: the tokens a score pad's page would have, then the page. */
.card, .mode-card, .board-list, .signin-card, .overlay-card, .sheet-card {
  --ink: #241a12; --ink-2: #4c3f30; --dim: #8a7b66; --dim-2: #b9ab92;
  --line: rgba(90, 60, 30, .22); --line-2: rgba(90, 60, 30, .12);
  --pill: rgba(90, 60, 30, .12); --glass: rgba(255, 255, 255, .55); --glass-2: rgba(90, 60, 30, .07); --panel: var(--paper-1);
  --link: #8c2a3b; --good: #1a8a45; --warn: #a3600a; --bad: #c4302a; --heart: #d4475d;
  --gold: #c99412; --gold-ink: #1a1200; --games-gold: #c48a12;
  color: var(--ink);
  background: linear-gradient(170deg, var(--paper-1), var(--paper-2));
  box-shadow: var(--paper-shadow);
}
:root[data-felt="green"] .card, :root[data-felt="green"] .mode-card { --link: #1b5233; }
:root[data-felt="blue"] .card, :root[data-felt="blue"] .mode-card { --link: #183660; }

.card { border-radius: var(--r-card); padding: 16px; margin: 0 0 18px; }
.card h3 { margin: 0 0 12px; font-size: 16px; font-weight: 650; }
.card.rows { padding: 0 16px; }

.fine { margin: 12px 6px 0; color: var(--dim); font-size: 12.5px; line-height: 1.5; }
.fine strong { color: var(--ink-2); font-weight: 600; }
.fine a { color: var(--link); }
.fine.in-card { margin-left: 0; margin-right: 0; }
.fine.version { font-family: var(--font-num); }
.fine.center { text-align: center; }

/* ── buttons ───────────────────────────────────────────────────────────── */

.btn {
  font: inherit; font-size: 16px; font-weight: 600;
  padding: 12px 18px; border-radius: var(--r-mid);
  color: var(--ink); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--glass); border: .5px solid var(--line); box-shadow: var(--shadow);
}
.btn:active { opacity: .7; }
.btn-primary { background: var(--gold); color: var(--gold-ink); border-color: transparent; }
.btn-quiet   { background: transparent; color: var(--link); box-shadow: none; border-color: transparent; }
.btn-wide    { display: flex; width: 100%; margin-top: 18px; }
.btn-small   { padding: 7px 14px; font-size: 13px; }
.btn:disabled { opacity: .4; cursor: default; }
.view .btn:not(.btn-primary):not(.btn-quiet) { box-shadow: none; }

.icon {
  font: inherit; font-size: 20px; line-height: 0;
  width: 40px; height: 40px; border-radius: 20px;
  display: grid; place-items: center; flex: none; padding: 0;
  color: var(--ink); cursor: pointer;
  background: var(--glass); border: .5px solid var(--line);
}
.icon:active { opacity: .7; }

.pill {
  display: block; width: 100%; margin: 0 0 14px;
  font: inherit; font-size: 13.5px; font-weight: 600;
  padding: 10px 14px; border-radius: 999px; cursor: pointer;
  background: var(--felt-glass); color: var(--felt-ink); border: .5px solid var(--felt-line);
}

/* ── the gate ──────────────────────────────────────────────────────────── */

.gate { min-height: 100dvh; display: grid; place-items: center; padding: 24px; }
.signin-card { max-width: 340px; width: 100%; text-align: center; padding: 26px 22px 22px; border-radius: var(--r-card); }
.signin-card h1 { margin: 14px 0 6px; font-size: 30px; letter-spacing: -.03em; }
.signin-card .lede { margin: 0 0 22px; color: var(--ink-2); font-size: 15px; line-height: 1.45; }
.signin-card .btn-wide { margin-top: 0; }
.brand { display: block; width: 88px; height: 88px; margin: 0 auto; border-radius: 22.5%; box-shadow: 0 0 0 1px var(--line), 0 6px 18px rgba(0,0,0,.14); }
.gate-msg { margin: 0 0 18px; padding: 11px 13px; border-radius: var(--r-mid); background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn); font-size: 13px; line-height: 1.45; text-align: left; }

/* ── the home ──────────────────────────────────────────────────────────── */

.mode-cards { display: grid; gap: 18px; }
.mode-card {
  display: flex; gap: 14px; align-items: stretch; width: 100%; text-align: left;
  font: inherit; cursor: pointer; padding: 16px; border-radius: var(--r-card); border: 0;
}
.mode-card:active { translate: 0 2px; }
.mode-card:disabled { opacity: .6; cursor: default; }
.mode-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; }
.mode-card-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.mode-card h3 { margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -.3px; }
.mode-card .shape { color: var(--dim); font-size: 12.5px; font-family: var(--font-num); white-space: nowrap; }
.mode-card .blurb { margin: 5px 0 0; color: var(--ink-2); font-size: 14px; line-height: 1.45; }
.mode-art { flex: none; width: 62px; display: flex; align-items: center; justify-content: center; position: relative; }
.mode-art .die { --ds: 40px; pointer-events: none; }
.mode-art .die + .die { position: absolute; --ds: 32px; right: -2px; bottom: 6px; rotate: 14deg; }
.mode-art .die:first-child { rotate: -8deg; translate: -6px -6px; }
.mode-card-stats { display: flex; gap: 18px; margin-top: 12px; padding-top: 11px; border-top: .5px solid var(--line-2); }
.mode-card-stats div { display: flex; flex-direction: column; gap: 1px; }
.mode-card-stats .v { font-family: var(--font-num); font-size: 18px; font-weight: 600; font-variant-numeric: tabular-nums; }
.mode-card-stats .k { font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .4px; }
.mode-card-stats .v.none { color: var(--dim-2); }
.mode-card-stats .v.you { color: var(--gold); }
/* A sheet in play stays CLOTH (it is the table you left), raised on the felt. */
.mode-card.resume {
  --ink: var(--felt-ink); --ink-2: var(--felt-ink); --dim: var(--felt-dim); --line-2: var(--felt-line);
  background: var(--felt-glass); color: var(--felt-ink); box-shadow: inset 0 0 0 1px var(--felt-line), 0 8px 18px rgba(0,0,0,.22);
}

/* ── a sheet in play ───────────────────────────────────────────────────── */

#view-game {
  height: 100%; max-width: 620px;
  display: flex; flex-direction: column; overflow: hidden; gap: 0;
  padding: calc(4px + var(--glass-t) + env(safe-area-inset-top, 0px)) calc(10px + env(safe-area-inset-right, 0px)) calc(10px + env(safe-area-inset-bottom, 0px)) calc(10px + env(safe-area-inset-left, 0px));
}
.game-head { display: flex; align-items: center; gap: 8px; padding: 2px 0 8px; flex: none; }
.game-stat { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.05; min-width: 44px; }
.game-stat-total { margin-left: 6px; }
.game-stat-turn { margin-left: auto; margin-right: 4px; align-items: flex-end; }
.game-stat-v { font-family: var(--font-num); font-size: 28px; font-weight: 700; font-variant-numeric: tabular-nums; }
.game-stat-turn .game-stat-v { font-size: 20px; font-weight: 600; }
.game-stat-k { font-size: 10.5px; color: var(--felt-dim); text-transform: uppercase; letter-spacing: .5px; white-space: nowrap; }

/* THE SPEAKER (CLAUDE.md 5e, letters' .snd-g). */
.snd-g { width: 22px; height: 22px; fill: currentColor; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.snd-g .ol { fill: none; }
.sound-btn[aria-pressed="true"] .snd-off, .sound-btn[aria-pressed="false"] .snd-on { display: none; }
.sound-btn[aria-pressed="false"] { opacity: .62; }

/* AT A TABLE: A TAB ON THE CARD PER PLAYER (dice-v8, the owner: "the name of
   the user should be a tab of the card so it's continuously drawn and more
   obvious that the card changes"). The card on show has its tab in the same
   paper, joined to it by two inward curves; the others stand behind in a
   darker paper. A gold dot is whose turn it is. Flush left: when the first
   tab is the card's, the card's top-left corner is square (.tab-first). */
.seat-tabs { flex: none; display: flex; align-items: flex-end; gap: 3px; margin-bottom: -1px; position: relative; z-index: 1; min-width: 0; padding-right: 12px; }
.seat-tab {
  position: relative; flex: 0 1 auto; min-width: 0; max-width: 46%;
  display: flex; align-items: baseline; gap: 6px; padding: 6px 11px 6px; border: 0; border-radius: 11px 11px 0 0;
  font: inherit; cursor: pointer; text-align: left;
  background: color-mix(in srgb, var(--paper-2) 74%, #000); color: #3a2a1c;
  box-shadow: inset 0 -5px 6px -5px rgba(0, 0, 0, .35);
}
.seat-tab .tb-n { min-width: 0; font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.seat-tab .tb-v { flex: none; font-family: var(--font-num); font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; }
.seat-tab.turn .tb-n::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--gold); box-shadow: 0 0 0 1.5px rgba(0,0,0,.18); margin-right: 5px; vertical-align: 1px; animation: blink 1.2s ease-in-out infinite; }
@keyframes blink { 50% { opacity: .25; } }
.seat-tab.away { opacity: .6; }
.seat-tab.lead .tb-v::after { content: " ★"; font-size: 12px; color: var(--gold); vertical-align: 2px; }
.seat-tab.viewing {
  z-index: 2; padding-top: 9px; padding-bottom: 7px;
  background: var(--paper-1); color: #241a12; box-shadow: inset 0 1px 0 rgba(255,255,255,.8), 0 -1px 0 .5px rgba(60,40,10,.12);
}
.seat-tab.viewing::before, .seat-tab.viewing::after { content: ""; position: absolute; bottom: 0; width: 10px; height: 10px; pointer-events: none; }
.seat-tab.viewing::before { left: -10px; background: radial-gradient(circle at 0 0, transparent 9.5px, var(--paper-1) 10px); }
.seat-tab.viewing::after { right: -10px; background: radial-gradient(circle at 100% 0, transparent 9.5px, var(--paper-1) 10px); }
.seat-tab.viewing:first-child::before { display: none; }
.sheet-card.tab-first { border-top-left-radius: 0; }
/* Four or more at a table: the tabs share the width, name over total. */
.seat-tabs.many { padding-right: 0; }
.seat-tabs.many .seat-tab { flex: 1 1 0; max-width: none; flex-direction: column; align-items: flex-start; gap: 0; padding: 5px 8px 5px; }
.seat-tabs.many .seat-tab.viewing { flex-grow: 1.35; padding-top: 7px; }
.seat-tabs.many .tb-n { max-width: 100%; font-size: 12.5px; }
.seat-tabs.many .tb-v { font-size: 15px; line-height: 1.15; }

/* THE SCORE CARD: two columns of boxes that share the height there is. */
.sheet-card {
  flex: 1 1 auto; min-height: 0; max-height: 470px;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0;
  border-radius: 16px; padding: 4px; overflow: hidden;
  background: linear-gradient(170deg, var(--paper-1), var(--paper-2));
}
/* the pad's rules, a column at a time */
.sheet-col {
  display: grid; grid-template-rows: repeat(7, minmax(0, 1fr)); min-height: 0;
  background: repeating-linear-gradient(to bottom, transparent 0, transparent calc(100% / 7 - 1px), var(--paper-rule) calc(100% / 7 - 1px), var(--paper-rule) calc(100% / 7));
}
.sheet-col + .sheet-col { border-left: 1.5px solid rgba(181, 24, 44, .28); }
.box {
  appearance: none; -webkit-appearance: none; font: inherit; color: var(--ink);
  display: flex; align-items: center; gap: 8px; min-height: 0; width: calc(100% - 6px);
  padding: 0 8px; margin: 2px 3px; border: 0; border-radius: 10px; background: transparent; cursor: pointer; text-align: left;
  position: relative;
}
.box .bx-g { flex: none; line-height: 0; }
.box .bx-g .die { --ds: 24px; }
.box .bx-k { flex: 1; min-width: 0; font-size: 15px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ink-2); }
.box .bx-v { flex: none; font-family: var(--font-num); font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; min-width: 1.6em; text-align: right; }
/* A NAME WITH A LINE UNDER IT: the bonus row's progress, Five of a kind's extras. */
.box .bx-kw { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.box .bx-kw .bx-k { flex: none; }
.box .bx-s { font-size: 11.5px; font-weight: 600; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; line-height: 1.25; }
.box .bx-s:empty { display: none; }
.box .bx-x { color: #8a6200; }
.box .bx-x .xp { font-size: 15px; margin-right: 3px; }
/* A SHADOW: points that are not a box's own (the +35, the +100s), quieter than
   a score but there to be added — the card's numbers and its shadows make the total. */
.xp {
  display: inline-block; line-height: 1.15;
  font-family: var(--font-num); font-weight: 700; font-variant-numeric: tabular-nums;
  color: #a77400; text-shadow: 0 1px 0 rgba(255, 255, 255, .7);
}
/* filled: the number, written */
.box.filled { cursor: default; background: rgba(90, 60, 30, .075); }
.box.filled .bx-k { color: var(--dim); font-weight: 500; }
.box.zero .bx-v { color: var(--dim); }
/* OPEN, WITH DICE ON THE TABLE (dice-v3: the owner found pencil-blue numbers
 * "not obvious enough"): a box these dice score in is washed blue and rimmed,
 * its points in a solid blue pill; a box they would only zero fades back, its
 * 0 in grey. The blue is the paper's, the same in both themes. */
.box.can { background: #e2eafb; box-shadow: inset 0 0 0 1.5px rgba(47, 98, 207, .5); }
.box.can .bx-k { color: #1d3f8a; }
.box .bx-v.pot {
  color: #fff; background: #2f62cf; font-size: 20px; font-weight: 700;
  min-width: 2.1em; padding: 3px 10px; border-radius: 999px; text-align: center;
  box-shadow: 0 1px 2px rgba(20, 40, 90, .35);
}
.box.nil .bx-k { opacity: .5; }
.box.nil .bx-g { opacity: .55; }
.box .bx-v.pot.nil { color: var(--dim-2); background: transparent; box-shadow: none; font-weight: 600; padding: 0; min-width: 1.6em; text-align: right; }
/* CROSSED OUT (a zero): no "0" — a pen line through the whole box, as on a
 * paper pad (the owner, dice-v3: a scratched 0 read like an option). */
.box.filled.zero .bx-k, .box.filled.zero .bx-g { opacity: .55; }
.box.filled.zero::after {
  content: ""; position: absolute; left: 12px; right: 14px; top: 50%; height: 2.5px; margin-top: -1px;
  border-radius: 2px; background: #2a1d14; opacity: .8; transform: rotate(-3deg); pointer-events: none;
}
.box.open:not(:disabled):active { background: var(--pill); }
.box:disabled { cursor: default; }
/* the box you picked: gold, waiting for Score */
.box.sel { background: color-mix(in srgb, var(--gold) 26%, transparent); box-shadow: inset 0 0 0 2px var(--gold); }
.box.sel .bx-v { color: #8a6200; }
.box.sel .bx-k { color: var(--ink); }
.box.sel .bx-v.pot { background: var(--gold); color: #1a1200; box-shadow: none; }
.box.sel .bx-v.pot.nil { background: transparent; color: var(--bad); }
.box.hint { box-shadow: inset 0 0 0 2px var(--gold); animation: hintpulse 1s ease-in-out 3; }
@keyframes hintpulse { 50% { background: color-mix(in srgb, var(--gold) 22%, transparent); } }
.box.just { animation: justfilled .9s ease-out; }
@keyframes justfilled { 0% { background: color-mix(in srgb, var(--gold) 45%, transparent); } 100% { background: transparent; } }
/* the bonus row: not a box, a running sum */
.box.bonus { cursor: pointer; }
.box.bonus:active { background: var(--pill); }
/* A tap on the bonus row: what feeds the extra points in gold, the rest faded. */
#sheet.explaining .box { transition: opacity .2s ease, box-shadow .2s ease; }
#sheet.explaining .box:not(.why) { opacity: .3; }
#sheet.explaining .box.why { box-shadow: inset 0 0 0 2px var(--gold); background: color-mix(in srgb, var(--gold) 14%, transparent); }
.box.bonus .bx-v { font-size: 17px; }
.box.bonus .bx-v .xp { font-size: 20px; }
.box.bonus:not(.made) .bx-v .xp { color: var(--dim-2); font-weight: 600; opacity: .7; }
.box.bonus .bonus-bar { position: relative; display: block; flex: none; height: 3px; margin-top: 3px; max-width: 120px; border-radius: 2px; background: var(--pill); overflow: hidden; }
.box.bonus .bonus-bar i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--good); border-radius: 2px; transition: width .3s; }


/* ALWAYS TWO LINES TALL (dice-v7). It grew a line when a note wrapped and
   shrank back when the note's timer ran out, and the card above it shrank
   and grew with it: the bottom boxes moved up to 38px, and on a big phone the
   dice and Roll 19px — under a finger already on its way (the owner: taps
   that "don't register until i tap again"). eval/tap_shift.mjs holds it. */
.game-note {
  flex: none; margin: 6px 0 0; height: 2.8em; padding: 0 6px; overflow: hidden;
  display: grid; align-content: center;
  color: var(--felt-dim); font-size: 13.5px; line-height: 1.4; text-align: center;
  transition: opacity .2s;
}
.game-note.warn { color: var(--gold-lit); }
.game-note.strong { color: var(--felt-ink); font-weight: 600; }

/* THE TRAY: a well in the cloth, the dice in it. */
.tray {
  flex: none; display: flex; justify-content: center; align-items: center; gap: var(--dg, 10px);
  margin: 6px 0 0; padding: 18px 8px 14px; border-radius: 22px;
  background: radial-gradient(ellipse at 50% 40%, color-mix(in srgb, var(--felt-2) 70%, #000), var(--felt-2));
  box-shadow: inset 0 3px 12px rgba(0, 0, 0, .45), 0 0 0 1px var(--felt-line);
  /* As wide as five fit: container units, not vw — a die wider than the
     screen widened a phone's layout viewport, and vw with it. */
  container-type: inline-size;
  --ds: min(66px, calc((100cqi - 56px) / 5));
}

/* A DIE: a rounded cube face, lit from the top left, nine pip places. */
.die {
  --ds: 56px;
  appearance: none; -webkit-appearance: none; border: 0; padding: 0; margin: 0; font: inherit; cursor: pointer;
  position: relative; flex: none; width: var(--ds); height: var(--ds); border-radius: 22%;
  background: radial-gradient(circle at 30% 24%, var(--die-1), var(--die-2) 62%, var(--die-3));
  box-shadow: inset 0 calc(var(--ds) * -.05) 0 rgba(0, 0, 0, .14), inset 0 calc(var(--ds) * .03) 0 rgba(255, 255, 255, .5),
              0 calc(var(--ds) * .07) calc(var(--ds) * .14) rgba(0, 0, 0, .38);
  display: block;
  transition: translate .18s ease, box-shadow .18s ease;
}
.die > .pg { position: absolute; inset: 15%; display: grid; grid-template: repeat(3, 1fr) / repeat(3, 1fr); pointer-events: none; }
.die i { display: block; place-self: center; width: 72%; aspect-ratio: 1; border-radius: 50%; opacity: 0;
  background: radial-gradient(circle at 40% 35%, color-mix(in srgb, var(--pip) 70%, #fff), var(--pip) 60%); }
.die[data-v="1"] i { background: radial-gradient(circle at 40% 35%, color-mix(in srgb, var(--pip-one) 70%, #fff), var(--pip-one) 60%); width: 92%; }
/* which of the nine places show, per face */
.die[data-v="1"] i:nth-child(5),
.die[data-v="2"] i:nth-child(3), .die[data-v="2"] i:nth-child(7),
.die[data-v="3"] i:nth-child(3), .die[data-v="3"] i:nth-child(5), .die[data-v="3"] i:nth-child(7),
.die[data-v="4"] i:nth-child(1), .die[data-v="4"] i:nth-child(3), .die[data-v="4"] i:nth-child(7), .die[data-v="4"] i:nth-child(9),
.die[data-v="5"] i:nth-child(1), .die[data-v="5"] i:nth-child(3), .die[data-v="5"] i:nth-child(5), .die[data-v="5"] i:nth-child(7), .die[data-v="5"] i:nth-child(9),
.die[data-v="6"] i:nth-child(1), .die[data-v="6"] i:nth-child(3), .die[data-v="6"] i:nth-child(4), .die[data-v="6"] i:nth-child(6), .die[data-v="6"] i:nth-child(7), .die[data-v="6"] i:nth-child(9) { opacity: 1; }   /* opacity, not visibility: a visible child shows through a hidden screen (the menu pins the screen under it hidden) */
/* before the first roll: a blank die, waiting */
.die[data-v="0"] { opacity: .45; }
/* held: lifted out of the tray, rimmed in gold, the word under it */
.die.held { translate: 0 calc(var(--ds) * -.16); box-shadow: inset 0 calc(var(--ds) * -.05) 0 rgba(0,0,0,.14), 0 0 0 3px var(--gold-lit), 0 calc(var(--ds) * .2) calc(var(--ds) * .22) rgba(0,0,0,.4); }
.die.held::after {
  content: "held"; position: absolute; left: 50%; bottom: calc(var(--ds) * -.42); translate: -50% 0;
  font-size: 10.5px; font-weight: 700; letter-spacing: .6px; text-transform: uppercase; color: var(--gold-lit);
}
.die.hint { box-shadow: inset 0 calc(var(--ds) * -.05) 0 rgba(0,0,0,.14), 0 0 0 3px var(--gold-lit), 0 0 18px 4px color-mix(in srgb, var(--gold-lit) 60%, transparent); }
.die:disabled { cursor: default; }
.tray .die { --ds: inherit; }
.tray.watching .die { cursor: default; }

/* ── the controls ──────────────────────────────────────────────────────── */

.controls { flex: none; display: flex; gap: 10px; margin-top: 12px; }
#view-game .controls .btn:not(.btn-primary), #view-game .icon {
  background: var(--felt-glass); color: var(--felt-ink); border-color: var(--felt-line); box-shadow: none;
}
#hint-btn { flex: none; padding: 14px 16px; }
.roll-btn { flex: 1; padding: 14px 18px; font-size: 19px; font-weight: 700; border-radius: 16px; min-height: 56px; }
.roll-btn .pips { display: inline-flex; gap: 5px; margin-left: 6px; }
.roll-btn .pips i { width: 9px; height: 9px; border-radius: 50%; background: currentColor; opacity: .85; }
.roll-btn .pips i.used { opacity: .22; }
.roll-btn.score .pips { display: none; }
.roll-btn:disabled { opacity: .45; }
.btn-glyph svg { flex: none; }

/* ── the end of a sheet ────────────────────────────────────────────────── */

.overlay {
  position: fixed; inset: 0; z-index: 1000; display: grid; place-items: center;
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom, 0px));
  background: color-mix(in srgb, var(--felt-2) 60%, transparent);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.overlay-card { width: min(340px, 92%); padding: 24px 20px; text-align: center; border-radius: var(--r-card); max-height: 92%; overflow: auto; }
.overlay-mark { line-height: 0; display: flex; justify-content: center; gap: 6px; min-height: 40px; }
.overlay-mark .die { --ds: 40px; pointer-events: none; }
.overlay-mark .die:nth-child(odd) { rotate: -9deg; }
.overlay-mark .die:nth-child(even) { rotate: 7deg; translate: 0 5px; }
.overlay-card h2 { margin: 14px 0 4px; font-size: 26px; letter-spacing: -.4px; }
.overlay-line { margin: 0; color: var(--dim); font-size: 14px; line-height: 1.5; }
.overlay-stats { display: flex; justify-content: center; gap: 20px; margin: 18px 0 0; padding: 14px 0 0; border-top: .5px solid var(--line-2); }
.overlay-stats div { display: flex; flex-direction: column; gap: 2px; }
.overlay-stats dt { font-size: 10.5px; color: var(--dim); text-transform: uppercase; letter-spacing: .4px; order: 2; }
.overlay-stats dd { margin: 0; font-family: var(--font-num); font-size: 21px; font-weight: 700; font-variant-numeric: tabular-nums; order: 1; }
.overlay-stats dd.you { color: var(--gold); }
.overlay-submit { margin: 14px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--dim); min-height: 17px; }
.overlay-btns { display: flex; gap: 10px; margin-top: 18px; }
.overlay-btns .btn { flex: 1; padding-left: 10px; padding-right: 10px; }
.overlay-card .btn-quiet.btn-wide { margin-top: 8px; }
.standings { margin: 16px 0 0; text-align: left; border-top: .5px solid var(--line-2); }
.standings .st-row { display: flex; align-items: center; gap: 10px; padding: 8px 2px; border-bottom: .5px solid var(--line-2); }
.standings .st-p { width: 22px; font-family: var(--font-num); font-weight: 700; color: var(--dim); text-align: right; }
.standings .st-n { flex: 1; font-weight: 600; }
.standings .st-l { font-size: 11.5px; color: var(--dim); font-weight: 500; margin-left: 4px; }
.standings .st-v { font-family: var(--font-num); font-size: 18px; font-weight: 700; }
.standings .st-row.win .st-p, .standings .st-row.you .st-n { color: var(--gold); }

/* A ZERO, ASKED ABOUT */
.ask-card h2 { margin-top: 4px; }
.btn-zero { background: var(--bad); color: #fff; }

/* EVERY SCORE AT A TABLE */
.scores-card { width: min(560px, 96%); padding: 14px 10px 10px; text-align: left; }
.scores-head { display: flex; align-items: center; justify-content: space-between; padding: 0 6px 8px; }
.scores-head h2 { margin: 0; font-size: 22px; }
.scores-head .icon, #view-game .scores-head .icon { color: #241a12; background: rgba(90, 60, 30, .12); border-color: transparent; }
.scores-scroll { overflow-x: auto; }
.scores-table { border-collapse: collapse; width: 100%; font-size: 14px; }
.scores-table th, .scores-table td { padding: 6px 7px; border-bottom: .5px solid var(--line-2); white-space: nowrap; }
.scores-table th { font-size: 12px; font-weight: 700; text-align: right; max-width: 80px; overflow: hidden; text-overflow: ellipsis; }
.scores-table th:first-child, .scores-table td:first-child { text-align: left; color: var(--ink-2); font-weight: 500; }
.scores-table td { text-align: right; font-family: var(--font-num); font-weight: 600; font-variant-numeric: tabular-nums; }
.scores-table td.open { color: var(--dim-2); }
.scores-table tr.sum td { font-weight: 800; color: var(--ink); border-top: 1px solid var(--line); }
.scores-table th.turn { color: #8a6200; }

/* ── segmented control ─────────────────────────────────────────────────── */

.segmented { display: flex; gap: 3px; padding: 3px; background: var(--glass-2); border-radius: var(--r-sm); border: .5px solid var(--line-2); }
.segmented button {
  flex: 1; font: inherit; font-size: 14px; font-weight: 600; padding: 8px 6px; border: 0; border-radius: 8px;
  background: transparent; color: var(--ink); cursor: pointer;
}
/* A supporter's choice, seen by everybody else: there, a shade back (dice-v6). */
.segmented button.locked { opacity: .45; }
.segmented button[aria-selected="true"], .segmented button.is-on { background: var(--gold); color: var(--gold-ink); box-shadow: var(--shadow); }
.segmented.seg-sm { flex: none; }
.segmented.seg-sm button { flex: none; font-size: 13px; padding: 6px 10px; }

/* ── the leaderboards ──────────────────────────────────────────────────── */

h3.sec-sub { margin: 18px 4px 0; font-size: 17px; font-weight: 700; }
.board-list { margin-top: 10px; padding: 0; overflow: hidden; border-radius: var(--r-card); }
.board-row { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: .5px solid var(--line-2); }
.board-row:last-child { border-bottom: 0; }
.board-row.you { background: color-mix(in srgb, var(--gold) 16%, transparent); }
.board-rank { width: 26px; flex: none; text-align: right; font-family: var(--font-num); font-weight: 700; font-size: 15px; font-variant-numeric: tabular-nums; color: var(--dim); }
.board-row.you .board-rank { color: var(--gold); }
.board-who { flex: 1; min-width: 0; }
.board-name { font-size: 15px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.board-row.you .board-name { font-weight: 700; }
.board-meta { font-size: 11.5px; color: var(--dim); margin-top: 1px; }
.board-score { font-family: var(--font-num); font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.board-empty { padding: 26px 20px; text-align: center; color: var(--dim); font-size: 14px; line-height: 1.5; }
.board-you { margin: 8px 6px 0; }
.bot-tag { font-size: 10.5px; font-weight: 700; letter-spacing: .3px; color: var(--dim); border: .5px solid var(--line); border-radius: 6px; padding: 1px 5px; margin-left: 6px; vertical-align: 1px; }

.stats-list { margin: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px 10px; }
.stats-list div { display: flex; flex-direction: column; gap: 2px; }
.stats-list dt { font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .4px; order: 2; }
.stats-list dd { margin: 0; font-family: var(--font-num); font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; order: 1; }

/* ── settings rows ─────────────────────────────────────────────────────── */

.rows > .row, .rows > div > .row { padding: 13px 0; border-bottom: .5px solid var(--line-2); display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.rows > .row:last-child, .rows > div > .row:last-child { border-bottom: 0; }
.rows > .row.row-stack { flex-direction: column; align-items: stretch; gap: 8px; }
.row-head { display: flex; align-items: center; justify-content: space-between; }
.row-k { font-size: 15px; font-weight: 500; }
.row-v { font-family: var(--font-num); font-weight: 600; font-variant-numeric: tabular-nums; }
.row-note { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--dim); }
.row-line { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; }
.rows > button.row-tap {
  appearance: none; -webkit-appearance: none; width: 100%; background: none; border: 0;
  border-bottom: 1px solid var(--line-2); font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.rows > button.row-tap:active { background: var(--pill); }
.row-tap .chev { color: var(--dim); font-size: 22px; line-height: 1; margin-top: -2px; }
.name-input {
  width: 100%; font: inherit; font-size: 16px; padding: 11px 12px;     /* 16px: below that iOS zooms to the field */
  color: var(--ink); background: var(--pill); border: 1px solid var(--line); border-radius: 10px;
}
.name-input:focus { outline: 2px solid var(--gold); outline-offset: 0; border-color: transparent; }
.code-row { display: flex; gap: 10px; }
.code-input { flex: 1; font-family: var(--font-num); font-size: 22px; font-weight: 700; letter-spacing: .3em; text-transform: uppercase; text-align: center; }

.switch { position: relative; display: inline-block; width: 51px; height: 31px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; z-index: 2; }
.switch span { position: absolute; inset: 0; border-radius: 999px; background: var(--pill); transition: background .2s ease; }
.switch span::after { content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .2s ease; }
.switch input:checked + span { background: var(--good); }
.switch input:checked + span::after { transform: translateX(20px); }
.switch input:disabled + span { opacity: .4; }

.prose p { margin: 0 0 12px; font-size: 14px; line-height: 1.6; color: var(--ink-2); }
.prose p:last-child { margin-bottom: 0; }
.rules-table { width: 100%; border-collapse: collapse; margin: 4px 0 14px; font-size: 13.5px; }
.rules-table td { padding: 6px 0; border-bottom: .5px solid var(--line-2); vertical-align: top; color: var(--ink-2); }
.rules-table td:first-child { font-weight: 650; color: var(--ink); padding-right: 10px; white-space: nowrap; }
.update-note { color: var(--warn) !important; }

/* ── tables: the lobby and a table before the dice ─────────────────────── */

.lobby-list .lobby-row { gap: 12px; }
.lb-body { flex: 1; min-width: 0; }
.lb-title { font-size: 15.5px; font-weight: 650; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-note { font-size: 12.5px; color: var(--dim); margin-top: 2px; }
.lb-code { font-family: var(--font-num); font-weight: 700; letter-spacing: .12em; }
.code-card { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.code-k { font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .5px; }
.code-v { font-family: var(--font-num); font-size: 38px; font-weight: 800; letter-spacing: .18em; }
.seat-row .seat-n { flex: 1; font-weight: 600; font-size: 15.5px; }
.seat-row .seat-t { font-size: 12px; color: var(--dim); margin-left: 6px; font-weight: 500; }
.seat-row .btn { padding: 6px 12px; font-size: 13px; box-shadow: none; }
.bot-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.bot-chip { font: inherit; display: inline-flex; flex-direction: column; align-items: flex-start; gap: 1px; padding: 9px 13px; border-radius: 12px; cursor: pointer;
  background: rgba(90, 60, 30, .08); color: var(--ink); border: .5px solid var(--line); }
.bot-chip b { font-size: 15px; }
.bot-chip span { font-size: 11.5px; color: var(--dim); }
.bot-chip:disabled { opacity: .4; }
#view-room .btn-wide { margin-top: 4px; }
#room-leave { margin-top: 18px; }

/* ── the menu sheet ────────────────────────────────────────────────────── */

/* IN FLOW, NOT FIXED (IOS.md §15): the page is the menu's scroller. */
.sheet { position: relative; z-index: 1100; }
.sheet-body {
  padding: calc(8px + var(--glass-t) + env(safe-area-inset-top, 0px)) calc(16px + env(safe-area-inset-right, 0px)) calc(32px + env(safe-area-inset-bottom, 0px)) calc(16px + env(safe-area-inset-left, 0px));
  max-width: 560px; width: 100%; margin: 0 auto;
}
.sheet-body > .view-head { padding-bottom: 4px; }
h2.sec { margin: 26px 4px 10px; font-size: 24px; font-weight: 700; letter-spacing: -.4px; }
.sheet-body section:first-of-type h2.sec { margin-top: 14px; }

/* ── the foot of settings (CLAUDE.md 5) ───────────────────────────────── */

#tipjar-card { margin-top: 14px; }
/* SUPPORTER PERKS (index.html): the card keeps its top padding and its
   rows sit flush inside it (mahjong's). */
#support-card { padding: 16px 16px 0; }
#support-card .support-thanks, #support-card .support-perks { margin: 0 0 12px; }
#support-card .rows { margin: 0 -16px; }
#support-card .rows > button.row-tap { padding: 13px 16px; border-bottom: 0; border-top: .5px solid var(--line-2); }
#support-card .rows > .row-stack { padding: 4px 16px 14px; border-bottom: 0; }
#support-card .row-k { flex: 1; }
.row-tap .row-v { font-family: inherit; font-weight: 500; color: var(--dim); display: inline-flex; align-items: center; gap: 6px; }
.row-tap .row-v.own { color: var(--ink); }
.name-actions { display: flex; gap: 8px; align-items: center; }
.name-actions .btn { padding: 8px 14px; font-size: 14px; }
#private-note { margin-top: 8px; }
/* THE SUPPORTER'S MARK: a small flat gold die by the name (the house's rule:
   subtle, ~.8em, the game's own object as a silhouette — pips cut out). */
.mark { display: inline-block; color: var(--gold); margin-left: 5px; vertical-align: -1px; cursor: pointer; line-height: 0; }
.mark svg { width: .8em; height: .8em; display: inline-block; fill: currentColor; }
#tipjar .tip-glyph { color: var(--heart); font-size: 18px; line-height: 1; margin-right: 2px; }
#tipjar .row-k { flex: 1; }
:root { --games-gold: #c48a12; }
#games-card { margin-top: 14px; }
#games-row { padding: 12px 0; }
.games-lockup { display: inline-flex; flex: none; flex-direction: column; align-items: flex-end; line-height: 1; font-family: "SF Pro Rounded", ui-rounded, var(--font); font-weight: 700; }
.games-lockup .gl-mark { font-size: 22px; letter-spacing: -0.01em; color: var(--ink); }
.games-lockup .gl-ca { color: var(--dim); }
.games-lockup .gl-sub { font-size: 10px; letter-spacing: .02em; color: var(--games-gold); margin-top: -1px; margin-right: 1px; }
#games-row .games-more { flex: 1; text-align: right; color: var(--dim); font-weight: 400; }
#account-card { padding: 16px 16px 0; }
#account-card #account-who { margin: 0 0 12px; }
#account-card .rows { margin: 0 -16px; }
#account-card .rows > button.row-tap { padding: 13px 16px; border-bottom: 0; border-top: .5px solid var(--line-2); }
.rows > button.row-tap.danger { color: var(--bad); }
details.technical { padding: 0; overflow: hidden; }
details.technical > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 13px 16px; }
details.technical > summary::-webkit-details-marker { display: none; }
details.technical > summary .chev { color: var(--dim); font-size: 22px; line-height: 1; margin-top: -2px; transition: transform .15s; }
details.technical[open] > summary .chev { transform: rotate(90deg); }
details.technical .kv { margin: 0; padding: 4px 16px 12px; border-top: .5px solid var(--line-2); }
details.technical .kv > div { display: flex; gap: 12px; padding: 8px 0; border-bottom: .5px solid var(--line-2); }
details.technical .kv > div:last-child { border-bottom: 0; }
details.technical .kv dt { flex: 0 0 76px; font-size: 13px; color: var(--dim); }
details.technical .kv dd { margin: 0; flex: 1; min-width: 0; font-size: 12px; font-family: var(--font-mono); color: var(--ink-2); line-height: 1.5; overflow-wrap: anywhere; }
details.technical > .row-note { padding: 0 16px 14px; }

.toast {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: calc(24px + env(safe-area-inset-bottom, 0px)); z-index: 1300;
  max-width: min(92vw, 420px); padding: 10px 14px; border-radius: 14px;
  background: rgba(255, 250, 240, .96); color: #241a12; box-shadow: 0 8px 24px rgba(0,0,0,.3);
  font-size: 14px; line-height: 1.4; text-align: center;
}
.toast-link { color: #8c2a3b; font-weight: 600; }

.banner {
  position: fixed; left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: var(--r-mid);
  font-size: 13.5px; line-height: 1.45; z-index: 1200;
  background: rgba(255, 250, 240, .97); color: #241a12; box-shadow: 0 8px 24px rgba(0,0,0,.3);
}
.banner .banner-retry { margin-left: auto; padding: 6px 13px; font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1.2; border: 0; border-radius: 999px; background: #d9a520; color: #1a1200; cursor: pointer; }
.banner .banner-retry:disabled { opacity: .45; }
.banner .banner-retry + button { margin-left: 4px; }
.banner button { margin-left: auto; flex: none; font: inherit; font-size: 20px; line-height: 1; border: 0; background: transparent; color: inherit; cursor: pointer; }

/* ── bigger screens ────────────────────────────────────────────────────── */

@media (min-height: 800px) {
  .sheet-card { max-height: 620px; }
  .box .bx-v { font-size: 24px; }
  .box .bx-k { font-size: 16px; }
}
@media (max-height: 640px) {
  .box .bx-k { font-size: 13.5px; }
  .box .bx-v { font-size: 19px; }
  .box .bx-g .die { --ds: 20px; }
  .tray { padding: 14px 8px 12px; --ds: min(54px, calc((100cqi - 56px) / 5)); }
  .controls { margin-top: 8px; }
  .roll-btn { min-height: 50px; }
  .game-stat-v { font-size: 24px; }
}
@media (min-width: 700px) {
  .tray { --ds: 72px; --dg: 16px; }
}

/* A PHONE TURNED SIDEWAYS (dice-v4; the owner: turned by accident, the sheet
   squeezed to a strip its rows wrote over each other). Too short for a sheet
   over a tray, so they stand side by side: the sheet the whole height on the
   left, the header, the seats, the dice and Roll on the right. Turned back
   upright, app.js's reseat puts the locked page at the top again (IOS.md §15). */
@media (orientation: landscape) and (max-height: 560px) {
  #view-game {
    max-width: 980px;
    display: grid; column-gap: 16px;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr) auto auto auto;
    grid-template-areas: "tabs head" "sheet ." "sheet ." "sheet note" "sheet tray" "sheet controls";
    padding-top: calc(10px + env(safe-area-inset-top, 0px));
  }
  #view-game > .game-head { grid-area: head; }
  #view-game > .seat-tabs { grid-area: tabs; align-self: end; }
  #view-game:has(> .seat-tabs[hidden]) { grid-template-areas: "sheet head" "sheet ." "sheet ." "sheet note" "sheet tray" "sheet controls"; }
  #view-game > .sheet-card { grid-area: sheet; max-height: none; }
  #view-game > .game-note { grid-area: note; }
  #view-game > .tray { grid-area: tray; padding: 14px 8px 18px; --ds: min(58px, calc((100cqi - 56px) / 5)); }
  #view-game > .controls { grid-area: controls; margin-top: 8px; }
  .roll-btn { min-height: 50px; }
}
