/* ============================================================
   Camp Yahtzee — phone-first styles.
   Every surface keeps the polarity of its theme (light surfaces in
   light mode, dark in dark mode) so text stays readable wherever it
   is measured, and no background ever traps the fallback text colour.
   ============================================================ */

:root {
  --bg: #f5ecdb;
  --bg-deep: #e7d9bd;
  --card: #fffbf1;
  --card-2: #f2e7d3;
  --tint: #fbeccb;
  --gold-bg: #f4d488;
  --gold-ink: #1b1208;
  --ink: #1b1208;
  --ink-2: #4a3b2a;
  --ink-3: #6b5941;
  --line: #c9b591;
  --accent: #a2360a;
  --accent-ink: #fffbf1;
  --felt: #1c5a4c;
  --felt-2: #10402f;
  --felt-hole: #0c3226;
  --felt-ink: #f4f1e6;
  --die: #fffcf3;
  --die-2: #ded0b4;
  --pip: #241a10;
  --die-cap: #ded0b4;
  --die-cap-ink: #1b1208;
  --good: #0f6b3a;
  --bad: #8a2b12;
  --shadow: 0 2px 0 rgba(27, 18, 8, 0.12), 0 10px 22px -14px rgba(27, 18, 8, 0.6);
  --radius: 14px;
  color-scheme: light;
}

[data-theme='dark'] {
  --bg: #141009;
  --bg-deep: #1f1810;
  --card: #241d14;
  --card-2: #2f2619;
  --tint: #3c2c12;
  --gold-bg: #6a4708;
  --gold-ink: #f8f1e2;
  --ink: #f8f1e2;
  --ink-2: #d3c5ad;
  --ink-3: #b7a68b;
  --line: #4a3d2b;
  --accent: #ff9c5c;
  --accent-ink: #1b0f05;
  --felt: #0e3b32;
  --felt-2: #07281f;
  --felt-hole: #082019;
  --felt-ink: #eaf3ee;
  --die: #fffaef;
  --die-2: #cbbfa4;
  --pip: #211609;
  --die-cap: #6b5941;
  --die-cap-ink: #f8f1e2;
  --good: #6fe3a3;
  --bad: #ff9c7a;
  --shadow: 0 2px 0 rgba(0, 0, 0, 0.55), 0 12px 26px -16px rgba(0, 0, 0, 0.95);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { background: var(--bg); -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  background: linear-gradient(180deg, var(--bg) 0%, var(--bg-deep) 100%);
  color: var(--ink);
  font-family: ui-rounded, 'SF Pro Rounded', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size: 17px;
  line-height: 1.32;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
}

h1, h2, h3, p, ul, ol { margin: 0; padding: 0; }
ul, ol { list-style: none; }
button { font: inherit; color: inherit; margin: 0; }
b { font-weight: 800; }

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.app {
  max-width: 620px;
  margin: 0 auto;
  padding: calc(8px + env(safe-area-inset-top)) 12px calc(24px + env(safe-area-inset-bottom));
}
[hidden] { display: none !important; }
#dice[inert], .felt [inert] { pointer-events: none; }
.screen[hidden] { display: none !important; }

/* ───────────────────── buttons ───────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; min-width: 44px; padding: 10px 16px;
  border: 2px solid transparent; border-radius: 999px;
  background: var(--card); color: var(--ink);
  font-weight: 800; text-align: center; letter-spacing: 0.01em;
  box-shadow: var(--shadow); cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: transform 0.08s ease;
}
.btn:active { transform: translateY(2px) scale(0.99); }
.btn:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.btn:disabled { cursor: not-allowed; box-shadow: none; background: var(--card-2); color: var(--ink-3); border-style: dashed; }

.btn-add { background: var(--accent); color: var(--accent-ink); padding: 10px; }
.btn-add:disabled { background: var(--card-2); color: var(--ink-3); }
.btn-primary {
  background: var(--gold-bg); color: var(--gold-ink);
  width: 100%; font-size: 19px; padding: 12px 18px; border-color: var(--gold-ink);
}
.btn-primary:disabled { background: var(--card-2); color: var(--ink-3); border-color: var(--line); }
.btn-ghost {
  background: transparent; color: var(--ink); border-color: var(--line);
  box-shadow: none; font-size: 15px; font-weight: 700; padding: 10px 13px;
}
.btn-icon { background: var(--card); padding: 10px; width: 44px; gap: 0; }
.btn-dice-mode { position: relative; border-color: var(--line); }
.btn-dice-mode .face { display: none; }
.btn-dice-mode[data-mode='phone'] .die-ico { display: block; }
.btn-dice-mode[data-mode='table'] .table-ico { display: block; color: var(--accent); }
.btn-dice-mode[data-mode='table'] { border: 2px solid var(--accent); }
/* While Undo is offered the title steps out of the row (the name above it is already
   40px tall, so "Ana's scorecard" is the one thing here nobody needs) and the button
   gets the whole width — anything less and "Undo Eduard's Full house (25)" ends in an
   ellipsis, which is the vagueness the label exists to remove. Nothing shifts: the
   row keeps its height either way. */
.card-head.has-undo .card-title { display: none; }
.btn-undo {
  background: transparent; border-color: var(--line); box-shadow: none;
  font-size: 15px; font-weight: 800; padding: 8px 12px;
  min-width: 0; max-width: 100%; flex: 1 1 auto; justify-content: center;
}
.undo-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.undo-txt b { font-weight: 900; }
.btn-undo.invisible { visibility: hidden; }
.undo-who { color: var(--ink-2); }
.card-title { flex: 1 1 auto; }
.btn-mini {
  min-height: 44px; padding: 8px 12px; background: transparent;
  border: 2px solid transparent; box-shadow: none;
  font-size: 13px; font-weight: 800; color: var(--ink-3); letter-spacing: 0.04em;
}

/* ───────────────────── setup ───────────────────── */
.brand { padding: 10px 2px 0; }
.brand-mark { display: inline-flex; color: var(--accent); }
.brand-title {
  margin-top: 4px;
  font-size: clamp(36px, 11.5vw, 54px);
  line-height: 0.9; font-weight: 900; letter-spacing: -0.04em; text-transform: uppercase;
}
.brand-sub { margin-top: 10px; color: var(--ink-2); font-size: 16px; }

.setup-body { margin-top: 12px; }
.add-form {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 12px; box-shadow: var(--shadow);
}
.field-label {
  display: block; font-size: 14px; font-weight: 800;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2);
}
.field-row { display: flex; gap: 8px; margin-top: 8px; }
.name-input {
  flex: 1 1 auto; min-width: 0; min-height: 48px; padding: 10px 14px;
  border: 2px solid var(--line); border-radius: 12px;
  background: var(--bg); color: var(--ink);
  font: inherit; font-size: 19px; font-weight: 700;
}
.name-input:focus { outline: none; border-color: var(--accent); }
.name-input::placeholder { color: var(--ink-3); opacity: 1; font-weight: 600; }
.field-note { margin-top: 8px; color: var(--ink-2); font-size: 14px; }

