/* ── Theme token overrides ───────────────────────────────────────────────── */
/* In light mode the default dark navy card back stands out too much against
   the warm stone table. Use the sunken surface tone so backs are quiet. */
[data-theme="warm-stone"] {
  --card-face-back: var(--surface-sunken);
}

/* ── CSS custom properties ──────────────────────────────────────────────── */
:root {
  /* Semantic colors (not theme-dependent) */
  --color-neg:     #f87171;
  --color-warn:    #fbbf24;
  --color-info:    #60a5fa;
  --color-neutral: #a0aec0;

  /* Badge themes */
  --badge-gt-bg:   #92400e;
  --badge-t-bg:    #1e3a8a;
  --badge-t-color: #93c5fd;
}

/* ── Reset & base ──────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  font-family: var(--font-ui);
  background: var(--surface-table);
  color: var(--ink-strong);
  height: 100vh;
  height: 100dvh; /* excludes Safari bottom bar on mobile */
  overflow: hidden;
  user-select: none;
  /* Prevent rubber-band scroll; also blocks accidental zoom on double-tap */
  touch-action: manipulation;
}

.screen {
  width: 100vw;
  height: calc(100vh - 36px);
  height: calc(100dvh - 36px);
  margin-top: 36px;
}

/* ── Top menu bar ──────────────────────────────────────────────────────── */
#top-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 36px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 12px;
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--card-border-strong);
  z-index: 120;
}
#top-bar-brand { justify-self: start; display: flex; align-items: center; gap: 10px; }
#top-bar > #status-msg { justify-self: center; }
#top-bar-actions { justify-self: end; }
#top-bar-title {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 14px; font-weight: 600; letter-spacing: 2px;
  color: var(--accent-text-on-surface);
  cursor: pointer;
  transition: color var(--t-fast);
}
#top-bar-title:hover { color: var(--ink-strong); }
/* Logo (the phoenix+dragon favicon) sits inside the main-menu button. */
#top-bar-logo { width: 22px; height: 22px; display: block; flex-shrink: 0; }
#top-bar-score {
  font-size: 12px; color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
#top-bar-actions { display: flex; gap: 8px; align-items: center; }
#top-bar-actions button {
  padding: 4px 8px;
  font-size: 16px;
  background: var(--surface-raised);
  border: 1px solid var(--card-border);
  color: var(--ink-strong);
}
#top-bar-actions button:hover:not(:disabled) {
  background: var(--surface-sunken);
  color: var(--ink-strong);
}
#top-bar-actions button:disabled { opacity: 0.4; cursor: default; }
#btn-save-hands, #btn-toggle-log { font-size: 10px; }
/* Theme toggle (☀/☾) and settings (⚙) are single-glyph icon buttons. Their emoji
   have different intrinsic widths, so give both an equal fixed width and centre
   the glyph — otherwise they render slightly different sizes (mobile + desktop). */
#btn-theme-toggle, #btn-settings {
  width: 34px;
  padding-left: 0;
  padding-right: 0;
  text-align: center;
}
.hidden { display: none !important; }
.muted  { color: var(--ink-muted); font-size: 13px; }

/* ── Lobby ─────────────────────────────────────────────────────────────── */
#screen-lobby {
  display: flex; align-items: center; justify-content: center;
  background: radial-gradient(ellipse at center, var(--surface-raised) 0%, var(--surface-sunken) 100%);
}

.lobby-box {
  background: var(--surface-raised);
  border: 1px solid var(--card-border-strong);
  border-radius: 12px;
  padding: 40px;
  width: 320px;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-card-drag);
}

.lobby-box h1 { font-size: 36px; letter-spacing: 4px; text-align: center; color: var(--ink-strong); }

.lobby-box label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 13px; color: var(--ink-muted);
}

.lobby-box input {
  background: var(--surface-sunken); border: 1px solid var(--card-border-strong); border-radius: 6px;
  color: var(--ink-strong); padding: 8px 10px; font-size: 15px; outline: none;
}
.lobby-box input:focus { border-color: var(--focus-ring); }

/* ── Table layout ──────────────────────────────────────────────────────── */
#screen-table {
  display: grid;
  grid-template-rows: 1fr 44px 120px;
  grid-template-areas:
    "middle"
    "actions"
    "hand";
  gap: 0;
  position: relative;
}

/* top player floats above middle */
#zone-top {
  position: absolute;
  top: 36px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}

#status-msg {
  font-size: 13px;
  color: var(--ink-muted);
  padding: 0 12px;
  white-space: nowrap;
}

/* ── Middle ────────────────────────────────────────────────────────────── */
#middle {
  grid-area: middle;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 8px;
  position: relative;
}

.zone-side {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  width: 80px;
}

.pname {
  font-size: 12px; color: var(--ink-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 80px;
}

/* ── Badges (GT and T) ─────────────────────────────────────────────────── */
.badge {
  font-weight: bold; font-size: 11px; letter-spacing: 1px;
  padding: 2px 5px; border-radius: 4px; border: 1px solid;
  pointer-events: none; white-space: nowrap; flex-shrink: 0;
}
.badge-gt { background: var(--badge-gt-bg); color: var(--color-warn);    border-color: var(--color-warn); }
.badge-t  { background: var(--badge-t-bg);  color: var(--badge-t-color); border-color: var(--badge-t-color); }

/* Name + badge row inside each player zone */
.zone-namerow {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  max-width: 100%;
}

#trick-area {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px;
  min-height: 160px;
}

