:root {
  /* ---- Site chrome: "Santorini dusk" — dome-blue panels and whitewash
     cream on a near-black night sky, not a light-mode flip. ---- */
  --bg: #0e1620;
  --bg-glow: #16283a;
  --panel-bg: #1c3a52;
  --panel-border: #c9a870;
  --surface-tint: #234863;
  --surface-tint-hover: #2a5573;
  --surface-border: #3a6885;
  --text: #f5f2e8;
  --text-dim: #a9c4d6;
  --accent: #e8e0cc;
  --on-accent: #1c3a52;
  --accent-2: #2f7fa8;

  /* ---- Board: "Monte Carlo" (the original felt-table look) — the
     default board skin; other skins override these under
     [data-board-theme="..."]. ---- */
  --wood-dark: #1c1916;
  --wood-light: #2d2822;
  --felt: #175c3c;
  --felt-edge: #124a30;
  --point-a: #e6d5ae;
  --point-a-edge: #cbb583;
  --point-b: #d95a30;
  --point-b-edge: #b8471f;
  --cream: #efe3cc;
  --white-checker: #f3ead6;
  --white-checker-ring: #d3c39a;
  --white-checker-edge: #b8a888;
  --black-checker: #201c18;
  --black-checker-ring: #3a3530;
  --black-checker-edge: #050403;
  --gold: #d8b978;
  /* Numbers live on the wood rail now, not the felt — every theme's wood
     tone is a similar dark warm brown, so one light color reads well
     everywhere and there's no need for a per-theme override anymore. */
  --point-number-color: #e8d9b8;
  --highlight-color: #ffd128;

  /* ---- Avatars: deliberately its own fixed palette, not the board
     variables above — those get overridden per data-board-theme, and an
     avatar's colors should never shift just because someone picked a
     different board skin. ---- */
  --av-felt: #175c3c;
  --av-terracotta: #d95a30;
  --av-accent: #2f7fa8;
  --av-gold: #d8b978;
  --av-plum: #5c4a72;
  --av-wood: #1c1916;
  --av-cream: #efe3cc;
  --av-panel: #1c3a52;
  --av-skin-1: #f0d5b8;
  --av-skin-2: #e0b088;
  --av-skin-3: #c17f4e;
  --av-skin-4: #8d5524;
  --av-skin-5: #5c3a21;
  --av-hair-dark: #2b2016;
  --av-hair-warm: #6b4226;
  --av-hair-ash: #d8b978;
  --av-hair-copper: #8a4a2f;
  --av-lips: #a8503f;

  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

/* Mobile touch tuning: kill the native tap-highlight flash and the ~gray
   flash box on every tap, disable double-tap-to-zoom on fast repeated taps
   (points get tapped in quick succession when moving a checker), and stop
   pull-to-refresh/rubber-banding from firing on fast taps near a screen
   edge. All invisible on desktop, all felt as "janky" on a real phone. */
html, body { overscroll-behavior: contain; }

button, .point, .bar-slot, .off-cell {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

body {
  margin: 0;
  /* svh (not vh) so mobile Safari's collapsible address bar doesn't inflate
     this past what's actually visible — with vh, vertical centering (see
     the portrait override below) pushed content down past the fold,
     leaving a large dead gap up top. */
  min-height: 100svh;
  background: radial-gradient(ellipse at top, var(--bg-glow), var(--bg));
  color: var(--text);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 40px 16px;
}

.hidden { display: none !important; }

/* ---------- Setup screen ---------- */

#setup-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.site-footer {
  color: var(--text-dim);
  font-size: 12px;
  text-align: center;
  opacity: 0.7;
}

.landing-hero {
  width: 680px;
  max-width: 92vw;
  position: relative;
}

.setup-card {
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 16px;
  padding: 36px 40px;
  width: 680px;
  max-width: 92vw;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}

.setup-columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
}

.setup-card-heading {
  margin: 0 0 20px;
  font-size: 15px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}

.brand-lockup {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 4px;
}

.brand-icon {
  width: 40px;
  height: 40px;
  border-radius: 9px;
  flex-shrink: 0;
  box-shadow: 0 4px 14px rgba(0,0,0,0.35);
}

.landing-hero h1 {
  margin: 0;
  font-size: 32px;
  font-family: Georgia, "Times New Roman", serif;
  font-weight: 400;
  letter-spacing: 0.02em;
}

.subtitle {
  margin: 0 0 24px;
  color: var(--text-dim);
  font-size: 14px;
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

.feature-item {
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  padding: 14px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
}

.feature-title {
  font-weight: 700;
  font-size: 13px;
}

.feature-text {
  font-size: 11.5px;
  color: var(--text-dim);
  line-height: 1.4;
}

.setup-group { margin-bottom: 22px; }

.setup-group > label {
  display: block;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin-bottom: 10px;
}

.pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

#analysis-view-tabs {
  margin-bottom: 16px;
}

.pill {
  background: var(--surface-tint);
  color: var(--text);
  border: 1px solid var(--surface-border);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.pill:hover { background: var(--surface-tint-hover); }
.pill:active { transform: scale(0.96); }

.pill.selected {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.custom-length-row {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-dim);
}

.custom-length-row input {
  width: 90px;
  background: var(--surface-tint);
  border: 1px solid var(--surface-border);
  border-radius: 8px;
  color: var(--text);
  padding: 6px 10px;
  font-size: 14px;
}

.hint {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--text-dim);
}

.online-error {
  color: #ff9d8a;
}

.mode-tabs {
  margin-bottom: 22px;
}

/* ---------- Board style picker ---------- */