.chips { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.chip {
  display: flex; align-items: center; gap: 10px; min-height: 52px;
  padding: 7px 7px 7px 11px;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow); animation: chip-in 0.2s ease both;
}
@keyframes chip-in { from { transform: translateY(-6px) scale(0.97); } }
.chip-seat {
  flex: none; display: grid; place-items: center; width: 30px; height: 30px;
  border-radius: 50%; background: var(--gold-bg); color: var(--gold-ink);
  font-size: 14px; font-weight: 900;
}
.chip-name { flex: 1 1 auto; min-width: 0; font-size: 19px; font-weight: 800; overflow-wrap: anywhere; }
.chip-remove {
  flex: none; width: 44px; height: 44px; display: grid; place-items: center;
  background: var(--card-2); border: 1px solid var(--line); border-radius: 50%;
  color: var(--ink); cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.chip-remove:active { background: var(--tint); }
.chip-remove:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.chips-empty { color: var(--ink-2); font-size: 16px; padding: 10px 2px; }

/* With a full table the roster is taller than the phone, so Start must stay in
   reach. The fade is a ::before (not a background on the bar) so it never joins
   any text element's ancestor chain. */
.setup-actions { margin-top: 14px; position: sticky; bottom: calc(8px + env(safe-area-inset-bottom)); z-index: 6; }
.setup-actions::before {
  content: ''; position: absolute; inset: -22px -12px -10px; z-index: -1;
  background: linear-gradient(180deg, transparent, var(--bg) 58%);
  pointer-events: none;
}
.setup-tools { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; }

.evening {
  margin-top: 16px; padding: 12px;
  background: var(--card-2); border: 1px dashed var(--line); border-radius: var(--radius);
}
.evening-title {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 12px; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-2);
}
.games b { font-size: 15px; color: var(--ink); }
.evening p { color: var(--ink-2); font-size: 15px; margin-top: 6px; }
.evening b { color: var(--ink); }

/* ───────────────────── game ───────────────────── */
.game-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.round-wrap { flex: 1 1 auto; min-width: 0; }
.game-top-actions { flex: none; }
.round {
  font-size: 14px; font-weight: 800; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ink-2);
}
.round-pips { display: flex; gap: 3px; margin-top: 4px; }
.round-pips i {
  width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--ink-3); box-sizing: border-box;
}
.round-pips i.done { background: var(--ink-3); }
.round-pips i.now { background: var(--accent); border-color: var(--accent); }
.game-top-actions { display: flex; gap: 5px; }