.played-cards {
  position: absolute;
  display: flex; flex-wrap: wrap; gap: 2px; justify-content: center; align-items: center;
  pointer-events: none;
  z-index: 10;
  --card-w: 3rem;
  --card-h: calc(3rem * 7 / 5);
}
/* The played cards are .card--xs, which pins its own --card-w/--card-h and would
   ignore the zone's sizing (matters when mobile shrinks the played cards). Make
   them follow the zone at every breakpoint. */
.played-cards .card { --card-w: inherit; --card-h: inherit; }

/* All four zones use translate(-50%,-50%) so their CSS (left,top) is the
   stable CENTER of the zone regardless of content size. flyCards measures
   getBoundingClientRect() on the (possibly empty) destination element, so
   without this the animation lands at the wrong spot when the element grows. */

/* Center at (50%, 160px) — top edge ~126px (1 row) / ~92px (2 rows) */
#played-top {
  top: 160px;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: calc(100% - 200px);
}

/* Center at (50%, 100%-260px) — bottom edge ~226px (1 row) / ~192px (2 rows) from bottom */
#played-bottom {
  top: calc(100% - 260px);
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: calc(100% - 200px);
}

/* Centers in middle row (1fr = 100% - 164px fixed rows); 300px from each edge.
   At 300px center + max 7-card row (348px wide), left edge = 300-174 = 126px,
   which clears zone-side right edge (80px zone + 8px padding = 88px). */
#played-left {
  top: calc(50% - 82px);
  left: 300px;
  transform: translate(-50%, -50%);
  max-width: 400px;
}

#played-right {
  top: calc(50% - 82px);
  left: calc(100% - 300px);
  transform: translate(-50%, -50%);
  max-width: 400px;
}

/* 2-row balanced layout for 8+ card combinations */
.played-cards--rows {
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: center;
}
.played-row { display: flex; gap: 2px; }

#wish-banner {
  font-size: 13px; color: var(--color-warn);
  background: var(--surface-raised); border: 1px solid var(--color-warn);
  padding: 4px 12px; border-radius: 12px;
}
#dragon-gift-banner {
  font-size: 13px; color: var(--color-neg);
  background: var(--surface-raised); border: 1px solid var(--color-neg);
  padding: 4px 12px; border-radius: 12px;
  margin-top: 4px;
}

/* ── Card backs (opponents) ────────────────────────────────────────────── */
.card-backs { display: flex; flex-wrap: wrap; gap: 2px; justify-content: center; }
.card-backs.vertical {
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
}
.card-backs.vertical .card-back { transform: rotate(90deg); }
.card-backs .card:hover         { transform: none; box-shadow: var(--shadow-card-rest); }
/* Face-up reveal on the side seats: rotate outward so the top points toward
   the screen edge (matches each side player's perspective). Hover keeps it. */
#backs-left  .card, #backs-left  .card:hover { transform: rotate(-90deg); transform-origin: 50% 50%; }
#backs-right .card, #backs-right .card:hover { transform: rotate( 90deg); transform-origin: 50% 50%; }

/* Face-up bot cards shown inside the card-backs containers
   (spectator / out-player / round-over reveal). Single row per zone, upright
   readable size, oriented so the face points toward the player who holds them. */
.card-backs .card {
  --card-w:           2.4rem;
  --card-h:           calc(2.4rem * 7 / 5);
  --card-letter-size: 0.85rem;
  --card-pad:         0.32rem;
  flex-shrink: 0;
  cursor: default;
  margin: 0 !important;
}
/* Side zones: rotated landscape cards in a column — collapse the portrait
   layout box to landscape height so cards tile tightly without extra gaps. */
.card-backs.vertical .card {
  margin: calc((var(--card-w) - var(--card-h)) / 2) 0 !important;
}
.card-backs.vertical {
  gap: 3px;
  flex-wrap: wrap;
  align-content: flex-start;
  overflow: visible;
  max-height: calc(100vh - 220px);
  max-height: calc(100dvh - 220px);
}
/* Top zone: single upright row, no wrapping (face-up reveal fits a full hand). */
#backs-top { flex-direction: row; flex-wrap: nowrap; gap: 3px; justify-content: center; }

.card-back {
  width: 20px; height: 30px;
  background: var(--card-face-back);
  border: 1px solid var(--card-border);
  border-radius: 3px;
}

/* ── My hand ───────────────────────────────────────────────────────────── */
#my-hand {
  grid-area: hand;
  justify-content: center;
  overflow-x: auto;
  min-height: 0;
  padding: 6px 8px;
  gap: 0;
  /* --card-h must be explicit: `:root` computes it once at 9.1rem and that
     inherited value doesn't update when --card-w is overridden here. */
  --card-w:           3.75rem;
  --card-h:           calc(3.75rem * 7 / 5);   /* 5.25rem ≈ 84px, true 5:7 ratio */
  --card-letter-size: 1.25rem;
  --card-pad:         0.44rem;
}

/* Cards always fully visible — no collapse on hover/blur */
#my-hand > .card {
  margin-right: var(--card-gap);
}
/* Drag-to-reorder: hint that hand cards are draggable, and fade the source
   while the browser's native drag preview follows the cursor. */