.board-swatch-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.board-swatch {
  width: 64px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.board-swatch-preview {
  width: 60px;
  height: 42px;
  border-radius: 6px;
  border: 2px solid transparent;
  background: var(--felt);
  position: relative;
  overflow: hidden;
}

.board-swatch.selected .board-swatch-preview {
  border-color: var(--accent);
}

.board-swatch-preview span {
  position: absolute;
  top: 0;
  width: 12px;
  height: 100%;
}

.board-swatch-preview span:nth-child(1) { left: 6px; background: var(--point-a); clip-path: polygon(0 0, 100% 0, 50% 100%); }
.board-swatch-preview span:nth-child(2) { left: 20px; background: var(--point-b); clip-path: polygon(0 0, 100% 0, 50% 100%); }
.board-swatch-preview span:nth-child(3) { right: 6px; left: auto; width: 10px; height: 10px; top: 6px; border-radius: 50%; background: var(--white-checker); }
.board-swatch-preview span:nth-child(4) { right: 6px; left: auto; width: 10px; height: 10px; bottom: 6px; top: auto; border-radius: 50%; background: var(--black-checker); }

.board-swatch-label {
  font-size: 11px;
  color: var(--text-dim);
  text-align: center;
  line-height: 1.2;
}

.board-swatch.selected .board-swatch-label { color: var(--text); }

.text-input {
  width: 100%;
  background: var(--surface-tint);
  border: 1px solid var(--surface-border);
  border-radius: 8px;
  color: var(--text);
  padding: 9px 12px;
  font-size: 14px;
  box-sizing: border-box;
}

.text-input::placeholder {
  color: var(--text-dim);
}

.text-input:focus {
  outline: none;
  border-color: var(--accent);
}

#online-room-code {
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.share-link-row {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.share-link-row .text-input {
  flex: 1;
  font-size: 13px;
}

#online-create-panel, #online-join-panel, #online-waiting-panel {
  margin-top: 4px;
}

.primary-btn {
  width: 100%;
  padding: 13px;
  border-radius: 10px;
  border: none;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: opacity 0.15s, transform 0.05s;
}

.primary-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.primary-btn:not(:disabled):hover { opacity: 0.92; }
.primary-btn:not(:disabled):active { transform: scale(0.99); }

/* ---------- Game screen ---------- */

#game-screen {
  width: 980px;
  max-width: 98vw;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  padding: 10px 22px;
}

.topbar-left,
.topbar-right {
  display: flex;
  align-items: center;
  gap: 10px;
}

.topbar-left { gap: 16px; }

.topbar-divider {
  width: 1px;
  align-self: stretch;
  margin: 2px 0;
  background: var(--panel-border);
  flex-shrink: 0;
}

.settings-wrap {
  position: relative;
}

.reaction-wrap {
  position: relative;
}

.reaction-panel {
  width: auto;
  padding: 8px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}

.reaction-choice {
  background: none;
  border: none;
  border-radius: 8px;
  font-size: 22px;
  line-height: 1;
  padding: 7px;
  cursor: pointer;
  transition: background 0.12s, transform 0.12s;
}

.reaction-choice:hover { background: var(--surface-tint-hover); transform: scale(1.12); }
.reaction-choice:active { background: var(--surface-tint-hover); transform: scale(1.05); }

/* A reacted emoji floats up over the sender's avatar and fades — see
   showReactionBubble in js/ui.js. Positioned via inline left/top set at
   creation time, so only the animation itself lives here. */
.reaction-bubble {
  position: fixed;
  transform: translate(-50%, -100%);
  font-size: 34px;
  line-height: 1;
  z-index: 70;
  pointer-events: none;
  animation: reaction-pop 1.8s ease-out forwards;
}

@keyframes reaction-pop {
  0% { opacity: 0; transform: translate(-50%, -70%) scale(0.4); }
  18% { opacity: 1; transform: translate(-50%, -130%) scale(1.2); }
  32% { transform: translate(-50%, -118%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -190%) scale(1); }
}

.icon-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--surface-border);
  background: var(--surface-tint);
  color: var(--text);
  font-size: 16px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-btn:hover { background: var(--surface-tint-hover); }
.icon-btn:active { background: var(--surface-tint-hover); transform: scale(0.94); }

.settings-panel {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  width: 220px;
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  padding: 16px;
  box-shadow: 0 16px 40px rgba(0,0,0,0.5);
  z-index: 30;
}

.settings-panel .setup-group { margin-bottom: 16px; }

.settings-divider {
  height: 1px;
  background: var(--panel-border);
  margin: 14px 0;
}

.settings-action {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  border-radius: 8px;
  padding: 9px 10px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background 0.12s;
}

.settings-action:hover { background: var(--surface-tint-hover); }
.settings-action:active { background: var(--surface-tint-hover); }

.settings-action.danger { color: #e0685c; }
.settings-action.danger .settings-action-icon { color: #e0685c; }
.settings-action.danger:hover { background: rgba(224,72,58,0.12); }
.settings-action.danger:active { background: rgba(224,72,58,0.12); }

.settings-action-icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  color: var(--text-dim);
}

.settings-action-icon svg { width: 16px; height: 16px; }

.setup-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.setup-toggle-label {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.setup-toggle-label label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.switch {
  width: 42px;
  height: 24px;
  border-radius: 999px;
  border: 1px solid var(--surface-border);
  background: var(--surface-tint);
  position: relative;
  cursor: pointer;
  padding: 0;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}

.switch:active { opacity: 0.85; }

.switch[aria-checked="true"] {
  background: var(--av-gold, #c9a04a);
  border-color: var(--av-gold, #c9a04a);
}

.switch-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0,0,0,0.35);
  transition: transform 0.15s;
}

.switch[aria-checked="true"] .switch-thumb { transform: translateX(18px); }

.topbar-logo {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  flex-shrink: 0;
}

.score-box {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 80px;
}

.score-box-right { flex-direction: row-reverse; }

.score-text {
  display: flex;
  flex-direction: column;
}

.score-box-right .score-text { align-items: flex-end; }

.topbar-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  box-shadow: 0 2px 8px rgba(0,0,0,0.4);
  flex-shrink: 0;
}

.topbar-avatar:empty { display: none; }

.topbar-avatar svg { width: 32px; height: 32px; }

.score-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
}

.score-value {
  font-size: 26px;
  font-weight: 700;
  line-height: 1.1;
}

.match-info {
  text-align: center;
  font-size: 13px;
  color: var(--text-dim);
}

.badge {
  display: inline-block;
  margin-top: 4px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
}

/* ---------- Board ---------- */

.board-wrap {
  /* Flat, not a gradient: the point numbers live in this margin (see
     .point-number below), and a gradient meant different numbers sat on
     visibly different shades of wood — border and fill are the same solid
     color so the whole margin reads as one consistent background. */
  background: var(--wood-dark);
  border: 10px solid var(--wood-dark);
  border-radius: 10px;
  padding: 14px;
  box-shadow: 0 20px 50px rgba(0,0,0,0.55);
}

/* ---------- Board skins ----------
   "Monte Carlo" (the default, defined in :root) is unstyled here. Each
   other skin overrides the same board-only variable set via a
   data-board-theme attribute — applied to .board-wrap for the real board
   (reaching the frame plus everything inside #board through cascade), and
   reused on the small picker swatches below so each preview can show its
   own theme independent of whichever one is currently active. */