.turn {
  margin-top: 6px; padding: 8px 13px 9px;
  border-radius: 18px; background: var(--gold-bg); color: var(--gold-ink);
  border: 2px solid var(--gold-ink); box-shadow: var(--shadow);
  position: relative;
}
.turn-kicker { font-size: 12px; font-weight: 900; letter-spacing: 0.18em; text-transform: uppercase; opacity: 0.85; }
.turn-name {
  font-size: clamp(30px, 9.4vw, 44px); font-weight: 900; line-height: 1.04;
  letter-spacing: -0.035em; overflow-wrap: anywhere;
}
.turn-hint { margin-top: 2px; font-size: 14px; font-weight: 600; }
.turn.passed { animation: hand-over 0.4s ease both; }
@keyframes hand-over {
  0% { transform: translateX(-20px) rotate(-1deg); opacity: 0.25; }
  60% { transform: translateX(4px); }
}

.felt {
  position: relative;
  margin-top: 8px; padding: 10px 8px 9px;
  border-radius: 20px; background: linear-gradient(180deg, var(--felt) 0%, var(--felt-2) 100%);
  border: 2px solid var(--felt-hole);
  box-shadow: inset 0 2px 12px rgba(0, 0, 0, 0.4), var(--shadow);
  color: var(--felt-ink);
}
.dice { display: flex; justify-content: center; gap: 8px; position: relative; }