#my-hand > .card { cursor: grab; }
#my-hand > .card:active { cursor: grabbing; }
#my-hand > .card.is-dragging {
  opacity: 0.25;
  filter: grayscale(0.4);
}
/* Override the global is-disabled `pointer-events: none` so dimmed (illegal
   on this turn) cards can still be dragged to reorder. Hover/click logic in
   toggleCard already gracefully ignores selections that aren't legal. */
#my-hand > .card.is-disabled { pointer-events: auto; }
#my-hand > .card.is-disabled:hover { transform: none; box-shadow: var(--shadow-card-rest); }

/* Same fix for card--xs used in the trick/played area. */
.card--xs {
  --card-h: calc(3rem * 7 / 5);
}

/* ── Action bar ────────────────────────────────────────────────────────── */
#action-bar {
  grid-area: actions;
  display: flex; align-items: center; justify-content: center;
  gap: 80px;
  padding: 0 16px;
  background: var(--surface-raised);
  border-top: 1px solid var(--card-border-strong);
  border-bottom: 1px solid var(--card-border-strong);
}
#action-left  { display: flex; align-items: center; gap: 10px; }
#action-right { display: flex; align-items: center; gap: 10px; }
#btn-pass-turn {
  background: transparent; border-color: var(--card-border);
  color: var(--ink-muted);
}
#btn-pass-turn:hover:not(:disabled) { background: var(--surface-sunken); color: var(--ink-strong); }
#btn-pass-turn:disabled { opacity: 0.25; }
#tichu-confirm {
  display: flex; align-items: center; gap: 6px;
}
.tichu-confirm-label {
  font-size: 13px; color: var(--ink-strong); white-space: nowrap;
}
#btn-tichu-yes {
  background: var(--focus-ring); border-color: transparent; color: var(--accent-ink);
}
#btn-tichu-yes:hover { background: color-mix(in srgb, var(--focus-ring) 80%, black); }
#btn-tichu-no {
  background: transparent; border-color: var(--card-border); color: var(--ink-muted);
}
#btn-tichu-no:hover { background: var(--surface-sunken); color: var(--ink-strong); }
#ph-role-confirm {
  display: flex; align-items: center; gap: 6px;
}
.ph-role-label {
  font-size: 13px; color: var(--ink-strong); white-space: nowrap;
}
#ph-role-btns { display: flex; gap: 6px; }

/* ── Card integration with tichu-cards.css design system ──────────────── */

/* Suppress hover lift on non-interactive card contexts. */
.played-cards .card:hover,
.pt-slot .card:hover,
#gt-cards .card:hover {
  transform: none;
  box-shadow: var(--shadow-card-rest);
}

/* Pass-hand slots: show pointer cursor only on non-disabled cards. */
.pt-slot .card {
  cursor: default;
  /* The placed card is a .card--xs, which pins BOTH --card-w (3rem) and --card-h
     (calc(3rem*7/5)) on the card itself — decoupled from the slot. That matches
     on desktop (slot is also 3rem) but on mobile the slot shrinks to 2.5rem while
     the card stayed 3rem tall, so it overflowed the bottom of the slot. Inherit
     both dimensions from .pt-slot so the card always matches its slot at every
     breakpoint. */
  --card-w: inherit;
  --card-h: inherit;
}

/* Cards inside the pass selection hand keep normal interactive cursor. */
#pass-hand .card {
  cursor: pointer;
}

/* ── Buttons ───────────────────────────────────────────────────────────── */
button {
  background: var(--surface-raised);
  border: 1px solid var(--card-border-strong);
  color: var(--ink-strong);
  border-radius: 6px;
  padding: 7px 18px; font-size: 13px; cursor: pointer;
  font-family: var(--font-ui);
  transition: background var(--t-fast);
}
button:hover:not(:disabled) { background: var(--surface-sunken); }
button:disabled { opacity: 0.35; cursor: default; }
button.btn-primary {
  background: var(--focus-ring);
  border-color: transparent;
  color: var(--accent-ink);
}
button.btn-primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--focus-ring) 80%, black);
}
button.btn-load-hand {
  background: transparent;
  border-color: var(--card-border);
  color: var(--ink-muted);
  margin-top: 8px;
}
button.btn-load-hand:hover:not(:disabled) {
  background: var(--surface-sunken);
  color: var(--ink-strong);
}
button.btn-secondary {
  background: transparent;
  border-color: var(--card-border-strong);
  color: var(--ink-muted);
}
button.btn-secondary:hover:not(:disabled) { background: var(--surface-sunken); }
button.btn-back {
  background: transparent; border: none;
  color: var(--ink-faint); font-size: 13px; padding: 2px 0; cursor: pointer; align-self: flex-start;
}
button.btn-back:hover:not(:disabled) { color: var(--ink-strong); }
button.btn-danger  { background: #7f1d1d; border-color: var(--color-neg); color: #fecaca; }

/* ── Lobby sub-views ───────────────────────────────────────────────────── */
.lobby-view {
  display: flex; flex-direction: column; gap: 14px; width: 100%;
}
.lobby-view h2 { font-size: 18px; color: var(--ink-strong); letter-spacing: 1px; }
.radio-group { display: flex; flex-direction: column; gap: 8px; }
.radio-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; color: var(--ink-muted); cursor: pointer;
}
.radio-row input[type="radio"] { accent-color: var(--focus-ring); cursor: pointer; }
.bot-select-rows { display: flex; flex-direction: column; gap: 14px; margin-bottom: 4px; }
/* Seat label on its own line, options in a 3-col grid below — one column per
   difficulty option (normal / skilled / strong). */