[data-board-theme="onyx"] {
  --wood-dark: #2a1d14;
  --wood-light: #4a3524;
  --felt: #141414;
  --felt-edge: #0a0a0a;
  --point-a: #d9822e;
  --point-a-edge: #b8691f;
  --point-b: #3f7d44;
  --point-b-edge: #2c5a30;
  --white-checker: #ecdfc0;
  --white-checker-ring: #d0c19a;
  --white-checker-edge: #b8a888;
  --black-checker: #7a2530;
  --black-checker-ring: #5c1c24;
  --black-checker-edge: #3d1218;
  --gold: #c9a04a;
  --highlight-color: #4fd8e8;
}

[data-board-theme="dusk"] {
  --wood-dark: #3d2e22;
  --wood-light: #5c4433;
  --felt: #2f6fb8;
  --felt-edge: #1f5590;
  --point-a: #e8b8c8;
  --point-a-edge: #d494a8;
  --point-b: #7fb8ae;
  --point-b-edge: #5f9c92;
  --white-checker: #dcece6;
  --white-checker-ring: #bcd8cf;
  --white-checker-edge: #9cc0b5;
  --black-checker: #4a4a4a;
  --black-checker-ring: #363636;
  --black-checker-edge: #202020;
  --gold: #a8c4d8;
  --highlight-color: #8aff6b;
}

[data-board-theme="emerald"] {
  --wood-dark: #2e2015;
  --wood-light: #4a3524;
  --felt: #3a9142;
  --felt-edge: #2a7032;
  --point-a: #f2f2ee;
  --point-a-edge: #d8d8d0;
  --point-b: #1e1e1e;
  --point-b-edge: #0a0a0a;
  --white-checker: #f0f0ec;
  --white-checker-ring: #d4d4cc;
  --white-checker-edge: #b8b8ac;
  --black-checker: #202020;
  --black-checker-ring: #383838;
  --black-checker-edge: #050505;
  --gold: #c9a04a;
}

[data-board-theme="rose"] {
  --wood-dark: #2e2015;
  --wood-light: #4a3020;
  --felt: #1f2a52;
  --felt-edge: #141c3a;
  --point-a: #d0577a;
  --point-a-edge: #b23f60;
  --point-b: #6b4a8a;
  --point-b-edge: #52396c;
  --white-checker: #e8b3c0;
  --white-checker-ring: #d494a4;
  --white-checker-edge: #b8768a;
  --black-checker: #6b5040;
  --black-checker-ring: #4f3a2e;
  --black-checker-edge: #33241a;
  --gold: #b8879e;
  --highlight-color: #ffe9a8;
}

[data-board-theme="sahara"] {
  --wood-dark: #2e2015;
  --wood-light: #4a3524;
  --felt: #e0c896;
  --felt-edge: #c9ad78;
  --point-a: #1e1e1e;
  --point-a-edge: #0a0a0a;
  --point-b: #d9822e;
  --point-b-edge: #b8691f;
  --white-checker: #f2ede0;
  --white-checker-ring: #d8d0bc;
  --white-checker-edge: #b8ac94;
  --black-checker: #202020;
  --black-checker-ring: #383838;
  --black-checker-edge: #050505;
  --gold: #c9a04a;
  --highlight-color: #4fa8f5;
}

[data-board-theme="bodrum"] {
  --wood-dark: #1e474c;
  --wood-light: #3f7d84;
  --felt: #e2cca3;
  --felt-edge: #c8ac7c;
  --point-a: #2a6b70;
  --point-a-edge: #1b4c50;
  --point-b: #f0ece0;
  --point-b-edge: #d6d0bc;
  --white-checker: #f2efe4;
  --white-checker-ring: #d8d3c4;
  --white-checker-edge: #b8b2a0;
  --black-checker: #326e73;
  --black-checker-ring: #245256;
  --black-checker-edge: #15393c;
  --gold: #9fb8ba;
  --highlight-color: #ff8a5c;
}

[data-board-theme="cherry"] {
  --wood-dark: #8f6a3e;
  --wood-light: #caa06e;
  --felt: #5c2a1f;
  --felt-edge: #3d1a12;
  --point-a: #f0e6d2;
  --point-a-edge: #d6c9a8;
  --point-b: #b8c9a0;
  --point-b-edge: #9aad84;
  --white-checker: #f2ecd8;
  --white-checker-ring: #d8cfb8;
  --white-checker-edge: #b8ac90;
  --black-checker: #a8794a;
  --black-checker-ring: #8a6038;
  --black-checker-edge: #5c3f22;
  --gold: #c9a04a;
  --highlight-color: #5be8a0;
}

.board {
  background: radial-gradient(ellipse at 50% 50%, var(--felt), var(--felt-edge));
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  height: 540px;
  position: relative;
  overflow: visible;
}

.row {
  display: flex;
  flex: 1;
  position: relative;
}

.quadrant {
  display: flex;
  flex: 1;
  padding: 0 6px;
  position: relative;
}

.point {
  flex: 1;
  position: relative;
  min-width: 0;
}

.point-triangle {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.point.top .point-triangle {
  clip-path: polygon(4% 0%, 96% 0%, 50% 82%);
}

.point.bottom .point-triangle {
  clip-path: polygon(4% 100%, 96% 100%, 50% 18%);
}

.point.shade-a .point-triangle { background: var(--point-a); }
.point.shade-b .point-triangle { background: var(--point-b); }

.point.legal-target .point-triangle::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--highlight-color);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.7);
}

/* Points have no hover state worth the name (nothing meaningful happens on
   desktop hover), but touch devices have no hover at all — this is the
   only visual acknowledgment a tap on a point gets. */
.point:active .point-triangle { filter: brightness(1.2); }

.point-number {
  position: absolute;
  font-size: 12px;
  font-weight: 700;
  color: var(--point-number-color);
  left: 50%;
  transform: translateX(-50%);
  z-index: 6;
  pointer-events: none;
}

/* Sits on the wood rail (board-wrap's padding + border, ~24px total)
   rather than on the felt itself, so checkers can start right at the
   point's own edge like a real board instead of leaving room for a label. */
.point.top .point-number { top: -18px; }
.point.bottom .point-number { bottom: -18px; }

.checkers {
  position: absolute;
  left: 0;
  right: 0;
  display: flex;
  width: 100%;
  gap: 1px;
  align-items: center;
  z-index: 3;
}