.die {
  position: relative; flex: none; width: 58px; height: 58px; padding: 0;
  border: 0; border-radius: 15px;
  background: linear-gradient(158deg, var(--die) 0%, var(--die) 52%, var(--die-2) 100%);
  box-shadow: 0 4px 0 var(--die-2), 0 9px 14px -6px rgba(0, 0, 0, 0.5);
  cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.dice[data-armed='false'] .die {
  cursor: default; background: var(--felt-hole); box-shadow: inset 0 2px 7px rgba(0, 0, 0, 0.45);
}
.dice[data-armed='false'] .die::before {
  content: ''; position: absolute; inset: 4px; border: 2px dashed var(--felt-ink);
  border-radius: 11px; opacity: 0.5;
}
.die:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.die .face { position: absolute; inset: 0; opacity: 0; }
.die[data-value='1'] .face[data-face='1'],
.die[data-value='2'] .face[data-face='2'],
.die[data-value='3'] .face[data-face='3'],
.die[data-value='4'] .face[data-face='4'],
.die[data-value='5'] .face[data-face='5'],
.die[data-value='6'] .face[data-face='6'] { opacity: 1; }
.die .pip {
  position: absolute; width: 10px; height: 10px; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #7a6d5b, var(--pip) 72%);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.55);
}
.die.tumble { animation: tumble 0.32s cubic-bezier(0.3, 0.85, 0.4, 1) both; }
@keyframes tumble {
  0% { transform: translateY(-15px) rotate(-22deg) scale(0.94); }
  55% { transform: translateY(3px) rotate(8deg) scale(1.05); }
  100% { transform: none; }
}
.die[aria-pressed='true'] {
  transform: translateY(-5px) rotate(-3deg);
  box-shadow: 0 0 0 3px var(--accent), 0 5px 0 var(--die-2), 0 10px 14px -6px rgba(0, 0, 0, 0.5);
}
.die[aria-pressed='true']::after {
  content: ''; position: absolute; top: 0; right: 0; width: 0; height: 0;
  border-style: solid; border-width: 0 17px 17px 0;
  border-color: transparent var(--accent) transparent transparent;
}
.die.yah-pop { animation: yah-pop 0.55s ease both; }
@keyframes yah-pop {
  0% { transform: scale(1); }
  30% { transform: scale(1.18) rotate(-7deg); }
  60% { transform: scale(1.12) rotate(6deg); }
}

.roll-row { display: flex; align-items: center; gap: 10px; margin-top: 11px; }
.btn-roll {
  flex: 1 1 auto; min-width: 0; min-height: 54px; font-size: 19px;
  background: var(--card); color: var(--ink); border-color: var(--ink);
}
.btn-roll:disabled { background: var(--felt-2); color: var(--felt-ink); border-color: transparent; box-shadow: none; }
.rolls {
  flex: none; display: flex; align-items: baseline; gap: 6px;
  color: var(--felt-ink); font-size: 13px; font-weight: 800;
  letter-spacing: 0.1em; text-transform: uppercase;
}
.rolls b { display: block; font-size: 26px; line-height: 1; letter-spacing: 0; font-variant-numeric: tabular-nums; }

.card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 10px 2px 5px; }
.card-title { font-size: 17px; font-weight: 900; letter-spacing: -0.01em; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.card { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 8px; align-items: start; }
.card-col { display: flex; flex-direction: column; gap: 4px; }
.card-section {
  font-size: 11px; font-weight: 900; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3); padding: 2px 4px 0;
}
.box {
  display: flex; align-items: center; gap: 6px; width: 100%; min-height: 44px;
  padding: 5px 9px; text-align: left;
  background: var(--card); color: var(--ink);
  border: 1.5px dashed var(--line); border-radius: 12px;
  box-shadow: var(--shadow); cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  transition: transform 0.08s ease;
}
.box:active { transform: translateY(2px); }
.box:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.box-name { flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 800; letter-spacing: -0.01em; }
.box-score { flex: none; display: grid; place-items: center; min-width: 30px; }
.box .score-value { font-size: 21px; font-weight: 900; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.box:disabled {
  cursor: default; box-shadow: none; background: var(--card-2);
  border-style: dashed; border-color: var(--line); color: var(--ink);
}
.box.pickable { background: var(--card); border: 2px solid var(--ink); }
.box.pickable .score-value { color: var(--accent); }
.box.pickable:not(.pickable-zero):not(.pickable-best) .score-value { text-decoration: underline 2px; text-underline-offset: 3px; }
.box.pickable-best { background: var(--tint); border-color: var(--accent); border-left-width: 7px; }
.box.pickable-zero { border: 2px dashed var(--line); box-shadow: none; background: var(--card); }
.box.pickable-zero .score-value { color: var(--ink-3); }
.box[data-state='recorded'] {
  background: var(--gold-bg); border: 2px solid var(--gold-ink);
  color: var(--gold-ink); cursor: default; box-shadow: none;
}
.box[data-state='recorded'] .box-name { text-decoration: line-through 1.5px; text-decoration-thickness: 1.5px; }
.box[data-state='recorded'] .score-value { color: var(--gold-ink); text-decoration: none; font-size: 22px; }
.box.last { box-shadow: 0 0 0 3px var(--accent); }
.box.last .box-name { text-decoration: underline 2.5px; text-underline-offset: 4px; }
.box.just { animation: box-locked 0.45s ease both; }
@keyframes box-locked { 35% { transform: scale(1.05); } }

/* One row of four, always: flex-basis 0 (not %) so the gaps can never push the
   fourth chip onto a second line and steal half a row of the turn. */
.totals { display: flex; flex-wrap: nowrap; gap: 5px; margin-top: 8px; }
.tot {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 0;
  padding: 3px 3px; border-radius: 11px; text-align: center;
  background: var(--card-2); border: 1px solid var(--line);
}
.tot-label { font-size: 11px; font-weight: 900; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-2); }
.tot b { font-size: 21px; line-height: 1.05; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.tot-total { background: var(--gold-bg); border-color: var(--gold-ink); color: var(--gold-ink); }
.tot-total .tot-label { color: var(--gold-ink); opacity: 0.8; }
.tot-total b { color: var(--gold-ink); }

.board-tools { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-top: 12px; }
.board-title {
  font-size: 12px; font-weight: 900; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3); padding-left: 2px;
}
.board-note { font-size: 12px; font-weight: 700; color: var(--ink-3); text-align: right; }
.board { display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
.board-row {
  display: flex; align-items: center; gap: 10px; min-height: 52px;
  padding: 6px 12px; border-radius: 12px;
  background: var(--card); border: 1.5px solid var(--line);
}
.board-row[aria-current='true'] { background: var(--tint); border: 2px solid var(--accent); }
.board-seat {
  flex: none; display: grid; place-items: center; width: 26px; height: 26px;
  border-radius: 50%; background: var(--card-2); color: var(--ink-2);
  font-size: 12px; font-weight: 900;
}
.board-row[aria-current='true'] .board-seat { background: var(--accent); color: var(--accent-ink); }
.board-name {
  flex: 1 1 auto; min-width: 0; font-size: 18px; font-weight: 800;
  letter-spacing: -0.01em; overflow-wrap: anywhere;
}
.board-row[aria-current='true'] .board-name::after {
  content: ' • to play'; font-size: 12px; font-weight: 900; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--accent);
}
.board-total {
  flex: none; min-width: 40px; text-align: right; font-size: 27px; font-weight: 900;
  font-variant-numeric: tabular-nums; letter-spacing: -0.02em;
}
.board-row.leading .board-total { color: var(--accent); }