.bot-select-row { display: flex; flex-direction: column; gap: 6px; }
.bot-select-label { font-size: 13px; color: var(--ink-strong); font-weight: 600; text-transform: capitalize; }
.bot-select-opts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px 14px; }
.bot-select-opts .radio-row { font-size: 13px; }
#waiting-code-row {
  display: flex; align-items: center; gap: 10px;
}
.waiting-code {
  font-family: monospace; font-size: 20px; letter-spacing: 2px;
  color: var(--ink-strong); flex: 1;
}
#btn-copy-code {
  font-size: 12px; padding: 4px 10px;
}
#waiting-player-list { display: flex; flex-direction: column; gap: 6px; }
.waiting-player {
  font-size: 14px; padding: 6px 10px;
  border-radius: 6px; display: flex; align-items: center; gap: 8px;
}
.waiting-player::before {
  content: ''; width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;
}
.waiting-player.joined { background: var(--surface-sunken); color: var(--ink-strong); }
.waiting-player.joined::before { background: var(--focus-ring); }
.waiting-player.empty { background: var(--surface-table); color: var(--ink-faint); font-style: italic; }
.waiting-player.empty::before { background: var(--card-border-strong); }

/* ── Auth views ────────────────────────────────────────────────────────── */
.auth-tabs {
  display: flex;
  border-bottom: 1px solid var(--card-border-strong);
}
.auth-tab {
  flex: 1;
  background: transparent;
  border: none;
  /* Match the container's 1px bottom border and pull the tab down by 1px so
     the tab's own border-bottom sits on the exact same row of pixels as the
     container line — active and inactive tabs share one continuous baseline. */
  border-bottom: 1px solid transparent;
  margin-bottom: -1px;
  /* Kill the 6px border-radius the base `button { ... }` rule applies — at
     1px border thickness it rounds the line's ends upward, producing a "bow"
     shape. We want a flat edge-to-edge underline. */
  border-radius: 0;
  color: var(--ink-muted);
  padding: 8px 0;
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
/* Match the .auth-tab specificity for hover so the base button hover (which
   paints a surface-sunken background) doesn't override. We only want a colour
   change on hover, not a background. */
.auth-tab:hover:not(:disabled) {
  color: var(--ink-strong);
  background: transparent;
}
.auth-tab.is-active {
  color: var(--ink-strong);
  border-bottom-color: var(--focus-ring);
}
.auth-form { display: flex; flex-direction: column; gap: 10px; }
.auth-error {
  color: var(--color-neg);
  font-size: 13px;
  margin: 0;
}
.auth-status {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 13px;
  color: var(--ink-muted);
}
.btn--link {
  background: transparent;
  border: none;
  color: var(--ink-muted);
  text-decoration: underline;
  padding: 2px 0;
  cursor: pointer;
  font: inherit;
  font-size: 13px;
  align-self: flex-start;
}
/* Bumped specificity to beat the base `button:hover:not(:disabled)` rule
   that would otherwise paint a dark surface-sunken background behind the
   text on hover. */
.btn--link:hover:not(:disabled) {
  color: var(--ink-strong);
  background: transparent;
}

/* ── Overlays ──────────────────────────────────────────────────────────── */
.overlay {
  position: fixed; inset: 0;
  background: var(--surface-overlay);
  display: flex; align-items: center; justify-content: center;
  z-index: 100;
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms var(--ease-out-quart);
}
.overlay.is-visible {
  opacity: 1;
  pointer-events: auto;
}

.ov-box {
  background: var(--surface-raised);
  border: 1px solid var(--card-border-strong);
  border-radius: 12px;
  padding: 32px;
  max-width: 480px; width: 90%; min-width: 0;
  display: flex; flex-direction: column; gap: 16px;
}
.ov-box.wide { max-width: 640px; }
.ov-box h2 { font-size: 22px; color: var(--ink-strong); }
.ov-box p  { color: var(--ink-muted); font-size: 14px; }

.ov-actions { display: flex; gap: 10px; flex-wrap: wrap; }
/* Settings close: right-align + primary colour so it reads as the dialog's
   dismiss action, not another tool in the "tools" row above it. */
#ov-settings .ov-actions { justify-content: flex-end; }

#ov-gt .ov-box { max-width: 680px; }

/* Round-over: dock as a compact panel without darkening the table, so the
   revealed leftover cards in every seat stay visible behind it. */
#ov-round { background: transparent; pointer-events: none; }
#ov-round .ov-box {
  pointer-events: auto;
  max-width: 320px;
  padding: 20px 24px;
  gap: 10px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.4);
}

/* Side zones widen during reveal so the upright cards fit without overlap. */
.zone-side:has(.card-backs .card) { width: auto; min-width: 80px; }

#gt-cards {
  display: flex; gap: 4px; flex-wrap: nowrap;
  --card-w: 4.5rem;
  --card-h: calc(4.5rem * 7 / 5);
}
#gt-cards .card { flex-shrink: 0; }