.point.top .checkers {
  top: 4px;
  flex-direction: column;
  justify-content: flex-start;
}

.point.bottom .checkers {
  bottom: 4px;
  flex-direction: column-reverse;
  justify-content: flex-start;
}

.checker {
  width: 82%;
  max-width: 46px;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  margin: 0 auto;
  position: relative;
  flex-shrink: 0;
  box-shadow: 0 2px 4px rgba(0,0,0,0.5);
}

.checker.white {
  background:
    radial-gradient(circle at 50% 50%, var(--white-checker) 0 58%, var(--white-checker-ring) 60% 66%, var(--white-checker) 68% 100%);
  border: 1px solid var(--white-checker-edge);
}

.checker.black {
  background:
    radial-gradient(circle at 50% 50%, var(--black-checker) 0 58%, var(--black-checker-ring) 60% 66%, var(--black-checker) 68% 100%);
  border: 1px solid var(--black-checker-edge);
}

.checker.checker-flying {
  box-shadow: 0 14px 22px rgba(0,0,0,0.55);
}

.checker.active-checker {
  box-shadow: 0 0 0 3px #ffd76a, 0 2px 6px rgba(0,0,0,0.6);
  transform: scale(1.08);
  z-index: 4;
}

.checker-count {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: inherit;
}