/* ───────────────────── dice mode selector ───────────────────── */
.dice-mode {
  margin: 0 0 12px; padding: 12px;
  background: var(--card); border: 2px solid var(--accent); border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.dice-mode-legend {
  padding: 0 6px; font-size: 13px; font-weight: 900; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--accent);
}
.seg { display: flex; gap: 6px; }
.seg-stack { flex-direction: column; }
.seg-opt {
  flex: 1 1 0; min-width: 0; min-height: 62px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 4px; padding: 8px 6px;
  background: var(--bg); color: var(--ink); border: 2px solid var(--line);
  border-radius: 12px; font-size: 14px; font-weight: 800; text-align: center;
  cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.seg-opt:active { transform: translateY(1px); }
.seg-opt:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
.seg-opt[aria-checked='true'] {
  background: var(--gold-bg); color: var(--gold-ink);
  border: 3px solid var(--gold-ink); font-weight: 900;
}
.seg-stack .seg-opt { flex-direction: row; justify-content: flex-start; gap: 12px; min-height: 56px; padding: 10px 14px; font-size: 18px; text-align: left; }
.dice-mode-note { margin-top: 8px; color: var(--ink-2); font-size: 14px; font-weight: 600; }
.dice-mode-note b { color: var(--ink); }

/* ───────────────────── real dice at the table: slots + keypad ───────────────────── */
.slots { display: flex; justify-content: center; gap: 8px; }
.slot {
  position: relative; flex: none; width: 58px; height: 58px; padding: 0;
  border: 0; border-radius: 15px; cursor: pointer;
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
  background: var(--felt-hole); box-shadow: inset 0 2px 7px rgba(0, 0, 0, 0.45);
  color: var(--felt-ink);
}
.slot:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
.slot[data-filled='false']::before {
  content: ''; position: absolute; inset: 4px; border: 2px dashed var(--felt-ink);
  border-radius: 11px; opacity: 0.5;
}
/* .die inside a slot is a SPAN, so it needs a box of its own — an inline span
   inside a button silently collapses to 0×20 and the face never paints. */
.slot .slot-n {
  position: absolute; inset: 0; display: grid; place-content: center;
  font-size: 19px; font-weight: 900; opacity: 0.75;
}
.slot[data-filled='true'] .slot-n { display: none; }
.slot .die { position: absolute; inset: 0; display: none; border-radius: 15px; }
.slot .die .pip { width: 8px; height: 8px; }
.slot[data-filled='true'] .die {
  display: block; box-shadow: 0 3px 0 var(--die-2), 0 8px 14px -8px rgba(0, 0, 0, 0.6);
}
.slot[data-pending='true'] { box-shadow: inset 0 2px 7px rgba(0, 0, 0, 0.45), 0 0 0 3px var(--accent); }
.slot[data-pending='true'][data-filled='false']::before { opacity: 1; border-style: solid; }
.die.slot-set { animation: slot-set 0.22s ease both; }
@keyframes slot-set { 0% { transform: scale(0.7); } 60% { transform: scale(1.1); } }
.slots.ready { animation: tray-ready 0.4s ease both; }
@keyframes tray-ready { 40% { transform: translateY(-4px); } }

.keypad { margin-top: 7px; display: flex; flex-direction: column; gap: 6px; }
.keys { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.key {
  position: relative; min-height: 70px; width: 100%; padding: 0; border: 0;
  border-radius: 14px; cursor: pointer; overflow: hidden;
  background: linear-gradient(158deg, var(--die) 0%, var(--die) 55%, var(--die-2) 100%);
  box-shadow: 0 3px 0 var(--die-2), 0 8px 14px -8px rgba(0, 0, 0, 0.55);
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.key:active { transform: translateY(2px); }
.key:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* The pip area stops where the cap strip begins: nothing is ever painted on a pip,
   so a key is always a faithful picture of the die lying on the table. Inside it the
   pips sit on a centred SQUARE, the way a die face is — a 52x56 key leaves a 42x30
   area, and spreading five pips over that squashed them until they nearly touched. */
.key .kface { position: absolute; inset: 5px 5px 21px; display: grid; place-items: center; }
.key .kface-sq { position: relative; height: 100%; aspect-ratio: 1; max-width: 100%; }
.key .kface .pip {
  position: absolute; width: 8px; height: 8px; border-radius: 50%;
  background: radial-gradient(circle at 34% 30%, #7a6d5b, var(--pip) 72%);
}
.klabel {
  position: absolute; left: 0; right: 0; bottom: 0; height: 19px; z-index: 2;
  display: flex; align-items: center; justify-content: center; gap: 3px;
  background: var(--die-cap); color: var(--die-cap-ink);
  font-size: 12.5px; font-weight: 900; font-variant-numeric: tabular-nums; line-height: 1;
}
.knum { font-size: 13px; }
/* the count is hidden entirely at zero — a permanent marker read as an extra pip */
.kcount { font-size: 11.5px; opacity: 0.85; }
.key[data-count='0'] .kcount { display: none; }
.btn-key-tool {
  flex: 1 1 0; min-width: 0; min-height: 44px; padding: 6px 8px; font-size: 13px;
  background: transparent; color: var(--felt-ink); border-color: var(--felt-ink); box-shadow: none;
}
.btn-key-tool .lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.entry-bar { display: flex; align-items: center; gap: 6px; }
.entry-count {
  flex: none; min-width: 62px; text-align: center; padding: 3px 8px; border-radius: 999px;
  border: 2px solid var(--felt-ink); color: var(--felt-ink);
  font-size: 14px; font-weight: 900; font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.entry-count[data-ready='true'] { background: var(--gold-bg); border-color: var(--gold-ink); color: var(--gold-ink); }
.entry-hint { color: var(--felt-ink); font-size: 14px; font-weight: 700; }
.entry-hint.nudge { animation: nudge 0.3s ease both; }
@keyframes nudge { 25% { transform: translateX(-5px); } 60% { transform: translateX(4px); } }

/* The hand-over note sits inside the felt tray, exactly over the dice row — sized
   and placed from that row's own box in showHandover(). It used to float at the
   bottom of the screen and sat on the Sixes box, which is the first thing the next
   player reaches for; anything fixed also ends up over somebody's score. Nothing
   it can touch is needed to take a turn (the dice it hides are spent), the note is
   in flow so it can never be parked on screen, and it holds full opacity, so the
   contrast tool can never catch a mid-fade frame. */
.handover {
  position: absolute; z-index: 4; margin: 0;
  display: grid; place-content: center; text-align: center;
  padding: 0 10px; border-radius: 16px;
  background: var(--ink); color: var(--bg);
  font-size: 18px; font-weight: 800; line-height: 1.12; letter-spacing: -0.01em;
  opacity: 0; visibility: hidden; pointer-events: none;
  overflow: hidden;
}
.handover.show { opacity: 1; visibility: visible; animation: handover 1.3s ease both; }
@keyframes handover {
  0% { transform: scale(0.93); }
  12%, 88% { transform: scale(1); }
  100% { transform: scale(0.99); }
}

/* ───────────────────── game over ───────────────────── */
.win {
  position: relative; overflow: hidden; text-align: center;
  padding: 20px 16px 18px; border-radius: 22px;
  background: var(--gold-bg); color: var(--gold-ink);
  border: 2px solid var(--gold-ink); box-shadow: var(--shadow);
}
.win-kicker { font-size: 13px; font-weight: 900; letter-spacing: 0.2em; text-transform: uppercase; opacity: 0.85; }
.win-name {
  margin-top: 4px; font-size: clamp(30px, 9.6vw, 46px); font-weight: 900;
  letter-spacing: -0.04em; line-height: 1.04; overflow-wrap: anywhere;
}
.win-sub { margin-top: 6px; font-size: 15px; font-weight: 600; }
.win.reveal .win-name { animation: rise 0.7s cubic-bezier(0.2, 1.4, 0.5, 1) both; }
@keyframes rise { from { transform: translateY(14px) scale(0.92); opacity: 0; } }
.confetti { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.confetti:empty { display: none; }
.confetti i { position: absolute; width: 8px; height: 12px; border-radius: 2px; animation: fall linear both; }
@keyframes fall {
  from { transform: translateY(-20px) rotate(-18deg); opacity: 1; }
  to { transform: translateY(180px) rotate(200deg); opacity: 0; }
}

.final { margin-top: 12px; display: flex; flex-direction: column; gap: 8px; }
.final-row {
  display: flex; align-items: center; gap: 12px; min-height: 62px;
  padding: 9px 12px; border-radius: 16px;
  background: var(--card); border: 1.5px solid var(--line); box-shadow: var(--shadow);
}
.final-row.first { background: var(--tint); border-color: var(--accent); }
.final-rank {
  flex: none; display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%; background: var(--card-2); color: var(--ink-2);
  font-size: 15px; font-weight: 900;
}
.final-row.first .final-rank { background: var(--accent); color: var(--accent-ink); }
.final-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.final-name { font-size: 21px; font-weight: 900; letter-spacing: -0.02em; overflow-wrap: anywhere; }
.final-meta { font-size: 12px; font-weight: 700; color: var(--ink-2); letter-spacing: 0.03em; }
.final-total {
  flex: none; font-size: 28px; font-weight: 900; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.evening-over { margin-top: 14px; }
.session { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.session-row {
  display: grid; grid-template-columns: 1fr auto auto; gap: 12px; align-items: center;
  min-height: 48px; padding: 8px 12px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--line);
}
.session-name { font-size: 21px; font-weight: 900; letter-spacing: -0.02em; overflow-wrap: anywhere; }
.session-cell { text-align: right; }
.session-cell span { display: block; font-size: 10px; font-weight: 900; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-3); }
.session-cell b { font-size: 25px; font-weight: 900; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }

.over-actions { margin-top: 16px; display: flex; flex-direction: column; gap: 6px; }
.over-note { font-size: 14px; font-weight: 700; color: var(--ink-2); text-align: center; }
.over-actions .btn-ghost { justify-content: center; margin-top: 4px; }

/* ───────────────────── how-to sheet ───────────────────── */
.sheet-wrap { position: fixed; inset: 0; z-index: 40; display: flex; align-items: flex-end; }
.sheet-wrap[hidden] { display: none; }
.sheet-backdrop { position: absolute; inset: 0; background: rgba(8, 5, 2, 0.66); }
.sheet {
  position: relative; width: 100%; max-width: 620px; margin: 0 auto;
  max-height: min(86vh, 86dvh); display: flex; flex-direction: column;
  padding: 6px 16px calc(14px + env(safe-area-inset-bottom));
  background: var(--bg); border-radius: 22px 22px 0 0;
  box-shadow: 0 -14px 44px -12px rgba(0, 0, 0, 0.7);
  animation: sheet-up 0.24s ease both;
}
@keyframes sheet-up { from { transform: translateY(24px); opacity: 0.4; } }
.sheet-grip { width: 44px; height: 5px; border-radius: 3px; background: var(--line); margin: 4px auto 10px; flex: none; }
.sheet-title { font-size: 26px; font-weight: 900; letter-spacing: -0.03em; margin-bottom: 8px; }
.sheet-body { overflow-y: auto; color: var(--ink-2); font-size: 16px; display: flex; flex-direction: column; gap: 8px; }
.sheet-body b { color: var(--ink); }
.sheet-body i { color: var(--ink); font-style: italic; }
.sheet-body h3 {
  font-size: 12px; font-weight: 900; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-3); margin-top: 4px;
}
.sheet-body .rules { display: flex; flex-direction: column; gap: 6px; }
.sheet .btn-primary { margin-top: 12px; flex: none; }
.game-option-list { display: flex; flex-direction: column; gap: 8px; overflow-y: auto; }
.game-option-list .btn { justify-content: flex-start; white-space: normal; overflow-wrap: anywhere; text-align: left; }
#game-options { font-size: 12px; padding: 0; }
#game-options-sheet .sheet { overflow-y: auto; }

/* ───────────────────── the table / glance standings ─────────────────────
   For when the phone is lying face-up in the middle of the table: standings at a
   size you can read from across it. Plain solid surfaces only (the contrast tool
   treats gradients and color-mix() as separate candidate backgrounds). */
.table-sub { font-size: 14px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-2); margin-bottom: 10px; }
.sheet-rows { display: flex; flex-direction: column; gap: 6px; overflow-y: auto; }
.sheet-row {
  display: flex; align-items: center; gap: 10px; min-height: 56px;
  padding: 8px 12px; border-radius: 14px;
  background: var(--card); border: 1.5px solid var(--line); box-shadow: var(--shadow);
}
.sheet-row.lead { background: var(--tint); border-color: var(--accent); }
.sheet-row.playing { border: 2px solid var(--gold-ink); background: var(--gold-bg); color: var(--gold-ink); }
.sheet-rank {
  flex: none; display: grid; place-items: center; width: 34px; height: 34px;
  border-radius: 50%; background: var(--card-2); color: var(--ink-2);
  font-size: 15px; font-weight: 900;
}
.sheet-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.sheet-name { font-size: 27px; font-weight: 900; letter-spacing: -0.03em; overflow-wrap: anywhere; }
.sheet-meta { font-size: 13px; font-weight: 700; color: var(--ink-2); letter-spacing: 0.02em; }
.sheet-row.playing .sheet-meta { color: var(--gold-ink); }
.sheet-total { flex: none; font-size: 38px; font-weight: 900; letter-spacing: -0.04em; font-variant-numeric: tabular-nums; }
.sheet-session { margin-top: 14px; }
.sheet-session ul { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.sheet-h3 {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 12px; font-weight: 900; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-2);
}
.sheet-h3 b { font-size: 15px; color: var(--ink); }

/* ───────────────────── motion, size ───────────────────── */
@media (prefers-reduced-motion: reduce) {
  .die.tumble, .turn.passed, .handover.show, .box.just, .die.yah-pop, .die.slot-set,
  .slots.ready, .entry-hint.nudge,
  .win.reveal .win-name, .chip, .sheet { animation: none !important; }
  .confetti { display: none !important; }
  * { transition-duration: 1ms !important; }
}
html.no-motion .die.tumble, html.no-motion .turn.passed, html.no-motion .box.just,
html.no-motion .die.yah-pop, html.no-motion .win.reveal .win-name, html.no-motion .chip,
html.no-motion .die.slot-set, html.no-motion .slots.ready, html.no-motion .entry-hint.nudge,
html.no-motion .sheet { animation: none !important; }
html.no-motion .confetti { display: none !important; }
html.no-motion .yah-flash { animation-duration: 0.7s; }
@media (prefers-reduced-motion: reduce) { .yah-flash { animation-duration: 0.7s !important; } }

@media (max-width: 384px) {
  .die { width: 55px; height: 55px; }
  .slot { width: 55px; height: 55px; }
  .box-name { font-size: 14px; }
  .box .score-value { font-size: 19px; }
}
@media (max-height: 720px) {
  /* real-dice mode has no roll row, so the tray earns back the space it needs:
     the gold "Now playing" hint already says what to do, the pill says 5 of 5. */
  /* on a short phone the hint only earns its row while the five faces are still
     coming in; once they are all in, the lit boxes say what to do */
  html.mode-table .entry-hint[data-ready='true'] { display: none; }
  html.mode-table .keypad { margin-top: 5px; }
  html.mode-table .felt { padding-bottom: 5px; }
  .app { padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
  .brand { padding-top: 4px; }
  .brand-title { font-size: 30px; }
  .brand-sub { font-size: 14px; margin-top: 6px; }
  .add-form { padding: 10px; }
  .chip { min-height: 50px; }
  .round-pips { display: none; }
  .turn { padding: 4px 11px 5px; }
  .turn-kicker { font-size: 11px; letter-spacing: 0.14em; }
  .turn-name { font-size: 27px; }
  .turn-hint { display: none; }
  .game-top { padding-top: 0; }
  .felt { margin-top: 5px; padding: 7px 6px 6px; }
  .dice { gap: 6px; }
  .die { width: 46px; height: 46px; }
  .slots { gap: 6px; }
  .slot { width: 44px; height: 44px; border-radius: 12px; }
  .slot .die { border-radius: 12px; }
  .slot[data-filled='false']::before { border-radius: 9px; }
  .keypad { margin-top: 6px; gap: 5px; }
  .keys { gap: 5px; }
  /* tall enough that the pip square reaches the key's full width */
  .key { min-height: 68px; }
  .entry-bar { gap: 5px; }
  .roll-row { margin-top: 7px; }
  .btn-roll { min-height: 46px; font-size: 17px; }
  .card-head { margin: 5px 2px 3px; }
  .card-title { font-size: 15px; }
  .card-section { display: none; }
  .card-col { gap: 3px; }
  .card-section { font-size: 10px; }
  .box { min-height: 44px; padding: 4px 8px; }
  .box-name { font-size: 13.5px; }
  .box .score-value { font-size: 18px; }
  .totals { margin-top: 6px; }
  .tot { padding: 1px 4px; }
  .tot-label { font-size: 10px; }
  .tot b { font-size: 19px; }
  .board-tools { margin-top: 8px; }
  .board-row { min-height: 44px; }
}
@media (min-width: 700px) {
  body { font-size: 18px; }
  .app { padding-top: calc(22px + env(safe-area-inset-top)); }
  .card { gap: 0 14px; }
  .die { width: 66px; height: 66px; }
  .box { min-height: 50px; }
}

/* Yahtzee slam — decorative, never blocks a tap */
.yah-flash {
  position: fixed; inset: 0; z-index: 25; display: grid; place-content: center;
  gap: 4px; text-align: center; pointer-events: none;
  background: rgba(12, 8, 3, 0.72);
  animation: yah-flash 1.15s ease both;
}
.yah-flash[hidden] { display: none !important; }
.yah-word {
  font-size: clamp(46px, 16vw, 84px); font-weight: 900; letter-spacing: -0.05em;
  text-transform: uppercase; line-height: 0.95; color: #ffdc84;
  text-shadow: 0 4px 0 rgba(0, 0, 0, 0.35);
}
.yah-sub { font-size: 20px; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: #f6f1e4; }
@keyframes yah-flash {
  0% { opacity: 0; }
  12% { opacity: 1; }
  70% { opacity: 1; }
  100% { opacity: 0; }
}