/* ── Pass overlay ──────────────────────────────────────────────────────── */
.pass-targets {
  display: flex; gap: 16px; justify-content: center;
}
.pass-target {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
}
.pt-label { font-size: 12px; color: var(--ink-muted); }
.pt-slot {
  --card-w: 3rem;
  --card-h: calc(3rem * 7 / 5);
  width: calc(var(--card-w) + 4px); height: calc(var(--card-h) + 4px);
  border: 2px dashed var(--card-border-strong);
  border-radius: 8px;
  position: relative;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; color: var(--ink-faint);
  cursor: pointer;
}
.pt-badge {
  position: absolute; top: 6px; left: 50%;
  transform: translateX(-50%) scale(0.8);
  transform-origin: top center;
  z-index: 2;
}
.pt-empty { color: var(--ink-faint); }
.pt-slot:hover { border-color: var(--focus-ring); }
.pt-slot.drag-over { border-color: var(--focus-ring); border-style: solid; background: rgba(255,255,255,0.05); }

.pass-target.filled .pt-slot { border-style: solid; border-color: var(--card-border-strong); }

.pass-section-label { font-size: 13px; color: var(--ink-muted); text-align: center; }

.pass-target.received .pt-slot {
  border-style: solid;
  border-color: var(--card-border-strong);
  opacity: 0.7;
}
.pass-target.received.arrived .pt-slot {
  border-color: var(--card-border-strong);
  opacity: 1;
}
.pass-target.received .pt-label { color: var(--ink-muted); }

#ov-pass .ov-box { max-width: 800px; }

#pass-hand {
  display: flex; gap: 4px; flex-wrap: nowrap; justify-content: center; margin-top: 8px;
}
#pass-hand .card {
  flex-shrink: 0;
  --card-w: 3rem;
  --card-h: calc(3rem * 7 / 5);
  width: 3rem;
  height: calc(3rem * 7 / 5);
}

#pass-select-section, #pass-received-section {
  display: flex; flex-direction: column; gap: 12px;
}
#btn-submit-pass, #btn-pass-ok { align-self: flex-end; }
#pass-wait-status { margin: 4px 0 0; text-align: center; }

/* ── Wish grid ─────────────────────────────────────────────────────────── */
.wish-grid {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
}
.wish-grid button { min-width: 44px; font-size: 15px; font-weight: 600; }
.wish-skip { width: 100%; background: var(--surface-sunken) !important; color: var(--ink-muted); margin-top: 2px; }

/* ── Animations ────────────────────────────────────────────────────────── */

/* Overlay modal box: slide up + fade in on open */
@keyframes overlay-box-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
.overlay.is-visible .ov-box {
  animation: overlay-box-in 220ms var(--ease-out-quart) both;
}

/* ── Dragon ────────────────────────────────────────────────────────────── */
#dragon-btns { display: flex; gap: 10px; flex-wrap: wrap; }

/* ── Bomb choice overlay ───────────────────────────────────────────────── */
#bomb-choice-list { display: flex; flex-direction: column; gap: 10px; }
.bomb-choice-row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--card-border);
}
.bomb-choice-row:last-child { border-bottom: none; }
.bomb-choice-cards { display: flex; gap: 3px; flex-wrap: wrap; flex: 1; }

/* ── Round over ────────────────────────────────────────────────────────── */
#round-body { display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
.score-row { display: flex; justify-content: space-between; }
.score-row .pts { font-weight: 700; color: var(--accent-text-on-surface); }
.score-row .pts.neg { color: var(--color-neg); }

/* ── Game log ──────────────────────────────────────────────────────────── */
#game-log {
  position: fixed;
  right: 0; top: 36px; bottom: 0;
  width: 260px;
  background: color-mix(in srgb, var(--surface-sunken) 92%, transparent);
  border-left: 1px solid var(--card-border-strong);
  display: flex;
  flex-direction: column;
  z-index: 110;
  font-size: 11px;
}
#log-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 5px 8px;
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--card-border-strong);
  color: var(--ink-muted);
  font-size: 11px;
  letter-spacing: 0.05em;
}
#log-header button {
  padding: 2px 8px;
  font-size: 10px;
  background: var(--surface-raised);
  border-color: var(--card-border);
  color: var(--ink-muted);
}
#log-entries {
  flex: 1;
  overflow-y: auto;
  padding: 4px 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.log-line {
  color: var(--ink-faint);
  line-height: 1.4;
  word-break: break-all;
  font-family: monospace;
}
.log-line:last-child { color: var(--ink-muted); }

/* ── Save Hand panel ───────────────────────────────────────────────────── */
#save-hands-panel {
  position: fixed;
  right: 8px;
  top: 42px;
  width: 280px;
  background: var(--surface-sunken);
  border: 1px solid var(--card-border-strong);
  border-radius: 4px;
  z-index: 112;
  padding: 8px;
  font-size: 12px;
  color: var(--ink-muted);
}
#save-hands-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 8px;
  font-weight: bold;
  color: var(--ink-strong);
}
#save-hands-header button {
  background: transparent;
  border: none;
  color: var(--ink-muted);
  cursor: pointer;
  font-size: 14px;
}
#save-hands-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
#inp-save-filename {
  width: 100%;
  box-sizing: border-box;
  background: var(--surface-sunken);
  border: 1px solid var(--card-border-strong);
  color: var(--ink-strong);
  padding: 4px 6px;
  border-radius: 3px;
  font-size: 12px;
}
#btn-do-save {
  padding: 4px 8px;
  font-size: 11px;
  cursor: pointer;
}
#save-hands-msg {
  font-size: 11px;
  color: var(--ink-muted);
  line-height: 1.3;
}