.checker.white .checker-count { color: #3a3222; }
.checker.black .checker-count { color: #efe3cc; }

.bar-cell {
  width: 26px;
  flex-shrink: 0;
}

.off-cell {
  width: 36px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 3px;
  cursor: default;
  border-radius: 6px;
}

.off-cell.legal-target {
  outline: 3px dashed var(--highlight-color);
  outline-offset: -2px;
}

.off-cell.legal-target:active { background: rgba(255, 255, 255, 0.1); }

.pip-count {
  flex-shrink: 0;
  text-align: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  letter-spacing: 0.02em;
}

#board.hide-pip-count .pip-count {
  display: none;
}

.bar-center {
  position: absolute;
  /* The bar sits at the center of the 24-point playing field, not the
     center of the whole board — the off-tray column exists on only one
     end of the row with nothing mirroring it on the other, so the true
     center is offset from 50% by half the off-cell's width (36px here). */
  left: calc(50% - 18px);
  top: 0;
  bottom: 0;
  width: 30px;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  pointer-events: none;
  z-index: 5;
  background: linear-gradient(180deg, var(--wood-light), var(--wood-dark));
  box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
  border-left: 1px solid rgba(0,0,0,0.3);
  border-right: 1px solid rgba(0,0,0,0.3);
}

.bar-slot {
  width: 100%;
  min-height: 74px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  pointer-events: auto;
}

.bar-slot .checker { width: 82%; }

.bar-slot.legal-target {
  outline: 3px dashed var(--highlight-color);
  outline-offset: 1px;
}

.bar-slot:active { background: rgba(255, 255, 255, 0.08); border-radius: 4px; }

.cube-slot {
  position: absolute;
  left: 50%;
  width: 26px;
  height: 26px;
  background: linear-gradient(135deg, #302a22, #17140f);
  border: 1px solid var(--gold);
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  color: var(--cream);
  font-size: 11px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.5);
  z-index: 7;
  transition: top 0.25s ease;
}

/* Owned outright by one side or the other, the cube sits well into that
   player's half — not just nudged past center — leaving centered/unowned
   as the one case it shares the bar's middle with the hit-checker slots. */
.cube-slot.pos-center { top: 50%; transform: translate(-50%, -50%); }
.cube-slot.pos-top { top: 10%; transform: translate(-50%, -50%); }
.cube-slot.pos-bottom { top: 90%; transform: translate(-50%, -50%); }

.cube-slot.owned-white { box-shadow: 0 0 0 2px var(--white-checker); }
.cube-slot.owned-black { box-shadow: 0 0 0 2px #6a6155; }

.off-tray {
  width: 100%;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-start;
  align-items: stretch;
  gap: 2px;
  padding: 6px 4px;
  cursor: default;
  background: rgba(0,0,0,0.15);
  border-radius: 6px;
  border: 1px solid rgba(0,0,0,0.2);
  overflow: hidden;
}

.off-tray.legal-target {
  outline: 3px dashed var(--highlight-color);
  outline-offset: -2px;
}

/* A borne-off checker renders as a flat "coin" — the checker seen from
   above, resting on its edge — rather than the full circular token used
   everywhere else on the board. Compact enough to stack all 15. */
.checker-coin {
  width: 100%;
  height: 9px;
  border-radius: 3px;
  flex-shrink: 0;
}

.checker-coin.white {
  background: linear-gradient(180deg, var(--white-checker), var(--white-checker-ring));
  border: 1px solid var(--white-checker-edge);
}

.checker-coin.black {
  background: linear-gradient(180deg, var(--black-checker-ring), var(--black-checker));
  border: 1px solid var(--black-checker-edge);
}

.off-white { align-items: flex-end; }
.off-black { align-items: flex-start; }

/* ---------- Dice on board ---------- */

.dice-tray {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  gap: 8px;
  padding: 10px;
  min-height: 20px;
  z-index: 6;
  pointer-events: none;
}

.dice-tray:empty {
  padding: 0;
  min-height: 0;
}

.dice-tray.suppressed {
  display: none;
}

/* Centered on the true midpoint of each side's playing quadrants (measured
   against the board's own geometry, not just an edge offset — an edge
   offset drifts off-center as tray content/width changes). */
.dice-tray-left { left: 23%; transform: translate(-50%, -50%); }
.dice-tray-right { left: 72.3%; transform: translate(-50%, -50%); }

/* When Confirm needs the dead-center spot but the player never got a
   legal move to make with this roll, the dice shrink and shift aside
   (same safe vertical band, just off to the side) instead of vanishing —
   they should always be able to see what they rolled. */
.dice-tray-right.compact {
  left: 60%;
  padding: 5px;
  gap: 4px;
}
.dice-tray-right.compact .die {
  width: 22px;
  height: 22px;
  padding: 2px;
}

.board-btn {
  position: absolute;
  top: 50%;
  z-index: 6;
  padding: 15px 26px;
  border-radius: 12px;
  border: none;
  background: var(--accent-2);
  color: #fff;
  font-size: 17px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.board-btn:hover { opacity: 0.92; }
.board-btn:active { opacity: 0.8; }

/* Roll, Double, Undo, and Confirm are all on the board together at various
   points in a turn — one consistent color reads as "the game's action
   button" rather than implying some are more/less important than others. */

.board-btn-left { left: 23%; transform: translate(-50%, -50%); }
.board-btn-right { left: 72.3%; transform: translate(-50%, -50%); }

.die {
  width: 34px;
  height: 34px;
  background: var(--cream);
  border-radius: 7px;
  display: grid;
  place-items: stretch;
  box-shadow: 0 3px 6px rgba(0,0,0,0.5);
  /* Fixed px, not a %: percentage padding on a flex item resolves against
     the *containing flex tray's* width, not the die's own — so with a %
     here, a die's pips would visibly shrink every time the tray holds more
     dice (2 dice, or 4 on a double) than the single opening-roll die did. */
  padding: 3px;
}

.die.used { opacity: 0.35; }

.die-pip-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

.die-pip-cell {
  display: flex;
  align-items: center;
  justify-content: center;
}

.die-pip {
  width: 68%;
  height: 68%;
  border-radius: 50%;
  background: #14100c;
}

/* ---------- Controls ---------- */

.control-panel {
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 12px;
  padding: 14px 22px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.message-area {
  font-size: 14px;
  color: var(--text-dim);
  min-height: 20px;
}

.action-btn {
  padding: 10px 20px;
  border-radius: 8px;
  border: none;
  background: var(--accent-2);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.action-btn.secondary {
  background: var(--surface-tint);
  border: 1px solid var(--surface-border);
  color: var(--text);
}

.action-btn:hover { opacity: 0.92; }
.action-btn:active { opacity: 0.8; }

/* ---------- Modal ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
}

.modal {
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 14px;
  padding: 28px 30px;
  width: 360px;
  max-width: 90vw;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}

.modal p {
  margin: 0 0 18px;
  font-size: 15px;
  line-height: 1.5;
  white-space: pre-line;
}

.modal-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
}

/* ---------- Account / sign-in ---------- */

.account-corner {
  position: absolute;
  top: 2px;
  right: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 8px;
}

.account-corner-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid var(--surface-border);
  background: var(--surface-tint);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.account-corner-btn:hover { background: var(--surface-tint-hover); }
.account-corner-btn:active { background: var(--surface-tint-hover); }

.account-corner-btn-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  color: var(--av-gold, #c9a04a);
}

.account-corner-btn-icon svg { width: 15px; height: 15px; }

.account-email {
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 8px;
  word-break: break-all;
}

#account-signed-in-row .settings-action { margin-top: 8px; }
#account-signed-in-row .settings-action:first-of-type { margin-top: 0; }

.auth-modal { text-align: left; }

.auth-modal-close {
  position: absolute;
  top: 14px;
  right: 14px;
}

.auth-step h3 {
  margin: 0 0 6px;
  font-size: 17px;
}

.auth-step .hint {
  margin: 0 0 16px;
  font-size: 13px;
}

.auth-step .text-input { width: 100%; margin-bottom: 12px; }

.auth-submit-btn { width: 100%; margin-bottom: 10px; }

.auth-error { color: #e0483a; }

.account-corner-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: inline-grid;
  place-items: center;
  vertical-align: middle;
  margin-right: 7px;
  flex-shrink: 0;
}

.account-corner-avatar svg { width: 13px; height: 13px; }

/* ---------- Profile editing ---------- */

.profile-modal {
  width: 480px;
  max-height: 88vh;
  overflow-y: auto;
}

.profile-field { margin-bottom: 16px; }

.profile-field label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 6px;
}

.profile-field .text-input { width: 100%; }

.location-autocomplete { position: relative; }

.location-suggestions {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--surface-tint);
  border: 1px solid var(--surface-border);
  border-radius: 8px;
  max-height: 200px;
  overflow-y: auto;
  z-index: 10;
  box-shadow: 0 10px 26px rgba(0,0,0,0.45);
}

.location-suggestion-item {
  padding: 8px 12px;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.location-suggestion-item:hover,
.location-suggestion-item.active { background: var(--surface-tint-hover); }

.location-suggestion-flag { font-size: 16px; }

.profile-avatar-picker {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 260px;
  overflow-y: auto;
  padding-right: 4px;
  margin-bottom: 4px;
}

.profile-avatar-family-label {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
  margin-bottom: 6px;
}

.profile-avatar-family-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.profile-avatar-btn {
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 2px solid transparent;
  padding: 0;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: transform 0.12s ease, border-color 0.12s ease;
}

.profile-avatar-btn:hover { transform: scale(1.07); }
.profile-avatar-btn.selected { border-color: var(--gold); }
.profile-avatar-btn svg { width: 28px; height: 28px; }

/* ---------- Match history ---------- */

.history-item {
  border-radius: 10px;
  padding: 12px 14px;
  background: var(--surface-tint);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.history-item-main { display: flex; flex-direction: column; gap: 2px; }

.history-item-title { font-size: 14px; font-weight: 600; }

.history-item-meta { font-size: 12px; color: var(--text-dim); }

.history-item-right { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }

.history-item-result {
  font-size: 12px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 20px;
  white-space: nowrap;
}

.history-item-result.won { background: rgba(79,184,106,0.18); color: #4fb86a; }
.history-item-result.lost { background: rgba(224,72,58,0.18); color: #e0483a; }

/* ---------- Leaderboard ---------- */

.leaderboard-item {
  border-radius: 10px;
  padding: 10px 14px;
  background: var(--surface-tint);
  display: flex;
  align-items: center;
  gap: 12px;
}

.leaderboard-item.rank-1 { border: 1px solid rgba(201,160,74,0.5); }

.leaderboard-rank {
  width: 22px;
  flex-shrink: 0;
  text-align: center;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-dim);
}

.leaderboard-item.rank-1 .leaderboard-rank { color: var(--av-gold, #c9a04a); }

.leaderboard-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  box-shadow: 0 2px 6px rgba(0,0,0,0.3);
}

.leaderboard-avatar svg { width: 22px; height: 22px; }

.leaderboard-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.leaderboard-name {
  font-size: 14px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.leaderboard-meta { font-size: 12px; color: var(--text-dim); }

.leaderboard-pr {
  flex-shrink: 0;
  text-align: right;
}

.leaderboard-pr-value { font-size: 17px; font-weight: 700; }

.leaderboard-pr-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-dim);
}

/* ---------- Match analysis ---------- */

.analysis-card {
  background: var(--panel-bg);
  border: 1px solid var(--panel-border);
  border-radius: 16px;
  padding: 28px 32px;
  width: 720px;
  max-width: 94vw;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
}

.analysis-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.analysis-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.header-action-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface-tint);
  border: 1px solid var(--surface-border);
  border-radius: 999px;
  padding: 7px 14px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s;
}

.header-action-btn:hover { background: var(--surface-tint-hover); }
.header-action-btn .settings-action-icon { color: var(--av-gold, #c9a04a); }

.patterns-insight {
  background: var(--surface-tint);
  border: 1px solid var(--surface-border);
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
  margin-bottom: 16px;
}

.patterns-insight strong { color: var(--accent, #c9a04a); }

.analysis-header h2 {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
}

.analysis-summary {
  display: flex;
  gap: 12px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

.analysis-stat {
  flex: 1;
  min-width: 110px;
  background: var(--surface-tint);
  border-radius: 10px;
  padding: 10px 14px;
}

.analysis-stat .stat-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin-bottom: 4px;
}

.analysis-stat .stat-value {
  font-size: 20px;
  font-weight: 700;
}

.analysis-list {
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-right: 4px;
}

.analysis-empty {
  color: var(--text-dim);
  font-size: 14px;
  text-align: center;
  padding: 30px 0;
}

.analysis-item {
  border-radius: 10px;
  padding: 10px 14px;
  background: var(--surface-tint);
  border-left: 4px solid var(--surface-border);
}

.analysis-item.severity-blunder { border-left-color: #e0483a; }
.analysis-item.severity-error { border-left-color: #e0a83a; }
.analysis-item.severity-doubtful { border-left-color: #e0d23a; }
.analysis-item.severity-good { border-left-color: #4fb86a; }

.analysis-item-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
  font-weight: 600;
}

.analysis-item-title-group {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}

.analysis-rank-badge {
  flex-shrink: 0;
  background: var(--accent);
  color: var(--on-accent);
  border-radius: 999px;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 700;
}

.analysis-item-error {
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.analysis-item-detail-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}

.analysis-item-detail {
  font-size: 12px;
  color: var(--text-dim);
}

.analysis-view-board-btn {
  flex-shrink: 0;
  background: none;
  border: 1px solid var(--surface-border);
  border-radius: 6px;
  padding: 2px 8px;
  font-size: 11px;
  color: var(--text-dim);
  cursor: pointer;
}

.analysis-view-board-btn:hover { background: var(--surface-tint-hover); }

.mini-board {
  margin-top: 10px;
  background: #1b2a1f;
  border-radius: 8px;
  padding: 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: relative;
}

.mini-board-row {
  display: flex;
  gap: 2px;
}

.mini-point {
  flex: 1;
  min-height: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}

.mini-board-row.top .mini-point { justify-content: flex-start; }
.mini-board-row.bottom .mini-point { justify-content: flex-end; }

.mini-checker {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  flex-shrink: 0;
}

.mini-checker.white { background: #f0ece0; border: 1px solid #b8b2a0; }
.mini-checker.black { background: #333; border: 1px solid #111; }

.mini-point-count {
  font-size: 9px;
  color: #cfd6cf;
}

.mini-board-extra {
  font-size: 10px;
  color: #cfd6cf;
  text-align: center;
}

.mini-board-labels {
  display: flex;
  gap: 2px;
}

.mini-point-label {
  flex: 1;
  text-align: center;
  font-size: 9.5px;
  font-weight: 600;
  color: #8a9c8e;
}

.mini-label-gap {
  flex: 0 0 22px;
}

.mini-bar-anchor,
.mini-off-anchor {
  flex: 0 0 22px;
  min-height: 72px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mini-bar-anchor::after,
.mini-off-anchor::after {
  content: '';
  width: 1px;
  height: 100%;
  background: rgba(255,255,255,0.12);
}

.mini-board-arrows {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* ---------- Mobile: portrait ---------- */

@media (max-width: 720px) {
  /* Tighten the overall setup-screen rhythm — the desktop spacing (20px
     screen gap, 36/40px card padding, 22px between setup groups) was built
     for a wide card and reads as loose/scrolly stacked single-column on a
     phone. */
  #setup-screen { gap: 14px; }

  /* Desktop pins this top-right and absolutely positioned, floating over
     the empty space to the right of a short "Riviera" title — on a phone
     the title's own width leaves no such gap, so the buttons sat directly
     on top of the logotype (or, stacked as its own row above it, ended up
     on a different margin than the logo entirely). Instead, put the logo
     and the account controls in the same flex row so they share one
     baseline, with everything else (subtitle, feature grid) wrapping to
     its own full-width line below. */
  .landing-hero {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 10px;
  }
  .brand-lockup { order: 1; margin: 0; }
  .subtitle { order: 3; flex-basis: 100%; margin-bottom: 12px; }
  .feature-grid { order: 4; flex-basis: 100%; }

  .account-corner {
    /* relative, not static: this still needs to be a positioning context
       for its own dropdown panel (.settings-panel, absolute + `top: 100%`)
       — with static it fell back to the next positioned ancestor up the
       tree (.landing-hero) and the panel opened far below the fold. */
    position: relative;
    order: 2;
    width: auto;
    margin: 0;
    gap: 8px;
  }

  /* Text labels ("Leaderboard", "Sign In"/name) are dropped at this width
     — two small round icon buttons read as a compact utility menu next to
     the logo, rather than two full pill buttons competing with it for
     space. The icon alone plus a tooltip-free aria-label keeps them
     identifiable; tapping still opens the exact same leaderboard screen /
     sign-in modal or account panel as the desktop pills do. */
  .account-corner-btn {
    width: 34px;
    height: 34px;
    padding: 0;
    border-radius: 50%;
    justify-content: center;
    gap: 0;
  }
  .account-corner-btn-label { display: none; }
  .account-corner-btn-icon, .account-corner-btn-icon svg { width: 16px; height: 16px; }
  .account-corner-avatar { width: 22px; height: 22px; margin-right: 0; }
  .account-corner-avatar svg { width: 15px; height: 15px; }

  .brand-icon { width: 32px; height: 32px; }
  .landing-hero h1 { font-size: 26px; }

  .setup-card { padding: 22px 18px; }
  .setup-card-heading { margin-bottom: 14px; }
  .setup-group { margin-bottom: 15px; }

  /* Desktop's single row of 4 doesn't fit a phone — back to 2x2, more
     compact than stacking to one column, just tightened up so the text
     still fits comfortably. */
  .feature-grid { grid-template-columns: 1fr 1fr; gap: 8px; }
  .feature-item { padding: 10px 10px; }
  .feature-title { font-size: 12px; }
  .feature-text { font-size: 10.5px; }

  /* The two-column setup layout needs real width per column (pill rows,
     inputs) — on a phone-width card that's too little, so stack instead. */
  .setup-columns { grid-template-columns: 1fr; gap: 0; }

  /* Minimal outer margin so the board runs nearly edge-to-edge instead of
     carrying the same padding as the desktop layout. Top-aligned, not
     centered — vertical centering left a large dead gap above the content
     (worse on real devices, where 100svh already undershoots the visible
     area whenever the browser's own address bar is showing).
     Safe-area-aware top padding: viewport-fit=cover (see index.html) lets
     the page paint under the status bar/notch instead of Safari showing
     its own white fill there, so content needs its own inset to avoid
     rendering underneath it. */
  body { padding: max(8px, env(safe-area-inset-top)) 4px 8px; align-items: flex-start; }
  #game-screen { width: 100%; }
  .board-wrap { border-width: 6px; padding: 10px; }
  /* Width-driven instead of height-driven: a real board is wider than it
     is tall, and letting height grow independently of width (the old
     `height: min(70svh, 760px)` here) produced a tall, narrow board that
     didn't read as a backgammon board at all. Filling the available width
     and deriving height from a fixed ratio keeps it board-shaped; the
     ratio is deliberately squatter than the desktop board's ~1.73:1
     (which would leave the board too short on a narrow phone) but still
     far closer to a real board than an unconstrained stretch. max-height
     is just a safety cap for unusually wide/short viewports (e.g. tablet
     portrait) — it shouldn't engage on a typical phone. */
  .board { width: 100%; aspect-ratio: 4 / 5; height: auto; max-height: min(70svh, 760px); }
  .point-number { font-size: 10px; }
  .point.top .point-number { top: -13px; }
  .point.bottom .point-number { bottom: -13px; }
  .topbar { padding: 8px 12px; }
  .topbar-left { gap: 6px; }
  .topbar-logo { width: 22px; height: 22px; border-radius: 5px; }
  .score-box { gap: 6px; min-width: 0; }
  .topbar-avatar { width: 30px; height: 30px; }
  .topbar-avatar svg { width: 20px; height: 20px; }
  .score-label { font-size: 10px; }
  .score-value { font-size: 20px; }
  .match-info { flex-shrink: 0; }
  .checker { max-width: 30px; }
  .dice-tray { padding: 6px; gap: 4px; flex-wrap: wrap; max-width: 60px; }
  .dice-tray .die { width: 22px; height: 22px; padding: 2px; border-radius: 5px; }
  .board-btn { padding: 16px 22px; font-size: 16px; border-radius: 12px; }

  /* Fills the row's full height just like desktop — it used to be
     content-sized (grow only as checkers arrived), which read as broken/
     shrunken most of the game. Still needs a visible background here or
     it disappears into the felt entirely. */
  .off-cell { width: 24px; padding: 2px; gap: 2px; }
  .off-tray {
    flex: 1;
    min-height: 0;
    background: rgba(0,0,0,0.15);
    border: 1px solid rgba(0,0,0,0.2);
    border-radius: 5px;
    padding: 3px 2px;
  }
  .checker-coin { height: 5px; border-radius: 2px; }
  .pip-count { font-size: 9px; }
  /* off-cell is 24px here, so the bar's true center shifts by half that
     instead of the desktop 36px off-cell's 18px. */
  /* off-cell is 24px here, so the bar's true center shifts by half that
     instead of the desktop 36px off-cell's 18px. Gap between the two bar
     slots is widened well past its old 5px — the cube sits centered in
     that gap (see .cube-slot.pos-center below), and on a short portrait
     board there's ample spare height (well over 100px) to give it real
     clearance instead of barely-there breathing room. */
  .bar-center { left: calc(50% - 12px); width: clamp(16px, 6.5vw, 24px); gap: clamp(18px, 8vw, 28px); }
  /* Never scaled down for portrait's much shorter board (only landscape
     had this) — a full desktop-sized 74px bar-slot pair plus a 26px cube
     barely fit a short board, so multiple bar checkers visually collided
     with the cube. Sized off vw instead of svh, since portrait's board
     height is itself width-driven (see .board's aspect-ratio above).
     A fixed `height` (not `min-height`) matters here too: the cube sits at
     a flat 50% of the whole bar, assuming bar-black and bar-white are the
     same size — with `min-height`, whichever side had more checkers on it
     grew taller than the other and ate into the cube's space. Fixed height
     keeps both slots equal regardless of how many checkers are on either,
     sized to comfortably hold 3 stacked checkers without growing. */
  .bar-slot { height: clamp(20px, 16vw, 52px); min-height: 0; }
  .cube-slot {
    width: clamp(14px, 6.5vw, 22px);
    height: clamp(14px, 6.5vw, 22px);
    font-size: clamp(7px, 3vw, 10px);
    border-radius: 4px;
  }
}

/* ---------- Mobile: landscape (the intended way to play on a phone) ---------- */

@media (max-height: 600px) and (orientation: landscape) {
  html, body { height: 100%; }

  body {
    /* Sized for the smallest possible viewport (browser chrome fully
       shown) so the layout never has to visibly shrink when a toolbar
       appears — it's already sized for that case. Using dvh here would
       make the whole board resize in real time as Safari's URL/tab bar
       toggles, which reads as the page suddenly shrinking. */
    height: 100svh;
    min-height: 0;
    max-height: 100svh;
    padding: max(3px, env(safe-area-inset-top)) max(8px, env(safe-area-inset-right)) max(3px, env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
    align-items: center;
    overflow: auto;
    box-sizing: border-box;
  }

  #game-screen {
    width: 100%;
    height: 100%;
    max-height: 100%;
    min-height: 0;
    gap: clamp(3px, 1.2svh, 8px);
  }

  .topbar {
    padding: clamp(2px, 0.8svh, 6px) 12px;
    flex-shrink: 0;
  }

  .topbar-left { gap: clamp(4px, 1svh, 8px); }
  .topbar-logo { width: clamp(16px, 3.4svh, 24px); height: clamp(16px, 3.4svh, 24px); border-radius: 4px; }
  .score-box { min-width: 50px; gap: clamp(4px, 1svh, 8px); }
  .topbar-avatar { width: clamp(26px, 5.2svh, 38px); height: clamp(26px, 5.2svh, 38px); }
  .topbar-avatar svg { width: clamp(18px, 3.6svh, 26px); height: clamp(18px, 3.6svh, 26px); }
  .score-label { font-size: clamp(7px, 1.8svh, 9px); }
  .score-value { font-size: clamp(11px, 3.4svh, 16px); }
  .match-info { font-size: clamp(7px, 1.9svh, 10px); }
  .badge { font-size: clamp(7px, 1.7svh, 9px); padding: 2px 6px; margin-top: 2px; }

  .board-wrap {
    flex: 1;
    min-height: 0;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(3px, 1svh, 6px);
    border-width: 5px;
    overflow: hidden;
  }

  /* Lock the board to the same proportions as the desktop board (932x540)
     so it scales as one unit — width and height never scale independently,
     which keeps checkers sized correctly relative to the points at any
     screen size instead of shrinking checkers to fit a short viewport. */
  .board {
    flex: none;
    aspect-ratio: 932 / 540;
    height: 100%;
    width: auto;
    max-width: 100%;
    max-height: 100%;
    min-height: 0;
  }

  .row, .quadrant, .point { min-height: 0; }

  /* board-wrap has almost no padding/border here and clips overflow, so
     (unlike desktop/portrait) numbers stay on the felt in this breakpoint
     rather than moving to the wood rail. */
  .point-number { font-size: clamp(8px, 1.8svh, 10px); }
  .point.top .point-number { top: 2px; }
  .point.bottom .point-number { bottom: 2px; }
  .point.top .checkers { top: 13px; }
  .point.bottom .checkers { bottom: 13px; }

  /* Percentage-based, matching the desktop checker-to-point ratio, so
     checkers scale together with the (aspect-ratio-locked) board instead
     of being capped by viewport height independently of point width. */
  .checker { width: 66%; max-width: none; }
  .checker-coin { height: clamp(3px, 1svh, 6px); border-radius: 2px; }
  .off-cell { width: clamp(15px, 4.6svh, 22px); }
  .pip-count { font-size: clamp(6px, 1.5svh, 8px); }
  .bar-cell { width: clamp(12px, 3.6svh, 20px); }
  .bar-center {
    width: clamp(14px, 4svh, 22px);
    gap: 2px;
    left: calc(50% - clamp(15px, 4.6svh, 22px) / 2);
  }
  .bar-slot { min-height: clamp(18px, 7svh, 36px); }
  .cube-slot {
    width: clamp(13px, 4svh, 19px);
    height: clamp(13px, 4svh, 19px);
    font-size: clamp(7px, 1.9svh, 9px);
    border-radius: 4px;
  }

  .dice-tray {
    padding: 3px;
    gap: 3px;
    flex-wrap: wrap;
    max-width: clamp(32px, 10svh, 48px);
    border-radius: 6px;
  }
  .dice-tray .die {
    width: clamp(11px, 3.6svh, 17px);
    height: clamp(11px, 3.6svh, 17px);
    padding: clamp(1px, 0.4svh, 2px);
    border-radius: 4px;
  }
  .board-btn {
    padding: clamp(6px, 2svh, 12px) clamp(10px, 3svh, 18px);
    font-size: clamp(11px, 3svh, 14px);
    border-radius: 8px;
  }

  .control-panel {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: clamp(2px, 0.8svh, 6px) 14px;
    gap: 10px;
    flex-shrink: 0;
    /* Stays this tall even when no buttons happen to be showing (the brief
       instant between rolling and a move being available), so the board
       never resizes as buttons come and go through a turn. */
    min-height: clamp(24px, 7.4svh, 36px);
    box-sizing: border-box;
  }

  .message-area {
    flex: 1;
    min-height: 0;
    min-width: 0;
    font-size: clamp(9px, 2.4svh, 11px);
    /* Always a single line — this row's height must stay fixed no matter
       how long the message is or how many action buttons are currently
       showing, otherwise the control panel grows/shrinks and the board
       (flex:1 in the same column) visibly resizes on every turn. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .action-btn {
    padding: clamp(3px, 1svh, 6px) 12px;
    font-size: clamp(10px, 2.6svh, 12px);
    white-space: nowrap;
  }

  #setup-screen { gap: clamp(6px, 1.5svh, 12px); }
  /* Landscape phone height is tight — the feature grid is a nice-to-know,
     not essential, so it's the first thing to give up the space here. */
  .feature-grid { display: none; }
  /* On a narrow-width landscape phone (e.g. iPhone SE, 667×375) the
     max-width:720px portrait breakpoint's account-corner rules also match
     here (both queries can be true at once). Their in-flow `position:
     relative` stacking makes sense in portrait, where the title's own
     width leaves no room beside it — but landscape has width to spare
     relative to its cramped height, so every pixel this row's real height
     costs here is a pixel taken from the (already scroll-clipped) setup
     card below it. Go back to floating over the empty space beside the
     title instead, the same way desktop does, which costs zero layout
     height; the smaller padding/font from the portrait rule (not
     overridden here) still applies and helps it clear the title safely. */
  .account-corner { position: absolute; top: 2px; right: 0; width: auto; margin-bottom: 0; }
  .setup-card {
    padding: clamp(10px, 3svh, 14px) 24px;
    max-height: 94svh;
    overflow-y: auto;
  }
  .landing-hero h1 { font-size: clamp(16px, 5svh, 20px); margin-bottom: 2px; }
  .subtitle { font-size: clamp(10px, 2.6svh, 12px); margin-bottom: clamp(6px, 2svh, 12px); }
  .setup-group { margin-bottom: clamp(5px, 1.8svh, 10px); }
  .setup-group > label { font-size: clamp(8px, 2svh, 10px); margin-bottom: clamp(3px, 1svh, 6px); }
  .pill-row { gap: 6px; }
  .pill { padding: clamp(3px, 1svh, 5px) 12px; font-size: clamp(10px, 2.6svh, 12px); }
  .custom-length-row { margin-top: 6px; font-size: clamp(9px, 2.2svh, 11px); }
  .hint { font-size: clamp(8px, 2svh, 10px); margin-top: 6px; }
  .primary-btn { padding: clamp(6px, 1.8svh, 9px); font-size: clamp(11px, 2.8svh, 13px); }
}