/* ── Settings overlay ──────────────────────────────────────────────────── */
.setting-row {
  display: flex; flex-direction: column; gap: 8px;
}
/* Admin tools (log / save hand) in the settings overlay. Desktop admins use the
   top-bar buttons, so this row is hidden there and only surfaced on mobile (see
   the media query). applyAdminState adds .hidden for non-admins, which wins over
   the mobile display via !important. */
#setting-row-admin { display: none; }
.setting-label { font-size: 14px; color: var(--ink-strong); }
.setting-options {
  display: flex; gap: 16px; flex-wrap: wrap;
}
.setting-options label {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--ink-muted); cursor: pointer;
}
.setting-options input[type="radio"] { accent-color: var(--focus-ring); cursor: pointer; }
.setting-options input[type="number"] {
  background: var(--surface-sunken); border: 1px solid var(--card-border-strong); border-radius: 6px;
  color: var(--ink-strong); padding: 5px 8px; font-size: 13px; outline: none; width: 80px;
  -moz-appearance: textfield;
}
.setting-options input[type="number"]::-webkit-inner-spin-button,
.setting-options input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.setting-options input[type="number"]:focus { border-color: var(--focus-ring); }

/* Slider + editable number paired control. */
.slider-group {
  display: flex; align-items: center; gap: 12px;
  flex: 1; min-width: 240px;
}
.slider-group input[type="range"] {
  flex: 1;
  accent-color: var(--focus-ring);
  cursor: pointer;
}
.slider-group input[type="number"] {
  flex-shrink: 0;
  width: 70px;
}

/* ── Mobile (≤ 600px) ──────────────────────────────────────────────────── */
@media (max-width: 600px) {

  /* Lobby */
  .lobby-box { width: calc(100vw - 24px); padding: 24px 18px; }

  /* Cap the single grid column at the viewport. Without an explicit column the
     implicit track is `auto`, which sizes to its WIDEST content (a 14-card hand
     or the 5-button action bar), stretching the whole board past the screen so
     everything clips at the edges. minmax(0,1fr) lets wide rows shrink/scroll
     inside the column instead of widening it. */
  #screen-table { grid-template-columns: minmax(0, 1fr); }

  /* Middle: less side padding, narrower side zones */
  #middle { padding: 0 8px; }
  .zone-side { width: 60px; }
  .pname { max-width: 60px; font-size: 11px; }

  /* Played zones (mobile): compact, overlapping combos so a long straight
     doesn't sprawl. Smaller cards; top/bottom overlap horizontally, left/right
     stack vertically — parallel to the side players' card-backs. renderTrick
     renders a flat card list on mobile so these margins apply directly. */
  .played-cards { --card-w: 2.2rem; --card-h: calc(2.2rem * 7 / 5); gap: 0; }

  /* Partner (top) & self (bottom): single overlapping row. */
  #played-top, #played-bottom {
    flex-wrap: nowrap;
    max-width: calc(100vw - 20px);
  }
  #played-top .card + .card,
  #played-bottom .card + .card { margin-left: -1.15rem; }   /* ~18px overlap */

  /* Center a compact, symmetric diamond in the play area (the 1fr middle row).
     The desktop `top` values (160px from the top, 100%−260px, 50%−82px) don't
     line up on a tall phone — the bottom card was stranded down by the hand
     while the sides sat near the middle, so the four cards read as off-centre.
     Play-area vertical centre = (table height − actions 44px − hand 130px) / 2;
     top/bottom sit ±96px from it, left/right sit exactly on it. Horizontal stays
     50% (top/bottom) and the symmetric 30% / 70% (left/right) set below. */
  #played-top    { top: calc((100% - 174px) / 2 - 96px); }
  #played-bottom { top: calc((100% - 174px) / 2 + 96px); }
  #played-left,
  #played-right  { top: calc((100% - 174px) / 2); }

  /* Left (Bot 1) & right (Bot 3): rotate 90° to match the side players'
     card-backs, stacked in an overlapping vertical column near their side. */
  #played-left, #played-right {
    flex-direction: column;
    flex-wrap: nowrap;
    max-width: none;
    max-height: none;
  }
  #played-left  { left: 30%; }
  #played-right { left: 70%; }
  /* Rotate the side plays landscape, each facing ITS player: right +90°, left
     −90° (mirror). transform-origin MUST be centre — the base .card sets it to
     50% 100% (for the hover lift), and rotating about the bottom edge shifts the
     card ½·height right AND down, throwing the left/right pair off-centre.
     Value placement: +90° puts the value at the card's TOP, −90° at the BOTTOM.
     In a combo the right column exposes each card's top (natural later-on-top
     paint) and the left column exposes each card's bottom (renderTrick reverses
     the paint order with descending z-index) — so every value stays visible. */
  #played-right .card { transform: rotate( 90deg); transform-origin: 50% 50%; }
  #played-left  .card { transform: rotate(-90deg); transform-origin: 50% 50%; }
  /* Collapse each rotated card's portrait layout box (--card-h tall) toward its
     landscape visual height (--card-w); the extra -1rem is the overlap. */
  #played-left  .card,
  #played-right .card {
    margin: calc((var(--card-w) - var(--card-h)) / 2) 0;
  }
  #played-left  .card + .card,
  #played-right .card + .card {
    margin-top: calc((var(--card-w) - var(--card-h)) / 2 - 1rem);
  }

  /* My hand: 3rem cards, mild overlap so cards stay readable.
     --card-gap: -0.75rem → 12px overlap, 36px visible per card. This is the
     DEFAULT/roomy spacing; when the full hand would overflow (e.g. 14 cards on a
     narrow phone) fitHandWidth() in game.js tightens --card-gap at runtime so
     the whole hand fits without horizontal scrolling. */
  #my-hand {
    --card-w:           3rem;
    --card-h:           calc(3rem * 7 / 5);
    --card-letter-size: 1rem;
    --card-pad:         0.35rem;
    --card-gap:         -0.75rem;
  }

  /* Hide the upside-down mirror value at the bottom-right of each card.
     With any overlap it bleeds through the gap and looks messy on mobile. */
  .card__corner--bottom { display: none; }

  /* Action bar: drop the large fixed gap, spread buttons across the bar.
     Compact button metrics so all five (call tihu · pass | unselect · bomb! ·
     play) fit a ~360px bar without the rightmost button being clipped by the
     body's overflow:hidden. */
  #action-bar { gap: 4px; justify-content: space-between; padding: 0 6px; }
  #action-left  { gap: 5px; }
  #action-right { gap: 5px; }
  button { padding: 7px 12px; }
  #action-bar .btn { padding: 6px 9px; font-size: 0.8rem; }

  /* Overlays: full-width, reduced padding, scrollable */
  .ov-box {
    width: calc(100vw - 16px);
    max-width: none !important;
    padding: 20px 16px;
    max-height: 90vh;
    overflow-y: auto;
  }

  /* GT overlay: 4 cards per row in a grid so sub-pixel rounding can't cause
     accidental 3-per-row wrapping. width/height on .card override the var()-based
     sizing; aspect-ratio keeps the 5:7 proportions without needing --card-h. */
  #gt-cards {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 4px;
    max-width: none;
    /* keep --card-h in sync for the band height (calc inside .card uses it) */
    --card-w: calc((100vw - 60px) / 4);
    --card-h: calc(var(--card-w) * 7 / 5);
  }
  #gt-cards .card {
    width: 100%;         /* fill the 1fr grid cell, overrides width:var(--card-w) */
    height: auto;
    aspect-ratio: 5 / 7;
    --card-letter-size: 1.1rem;
    --card-pad: 0.35rem;
  }

  /* Pass overlay: wrap cards into 2 rows at a smaller size */
  #pass-hand { flex-wrap: wrap; justify-content: center; }
  #pass-hand .card {
    --card-w: 2.25rem;
    --card-h: calc(2.25rem * 7 / 5);
    width:    2.25rem;
    height:   calc(2.25rem * 7 / 5);
  }
  .pt-slot {
    --card-w: 2.5rem;
    --card-h: calc(2.5rem * 7 / 5);
    width:  calc(var(--card-w) + 4px);
    height: calc(var(--card-h) + 4px);
  }
  .pt-badge { top: 3px; }
  .pass-targets { gap: 8px; }

  /* Wish buttons: taller touch targets */
  .wish-grid button { min-height: 44px; }

  /* Top bar: hide dev tools (moved into the settings overlay on mobile — see
     #setting-row-admin), shrink status text so it doesn't crowd the bar */
  #btn-save-hands, #btn-toggle-log { display: none; }
  #setting-row-admin { display: flex; }
  /* Mobile: show only the logo in the main-menu button, hide the "tihu" text. */
  #top-bar-name { display: none; }
  /* Give the status message the whole middle column instead of a fixed 38vw
     cap that truncated messages ("waiting for others…", "your turn", etc.) even
     when the bar had room. Sides size to their content; the status fills the
     rest, centred, and only ellipsises when genuinely out of space. */
  #top-bar { grid-template-columns: auto 1fr auto; }
  #top-bar > #status-msg {
    justify-self: stretch;
    text-align: center;
    max-width: none;
    padding: 0 6px;
  }
  #status-msg { font-size: 11px; overflow: hidden; text-overflow: ellipsis; }

  /* "play selected" → "play" (hide the word "selected" on narrow screens) */
  .hide-mobile { display: none; }

  /* Partner (top) card backs: force a single unwrapped row.
     JS (setCardCounts) sets flexWrap:'wrap' as an inline style when cardOverlap=0,
     which overrides plain CSS — !important is needed to win that battle. */
  #backs-top { flex-wrap: nowrap !important; gap: 1px; }
  .card-back { width: 14px; height: 21px; }
  .card-backs .card {
    --card-w:           1.6rem;
    --card-h:           calc(1.6rem * 7 / 5);
    --card-letter-size: 0.55rem;
    --card-pad:         0.2rem;
  }

  /* Side players (left/right) — FACE-DOWN stack only (:has(.card-back)):
     - cap the stack so it doesn't dominate the middle (14 cards × 13px ≈ 190px;
       cap at 160px so ~12 show, rest hidden);
     - single lined-up column: base CSS sets flex-wrap:wrap (for the face-up
       reveal), which would otherwise spill the capped stack into a second column.
     Scoped to the card-back stack so the FACE-UP reveal is untouched: its cards
     are rotated 90°, so their visual width exceeds the shrink-wrapped column box
     and overflow:hidden here would crop their left/right edges. Face-up falls
     back to the base overflow:visible (reveal uses .card, not .card-back). */
  .card-backs.vertical:has(.card-back) {
    /* Give the column an explicit width WIDER than a rotated card's visual width
       (card-back height 21px + buffer). Without it the column shrink-wraps to the
       14px un-rotated layout box, so overflow:hidden crops ~3.5px off each side of
       every rotated card. 26px lets the full 21px visual sit inside, centred. */
    width: 26px;
    /* Fit a full 14-card stack (~190px) without clipping the bottom cards; the
     side zone is centred in the large 1fr middle row so there's room. Content
     fits horizontally now, so overflow:hidden only ever caps the height. */
    max-height: calc(100dvh - 240px);
    overflow: hidden;
    flex-wrap: nowrap;
  }

  /* Prevent any ancestor clipping of rotated card backs */
  #middle, .zone-side { overflow: visible; }

  /* Face-up reveal (spectator / round-over) — overlap 20% so revealed hands stay
     compact without burying the values (matches the face-down default overlap).
     Each side rotates so the card BOTTOM faces the centre, mirroring how that
     player's cards are played: right +90° (value ends up at the top strip), left
     −90° (value at the bottom strip — renderSeatBacks reverses the paint order
     with a descending z-index so those bottoms stay exposed under the overlap).
     The top row overlaps leftward. Only affects reveal (.card), not the face-down
     .card-back stacks. */
  #backs-right .card { transform: rotate( 90deg); }
  #backs-left  .card { transform: rotate(-90deg); }
  .card-backs.vertical .card + .card {
    /* collapse to landscape height (base rule), then overlap 20% of the visual
       height — the visual height of a rotated card is its WIDTH (--card-w). */
    margin-top: calc((var(--card-w) - var(--card-h)) / 2 - var(--card-w) * 0.2) !important;
  }
  #backs-top { gap: 0; }
  #backs-top .card + .card { margin-left: calc(var(--card-w) * -0.2) !important; }

  /* Hand area: slightly taller row so cards aren't clipped */
  #screen-table { grid-template-rows: 1fr 44px 130px; }

  /* Safe-area padding for notched / home-bar iPhones */
  #action-bar { padding-bottom: env(safe-area-inset-bottom, 0px); }
  #my-hand    { padding-bottom: max(6px, env(safe-area-inset-bottom, 6px)); }
}

/* ── Load Hand overlay ─────────────────────────────────────────────────── */
#hands-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 300px;
  overflow-y: auto;
  margin-bottom: 12px;
}

.hand-file {
  padding: 10px 14px;
  background: var(--surface-raised);
  border: 1px solid var(--card-border);
  border-radius: 4px;
  cursor: pointer;
  color: var(--ink-muted);
  font-size: 13px;
  transition: background var(--t-fast);
}
.hand-file:hover {
  background: var(--surface-sunken);
  color: var(--ink-strong);
  border-color: var(--card-border-strong);
}

/* Stats view — wider box so stat values stay on one line */
.lobby-box--wide { width: min(440px, calc(100vw - 24px)); }
#stats-body { margin: 12px 0; }
.stat-line {
  position: relative;   /* positioning context for the ? tooltip below */
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 8px 4px; border-bottom: 1px solid var(--card-border);
}
.stat-key { color: var(--ink-muted); flex: 0 0 auto; }

/* per-stat "?" help marker + hover/focus tooltip */
.stat-help {
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px; margin-left: 6px; vertical-align: middle;
  border: 1px solid var(--card-border-strong); border-radius: 50%;
  font-size: 9px; font-weight: 700; line-height: 1; color: var(--ink-muted);
  cursor: help; user-select: none; outline: none;
}
.stat-help:hover, .stat-help:focus { color: var(--ink-strong); border-color: var(--ink-strong); }
/* tooltip is anchored to the whole row (left:0;right:0) so it never clips sideways */
.stat-help::after {
  content: attr(data-tip);
  position: absolute; top: 100%; left: 0; right: 0; margin-top: 4px;
  background: var(--surface-sunken); color: var(--ink-strong);
  border: 1px solid var(--card-border-strong); border-radius: 6px;
  box-shadow: var(--shadow-card-drag);
  padding: 7px 9px; font-size: 12px; line-height: 1.4; font-weight: 400;
  text-align: left; white-space: normal;
  opacity: 0; pointer-events: none; transition: opacity .12s ease; z-index: 50;
}
.stat-help:hover::after, .stat-help:focus::after { opacity: 1; }
.stat-val { color: var(--ink-strong); text-align: right; white-space: nowrap; }
.stats-msg { color: var(--ink-muted); font-size: 13px; text-align: center; padding: 12px; }
#stats-reset-row { margin-top: 8px; font-size: 13px; }
.stats-confirm-q { color: var(--ink-muted); margin-right: 6px; }
