/* ============================================================
   Surgeon Poker — modern dark-felt theme.
   Palette: deep emerald felt, brass accents, ivory text.
   ============================================================ */

:root {
  --bg-deep:       #0a1410;
  --bg-velvet:     #0d1b14;
  --felt:          radial-gradient(ellipse at center,
                     #1f5a3c 0%,
                     #16432d 55%,
                     #0a2417 100%);
  --felt-edge:     #4a2e16;
  --rail:          linear-gradient(180deg, #6b4523 0%, #3e2811 100%);
  --ivory:         #f5ecd6;
  --ivory-dim:     rgba(245, 236, 214, 0.65);
  --brass:         #d9b06a;
  --brass-bright:  #f1cf83;
  --accent:        #ff8c42;
  --danger:        #e35858;
  --success:       #6be0a9;
  --shadow-card:   0 18px 50px rgba(0,0,0,0.55), 0 2px 6px rgba(0,0,0,0.4);
  --shadow-soft:   0 4px 14px rgba(0,0,0,0.35);
  --radius-card:   18px;
  --radius-btn:    10px;
  --font-display:  'Bebas Neue', system-ui, sans-serif;
  --font-body:     'Inter', system-ui, -apple-system, Segoe UI, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body {
  height: 100%;
  margin: 0;
  background: radial-gradient(ellipse at top, #102218 0%, var(--bg-deep) 70%);
  color: var(--ivory);
  font-family: var(--font-body);
  font-size: 16px;
  overflow: hidden;
}

button, input { font: inherit; color: inherit; }

/* ===== Screen switcher ===== */
.screen { display: none; min-height: 100vh; }

/* ===== 🗡️ Dungeon side-game ===== */
.screen[data-show-on="dungeon"] { align-items: stretch; justify-content: flex-start; height: 100vh; }
.dungeon { max-width: 980px; width: 100%; margin: 0 auto; padding: 1rem; display: flex; flex-direction: column; gap: 0.8rem; height: 100%; min-height: 0; box-sizing: border-box; color: var(--ivory); }
.dungeon__top { display: flex; align-items: center; gap: 1rem; }
.dungeon__title { font-family: var(--font-display); font-size: 1.4rem; letter-spacing: 0.12em; color: var(--brass-bright); }
.dungeon__meta { flex: 1; color: var(--ivory-dim); font-variant-numeric: tabular-nums; }
.dungeon__ambient { margin: -0.4rem 0 0; font-size: 0.78rem; color: var(--ivory-dim); opacity: 0.65; font-style: italic; }
.dungeon__stage {
  background:
    linear-gradient(180deg, rgba(12,10,16,0.84), rgba(6,6,10,0.9)),
    url('/dungeon/maps/harrowstone.webp') center / cover no-repeat;
  border: 1px solid rgba(217,176,106,0.25); border-radius: 12px; padding: 1rem;
  display: flex; flex-direction: column; gap: 0.9rem;
  /* The battleboard GROWS to take the available vertical space (the chat logs get a
     fixed, bounded share below) so both the enemy row and the FULL hero row fit
     without scrolling. overflow:hidden is only a last-resort guard. */
  flex: 1 1 auto; min-height: 0; overflow: hidden;
}
/* The enemy field is a STATIC-height box — when it fills up the cards shrink
   (is-compact / is-packed, set in JS by enemy count) and, as a last-resort
   fallback, it scrolls internally — so a crowded battlefield never pushes the
   action bar / spellbook off the bottom of the screen. */
.dungeon__enemies { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; align-content: flex-start; flex: 1 1 auto; min-height: 64px; max-height: 30vh; overflow-y: auto; }
.dmon { position: relative; width: 112px; background: rgba(0,0,0,0.4); border: 1px solid rgba(200,80,80,0.4); border-radius: 10px; padding: 0.5rem 0.4rem; display: flex; flex-direction: column; align-items: center; gap: 0.25rem; cursor: pointer; color: inherit; transition: transform .1s, border-color .1s, box-shadow .1s; }
.dungeon__enemies.is-compact .dmon { width: 88px; padding: 0.3rem 0.25rem; gap: 0.15rem; }
.dungeon__enemies.is-compact .dmon__art { width: 48px; height: 48px; }
.dungeon__enemies.is-compact .dmon__glyph { font-size: 1.5rem; }
.dungeon__enemies.is-compact .dmon__name { font-size: 0.72rem; }
.dungeon__enemies.is-packed .dmon { width: 66px; padding: 0.2rem; gap: 0.1rem; }
.dungeon__enemies.is-packed .dmon__art { width: 38px; height: 38px; }
.dungeon__enemies.is-packed .dmon__glyph { font-size: 1.2rem; }
.dungeon__enemies.is-packed .dmon__name { font-size: 0.62rem; }
.dmon:hover:not(:disabled) { transform: translateY(-2px); border-color: rgba(255,120,120,0.85); }
.dmon.is-sel { border-color: var(--brass-bright); box-shadow: 0 0 0 2px rgba(241,207,131,0.4); }
/* The monster whose TURN it is glows hot red — mirrors the heroes' gold glow. */
.dmon.is-turn { border-color: rgba(255,140,90,0.95); box-shadow: 0 0 12px 3px rgba(255,110,70,0.65); }
/* 🎯 who's aiming here — one colored name per targeting human (ring colors match). */
.dmon__aim { font-size: 0.58rem; line-height: 1.1; font-weight: 700; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dmon.is-boss { border-color: rgba(220,170,60,0.9); background: rgba(40,28,10,0.5); }
.dmon.is-dead { opacity: 0.32; filter: grayscale(1); cursor: default; }
/* Full-art portrait backdrop (hero/villain cards) — the inline gradient keeps
   text legible; reinforce name/HP with a drop shadow. */
.dpc.has-portrait .dpc__name, .dpc.has-portrait .dpc__hp,
.dmon.has-portrait .dmon__name, .dmon.has-portrait .dmon__hp { text-shadow: 0 1px 3px rgba(0,0,0,0.95), 0 0 2px rgba(0,0,0,0.8); opacity: 0.85; }
/* The portrait IS the face now — hide the redundant token circle, but KEEP the
   status badges (Loot Lord / boss crown, Wild Shape glyph). The avatar box stays
   in place but goes transparent, so the portrait shows through where the circle
   was and the badges still anchor. Cards WITHOUT a paired portrait are untouched
   — their token is the only art they have. */
/* A solid dark-grey fill UNDER the portrait so transparent art (e.g. the ooze
   PNG) sits on grey rather than showing the felt through it. */
.dpc.has-portrait, .dmon.has-portrait { background-color: #4a4a4a; }   /* medium grey blends with dark AI art far better than the old blue-black (Tobias 2026-07-04) */
.dpc.has-portrait .dpc__avatar { background: transparent; border: none; box-shadow: none; }
.dpc.has-portrait .dpc__avatar .avatar-img,
.dpc.has-portrait .dpc__avatar > svg { display: none; }
.dmon.has-portrait .dmon__art { background-image: none !important; border: none; box-shadow: none; }
/* Dead monsters COLLAPSE to tiny corpse chips — the kill stays visible but no
   longer eats battleboard space (a big room half-slain must never force a
   scrollbar). The width selector carries .dungeon__enemies so it out-cascades
   the is-compact / is-packed width rules above at equal specificity (later in
   the file); the inner rules are more specific outright. */
.dungeon__enemies .dmon.is-dead { width: 46px; padding: 0.15rem 0.1rem; gap: 0.05rem; }
.dungeon__enemies .dmon.is-dead .dmon__art { width: 26px; height: 26px; }
.dungeon__enemies .dmon.is-dead .dmon__glyph { font-size: 1rem; }
.dungeon__enemies .dmon.is-dead .dmon__name { font-size: 0.55rem; max-width: 44px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dungeon__enemies .dmon.is-dead .dmon__hpbar,
.dungeon__enemies .dmon.is-dead .dcond,
.dungeon__enemies .dmon.is-dead .dbuff { display: none; }
.dungeon__enemies .dmon.is-dead .dmon__hp { font-size: 0.7rem; line-height: 1; }
.dmon__glyph { font-size: 2rem; line-height: 1; }
.dmon__art { position: relative; width: 64px; height: 64px; border-radius: 50%; background-size: cover; background-position: center; border: 1px solid rgba(0,0,0,0.4); }
/* Boss ring is BLOOD RED with a skull — gold ring + crown are the poker Loot
   Lord's regalia and belong to heroes only (Tobias 2026-07-04). */
.dmon.is-boss .dmon__art { border-color: rgba(205,45,45,0.9); box-shadow: 0 0 0 2px rgba(205,45,45,0.5); }
.dmon__crown { position: absolute; top: -8px; right: -4px; font-size: 0.95rem; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.6)); }
.dpc__avatar { width: 40px; height: 40px; border-radius: 50%; overflow: hidden; margin: 0 auto 0.15rem; }
.dpc__avatar img, .dpc__avatar svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.dpc { align-items: center; text-align: center; }
.dmon__name { font-size: 0.72rem; text-align: center; }
/* Status icons OVERLAY the token (absolute → never add card height, keeping the
   dungeon compact). On a HERO card: BUFFS top-LEFT (green), DEBUFFS top-RIGHT
   (red). On a monster card: debuffs span the top. Hover an icon for its name +
   summary (hero icons get pointer-events; monster icons stay click-through so
   you can still click the card to target). */
.dcond {
  position: absolute; top: 3px; left: 3px; right: 3px;
  display: flex; flex-flow: row wrap; gap: 3px;
  justify-content: flex-start; align-content: flex-start;
  pointer-events: none; z-index: 2;
}
.dcond__i {
  width: 18px; height: 18px; border-radius: 4px;
  background: rgba(0,0,0,0.55); padding: 1px;
  box-shadow: 0 0 0 1px rgba(217,72,72,0.85);   /* red ring = a debuff is active */
}
.dbuff {
  position: absolute; top: 3px; left: 3px; right: 50%;
  display: flex; flex-flow: row wrap; gap: 3px;
  justify-content: flex-start; align-content: flex-start;
  pointer-events: none; z-index: 2;
}
.dbuff__i {
  width: 18px; height: 18px; border-radius: 4px;
  background: rgba(0,0,0,0.55); padding: 1px;
  box-shadow: 0 0 0 1px rgba(96,196,108,0.9);   /* green ring = a buff is active */
}
/* A buff chip that carries a count (Mirror Image decoys, Glorious Challenge stack) — a tiny
   number badge in the corner of the icon. */
.dbuff__w { position: relative; display: inline-flex; }
.dbuff__n {
  position: absolute; bottom: -3px; right: -3px;
  min-width: 12px; height: 12px; padding: 0 2px; box-sizing: border-box;
  border-radius: 7px; background: #c0392b; color: #fff;
  font-size: 9px; line-height: 12px; font-weight: 800; text-align: center;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.7); pointer-events: none;
}
/* On hero AND monster cards, push debuffs to the RIGHT half so buffs own the top-left. */
.dpc .dcond, .dmon .dcond { left: 50%; right: 3px; justify-content: flex-end; }
/* Status icons are hoverable → native title tooltips (name + effect summary)
   work on BOTH heroes and monsters. A monster icon sits inside the .dmon target
   button, so a click on it still bubbles up to select the monster; only hover is
   captured for the tooltip. */
.dpc .dcond__i, .dpc .dbuff__i, .dmon .dcond__i { pointer-events: auto; }
/* Auto-skip countdown badge — just to the right of the hero token (only on the
   active human's card). Absolute so it never changes card height. */
.dpc__afk {
  position: absolute; top: 8px; left: calc(50% + 26px);
  font-size: 0.66rem; font-weight: 700; line-height: 1;
  color: var(--brass-bright); background: rgba(0,0,0,0.6);
  padding: 2px 5px; border-radius: 8px; white-space: nowrap;
  border: 1px solid rgba(217,176,106,0.5); pointer-events: none; z-index: 3;
}
.dpc__afk.is-urgent { color: #ff6f6f; border-color: rgba(255,90,90,0.8); animation: dpcAfkPulse 0.7s ease-in-out infinite; }
@keyframes dpcAfkPulse { 50% { opacity: 0.35; } }
.dmon__hpbar, .dpc__hpbar { width: 100%; height: 6px; background: rgba(255,255,255,0.12); border-radius: 3px; overflow: hidden; }
.dmon__hpbar span { display: block; height: 100%; background: linear-gradient(90deg,#c84a4a,#e87b5b); }
/* Blue XP-to-next bar under the green HP bar on a hero card (thinner, secondary). */
.dpc__xpbar { width: 100%; height: 4px; margin-top: 2px; background: rgba(255,255,255,0.10); border-radius: 2px; overflow: hidden; }
.dpc__xpbar span { display: block; height: 100%; background: linear-gradient(90deg,#3a7bd5,#5fa8ee); }
.dmon__hp { font-size: 0.7rem; font-variant-numeric: tabular-nums; color: var(--ivory-dim); }
.dmon__none { color: var(--ivory-dim); opacity: 0.6; font-style: italic; align-self: center; }
.dungeon__turn { text-align: center; font-weight: 600; color: var(--brass-bright); min-height: 1.2em; }
/* The hero row shows ALL its cards — no cap, no scrollbar. The battleboard grows to
   make room; for a big recruited party the cards shrink to fit (is-compact / is-packed,
   set in JS by party size), exactly like the enemy field. */
.dungeon__party { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; align-content: flex-start; flex: 0 0 auto; }
/* Shrink hero cards as the party grows so they always fit without scrolling. */
.dungeon__party.is-compact .dpc { width: 150px; padding: 0.35rem; gap: 0.2rem; }
.dungeon__party.is-compact .dpc__avatar { width: 32px; height: 32px; }
.dungeon__party.is-packed  .dpc { width: 120px; padding: 0.3rem; gap: 0.15rem; }
.dungeon__party.is-packed  .dpc__avatar { width: 28px; height: 28px; }
.dungeon__party.is-packed  .dpc__name { font-size: 0.72rem; }
.dpc { position: relative; width: 190px; background: rgba(0,0,0,0.4); border: 1px solid rgba(217,176,106,0.3); border-radius: 10px; padding: 0.5rem; display: flex; flex-direction: column; gap: 0.3rem; }
.dpc.is-low { border-color: rgba(220,80,80,0.7); }
.dpc.is-me { border-color: rgba(241,207,131,0.7); }
.dpc.is-turn { box-shadow: 0 0 0 2px rgba(241,207,131,0.55), 0 0 14px 4px rgba(241,207,131,0.5); border-color: var(--brass-bright); }
.dpc.is-out { opacity: 0.4; filter: grayscale(0.8); }
/* Ally targeting: party cards are clickable; the selected ally (your buff /
   dispel aim) wears a green ring — distinct from the gold "whose turn" glow. */
.dungeon__party .dpc[data-ally] { cursor: pointer; }
.dpc.is-target { border-color: #7bd06a; box-shadow: 0 0 0 2px rgba(123,208,106,0.55); }
/* OUT heroes (dead ☠️ / bailed 🪜) shrink to slim chips — still listed (the
   dead can be raised when the round turns) but no longer crowd the living.
   DYING (is-down) heroes stay FULL SIZE — they're the ones to watch. */
.dungeon__party .dpc.is-out { width: 96px; padding: 0.25rem; gap: 0.1rem; }
.dungeon__party .dpc.is-out .dpc__avatar { width: 22px; height: 22px; }
.dungeon__party .dpc.is-out .dpc__name { font-size: 0.68rem; }
.dungeon__party .dpc.is-out .dpc__xpbar,
.dungeon__party .dpc.is-out .dcond,
.dungeon__party .dpc.is-out .dbuff,
.dungeon__party .dpc.is-out .dpc__ac { display: none; }
.dungeon__party .dpc.is-out .dpc__hp { font-size: 0.62rem; }
/* Downed/dying: not greyed out (they're savable) — pulsing red border + bloody HP. */
.dpc.is-down { border-color: rgba(200,40,40,0.95); animation: dpc-dying 1s ease-in-out infinite; }
.dpc.is-down .dpc__hp { color: #e06a6a; font-weight: 700; }
@keyframes dpc-dying { 0%,100% { box-shadow: 0 0 0 1px rgba(200,40,40,0.5); } 50% { box-shadow: 0 0 8px 2px rgba(200,40,40,0.85); } }
/* Name sits LEFT (like the HP line) so it clears the portrait's face — the
   art crops center faces, and a centered name sat right on the nose (Tobias). */
.dpc__name { font-size: 0.82rem; font-weight: 600; align-self: flex-start; text-align: left; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dpc__hpbar span { display: block; height: 100%; background: linear-gradient(90deg,#3fa34d,#7bd06a); }
.dpc.is-low .dpc__hpbar span { background: linear-gradient(90deg,#c84a4a,#e8a15b); }
/* HP/Lv line sits BOTTOM-LEFT (the card centers everything else) so the
   absolutely-positioned 🛡 AC chip at bottom-right never covers it. */
.dpc__hp { font-size: 0.72rem; color: var(--ivory-dim); font-variant-numeric: tabular-nums; align-self: flex-start; text-align: left; max-width: calc(100% - 46px); }
/* ⏳ pre-loaded action chip — mirrors the AFK badge, on the other shoulder. */
.dpc__queued {
  position: absolute; top: 8px; right: 4px;
  font-size: 0.6rem; font-weight: 700; line-height: 1;
  color: var(--brass-bright); background: rgba(0,0,0,0.6);
  padding: 2px 5px; border-radius: 8px; white-space: nowrap; max-width: 46%;
  overflow: hidden; text-overflow: ellipsis;
  border: 1px solid rgba(217,176,106,0.5); pointer-events: none; z-index: 3;
}
.dungeon__queuehint { color: var(--brass-bright); font-size: 0.85em; cursor: help; }
.dungeon__loot { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.dloot { display: flex; align-items: center; gap: 0.5rem; background: rgba(40,30,10,0.5); border: 1px solid rgba(217,176,106,0.4); border-radius: 8px; padding: 0.3rem 0.6rem; }
.dloot__name { color: #ffe9a8; font-size: 0.85rem; }
.dlootroll { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; background: rgba(60,45,12,0.6); border: 1px solid rgba(241,207,131,0.65); border-radius: 8px; padding: 0.4rem 0.7rem; }
.dlootroll__head { color: #ffe9a8; font-weight: 600; font-size: 0.88rem; }
.dlootroll--wait { color: var(--ivory-dim); font-style: italic; }
/* Stable layout: a status line on top, then a FIXED row of action buttons that
   never change count/position (greyed when inactive) so quick clicks don't hit
   the wrong button. */
.dungeon__actions { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; }
.dungeon__actrow { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.dungeon__actstatus { min-height: 1.2em; color: var(--ivory-dim); font-style: italic; font-size: 0.85rem; }
/* Caster at-will element picker — a tight little ❄️🟢⚡ cluster beside Attack. */
.dungeon__cantrips { display: inline-flex; gap: 2px; margin: 0 4px; vertical-align: middle; }
.dungeon__cantrips .btn { padding: 0.25rem 0.45rem; line-height: 1; }
/* Spontaneous-caster metamagic toggles — ✨Empower +2 etc., lit when active. */
.dungeon__metamagic { display: inline-flex; gap: 2px; margin: 0 4px; vertical-align: middle; flex-wrap: wrap; }
.dungeon__metamagic .btn { padding: 0.2rem 0.4rem; line-height: 1; font-size: 0.72rem; }
.dungeon__actions .is-cooling { opacity: 0.5; }
/* Per-room ability use counter inside an action button (e.g. "2/3"). */
.dungeon__uses { font-size: 0.72em; opacity: 0.85; font-variant-numeric: tabular-nums; }
.dungeon__actrow .btn:disabled .dungeon__uses { opacity: 0.6; }
/* Abilities wrap to fit a class's spell list; nav (door/bail) sits on its own
   row with a little separation so it stays a stable target. */
.dungeon__actrow--abilities { flex-wrap: wrap; }
.dungeon__actrow--nav { margin-top: 0.15rem; }
.dungeon__actions { position: relative; }   /* anchor for the spellbook dropdown */
/* Spell/ability art icon inside a button. */
.spell-ic { width: 18px; height: 18px; border-radius: 3px; object-fit: cover; vertical-align: -4px; margin-right: 3px; box-shadow: 0 0 0 1px rgba(0,0,0,0.4); }
/* Caster "📖 Spellbook ▾" expandable menu. */
/* The toggle + popover live in this inline-block wrapper so the popover anchors
   to the BUTTON (drops straight down from it), not the whole action panel. */
.dungeon__sb-wrap { position: relative; display: inline-block; }
/* The spellbook is a FIXED, viewport-anchored panel pinned just above the bottom
   of the screen and centered. Because the action bar sits mid-screen (chat/logs
   below it), an absolutely-positioned popover would run off the top OR bottom; a
   fixed panel is always fully on-screen, capped to the viewport height, with a
   real internal scrollbar — no browser-zoom needed to reach the higher levels. */
.dungeon__spellbook {
  display: none; position: fixed; z-index: 200;
  left: 50%; transform: translateX(-50%); right: auto; top: auto; bottom: 14px;
  width: min(440px, 94vw); min-width: 280px; max-width: 94vw;
  max-height: 82vh; box-sizing: border-box; flex-direction: column;
  padding: 0.5rem; background: linear-gradient(180deg, rgba(20,24,18,0.98), rgba(10,14,10,0.99));
  border: 1px solid rgba(217,176,106,0.4); border-radius: 10px; box-shadow: 0 8px 32px rgba(0,0,0,0.8);
}
.dungeon__spellbook.is-open { display: flex; }
.dungeon__sb-head { font-size: 0.78rem; color: var(--brass-bright); margin-bottom: 0.4rem; text-align: center; flex: 0 0 auto; }
/* fills the panel and scrolls; min-height:0 lets the flex child actually shrink */
.dungeon__sb-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; gap: 0.5rem; padding-right: 2px; }
.dungeon__sb-lvlhead {
  font-size: 0.68rem; color: var(--brass-bright); letter-spacing: 0.06em; text-transform: uppercase;
  opacity: 0.85; margin-bottom: 0.25rem; padding: 2px 0;
  position: sticky; top: 0; background: rgba(14,16,12,0.98); z-index: 1;
}
.dungeon__sb-slots { color: #9fd29f; font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0; }
.dungeon__sb-row { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.dungeon__sb-spell {
  position: relative; width: 40px; height: 40px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; font-size: 1.2rem; line-height: 1;
  border-radius: 8px; border: 1px solid rgba(217,176,106,0.3);
  background: rgba(0,0,0,0.35); color: var(--ivory); cursor: pointer;
}
.dungeon__sb-spell:hover:not(:disabled) { border-color: var(--brass-bright); background: rgba(217,176,106,0.16); }
.dungeon__sb-spell:disabled { cursor: default; opacity: 0.5; }
.dungeon__sb-spell.is-locked { opacity: 0.4; }
.dungeon__sb-spell .spell-ic { width: 30px; height: 30px; margin: 0; vertical-align: 0; }
.dungeon__sb-badge {
  position: absolute; bottom: -3px; right: -3px; font-size: 0.58rem; line-height: 1;
  padding: 1px 3px; border-radius: 6px; background: rgba(10,10,14,0.95);
  border: 1px solid rgba(217,176,106,0.4); color: var(--ivory-dim); font-variant-numeric: tabular-nums;
}
.dungeon__sb-badge.dungeon__sb-lock { background: transparent; border: none; padding: 0; bottom: -2px; right: -1px; }
.dwait { color: var(--ivory-dim); font-style: italic; align-self: center; }
.dungeon__recruit { position: relative; }
.dungeon__recruit:empty { display: none; }
.dungeon__recruit-toggle { align-self: flex-start; }
.dungeon__recruit-count { opacity: 0.7; font-variant-numeric: tabular-nums; }
/* Collapsed by default. When opened it CENTERS on screen (not anchored to its
   button — anchoring pushed the top off-screen so the first bots couldn't be
   picked) and scrolls internally if the roster is long. */
.dungeon__recruit-pop {
  display: none;
  position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(94vw, 560px); max-height: 85vh; overflow-y: auto;   /* scroll when there are many bots */
  z-index: 1000;
  background: linear-gradient(180deg, rgba(20,18,26,0.99), rgba(10,10,14,0.995));
  border: 1px solid rgba(217,176,106,0.5); border-radius: 12px;
  padding: 0.6rem 0.7rem;
  box-shadow: 0 0 0 100vmax rgba(0,0,0,0.55), 0 12px 32px rgba(0,0,0,0.8);   /* dim backdrop */
}
.dungeon__recruit-pop.is-open { display: block; }
.dungeon__recruit-head { font-size: 0.78rem; color: var(--brass-bright); letter-spacing: 0.04em; margin-bottom: 0.4rem; position: sticky; top: -0.5rem; background: rgba(14,12,18,0.98); padding: 0.25rem 0; }
/* In the dungeon recruit popover the GRID must not scroll — the popover scrolls
   instead. Doubled class so this beats the later base `.bot-picker__grid` rule
   (overflow-y:auto) by specificity, not source order — otherwise the grid AND the
   popover both show a scrollbar (the "two scrollbars on the right" bug). */
.bot-picker__grid.bot-picker__grid--dungeon { max-height: none; overflow: visible; }
/* Two side-by-side scroll panes — party left, monsters right. */
/* The chat logs take a FIXED, bounded share so they never starve the battleboard
   above. They scroll INTERNALLY (each column) — that's expected for a chat log. */
.dungeon__logs { display: flex; gap: 0.5rem; flex: 0 0 16vh; min-height: 110px; }
.dungeon__logcol { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.dungeon__loghead { font-size: 0.72rem; letter-spacing: 0.05em; text-transform: uppercase; padding: 2px 6px 3px; opacity: 0.9; }
.dungeon__logcol--hero  .dungeon__loghead { color: #9fd29f; }
.dungeon__logcol--enemy .dungeon__loghead { color: #e2a0a0; }
.dungeon__log { list-style: none; margin: 0; padding: 0.4rem 0.6rem; flex: 1; min-height: 70px; overflow-y: auto; background: rgba(0,0,0,0.3); border: 1px solid rgba(217,176,106,0.15); border-radius: 8px; font-size: 0.82rem; line-height: 1.4; color: var(--ivory-dim); }
.dungeon__logcol--hero  .dungeon__log { border-color: rgba(122,184,122,0.25); }
.dungeon__logcol--enemy .dungeon__log { border-color: rgba(214,120,120,0.25); }
.dungeon__spectating { color: #9ec5f0; font-style: italic; }
.dungeon__chat { display: flex; gap: 0.4rem; align-items: center; }
.dungeon__chat input {
  flex: 1; min-width: 0;
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(217,176,106,0.3);
  border-radius: 6px;
  color: var(--ivory);
  font: inherit; font-size: 0.85rem;
  padding: 6px 10px;
}
.dungeon__chat input::placeholder { color: var(--ivory-dim); }
.dungeon__chat input:focus { outline: none; border-color: rgba(217,176,106,0.6); }
.dungeon__log li { padding: 1px 0; }
.dungeon__log .dlog__b { display: block; }
/* Subtle event tints — heal gold, death red, buff blue, debuff purple. */
.dungeon__log .dlog-k--heal   { color: #e7cf8e; }
.dungeon__log .dlog-k--death  { color: #e58d8d; }
.dungeon__log .dlog-k--buff   { color: #8fb8ec; }
.dungeon__log .dlog-k--debuff { color: #c79cf0; }
.dungeon__log .droll { color: var(--brass-bright); font-weight: 700; }
.dungeon__log .dlog-say { color: #d8c6f0; font-style: italic; }
body[data-screen="loading"] .screen[data-show-on="loading"],
body[data-screen="login"]   .screen[data-show-on="login"],
body[data-screen="roster"]  .screen[data-show-on="roster"],
body[data-screen="confirm"] .screen[data-show-on="confirm"],
body[data-screen="table"]   .screen[data-show-on="table"],
body[data-screen="dungeon"] .screen[data-show-on="dungeon"] { display: flex; }

/* ===== Loading ===== */
.screen[data-show-on="loading"] {
  align-items: center; justify-content: center;
}
.loading-pulse {
  font-family: var(--font-display);
  letter-spacing: 0.3em;
  font-size: 1.5rem;
  color: var(--ivory-dim);
  animation: pulse 1.4s ease-in-out infinite;
}
@keyframes pulse { 0%,100% { opacity:.4; } 50% { opacity:1; } }

/* ===== Roster picker ===== */
/* html/body have overflow:hidden so .screen needs an explicit height
   for overflow-y: auto to actually create a scrollable region. */
.screen[data-show-on="roster"] {
  align-items: flex-start; justify-content: center; padding: 2rem 1.5rem;
  height: 100vh;
  overflow-y: auto;
}
.card.roster-card { width: min(900px, 100%); padding: 2rem; }
.roster-card__head { text-align: center; margin-bottom: 1.5rem; }
.hint.subtle { font-size: 0.75rem; opacity: 0.7; margin-top: 0.25rem; }
.roster-grid {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.roster-section-head {
  margin-top: 0.5rem;
  border-top: 1px solid rgba(241,207,131,0.18);
  padding-top: 0.85rem;
}
.roster-section-head:first-child { border-top: none; margin-top: 0; padding-top: 0; }
.roster-section-head h2 {
  margin: 0 0 0.15rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: 0.18em;
  color: var(--brass-bright);
}
.roster-section-head--human h2 { color: #7af5ff; }
.roster-section-head--bot   h2 { color: var(--brass-bright); }
.roster-section-head p {
  margin: 0 0 0.6rem;
  font-size: 0.75rem;
  color: var(--ivory-dim);
  letter-spacing: 0.02em;
}
.roster-section-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.75rem;
}
.roster-pick__worth {
  font-size: 0.7rem;
  color: var(--brass-bright);
  font-variant-numeric: tabular-nums;
  margin-top: 1px;
}
.roster-pick {
  position: relative;
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(217,176,106,0.18);
  border-radius: 14px;
  padding: 0.85rem 0.7rem 0.7rem;
  display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
  cursor: pointer;
  transition: transform .15s, border-color .15s, box-shadow .15s, background .15s;
  color: var(--ivory);
  font-family: var(--font-body);
}
.roster-pick--reserved { border-color: rgba(122,245,255,0.25); }
.roster-pick--bot      { border-color: rgba(241,207,131,0.25); }
.roster-pick__badge {
  position: absolute;
  top: 4px; right: 4px;
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  padding: 1px 5px;
  border-radius: 999px;
  pointer-events: none;
}
.roster-pick__badge--bot {
  background: rgba(241,207,131,0.18);
  color: var(--brass-bright);
  border: 1px solid rgba(241,207,131,0.45);
}
.roster-pick__badge--human {
  background: rgba(122,245,255,0.12);
  color: #7af5ff;
  border: 1px solid rgba(122,245,255,0.4);
}
.roster-pick:hover {
  transform: translateY(-3px);
  border-color: var(--brass-bright);
  background: rgba(217,176,106,0.1);
  box-shadow: 0 8px 22px rgba(0,0,0,0.5);
}
.roster-pick__avatar {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: rgba(0,0,0,0.4);
  border: 2px solid rgba(217,176,106,0.4);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.roster-pick__avatar svg { width: 100%; height: 100%; display: block; }
.roster-pick__nick {
  font-weight: 700;
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  text-align: center;
  word-break: break-word;
}
.roster-pick__chips {
  font-size: 0.78rem;
  color: var(--brass-bright);
  font-variant-numeric: tabular-nums;
}

/* legacy login screen kept for backward-compat; harmless if unused */
.screen[data-show-on="login"] {
  align-items: center; justify-content: center; padding: 1.5rem;
}

/* ===== Confirm + avatar screen ===== */
.screen[data-show-on="confirm"] {
  align-items: center; justify-content: center; padding: 2rem 1.5rem;
  overflow-y: auto;
}
.card.confirm-card {
  width: min(760px, 100%);
  padding: 2rem;
  max-height: calc(100vh - 4rem);
  display: flex; flex-direction: column;
}
.confirm-card__head { text-align: center; margin-bottom: 1.25rem; }
.confirm-card__head .brand { font-size: 1.7rem; }
.confirm-card__head .brand span { color: var(--ivory); }
.confirm-avatar-big {
  width: 120px; height: 120px;
  border-radius: 50%;
  background: rgba(0,0,0,0.4);
  border: 2px solid rgba(217,176,106,0.55);
  margin: 0 auto 1.25rem;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 4px rgba(241,207,131,0.08), var(--shadow-soft);
}
.confirm-avatar-big svg { width: 100%; height: 100%; }
.confirm-card__actions {
  margin-top: 1.4rem;
  display: flex; gap: 0.5rem; justify-content: space-between;
}
.confirm-card__actions .btn--primary { flex: 1; }
.card {
  background: linear-gradient(180deg, rgba(20,32,25,0.9), rgba(13,22,16,0.95));
  border: 1px solid rgba(217,176,106,0.18);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 2rem;
  width: min(440px, 100%);
  backdrop-filter: blur(8px);
}
.login-card__head { text-align: center; margin-bottom: 1.5rem; }
.brand {
  font-family: var(--font-display);
  font-size: 2.4rem;
  letter-spacing: 0.18em;
  margin: 0;
  color: var(--brass-bright);
  text-shadow: 0 2px 12px rgba(255, 200, 100, 0.18);
}
.subtitle { margin: 0.25rem 0 0; color: var(--ivory-dim); font-size: 0.85rem; letter-spacing: 0.08em; text-transform: uppercase; }
.field { display: block; margin-bottom: 1.25rem; }
.field__label {
  display: block;
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ivory-dim);
  margin-bottom: 0.5rem;
}
.field input[type="text"] {
  width: 100%;
  padding: 0.7rem 0.85rem;
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(245,236,214,0.15);
  border-radius: var(--radius-btn);
  color: var(--ivory);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.field input[type="text"]:focus {
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(217,176,106,0.18);
}
.avatar-search {
  display: flex; align-items: center; gap: 0.75rem;
  margin-bottom: 0.6rem;
}
.avatar-search input {
  flex: 1;
  padding: 0.55rem 0.75rem;
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(245,236,214,0.18);
  border-radius: var(--radius-btn);
  color: var(--ivory);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.avatar-search input:focus {
  border-color: var(--brass);
  box-shadow: 0 0 0 3px rgba(217,176,106,0.18);
}
.avatar-search__count {
  font-size: 0.75rem;
  color: var(--ivory-dim);
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.avatar-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 0.5rem;
  max-height: 52vh;
  overflow-y: auto;
  padding: 0.25rem 0.5rem 0.5rem 0.25rem;
  /* subtle scrollbar */
}
.avatar-grid::-webkit-scrollbar { width: 8px; }
.avatar-grid::-webkit-scrollbar-track { background: transparent; }
.avatar-grid::-webkit-scrollbar-thumb { background: rgba(217,176,106,0.25); border-radius: 4px; }
.avatar-pick {
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(245,236,214,0.1);
  border-radius: 10px;
  display: flex; flex-direction: column; align-items: center; gap: 0.25rem;
  cursor: pointer;
  transition: transform .15s, border-color .15s, box-shadow .15s;
  padding: 6px 6px 8px;
  overflow: hidden;
}
.avatar-pick svg { width: 100%; height: 100%; display: block; }
.avatar-pick:hover { transform: translateY(-2px); border-color: var(--brass); }
.avatar-pick[aria-checked="true"] {
  border-color: var(--brass-bright);
  box-shadow: 0 0 0 3px rgba(241,207,131,0.35), 0 4px 12px rgba(0,0,0,0.4);
  transform: translateY(-2px);
}
/* Token-pick variant: square art on top, name label below. */
.avatar-pick--token {
  position: relative;
  border-radius: 12px;
}
.avatar-pick--token .avatar-img {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
  object-fit: cover;
  background: rgba(0,0,0,0.5);
}
.avatar-pick__label {
  font-size: 0.66rem;
  letter-spacing: 0.02em;
  color: var(--ivory);
  text-align: center;
  line-height: 1.15;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.avatar-pick__sub {
  font-size: 0.58rem;
  letter-spacing: 0.02em;
  color: var(--ivory-dim);
  text-align: center;
  line-height: 1.1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.avatar-pick__pcbadge {
  position: absolute;
  top: 4px; left: 4px;
  font-size: 0.55rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  padding: 1px 4px;
  background: linear-gradient(180deg, var(--brass-bright), var(--brass));
  color: #2a1a05;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
/* Villain variant — crimson instead of brass. */
.avatar-pick__pcbadge--villain {
  background: linear-gradient(180deg, #b34141, #7a1f1f);
  color: #ffe5e5;
}
/* Named NPC variant — verdant green (allied / non-antagonist). */
.avatar-pick__pcbadge--npc {
  background: linear-gradient(180deg, #6db15a, #2e5a25);
  color: #eaffe1;
}
.avatar-pick__more {
  grid-column: 1 / -1;
  text-align: center;
  font-size: 0.78rem;
  color: var(--ivory-dim);
  padding: 0.5rem;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 0.4rem;
  padding: 0.7rem 1.2rem;
  border-radius: var(--radius-btn);
  border: 1px solid transparent;
  cursor: pointer;
  font-weight: 600;
  letter-spacing: 0.04em;
  transition: transform .12s, box-shadow .15s, background .15s, border-color .15s;
  background: rgba(255,255,255,0.05);
  color: var(--ivory);
  box-shadow: var(--shadow-soft);
}
.btn:hover:not(:disabled) { transform: translateY(-1px); }
.btn:active:not(:disabled) { transform: translateY(0); }
.btn:disabled { opacity: 0.4; cursor: not-allowed; box-shadow: none; }
.btn--sm { padding: 0.35rem 0.8rem; font-size: 0.8rem; }
.btn--primary {
  background: linear-gradient(180deg, var(--brass-bright), var(--brass));
  color: #2c1d05;
  border-color: rgba(255,255,255,0.18);
}
.btn--accent {
  background: linear-gradient(180deg, #ffaa66, var(--accent));
  color: #2b1505;
}
.btn--danger {
  background: linear-gradient(180deg, #ff7373, var(--danger));
  color: #2b0707;
}
.btn--ghost {
  background: rgba(255,255,255,0.05);
  border-color: rgba(245,236,214,0.16);
}
#joinBtn { width: 100%; margin-top: 0.5rem; font-size: 1.05rem; padding: 0.85rem; }
.hint {
  margin: 0.6rem 0 0;
  text-align: center;
  font-size: 0.8rem;
  color: var(--ivory-dim);
  min-height: 1.2em;
}
.hint.error { color: var(--danger); }

/* ===== Table screen ===== */
.screen[data-show-on="table"] {
  flex-direction: column;
  height: 100vh;
}
.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.6rem 1.25rem;
  background: linear-gradient(180deg, rgba(0,0,0,0.45), rgba(0,0,0,0.15));
  border-bottom: 1px solid rgba(217,176,106,0.18);
  z-index: 5;
}
.topbar__brand { flex: 0 0 auto; }
/* Blind-support toggle pinned beside the title (first tab stop). */
.topbar__blind { flex: 0 0 auto; margin-left: 0.5rem; white-space: nowrap; }
.topbar__blind.is-active { color: #ffe9a8; background: linear-gradient(180deg, rgba(180,120,30,0.55), rgba(120,70,10,0.65)); border-color: rgba(241,207,131,0.7); }
.topbar__me    { flex: 0 0 auto; }
/* Management actions (Sit out, Switch, Leave, Reset, +Bot, Pick AI) collapse
   into a single ≡ dropdown at ALL widths — keeps the topbar uncluttered on
   desktop too, not just on phones. Anchored to the bottom-right of the
   per-player .topbar__me block (which is position:relative). */
.topbar__menu {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  z-index: 70;
  flex-direction: column;
  align-items: stretch;
  gap: 0.3rem;
  margin-top: 0.3rem;
  padding: 0.5rem;
  background: linear-gradient(180deg, rgba(20,24,18,0.97), rgba(10,14,10,0.99));
  border: 1px solid rgba(217,176,106,0.4);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.7);
  min-width: 170px;
}
.topbar__menu.is-open { display: flex; }
.topbar__menu .btn { width: 100%; min-height: 34px; text-align: left; }
.topbar__menu-toggle { display: inline-flex; }
/* The clock sits in the middle and absorbs slack. */
.topbar__clock { flex: 1 1 auto; max-width: 420px; margin: 0 auto; }
/* Spectator list sits immediately right of the clock, before the
   per-player .topbar__me block. flex:0 0 auto so it shrinks to its
   content; max-width caps it so a busy room can't push everything else
   off the bar — overflowed names are revealed via the title tooltip. */
.topbar__spectators {
  flex: 0 1 auto;
  max-width: 320px;
  margin: 0 8px;
  padding: 3px 10px;
  display: flex;
  align-items: center;
  gap: 4px;
  background: linear-gradient(180deg, rgba(0,0,0,0.4), rgba(0,0,0,0.55));
  border: 1px solid rgba(241,207,131,0.18);
  border-radius: 999px;
  color: var(--ivory-dim);
  font-size: 0.78rem;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  user-select: none;
}
.topbar__spectators::before {
  content: '👁';
  margin-right: 2px;
  opacity: 0.7;
  flex: 0 0 auto;
}
/* Each watcher = a small token + their name. */
.topbar__spec-chip {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 7px 1px 1px;
  background: rgba(241,207,131,0.10);
  border: 1px solid rgba(241,207,131,0.18);
  border-radius: 999px;
}
.topbar__spec-token { flex: 0 0 auto; width: 22px; height: 22px; display: inline-flex; }
.topbar__spec-token svg, .topbar__spec-token img {
  width: 22px; height: 22px; border-radius: 50%; object-fit: cover;
  border: 1px solid rgba(241,207,131,0.3);
}
.topbar__spec-name {
  font-size: 0.72rem; color: var(--ivory-dim);
  max-width: 90px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Names-only fallback when the chips don't fit — plain comma-joined text. */
.topbar__spectators--names { display: block; }
.topbar__brand {
  font-family: var(--font-display);
  letter-spacing: 0.22em;
  color: var(--brass-bright);
  font-size: 1.1rem;
}
.topbar__me {
  display: flex; align-items: center; gap: 0.6rem;
  font-size: 0.9rem;
  position: relative;   /* anchor for the ≡ options dropdown */
}

/* ===== Topbar digital countdown clock ===== */
/* Topbar clock is now a horizontal row of cells (action + divider +
   hand-timer). Each cell stacks its own label above its digits.
   `justify-content: space-between` anchors the action cell to the
   left edge and the hand-timer cell to the right edge of the
   clock window; the divider floats in the middle gap. */
.topbar__clock {
  display: flex; flex-direction: row; align-items: stretch;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 11px;
  background: linear-gradient(180deg, rgba(0,0,0,0.55), rgba(0,0,0,0.7));
  border: 1px solid rgba(241,207,131,0.25);
  border-radius: 10px;
  min-width: 168px;
  user-select: none;
}
.topbar__clock-cell {
  display: flex; flex-direction: column;
  gap: 2px;
  /* Pin the cell width so the digits stay rock-still regardless of
     the label's length. Long labels like
     "Storgrim Thunderbeard · auto-fold in" used to expand the cell,
     re-centering the digits and making them jump every few seconds.
     Action cell hugs LEFT (it's anchored to the left edge of the
     clock), so label + digits left-justify within it. */
  align-items: flex-start;
  min-width: 212px;
}
.topbar__clock-cell--hand {
  /* Hand-timer cell hugs RIGHT (anchored to the right edge), so
     label + digits right-justify within it. Smaller min-width
     because the label is fixed "HAND TIMER" and the digits are mm:ss. */
  align-items: flex-end;
  min-width: 84px;
}
/* Label truncates rather than expanding the cell. */
.topbar__clock-label {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Lock the digits container width too — without this, the SVG
   group still re-centers slightly when minutes tick over. */
.topbar__clock-digits,
.topbar__clock-hand {
  min-width: 88px;
  justify-content: center;
}
.topbar__clock-label {
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ivory-dim);
  font-variant-numeric: tabular-nums;
}
/* Legacy wrapper, no longer used after the two-cell refactor.
   Kept defined so old cached HTML doesn't break layout. */
.topbar__clock-row {
  display: flex; align-items: center;
  gap: 10px;
  line-height: 1;
}
/* Hand-timer label uses the same style as the action label, just
   always brass (matches the brass digits) rather than mode-driven. */
.topbar__clock-label--hand { color: var(--brass) !important; }
.topbar__clock-digits {
  display: inline-flex; gap: 6px; align-items: center;
  line-height: 1;
}
.topbar__clock-digits svg { display: block; }
.topbar__clock-divider {
  width: 1px;
  align-self: stretch;
  background: rgba(241,207,131,0.45);
  margin: 4px 2px;
}
/* Hand-elapsed: same SVG digits as the action timer for size + font
   consistency. Different color (brass) so the two halves are visually
   distinct — action timer takes its color from .topbar__clock data-mode
   (brass-bright / red / cyan); hand-elapsed is always brass. */
.topbar__clock-hand {
  display: inline-flex; gap: 6px; align-items: center;
  line-height: 1;
}
.topbar__clock-hand svg { display: block; }
/* Need same specificity as the data-mode color rules above
   (.topbar__clock[data-mode=…]) so this isn't overridden. */
.topbar__clock[data-mode="action"]  .topbar__clock-hand,
.topbar__clock[data-mode="urgent"]  .topbar__clock-hand,
.topbar__clock[data-mode="next"]    .topbar__clock-hand,
.topbar__clock[data-mode="idle"]    .topbar__clock-hand { color: var(--brass); }
/* Mode-driven colors. Style the SVG segments via currentColor below.
   Action mode = bright blue so it visually contrasts with the always-
   brass hand-timer cell. Urgent (last 10s) still pulses red. */
.topbar__clock[data-mode="action"]  { color: #6db4ff; border-color: rgba(109,180,255,0.55); }
.topbar__clock[data-mode="action"] .topbar__clock-label { color: #6db4ff; }
.topbar__clock[data-mode="urgent"]  {
  color: #ff8888;
  border-color: var(--danger);
  animation: clockPulse 0.7s ease-in-out infinite;
}
.topbar__clock[data-mode="urgent"] .topbar__clock-label { color: #ffd9d9; }
.topbar__clock[data-mode="next"]    { color: #7af5ff; border-color: rgba(122, 245, 255, 0.45); }
.topbar__clock[data-mode="next"] .topbar__clock-label { color: #7af5ff; }
.topbar__clock[data-mode="idle"]    { color: rgba(245,236,214,0.35); }
.topbar__clock[data-mode="idle"] .topbar__clock-label { color: var(--ivory-dim); }
@keyframes clockPulse {
  0%,100% { transform: scale(1); }
  50%     { transform: scale(1.03); }
}
/* 7-segment digit SVG: drive the "on" segments via currentColor and the
   "off" ones via a dim tone of the same hue so the inactive segments
   are visible (like a real LED clock). */
.topbar__clock-digit-seg-on  { fill: currentColor; filter: drop-shadow(0 0 4px currentColor); }
.topbar__clock-digit-seg-off { fill: currentColor; opacity: 0.08; }
.me-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(217,176,106,0.4);
  overflow: hidden;
}
.me-avatar svg { width: 100%; height: 100%; }
.me-nick { font-weight: 600; }
/* Stack the nick + pronoun dropdown vertically so they sit as one
   block in the topbar. The select reads subtly underneath the
   nickname — small, ivory-dim, no chrome. */
.me-name-col { display: inline-flex; flex-direction: column; align-items: flex-start; line-height: 1.1; }
.me-gender {
  margin-top: 1px;
  background: transparent;
  border: none;
  color: var(--ivory-dim);
  font-size: 0.68rem;
  font-family: inherit;
  padding: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}
.me-gender:hover { color: var(--ivory); }
.me-gender:focus { outline: 1px solid rgba(217,176,106,0.5); outline-offset: 1px; }
/* "↺ Reset to Lv 1" — a bounded destructive action; tinted + bordered so it reads as
   a real button, not just another label. VoiceOver finds it via its aria-label. */
.me-reset {
  color: #cc7755;
  border: 1px solid rgba(204,119,85,0.45);
  border-radius: 5px;
  padding: 0 5px;
  margin-left: 4px;
}
.me-reset:hover { color: #e8906a; border-color: rgba(232,144,106,0.7); background: rgba(204,119,85,0.10); }
/* Burnt-orange cue: a non-proficient weapon is selected (−4 to hit). Applies to
   the closed weapon <select> and to the non-proficient <option>s themselves. */
.me-weapon.is-nonprof { color: #cc5500; }
.me-weapon.is-nonprof:hover { color: #e06a14; }
option.weapon-nonprof { color: #cc5500; }
/* Dropdown options need a dark background so they're readable
   against the page (browser default is white on most engines). */
.me-gender option {
  background: #14201a;
  color: var(--ivory);
}
.me-chips {
  color: var(--brass-bright);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

/* Screen-reader-only — visually hidden but read by assistive tech.
   Standard a11y pattern; used for invisible <label>s and other text
   that exists purely to give SR users context the visual UI conveys
   through layout/colour. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ===== Audio settings hover popover (off the volume button) =====
   Same pattern as the .me-purse Abadar popover. Wrapper is a span
   that contains both the visible mute button and a hidden popover
   div; :hover / :focus-within / .is-open reveal the popover. */
.audio-menu {
  position: relative;
  display: inline-flex;
  align-items: center;
  outline: none;
}
.audio-menu__pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 240px;
  max-width: 300px;
  background: linear-gradient(180deg, rgba(20,24,18,0.97), rgba(10,14,10,0.99));
  border: 1px solid rgba(217,176,106,0.4);
  border-radius: 10px;
  padding: 10px 12px 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.7);
  display: none;   /* fully out of the accessibility tree when closed (VoiceOver sees nothing) */
  opacity: 0;
  pointer-events: none;
  /* visibility:hidden (not just opacity) so the closed menu's controls leave the
     ACCESSIBILITY TREE — otherwise VoiceOver reads every slider/link/menu item
     even while the menu is visually closed. visibility still transitions. */
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s ease;
  z-index: 50;
  color: var(--ivory);
  font-size: 0.82rem;
  line-height: 1.4;
  text-align: left;
}
/* NOTE: NO :focus-within (it trapped keyboard/VoiceOver focus) and — since the
   Josh VoiceOver pass — NO :hover either: hover-open meant the panel could
   appear/vanish under the VO cursor (mouse drift), stranding it on content
   that just went invisible and blinding the macOS Item Chooser. The menu now
   opens ONLY on an explicit click/Enter (.is-open, a true disclosure with
   aria-expanded) and is display:none when closed — completely out of the
   accessibility tree, zero clutter. Esc/outside-click closes it. */
.audio-menu.is-open .audio-menu__pop {
  display: block;
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transform: translateY(0);
}
.audio-menu__row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  cursor: pointer;
  user-select: none;
}
/* Dev/reference page links inside the settings popover. */
.audio-menu__link { text-decoration: none; color: var(--ivory); border-radius: 6px; padding: 4px 6px; }
.audio-menu__link:hover { background: rgba(217,176,106,0.16); color: var(--brass-bright); }
/* Sub-group header inside the audio popover (e.g. "Combat sounds"). */
.audio-menu__grouphdr {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid rgba(245, 236, 214, 0.12);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
}
.audio-menu__row input[type="checkbox"] {
  width: 14px;
  height: 14px;
  cursor: pointer;
  accent-color: var(--brass);
}
/* Volume slider row sits just under the matching checkbox. The range
   input fills the available width; the percentage chip on the right
   provides numeric feedback so the user can tell exactly where they've
   set the level even on a small slider. */
.audio-menu__slider {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 2px 0 6px 22px; /* indent under the checkbox column */
}
.audio-menu__slider input[type="range"] {
  flex: 1 1 auto;
  height: 4px;
  accent-color: var(--brass);
  cursor: pointer;
}
.audio-menu__val {
  flex: 0 0 auto;
  width: 36px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 0.74rem;
  color: var(--ivory-dim);
}
.audio-menu__foot {
  font-size: 0.72rem;
  color: var(--ivory-dim);
  margin: 8px 0 0;
  padding-top: 6px;
  border-top: 1px solid rgba(217,176,106,0.12);
  line-height: 1.35;
}

/* ===== Blind-mode indicator chip =====
   Tiny topbar pill that lights up when blind support is active so a
   sighted helper (or Josh himself, via TTS) can confirm the mode.
   .is-listening pulses while the PTT mic is open. */
/* Blind-mode toggle button (in the mobile options menu) — lit amber when on,
   matching the 🦮 Blind status chip so its active state reads at a glance. */
#blindModeBtn.is-active {
  color: #ffe9a8;
  background: linear-gradient(180deg, rgba(180,120,30,0.55), rgba(120,70,10,0.65));
  border-color: rgba(241,207,131,0.7);
}

.blind-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: #ffe9a8;
  background: linear-gradient(180deg, rgba(180,120,30,0.55), rgba(120,70,10,0.65));
  border: 1px solid rgba(241,207,131,0.6);
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
}
.blind-chip.is-listening {
  background: linear-gradient(180deg, rgba(220,90,90,0.7), rgba(140,40,40,0.8));
  border-color: rgba(255,150,150,0.85);
  animation: blindMicPulse 0.9s ease-in-out infinite;
}
@keyframes blindMicPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,90,90,0.45); }
  50%      { box-shadow: 0 0 0 6px rgba(255,90,90,0.0); }
}

/* ===== Abadar-bank hover popover (off the chips badge) ===== */
/* The .me-purse wrapper holds the visible chips badge + a chevron +
   the hidden popover. Hovering the wrapper (or focusing it, or
   adding .is-open via tap on touch) reveals the popover. */
.me-purse {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  border-radius: 6px;
  cursor: default;
  outline: none;
}
.me-purse:hover, .me-purse:focus-within, .me-purse.is-open {
  background: rgba(217,176,106,0.08);
}
.me-purse__chev {
  font-size: 0.65rem;
  color: var(--brass);
  opacity: 0.7;
  transition: transform 0.15s ease;
}
.me-purse:hover .me-purse__chev,
.me-purse:focus-within .me-purse__chev,
.me-purse.is-open .me-purse__chev { transform: rotate(180deg); }
.me-purse__pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  min-width: 260px;
  max-width: 320px;
  background: linear-gradient(180deg, rgba(20,24,18,0.97), rgba(10,14,10,0.99));
  border: 1px solid rgba(217,176,106,0.4);
  border-radius: 10px;
  padding: 10px 12px 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.7);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-4px);
  transition: opacity 0.12s ease, transform 0.12s ease;
  z-index: 50;
  color: var(--ivory);
  font-size: 0.82rem;
  line-height: 1.4;
  font-weight: 400;
  text-align: left;
}
.me-purse:hover .me-purse__pop,
.me-purse:focus-within .me-purse__pop,
.me-purse.is-open .me-purse__pop {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}
.purse__head {
  font-family: var(--font-display);
  letter-spacing: 0.12em;
  font-size: 0.85rem;
  color: var(--brass-bright);
  margin-bottom: 8px;
  border-bottom: 1px solid rgba(217,176,106,0.18);
  padding-bottom: 6px;
}
.purse__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 2px 0;
  font-variant-numeric: tabular-nums;
}
.purse__row--debt { color: #ffb874; font-weight: 600; }
.purse__row--clear { color: var(--success); }
.purse__actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 10px 0 6px;
}
.purse__btn {
  background: linear-gradient(180deg, rgba(217,176,106,0.18), rgba(217,176,106,0.08));
  border: 1px solid rgba(217,176,106,0.45);
  color: var(--ivory);
  font: inherit;
  font-weight: 600;
  padding: 7px 10px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.1s ease;
}
.purse__btn:hover { background: linear-gradient(180deg, rgba(217,176,106,0.28), rgba(217,176,106,0.14)); }
.purse__btn:disabled { opacity: 0.4; cursor: not-allowed; }
.purse__btn--max {
  border-color: var(--brass);
  background: linear-gradient(180deg, rgba(241,207,131,0.28), rgba(217,176,106,0.14));
}
/* Spectate the dungeon — full-width, lit cool blue (a watcher's chair). */
.purse__btn--spectate {
  width: 100%;
  border-color: rgba(120,160,210,0.5);
  background: linear-gradient(180deg, rgba(80,120,190,0.24), rgba(50,80,130,0.14));
}
.purse__btn--spectate:hover { background: linear-gradient(180deg, rgba(100,150,210,0.34), rgba(60,100,150,0.2)); }
/* Re-buy: full-width money action, lit slightly green (a fresh stack). */
.purse__btn--rebuy {
  width: 100%;
  border-color: rgba(120,190,130,0.5);
  background: linear-gradient(180deg, rgba(90,170,110,0.24), rgba(60,120,80,0.14));
}
.purse__btn--rebuy:hover { background: linear-gradient(180deg, rgba(110,200,130,0.34), rgba(70,140,90,0.2)); }
.purse__hint {
  font-size: 0.78rem;
  color: var(--ivory-dim);
  font-style: italic;
  margin: 6px 0;
}
.purse__foot {
  font-size: 0.72rem;
  color: var(--ivory-dim);
  line-height: 1.35;
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px solid rgba(217,176,106,0.12);
}

/* Red dot in the leaderboard for indebted players. Visible to everyone,
   but the tooltip only shows the precise amount for the indebted user
   themselves. */
.lb__debt {
  display: inline-block;
  margin-left: 4px;
  color: #ff5252;
  font-size: 0.7em;
  text-shadow: 0 0 4px rgba(255,82,82,0.6);
  vertical-align: 0.1em;
}

.table-wrap {
  flex: 1;
  position: relative;
  display: flex; align-items: center; justify-content: center;
  gap: 1rem;
  /* Zero bottom padding so the chat log butts directly against the
     bottom edge of the felt. The legacy 120px gap was reserved for the
     actpanel popover, but bottom-seat panels now flip upward
     (`.seat--bottom .actpanel { bottom: calc(100% + 6px) }`) so the
     popover never extends below the felt and the gap is dead space. */
  padding: 1rem 1rem 0;
  min-height: 0;
}
.felt-col { display: contents; }  /* reserved for future grouping */
/* The reference asides come AFTER the felt in the DOM (so the felt's seats +
   action panel lead the tab order for keyboard/screen-reader play); flex `order`
   pulls them back to the left / right visually. */
.help-panel--left  { order: -1; }
.felt              { order: 0; }
.help-panel--right { order: 1; }

/* Top-center action-timer banner — whose turn + their countdown, at a glance. */
.action-timer {
  position: fixed; top: 8px; left: 50%; transform: translateX(-50%);
  z-index: 70; pointer-events: none;
  display: flex; align-items: baseline; gap: 10px; white-space: nowrap;
  padding: 4px 18px; border-radius: 999px;
  background: rgba(8, 12, 9, 0.82); border: 1.5px solid rgba(217,176,106,0.45);
  box-shadow: 0 6px 20px rgba(0,0,0,0.6);
  font-family: 'Bebas Neue', system-ui, sans-serif; letter-spacing: 0.05em;
  color: var(--ivory);
}
.action-timer[hidden] { display: none; }
.action-timer .at-who  { font-size: 1.05rem; color: var(--ivory-dim); text-transform: uppercase; }
.action-timer .at-secs { font-size: 1.5rem; font-weight: 800; color: var(--brass-bright); }
.action-timer[data-mode="action"] { border-color: var(--brass-bright); }
.action-timer[data-mode="next"]   { border-color: #4fb8c9; }
.action-timer[data-mode="next"] .at-secs { color: #9fe8f3; }
.action-timer[data-mode="urgent"] { border-color: #e25555; animation: at-pulse 1s ease-in-out infinite; }
.action-timer[data-mode="urgent"] .at-secs { color: #ff8a8a; }
@keyframes at-pulse { 0%,100% { box-shadow: 0 0 0 0 rgba(226,85,85,0.45); } 50% { box-shadow: 0 0 14px 4px rgba(226,85,85,0.55); } }

/* × dismiss button on an AI party member's card (dungeon kick). Bottom-left so it
   clears the buff icons (top-left) and the AC badge (bottom-right). */
.dpc__remove {
  position: absolute; bottom: 3px; left: 4px; z-index: 7;
  width: 18px; height: 18px; padding: 0; line-height: 15px;
  border-radius: 50%; border: 1px solid rgba(226,85,85,0.6);
  background: rgba(40,10,10,0.7); color: #ff9a9a;
  font-size: 0.85rem; cursor: pointer; opacity: 0.5; transition: opacity .12s ease, background .12s ease;
}
.dpc__remove:hover, .dpc__remove:focus-visible { opacity: 1; background: rgba(120,20,20,0.92); color: #fff; }

/* ===== Perimeter help panels ===== */
.help-panel {
  width: 240px;
  align-self: stretch;
  background: linear-gradient(180deg, rgba(20,32,25,0.7), rgba(13,22,16,0.8));
  border: 1px solid rgba(217,176,106,0.18);
  border-radius: 14px;
  padding: 0.9rem 1rem;
  overflow-y: auto;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ivory-dim);
  box-shadow: var(--shadow-soft);
  /* So tall content scrolls inside without forcing the page to grow */
  max-height: calc(100vh - 6rem);
}
.help-panel__title {
  margin: 0 0 0.45rem;
  font-family: var(--font-display);
  letter-spacing: 0.16em;
  color: var(--brass-bright);
  font-size: 0.92rem;
  font-weight: 400;
}
.help-panel__title:not(:first-child) {
  margin-top: 1.1rem;
  padding-top: 0.7rem;
  border-top: 1px solid rgba(217,176,106,0.18);
}
.help-panel__list { margin: 0; padding: 0; display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 0.6rem; }
.help-panel__list dt { grid-column: 1; }
.help-panel__list dd { grid-column: 2; margin: 0; }
.help-panel__list--compact { gap: 0.25rem 0.6rem; }
.help-key {
  display: inline-block;
  background: rgba(217,176,106,0.12);
  border: 1px solid rgba(217,176,106,0.35);
  color: var(--brass-bright);
  border-radius: 5px;
  padding: 0 6px;
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.help-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px;
  background: linear-gradient(180deg, var(--brass-bright), var(--brass));
  color: #2a1a05;
  border-radius: 999px;
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.04em;
}
.help-panel__rankings { list-style: none; counter-reset: rk; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.help-panel__rankings li { counter-increment: rk; padding-left: 1.6rem; position: relative; color: var(--ivory); }
.help-panel__rankings li::before {
  content: counter(rk);
  position: absolute; left: 0; top: 0;
  width: 1.2rem; height: 1.2rem;
  background: rgba(217,176,106,0.12);
  border: 1px solid rgba(217,176,106,0.3);
  color: var(--brass-bright);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.65rem;
  font-weight: 700;
}
.help-panel__rankings em {
  display: block;
  font-style: normal;
  color: var(--ivory-dim);
  font-size: 0.7rem;
  margin-top: 1px;
}
.help-panel__flow { list-style: none; padding: 0; margin: 0; counter-reset: flow; }
.help-panel__flow li { counter-increment: flow; padding-left: 1.4rem; position: relative; margin: 0 0 0.3rem; }
.help-panel__flow li::before {
  content: counter(flow) ".";
  position: absolute; left: 0; color: var(--brass-bright); font-weight: 700;
}
.help-panel__tips { list-style: none; padding: 0; margin: 0; }
.help-panel__tips li { padding-left: 1rem; position: relative; margin: 0 0 0.35rem; }
.help-panel__tips li::before { content: "→"; position: absolute; left: 0; color: var(--brass); }

@media (max-width: 1400px) {
  .help-panel { display: none; }
}
.felt {
  /* Fill the 16:9 screen: grow until EITHER the horizontal room or the vertical
     room runs out. (The old hard 1100px cap left ~200px of dead band above and
     below the felt on a 1080p display.) The height-derived term keeps the
     1.85:1 oval from overflowing the area between the topbar and the chat log. */
  width: min(1480px, 100%, calc((100vh - 170px) * 1.85));
  aspect-ratio: 1.85 / 1;
  max-height: 100%;
  border-radius: 50% / 35%;
  background: var(--felt);
  border: 14px solid;
  border-image: var(--rail) 1;
  border-image-slice: 1;
  position: relative;
  box-shadow:
    inset 0 0 80px rgba(0,0,0,0.55),
    inset 0 0 10px rgba(255,255,255,0.05),
    0 30px 80px rgba(0,0,0,0.6);
}
.center {
  position: absolute;
  inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.45rem;
  pointer-events: none;
}
.board {
  display: flex; gap: 0.55rem;
  min-height: 150px;
  pointer-events: auto;
}
/* Card aspect ratio = 70 / 106 (matches the Shackles back-art PNG —
   v3 at 929×1409 = 0.659). We set width and let aspect-ratio derive
   the height so every card slot stays in sync without us having to
   edit a dozen pixel pairs. Re-aspect the whole deck by tweaking
   --card-aspect in one place. */
:root { --card-aspect: 70 / 106; }
.card-svg { width: 92px; aspect-ratio: var(--card-aspect); display: block; filter: drop-shadow(0 5px 10px rgba(0,0,0,0.5)); transition: transform .25s; }
.card-svg--back { filter: drop-shadow(0 4px 8px rgba(0,0,0,0.6)); }
.card-svg--empty { opacity: 0.5; }
.board .card-svg { animation: dealIn .35s ease-out both; }
@keyframes dealIn { from { opacity: 0; transform: translateY(-12px) rotate(-6deg); } to { opacity: 1; transform: none; } }
/* ── Card-dealing animation overlay ──────────────────────────────────
   Full-felt layer that hosts the in-flight card backs pitched from the
   dealer to each seat at the start of a hand. Sits above the seat plates
   (z 1–4) but below banners/modals. pointer-events:none so it's purely
   visual and never intercepts clicks. Cards are positioned + animated in
   JS (Web Animations API) from client.js. */
.deal-overlay {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 6;
}
.deal-card {
  position: absolute;
  width: 34px;
  will-change: transform, opacity;
  filter: drop-shadow(0 6px 10px rgba(0,0,0,0.55));
}
.deal-card .card-svg { width: 100%; height: auto; display: block; }
@media (prefers-reduced-motion: reduce) {
  /* JS already skips the animation; this is belt-and-suspenders so any
     stray flying card can't linger or move for motion-sensitive users. */
  .deal-overlay { display: none; }
}

.seat__hole {
  display: flex; gap: 3px; margin-top: 4px; justify-content: center;
}
/* During the deal, an in-hand seat's hole cards start hidden (card--predeal)
   and fade in the moment their flying card lands — so they "land in position"
   rather than being there the whole time under the animation. */
.seat__hole .card-svg { transition: transform .25s, opacity .22s ease-out; }
.seat__hole .card-svg.card--predeal { opacity: 0; }
/* Default = OPPONENT cards (smaller so adjacent seats don't fight for space). */
.seat__hole .card-svg { width: 34px; height: auto; }
/* My own cards stay big and gold-bordered so I can read them at a glance. */
.seat__hole .card-svg--mine {
  width: 46px; height: auto;
  box-shadow: 0 0 0 2px rgba(241,207,131,0.55);
  border-radius: 4px;
}
.seat__waiting {
  margin-top: 5px;
  padding: 4px 8px;
  background: rgba(0,0,0,0.4);
  border: 1px dashed rgba(245,236,214,0.25);
  border-radius: 6px;
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  color: var(--ivory-dim);
  text-align: center;
}
.seat__bet {
  font-size: 0.72rem;
  color: var(--brass-bright);
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
.seat__bot-tag {
  display: inline-block;
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: rgba(122, 245, 255, 0.12);
  border: 1px solid rgba(122, 245, 255, 0.35);
  color: #7af5ff;
  padding: 1px 6px;
  border-radius: 999px;
  margin-top: 1px;
}
.seat__swords {
  display: inline-block;
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  color: var(--brass-bright);
  background: rgba(241,207,131,0.08);
  border: 1px solid rgba(217,176,106,0.32);
  padding: 1px 6px;
  border-radius: 999px;
  margin-top: 1px;
  font-variant-numeric: tabular-nums;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seat__afk-tag {
  display: inline-block;
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: rgba(227, 88, 88, 0.12);
  border: 1px solid rgba(227, 88, 88, 0.4);
  color: #ff9999;
  padding: 1px 6px;
  border-radius: 999px;
  margin-top: 1px;
}
/* Tiny × in the top-left of a bot's seat plate. Lets any seated human ask
   that specific bot to leave (it actually leaves after the current hand). */
.seat__remove {
  position: absolute;
  top: -8px; left: -8px;
  width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, rgba(60,18,18,0.95), rgba(40,10,10,0.95));
  color: #ff9999;
  border: 1px solid rgba(227, 88, 88, 0.55);
  border-radius: 50%;
  font-size: 0.85rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  padding: 0;
  z-index: 4;
  box-shadow: 0 2px 6px rgba(0,0,0,0.5);
  transition: background .12s, color .12s, transform .1s, border-color .12s;
}
.seat__remove:hover {
  background: linear-gradient(180deg, rgba(227,88,88,0.9), rgba(180,40,40,0.95));
  color: #fff;
  border-color: #ffb3b3;
  transform: scale(1.1);
}
/* Attack buttons (cosmetic combat gag) — a vertical stack on the seat's
   top-right corner, hidden until the seat is hovered. */
.seat__attacks {
  position: absolute;
  top: -8px; right: -8px;
  display: flex; flex-direction: column; gap: 3px;
  opacity: 0;
  transform: scale(0.85);
  transition: opacity 0.12s ease, transform 0.12s ease;
  z-index: 6;
}
.seat:hover .seat__attacks { opacity: 1; transform: scale(1); }
.seat__fight {
  width: 22px; height: 22px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(180deg, rgba(40,46,60,0.95), rgba(24,28,40,0.96));
  color: #cfe0ff;
  border: 1px solid rgba(150,180,230,0.5);
  border-radius: 50%;
  font-size: 0.8rem; line-height: 1;
  cursor: pointer;
  transition: transform 0.1s ease, background 0.1s ease, border-color 0.1s ease;
}
.seat__fight:hover {
  background: linear-gradient(180deg, rgba(120,150,210,0.95), rgba(70,95,160,0.97));
  color: #fff; border-color: #dce8ff;
  transform: scale(1.18);
}
.seat__fight--bolt { color: #ffe27a; border-color: rgba(240,210,90,0.55); }
.seat__fight--bolt:hover { background: linear-gradient(180deg, rgba(240,210,90,0.97), rgba(190,150,30,0.97)); color: #1a1400; border-color: #fff0b0; }
.seat__fight--stink { color: #b6e39a; border-color: rgba(150,210,120,0.5); }
.seat__fight--stink:hover { background: linear-gradient(180deg, rgba(150,210,120,0.97), rgba(90,150,60,0.97)); color: #0c1a06; border-color: #d6f5c0; }
/* "Sickened" badge (failed a Stinking Cloud save) — pure flavor. */
.seat__sickened {
  position: absolute;
  bottom: -6px; left: -6px;
  font-size: 0.9rem; line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.6));
  animation: sickenedBob 1.6s ease-in-out infinite;
  z-index: 6;
}
@keyframes sickenedBob { 0%,100% { transform: translateY(0) rotate(-6deg);} 50% { transform: translateY(-2px) rotate(6deg);} }

.seat__leaving {
  display: inline-block;
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: rgba(227, 88, 88, 0.18);
  border: 1px solid rgba(227, 88, 88, 0.5);
  color: #ffb3b3;
  padding: 1px 6px;
  border-radius: 999px;
  margin-top: 1px;
}
.seat.is-afk .seat__plate { opacity: 0.55; filter: grayscale(0.35); }
.seat.is-folded .seat__plate { opacity: 0.45; filter: grayscale(0.4); }
.seat.is-acting .seat__plate {
  box-shadow: 0 0 0 2px var(--brass-bright), 0 0 20px rgba(241,207,131,0.55);
  animation: actorPulse 1.4s ease-in-out infinite;
}
@keyframes actorPulse {
  0%,100% { box-shadow: 0 0 0 2px var(--brass-bright), 0 0 14px rgba(241,207,131,0.35); }
  50%     { box-shadow: 0 0 0 2px var(--brass-bright), 0 0 26px rgba(241,207,131,0.7); }
}
.seat__badge {
  position: absolute;
  top: -8px;
  right: -8px;
  /* Silver/black (was gold) so the D/SB/BB position chips read distinctly from
     the gold AI / green human controller markers. */
  background: linear-gradient(180deg, #eef1f5, #b6bcc6);
  color: #14171c;
  border: 1px solid rgba(255,255,255,0.55);
  font-size: 0.6rem;
  font-weight: 800;
  padding: 2px 6px;
  border-radius: 999px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow: var(--shadow-soft);
}
.seat { position: absolute; z-index: 1; }
/* Bring the player's own seat + the acting seat above their neighbors so
   their plates / hole cards aren't hidden by adjacent seats on the
   crowded side rails. The acting seat additionally has its glow pulse. */
.seat.is-me      { z-index: 3; }
.seat.is-acting  { z-index: 4; }
.seat__plate { position: relative; }

/* ===== Winner banner (centered, post-hand) =====
   Shown during the SHOWDOWN / COMPLETE state (~15s before next deal)
   so the room can see exactly who won and how much. Centered over
   the felt; pointer-events:none so the board cards underneath stay
   clickable. One .hand-banner__win block per winner (side pots
   stack vertically). */
.hand-banner {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  z-index: 12;
  pointer-events: none;
  animation: winnerFadeIn 0.35s ease-out;
}
.hand-banner__inner {
  display: flex; flex-direction: column; gap: 10px;
  max-width: 92%;
}
.hand-banner__win {
  display: flex; align-items: center; gap: 20px;
  /* Padding bumped to accommodate the doubled avatar without making
     the text feel cramped against the edge. */
  padding: 22px 30px 22px 22px;
  background: linear-gradient(180deg, rgba(20,32,25,0.92), rgba(8,16,11,0.96));
  border: 2px solid var(--brass-bright);
  border-radius: 18px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.7),
              inset 0 1px 0 rgba(241,207,131,0.25),
              0 0 0 1px rgba(0,0,0,0.5);
}
/* Avatar doubled to 128px (was 64px) — only on the winner banner.
   Seat-ring avatars and the leaderboard avatars are unaffected. */
.hand-banner__avatar {
  width: 128px; height: 128px;
  flex: 0 0 128px;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(0,0,0,0.5);
  border: 3px solid var(--brass);
  box-shadow: 0 0 22px rgba(241,207,131,0.4);
}
.hand-banner__avatar img,
.hand-banner__avatar svg {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.hand-banner__text {
  display: flex; flex-direction: column; gap: 2px;
  text-align: left;
}
.hand-banner__nick {
  font-family: var(--font-display);
  font-size: 1.5rem;
  letter-spacing: 0.08em;
  color: var(--brass-bright);
  text-shadow: 0 2px 6px rgba(0,0,0,0.8);
  line-height: 1;
}
.hand-banner__amount {
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--success);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 2px 6px rgba(0,0,0,0.6);
  line-height: 1.1;
}
.hand-banner__hand {
  font-size: 0.82rem;
  color: var(--ivory-dim);
  font-style: italic;
  margin-top: 2px;
  max-width: 380px;
}
/* Winning-cards row, low→high. After the deck-wide re-aspect to
   70:111 (taller cards), 50px width gave ~80px height which made
   the winner banner balloon vertically next to the 128px avatar.
   Dropped to 46px width = ~73px height — visually matches the
   pre-aspect-change card height while keeping all five cards in a
   single neat row under the text. */
.hand-banner__cards {
  display: flex;
  gap: 4px;
  margin-top: 8px;
}
.hand-banner__cards .card-svg {
  width: 46px; height: auto;
  filter: drop-shadow(0 3px 6px rgba(0,0,0,0.55));
}
@keyframes winnerFadeIn {
  from { opacity: 0; transform: scale(0.92); }
  to   { opacity: 1; transform: scale(1); }
}
/* Mobile: smaller-but-still-doubled avatar (was 46 single, now 92 doubled)
   + tighter padding so it doesn't bury the felt. */
@media (max-width: 720px) {
  .hand-banner__win { padding: 14px 18px 14px 14px; gap: 14px; border-radius: 14px; }
  .hand-banner__avatar { width: 92px; height: 92px; flex: 0 0 92px; }
  .hand-banner__nick { font-size: 1.1rem; }
  .hand-banner__amount { font-size: 1.1rem; }
  .hand-banner__hand { font-size: 0.72rem; max-width: 240px; }
  .hand-banner__cards .card-svg { width: 32px; height: auto; }
  .hand-banner__cards { gap: 3px; margin-top: 5px; }
}

/* ===== Reset modal ===== */
.modal { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center; }
.modal__backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.65); backdrop-filter: blur(4px); }
.modal__panel {
  position: relative;
  background: linear-gradient(180deg, rgba(20,32,25,0.98), rgba(13,22,16,0.98));
  border: 1px solid rgba(217,176,106,0.32);
  border-radius: var(--radius-card);
  box-shadow: 0 24px 60px rgba(0,0,0,0.7);
  padding: 1.6rem;
  width: min(520px, 92vw);
}
.modal__title {
  margin: 0 0 0.5rem;
  font-family: var(--font-display);
  letter-spacing: 0.15em;
  color: var(--brass-bright);
  font-size: 1.4rem;
}
.modal__body { margin: 0 0 1.2rem; color: var(--ivory-dim); font-size: 0.92rem; }
.modal__choices { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 1rem; }
.modal__choice {
  text-align: left;
  padding: 0.85rem 1rem;
  flex-direction: column;
  align-items: stretch;
  gap: 0.25rem;
  font-weight: 500;
}
.modal__choice strong { font-size: 0.95rem; }
.modal__choice span { font-size: 0.78rem; opacity: 0.85; font-weight: 400; }
.modal__actions { display: flex; justify-content: flex-end; }

.actionbar { display: flex; align-items: center; justify-content: center;
  padding: 0.5rem 1rem;
  background: linear-gradient(0deg, rgba(0,0,0,0.55), rgba(0,0,0,0.2));
  border-top: 1px solid rgba(217,176,106,0.12);
}
.actionbar--wait { padding: 0.4rem 1rem; }
.actionbar__status {
  font-size: 0.82rem;
  color: var(--ivory-dim);
  letter-spacing: 0.05em;
}
.btn[data-act]:disabled { opacity: 0.3; }

/* ===== Permanent action panel (PERSISTENT — outside seat ring) =====
   Lives in #actpanelHost inside the .felt. Never destroyed by
   renderTable. Draggable; drag offset applied via --drag-x / --drag-y
   CSS variables so it composes with the centering transform. */
.seat__plate--acting { /* legacy hook, no styling needed */ }
.actpanel-host {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 25;
}
.actpanel {
  position: relative;
  pointer-events: auto;
  transform: translate(var(--drag-x, 0px), var(--drag-y, 0px));
  padding: 7px 8px;
  border-radius: 10px;
  background: linear-gradient(180deg, rgba(0,0,0,0.7), rgba(0,0,0,0.88));
  border: 1px solid rgba(241,207,131,0.5);
  box-shadow: 0 6px 22px rgba(0,0,0,0.6);
  display: flex; flex-direction: column; gap: 5px;
  min-width: 230px;
  z-index: 20;
}
/* Seats on the BOTTOM half of the ellipse: by default the panel would
   extend down and collide with the chat-log strip. Flip its anchor to
   the top of the seat plate so it sits ABOVE the avatar instead. */
.seat--bottom .actpanel {
  top: auto;
  bottom: calc(100% + 6px);
}

/* Drag handle at the top of the panel. Grab + move to put the panel
   anywhere. Double-click to reset the offset. */
.actpanel__drag {
  display: flex; align-items: center; justify-content: space-between;
  gap: 6px;
  margin: -2px -2px 2px;
  padding: 2px 4px;
  cursor: grab;
  user-select: none;
  color: var(--ivory-dim);
  border-radius: 6px;
  background: rgba(241,207,131,0.06);
}
.actpanel__drag:hover { color: var(--brass-bright); background: rgba(241,207,131,0.12); }
.actpanel.is-dragging .actpanel__drag,
.actpanel__drag:active { cursor: grabbing; }
.actpanel__drag-grip {
  font-size: 0.78rem;
  letter-spacing: 0.4em;
  line-height: 1;
}
.actpanel__drag-reset {
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ivory-dim);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 2px 4px;
}
.actpanel__drag-reset:hover { color: var(--brass-bright); }
.actpanel.is-dragging { opacity: 0.92; }
.actpanel--idle .actpanel__btn,
.actpanel--idle .actpanel__preset,
.actpanel--idle .actpanel__amount { opacity: 0.45; }
.actpanel--idle { border-color: rgba(241,207,131,0.2); }

/* ===== Action panel toggle row (🎒 Loot Bank / 🏆 Leaderboard) ===== */
.actpanel__toggles {
  display: flex; gap: 4px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgba(241,207,131,0.15);
}
.actpanel__toggle {
  flex: 1;
  padding: 4px 6px;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  background: rgba(217,176,106,0.08);
  border: 1px solid rgba(217,176,106,0.22);
  color: var(--ivory-dim);
  border-radius: 6px;
  cursor: pointer;
  text-align: center;
}
.actpanel__toggle:hover { background: rgba(217,176,106,0.18); color: var(--ivory); }
.actpanel__toggle.is-open {
  background: rgba(217,176,106,0.25);
  border-color: var(--brass);
  color: var(--brass-bright);
  font-weight: 600;
}
.actpanel__section {
  margin-top: 6px;
  max-height: 360px;
  overflow-y: auto;
  border-top: 1px solid rgba(241,207,131,0.12);
  padding-top: 6px;
}

/* ===== Gear bank (now inline inside the action panel) ===== */
.bank {
  font-size: 0.74rem;
  color: var(--ivory);
  display: flex; flex-direction: column; gap: 4px;
}
.bank__row {
  display: grid;
  grid-template-columns: 26px 1fr auto;
  grid-template-areas: "icon label tier"
                        "icon actions actions";
  gap: 2px 6px;
  padding: 6px 8px;
  background: rgba(0,0,0,0.35);
  border: 1px solid rgba(241,207,131,0.12);
  border-radius: 8px;
}
.bank__icon  { grid-area: icon; color: var(--brass-bright); align-self: center; }
.bank__label { grid-area: label; color: var(--ivory); font-weight: 600; }
.bank__tier  { grid-area: tier; font-variant-numeric: tabular-nums; align-self: center; }
.bank__tier--off { color: rgba(245,236,214,0.4); }
.bank__tier--on  { color: var(--brass-bright); font-weight: 700; }
.bank__tier--max { color: #6be0a9; font-weight: 800; }
.bank__actions {
  grid-area: actions;
  display: flex; gap: 4px;
}
.bank__btn {
  flex: 1;
  font-size: 0.66rem;
  padding: 3px 5px;
  line-height: 1.1;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid rgba(217,176,106,0.35);
  background: rgba(217,176,106,0.1);
  color: var(--ivory);
  text-align: center;
}
.bank__btn small { font-size: 0.6rem; color: var(--brass-bright); }
.bank__btn--buy:not(:disabled):hover { background: rgba(217,176,106,0.25); }
.bank__btn--sell { background: rgba(180,60,60,0.18); border-color: rgba(227,88,88,0.45); }
.bank__btn--sell small { color: #ff9999; }
.bank__btn--sell:hover { background: rgba(180,60,60,0.32); }
.bank__btn--max  { background: rgba(107,224,169,0.15); border-color: rgba(107,224,169,0.4); color: #6be0a9; }
.bank__btn:disabled { opacity: 0.4; cursor: not-allowed; }
.bank__progress {
  position: relative;
  height: 18px;
  margin-top: 4px;
  background: rgba(0,0,0,0.5);
  border: 1px solid rgba(241,207,131,0.25);
  border-radius: 9px;
  overflow: hidden;
}
.bank__progress-bar {
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(90deg, var(--brass), var(--brass-bright));
  transition: width 0.3s ease-out;
}
.bank__progress-text {
  position: absolute;
  inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  color: var(--ivory);
  text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}

/* ===== Leaderboard (inside actpanel) ===== */
.lb {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex; flex-direction: column;
  gap: 2px;
}
.lb__row {
  display: grid;
  grid-template-columns: 24px 24px 1fr auto;
  align-items: center;
  gap: 6px;
  padding: 3px 6px;
  background: rgba(0,0,0,0.3);
  border: 1px solid rgba(241,207,131,0.1);
  border-radius: 6px;
  font-size: 0.72rem;
}
.lb__row.is-me {
  background: rgba(217,176,106,0.18);
  border-color: var(--brass);
}
.lb__rank { text-align: center; font-variant-numeric: tabular-nums; }
.lb__avatar {
  width: 24px; height: 24px;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(217,176,106,0.4);
}
.lb__avatar img, .lb__avatar svg { width: 100%; height: 100%; object-fit: cover; display: block; }
.lb__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb__bot {
  font-size: 0.55rem;
  letter-spacing: 0.06em;
  padding: 0 4px;
  margin-left: 4px;
  background: rgba(122,245,255,0.12);
  color: #7af5ff;
  border-radius: 3px;
}
.lb__wealth {
  font-variant-numeric: tabular-nums;
  color: var(--brass-bright);
  font-weight: 600;
  white-space: nowrap;
}
.lb__empty {
  text-align: center;
  color: var(--ivory-dim);
  font-style: italic;
  padding: 0.8rem 0.4rem;
  list-style: none;
}

/* ===== Left-side sidebar bank (collapsible) + hand rankings ===== */
.help-panel--bank {
  display: flex;
  flex-direction: column;
  padding: 0.75rem 0.65rem;
  gap: 0.4rem;
  position: relative;   /* anchor for the paper-doll popover */
}
/* ===== Loot Bank paper-doll popover ===== */
.bank-doll {
  position: fixed; z-index: 9999;   /* float over the felt; top/left set in JS from the button */
  top: 130px; left: 16px;
  width: 300px; max-width: 92vw;
  padding: 0.6rem;
  /* Vitruvian Gaspar art behind a darkened gradient so the slot text stays legible. */
  background:
    linear-gradient(180deg, rgba(18,22,15,0.68), rgba(9,12,8,0.74)),
    url('/assets/vitruvian_gaspar.webp') center top / cover no-repeat;
  border: 1px solid rgba(217,176,106,0.5);
  border-radius: 12px;
  box-shadow: 0 14px 40px rgba(0,0,0,0.8);
}
.bank-doll__head { display: flex; justify-content: space-between; align-items: center; color: var(--brass-bright); font-weight: 700; margin-bottom: 0.5rem; }
.bank-doll__close { background: none; border: none; color: var(--ivory-dim); cursor: pointer; font-size: 0.95rem; line-height: 1; padding: 3px 7px; border-radius: 6px; }
.bank-doll__close:hover { color: var(--ivory); background: rgba(255,255,255,0.08); }
.bank-doll__grid { display: grid; grid-template-columns: 1fr auto 1fr; gap: 0.4rem; align-items: stretch; }
.bank-doll__col { display: flex; flex-direction: column; gap: 0.4rem; }
.bank-doll__figure { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; padding: 0 4px; }
.bank-doll__avatar { width: 60px; height: 60px; border-radius: 10px; overflow: hidden; border: 1px solid rgba(217,176,106,0.4); }
.bank-doll__avatar svg, .bank-doll__avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bank-doll__chips { font-size: 0.7rem; color: var(--brass-bright); white-space: nowrap; }
.bank-doll__ringrow { margin-top: 0.4rem; }
.bank-doll__ringrow .doll-slot { flex-direction: row; align-items: center; }
.bank-doll__ringrow .doll-slot__btns { flex: 1; flex-direction: row; }
.doll-slot { display: flex; flex-direction: column; gap: 3px; background: rgba(0,0,0,0.28); border: 1px solid rgba(217,176,106,0.18); border-radius: 8px; padding: 5px; }
.doll-slot__icon { position: relative; width: 30px; height: 30px; }
.doll-slot__icon svg { width: 100%; height: 100%; }
.doll-slot__tier { position: absolute; bottom: -3px; right: -5px; font-size: 0.58rem; font-weight: 700; padding: 0 3px; border-radius: 4px; background: rgba(0,0,0,0.78); }
.doll-slot__tier.is-on { color: var(--brass-bright); }
.doll-slot__tier.is-max { color: #8effa0; }
.doll-slot__tier.is-off { color: var(--ivory-dim); }
.doll-slot__label { font-size: 0.62rem; color: var(--ivory-dim); }
.doll-slot__btns { display: flex; flex-direction: column; gap: 3px; }
.doll-slot__btns .bank__btn { width: 100%; font-size: 0.6rem; padding: 3px 4px; line-height: 1.15; }
.bank-doll .bank__progress { height: 18px; margin-top: 0.5rem; }
.bank-doll .bank__progress-text { font-size: 0.64rem; }
.help-panel--bank .help-panel__title {
  flex: 0 0 auto;
  margin: 0;
}
/* Toggle button that wraps the bank title + chevron. */
/* Visibly-clickable toggle header — readable as a button so users
   know they can click it to expand/collapse the section underneath. */
.help-panel__collapser {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: rgba(217,176,106,0.08);
  border: 1px solid rgba(217,176,106,0.25);
  border-radius: 8px;
  padding: 6px 10px;
  margin: 0;
  cursor: pointer;
  color: var(--brass-bright);
  text-align: left;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.help-panel__collapser:hover {
  background: rgba(217,176,106,0.18);
  border-color: var(--brass);
}
.help-panel__collapser:hover .help-panel__chevron { color: var(--ivory); }
.help-panel__chevron {
  font-size: 0.8rem;
  color: var(--brass);
  letter-spacing: 0;
  transition: color 0.15s ease;
}
/* Bank body — grows to fit its rows naturally when expanded.
   The native [hidden] attribute handles the collapsed state. */
.sidebar-bank {
  flex: 1 1 auto;
  overflow-y: auto;
  padding-right: 2px;
}
.sidebar-bank__empty {
  margin: 1rem 0.5rem;
  font-size: 0.78rem;
  color: var(--ivory-dim);
  font-style: italic;
  text-align: center;
}
/* Slight sidebar-specific bank tweaks — the column is 240px wide so
   we tighten ONLY the gear-row label/font to avoid wrapping, but
   keep the buy/hock buttons at their full ~0.76rem so they're
   actually tappable. Previously the buttons were 0.62rem with 2px
   padding, which made the whole bank "squished and unusable". */
.sidebar-bank .bank { gap: 5px; font-size: 0.78rem; }
.sidebar-bank .bank__row {
  grid-template-columns: 22px 1fr auto;
  padding: 6px 7px;
  gap: 3px 6px;
}
.sidebar-bank .bank__btn {
  font-size: 0.72rem;
  padding: 5px 6px;
  min-height: 34px;
}
.sidebar-bank .bank__btn small { font-size: 0.62rem; }
.sidebar-bank .bank__progress { height: 18px; }
.sidebar-bank .bank__progress-text { font-size: 0.64rem; }

/* Hand rankings header sits just above the rankings list; trim its
   top margin since the bank already gave us a gap. Also acts as a
   collapse toggle now — see the .help-panel__collapser--ranks rule
   added in client.js wiring. */
.help-panel__title--ranks {
  margin-top: 0.4rem;
  padding-top: 0.5rem;
  border-top: 1px solid rgba(217,176,106,0.18);
}
/* Hand rankings is now a collapsed <details> (a11y: keeps the list out of the
   screen-reader tree until opened). Make the summary read/behave as a toggle. */
.help-panel__ranks { margin: 0; }
.help-panel__ranks > summary { cursor: pointer; list-style-position: inside; }
.help-panel__ranks > summary:focus-visible { outline: 2px solid var(--brass-bright); outline-offset: 2px; }

/* ===== Right-side sidebar leaderboard ===== */
/* Tighter than the in-actpanel version since the panel is 240px wide
   and shows the full roster (no slice). Wealth shown without the 'gp'
   suffix to save horizontal room. */
.help-panel--leaderboard {
  display: flex;
  flex-direction: column;
  padding: 0.75rem 0.65rem;
}
.help-panel--leaderboard .help-panel__title {
  flex: 0 0 auto;
  margin: 0 0 0.25rem;
}
/* Leaderboard header row: title on the left, Hu/All filter on the right. */
.lb-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex: 0 0 auto; }
.lb-head .help-panel__title { margin: 0; }
.help-panel__sub {
  flex: 0 0 auto;
  margin: 0 0 0.55rem;
  font-size: 0.68rem;
  color: var(--ivory-dim);
  line-height: 1.3;
}
.lb--sidebar {
  /* Was flex:1 1 auto (filled the whole panel). Now shares the panel ~50/50
     with the Hall of Records below it (both flex:1 1 0). */
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  gap: 2px;
  padding-right: 2px;
}
/* ===== Hall of Records (under the leaderboard) ===== */
.lb-records {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgba(245, 236, 214, 0.12);
  overflow-y: auto;   /* 6 rows; scrolls in its half if the panel is short */
}
.lb-records__title { flex: 0 0 auto; }
.lb-records__row { flex: 0 0 auto; }
.lb-records__title {
  margin: 0 0 2px;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ivory-dim);
}
/* Header row: title + All / Humans / AI filter. */
.lb-records__head { display: flex; align-items: center; justify-content: space-between; gap: 6px; flex: 0 0 auto; }
.lb-records__filter { display: flex; gap: 2px; flex: 0 0 auto; }
.lb-records__fbtn {
  background: rgba(217,176,106,0.08);
  border: 1px solid rgba(217,176,106,0.22);
  color: var(--ivory-dim);
  font: inherit; font-size: 0.6rem; line-height: 1;
  padding: 3px 5px; border-radius: 5px; cursor: pointer;
  white-space: nowrap;
}
.lb-records__fbtn:hover { color: var(--ivory); border-color: rgba(217,176,106,0.4); }
.lb-records__fbtn.is-active { background: rgba(217,176,106,0.28); border-color: var(--brass); color: var(--brass-bright); }
.lb-records__row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px;
  font-size: 0.7rem;
  padding: 3px 5px;
  background: rgba(0, 0, 0, 0.18);
  border-radius: 4px;
}
.lb-records__label { white-space: nowrap; opacity: 0.85; }
.lb-records__who   { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lb-records__amt   { font-variant-numeric: tabular-nums; font-weight: 600; }
.lb-records__amt.is-win  { color: #7ddb8a; }
.lb-records__amt.is-loss { color: #e08a8a; }
.lb-records__empty { opacity: 0.5; }
.lb--sidebar .lb__row {
  grid-template-columns: 20px 22px 1fr auto;
  gap: 5px;
  padding: 2px 5px;
  font-size: 0.7rem;
}
.lb--sidebar .lb__avatar { width: 22px; height: 22px; }
.lb--sidebar .lb__rank { font-size: 0.78rem; }
.lb--sidebar .lb__bot {
  margin-left: 3px;
  font-size: 0.5rem;
  padding: 0 3px;
}

/* ===== Seat gear strip (hover-only popup) =====
   Hidden by default to keep the seat card compact. Pops up over the
   seat on hover so curious players can still see what gear an opponent
   is carrying. Position absolute so it never affects plate layout. */
.seat__gear {
  display: none;
  position: absolute;
  left: 50%;
  bottom: -6px;
  transform: translate(-50%, 100%);
  z-index: 35;
  background: rgba(8, 16, 11, 0.96);
  border: 1px solid rgba(241,207,131,0.45);
  border-radius: 8px;
  padding: 5px 8px;
  align-items: center; justify-content: center;
  gap: 4px;
  font-size: 0.62rem;
  box-shadow: 0 4px 14px rgba(0,0,0,0.55);
  white-space: nowrap;
  pointer-events: none;   /* avoid covering the seat click target */
}
.seat:hover .seat__gear { display: flex; }
.seat__gear-cell {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 14px; height: 14px;
  color: var(--brass-bright);
}
.seat__gear-cell svg { width: 14px; height: 14px; }
.seat__gear-cell--empty { color: rgba(245,236,214,0.18); }
.seat__gear-cell--max  { color: #6be0a9; }
.seat__gear-cell sup {
  font-size: 0.55rem;
  position: absolute;
  bottom: -4px; right: -6px;
  background: rgba(0,0,0,0.5);
  border-radius: 2px;
  padding: 0 1px;
  line-height: 1;
}
.seat__gear-total {
  margin-left: 4px;
  font-size: 0.6rem;
  color: var(--ivory-dim);
  font-variant-numeric: tabular-nums;
}
.actpanel__status {
  font-size: 0.7rem;
  color: var(--brass-bright);
  letter-spacing: 0.04em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.actpanel__row {
  display: flex; gap: 4px; align-items: stretch;
}
.actpanel__row--raise { gap: 4px; }
.actpanel__btn {
  padding: 0.4rem 0.5rem;
  font-size: 0.78rem;
  font-weight: 700;
  flex: 1;
  white-space: nowrap;
}
.actpanel__amount {
  flex: 1;
  min-width: 0;
  padding: 0.4rem 0.5rem;
  background: rgba(0,0,0,0.5);
  border: 1px solid rgba(245,236,214,0.18);
  border-radius: var(--radius-btn);
  color: var(--ivory);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  outline: none;
}
.actpanel__amount:focus { border-color: var(--brass); box-shadow: 0 0 0 2px rgba(217,176,106,0.18); }
/* Hide spinner arrows in number input — chip-clicks fill the value */
.actpanel__amount::-webkit-outer-spin-button,
.actpanel__amount::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.actpanel__amount { -moz-appearance: textfield; }

.actpanel__presets {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px;
}
.actpanel__preset {
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  padding: 4px 5px;
  background: rgba(217,176,106,0.10);
  border: 1px solid rgba(217,176,106,0.28);
  color: var(--ivory);
  border-radius: 6px;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  transition: background .12s, transform .1s, border-color .12s;
}
.actpanel__preset:hover {
  background: rgba(217,176,106,0.22);
  border-color: var(--brass-bright);
  transform: translateY(-1px);
}
.pot {
  font-family: var(--font-display);
  letter-spacing: 0.18em;
  font-size: 1.1rem;
  color: var(--brass-bright);
  background: rgba(0,0,0,0.35);
  padding: 0.25rem 0.9rem;
  border-radius: 20px;
  border: 1px solid rgba(217,176,106,0.35);
}
/* Headline pot variant — sits ABOVE the community board so the chip
   total is the most prominent thing on the felt. Big and gold. */
.pot--big {
  font-size: 2.4rem;
  letter-spacing: 0.22em;
  padding: 0.45rem 1.6rem;
  border-radius: 28px;
  border-width: 2px;
  border-color: rgba(217,176,106,0.6);
  background: linear-gradient(180deg, rgba(0,0,0,0.55), rgba(0,0,0,0.4));
  box-shadow: 0 6px 24px rgba(0,0,0,0.55), inset 0 1px 0 rgba(241,207,131,0.18);
  text-shadow: 0 2px 10px rgba(241,207,131,0.25);
  margin-bottom: 0.2rem;
}
.stage-banner {
  color: var(--ivory-dim);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.seat-ring {
  position: absolute; inset: 0; pointer-events: none;
}
.seat {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 102px;
  text-align: center;
  pointer-events: auto;
  /* Hard ceiling on seat size so growth in content (gear strip, timer,
     bet line, hole cards) can't push neighbors into overlap. Anything
     beyond is clipped — the bank UI in the action panel is the
     authoritative source for full info. */
  max-height: 170px;
}
.seat__plate {
  background: linear-gradient(180deg, rgba(0,0,0,0.55), rgba(0,0,0,0.7));
  border: 1px solid rgba(217,176,106,0.28);
  border-radius: 14px;
  padding: 5px 6px 7px;
  /* Tightened from 2px → 1px so nick + chips lines don't crowd each
     other when the avatar+name+chips stack is at its tallest. */
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  box-shadow: var(--shadow-soft);
  max-height: 170px;
  overflow: hidden;
}
/* The acting seat overrides max-height so its hole cards aren't
   clipped — z-index 4 already lifts it above neighbors. */
.seat.is-me .seat__plate,
.seat.is-acting .seat__plate {
  max-height: none;
  overflow: visible;
}
.seat.is-empty .seat__plate {
  background: rgba(0,0,0,0.25);
  border-style: dashed;
  border-color: rgba(245,236,214,0.18);
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.seat.is-empty .seat__plate:hover {
  background: rgba(217,176,106,0.15);
  border-color: var(--brass-bright);
}
/* Empty seats are now role=button tabindex=0 (keyboard + screen-reader
   reachable). Give the focused seat the same highlight as hover plus a
   clear focus ring so sighted keyboard users and low-vision players can
   see which seat they're about to take. */
.seat.is-empty .seat__plate--empty:focus-visible,
.seat.is-empty .seat__plate--empty:focus {
  outline: 3px solid var(--brass-bright);
  outline-offset: 2px;
  background: rgba(217,176,106,0.15);
  border-color: var(--brass-bright);
}
.seat.is-me .seat__plate {
  border-color: var(--brass-bright);
  box-shadow: 0 0 0 2px rgba(241,207,131,0.25), var(--shadow-soft);
}
.seat__avatar {
  position: relative;
  /* Token size bumped +20% (46 → 55) so character art is more legible
     at a glance. Mobile breakpoints scale proportionally below. */
  width: 55px; height: 55px;
  border-radius: 50%;
  background: rgba(0,0,0,0.5);
  border: 2px solid rgba(217,176,106,0.4);
  display: flex; align-items: center; justify-content: center;
  overflow: visible;   /* let the AI badge spill onto the corner */
}
.seat__avatar > svg,
.seat__avatar > .avatar-img { border-radius: 50%; overflow: hidden; }
/* AI intelligence-tier ring — recolors the token's existing thin frame so the
   tier reads at a glance without adding a second border. Kept low-opacity and
   subtle on purpose: bronze = low, silver = average, gold = high. Humans keep
   the default brass frame above. */
.seat__avatar--intel-low  { border-color: rgba(176, 112, 58, 0.60); }   /* bronze */
.seat__avatar--intel-avg  { border-color: rgba(196, 202, 212, 0.55); }  /* silver */
.seat__avatar--intel-high { border-color: rgba(226, 184, 88, 0.70); }   /* gold   */
.seat__avatar-ai {
  position: absolute;
  top: -4px; right: -6px;
  font-size: 0.52rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  padding: 1px 5px;
  background: linear-gradient(180deg, var(--brass-bright), var(--brass));
  color: #2a1a05;
  border: 1px solid rgba(40,24,5,0.6);
  border-radius: 999px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.55);
  z-index: 2;
}
.seat__avatar svg, .seat__avatar .avatar-img { width: 100%; height: 100%; object-fit: cover; }
.avatar-img { display: block; }
.roster-pick__avatar .avatar-img,
.confirm-avatar-big .avatar-img,
.me-avatar .avatar-img,
.avatar-pick .avatar-img { width: 100%; height: 100%; object-fit: cover; }
/* Tightened line-height on both text rows so the nickname can't be
   clipped by the chip line that immediately follows it. */
.seat__nick { font-size: 0.82rem; font-weight: 600; line-height: 1.05; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seat__chips { font-size: 0.78rem; line-height: 1.05; color: var(--brass-bright); font-variant-numeric: tabular-nums; }
.seat__empty { font-size: 0.75rem; color: var(--ivory-dim); letter-spacing: 0.08em; text-transform: uppercase; }

.prototype-note {
  position: absolute;
  bottom: 14px; left: 50%;
  transform: translateX(-50%);
  font-size: 0.78rem;
  color: var(--ivory-dim);
  background: rgba(0,0,0,0.45);
  border: 1px solid rgba(217,176,106,0.2);
  padding: 0.4rem 0.8rem;
  border-radius: 999px;
}

.actionbar {
  display: flex; gap: 0.6rem;
  padding: 0.8rem 1.25rem;
  background: linear-gradient(0deg, rgba(0,0,0,0.55), rgba(0,0,0,0.25));
  border-top: 1px solid rgba(217,176,106,0.18);
}
.raise-group { margin-left: auto; display: flex; gap: 0.5rem; align-items: center; }
.raise-group input {
  width: 110px;
  padding: 0.55rem 0.7rem;
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(245,236,214,0.15);
  border-radius: var(--radius-btn);
  color: var(--ivory);
  outline: none;
}

/* ===== Topbar debt indicator ===== */
.me-debt {
  color: #ffb874;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  background: rgba(255, 140, 66, 0.12);
  border: 1px solid rgba(255, 140, 66, 0.35);
  padding: 2px 8px;
  border-radius: 999px;
}

/* ===== Chat / event log panel (bottom strip) ===== */
.chat-panel {
  flex: 0 0 auto;
  /* 168 → 280 on desktop. Combined with the table-wrap 120px bottom-
     padding removal, the chat log now butts directly against the felt
     bottom and shows ~6 additional lines without scrolling. Mobile
     breakpoints further down override back to 80px / 64px so phones
     stay compact. */
  height: 280px;
  background: linear-gradient(180deg, rgba(8,16,11,0.95), rgba(5,10,7,0.98));
  border-top: 1px solid rgba(217,176,106,0.25);
  display: flex; flex-direction: column;
  position: relative;   /* anchor for the jump-to-present button */
  z-index: 6;
}
/* "Jump to present" arrow — floats at the bottom of the chat scroll area.
   Hidden while you're at the bottom (already on the latest); appears the
   moment you scroll up to read history, and bobs when new chat arrives
   while you're scrolled away. Click to snap back to the newest message. */
.chat-jump {
  position: absolute;
  /* Hug the RIGHT EDGE OF THE CHAT COLUMN (the .chat-panel__list is a centered
     760px column, so its scrollbar sits mid-screen on wide monitors — not at the
     panel's far-right edge). This keeps the arrow next to the scrollbar where the
     eye expects it, collapsing to the panel edge on narrow screens. */
  right: calc(max(0px, (100% - 760px) / 2) + 0.4rem);
  bottom: 3.6rem;       /* clears the input form below */
  z-index: 8;
  width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(241,207,131,0.5);
  background: linear-gradient(180deg, rgba(30,40,28,0.95), rgba(14,20,14,0.98));
  color: var(--brass-bright, #d6b15c);
  font-size: 1rem; line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0,0,0,0.5);
  transition: transform .12s, background .12s, border-color .12s, opacity .15s;
}
.chat-jump[hidden] { display: none; }   /* beats the base display:flex */
.chat-jump:hover {
  transform: translateY(1px);
  border-color: var(--brass-bright);
  background: linear-gradient(180deg, rgba(40,52,36,0.97), rgba(20,28,18,0.99));
}
.chat-jump--new {
  border-color: rgba(241,207,131,0.95);
  animation: chatJumpBob 1s ease-in-out infinite;
}
@keyframes chatJumpBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(3px); } }
.chat-panel__head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 0.35rem 1rem 0.25rem;
  border-bottom: 1px solid rgba(217,176,106,0.12);
}
.chat-panel__title {
  margin: 0;
  font-family: var(--font-display);
  letter-spacing: 0.18em;
  color: var(--brass-bright);
  font-size: 0.85rem;
}
.chat-panel__hint {
  font-size: 0.7rem;
  color: var(--ivory-dim);
  letter-spacing: 0.04em;
}
.chat-panel__list {
  list-style: none;
  /* Centered as a fixed-width column inside the full-width panel,
     so the conversation reads down the middle of the screen but each
     line is still left-justified internally (no awkward centering of
     the text itself). max-width keeps long lines readable on wide
     monitors; auto margins center the column. */
  margin: 0 auto;
  width: 100%;
  max-width: 760px;
  padding: 0.4rem 1rem 0.5rem;
  flex: 1;
  overflow-y: auto;
  /* No smooth scroll-behavior: the auto-pin to newest must land INSTANTLY,
     otherwise rapid messages make it chase the bottom and fall behind. */
  font-size: 0.85rem;
  line-height: 1.35;
  display: flex; flex-direction: column; gap: 0.2rem;
  text-align: left;
}
/* Subtle scrollbar so the panel doesn't feel desktop-default */
.chat-panel__list::-webkit-scrollbar { width: 8px; }
.chat-panel__list::-webkit-scrollbar-track { background: transparent; }
.chat-panel__list::-webkit-scrollbar-thumb {
  background: rgba(217,176,106,0.25);
  border-radius: 4px;
}
.chat-entry {
  display: flex; gap: 0.6rem;
  padding: 1px 0;
  color: var(--ivory-dim);
}
.chat-entry__time {
  flex: 0 0 auto;
  width: 48px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: rgba(245,236,214,0.4);
  font-size: 0.78rem;
}
.chat-entry__text { flex: 1; }
.chat-entry--hand   .chat-entry__text { color: var(--brass-bright); font-weight: 600; }
.chat-entry--win    .chat-entry__text { color: var(--success); font-weight: 600; }
.chat-entry--rebuy  .chat-entry__text { color: #ffd092; }
.chat-entry--leave  .chat-entry__text { color: #ff9999; }
.chat-entry--debt   .chat-entry__text { color: #ffb874; }
.chat-entry--info   .chat-entry__text { color: var(--ivory); }
.chat-entry--action .chat-entry__text { color: var(--ivory-dim); }
.chat-entry--lootlord .chat-entry__text { color: var(--brass-bright); font-weight: 700; letter-spacing: 0.04em; }
.chat-entry--banter .chat-entry__text { color: #cfe2b8; font-style: italic; }
.chat-entry--human  .chat-entry__text { color: #d9e9f7; font-weight: 600; }
.chat-entry--fight  .chat-entry__text { color: #e6c79a; }
/* Banter or local-SFX lines carry replayable audio (Crisp/Elfrip
   sound pools, or 11labs banter MP3). Make them visibly clickable
   — a subtle hover highlight + speaker glyph cues that there's
   something to interact with. */
.chat-entry--has-audio { cursor: pointer; }
.chat-entry--has-audio:hover { background: rgba(217,176,106,0.10); border-radius: 4px; }
.chat-entry--has-audio .chat-entry__text::before {
  content: '🔊 ';
  font-size: 0.85em;
  opacity: 0.55;
}

/* ===== Chat input row at the bottom of the chat panel ===== */
.chat-panel__input {
  display: flex;
  gap: 6px;
  /* Same centered max-width as the list above so the input lines up
     with the conversation column. */
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 6px 10px 8px;
  border-top: 1px solid rgba(217,176,106,0.15);
  background: rgba(0,0,0,0.35);
  box-sizing: border-box;
}
.chat-panel__input input {
  flex: 1;
  min-width: 0;
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(241,207,131,0.25);
  border-radius: 6px;
  color: var(--ivory);
  font-family: inherit;
  font-size: 0.82rem;
  padding: 5px 9px;
}
.chat-panel__input input:focus {
  outline: none;
  border-color: var(--brass);
  box-shadow: 0 0 0 2px rgba(217,176,106,0.18);
}
.chat-panel__input input::placeholder { color: rgba(245,236,214,0.4); }
.chat-panel__input input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.chat-panel__input button:disabled { opacity: 0.4; cursor: not-allowed; }

/* ===== Action timer countdown under acting seat ===== */
.seat__timer {
  display: inline-block;
  font-size: 0.7rem;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--brass-bright);
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(241,207,131,0.45);
  padding: 1px 7px;
  border-radius: 999px;
  margin-top: 2px;
  /* Fixed width so neither the human's mm:ss tick nor the bot's
     "thinking..." dot frames reflow the seat plate around it. */
  min-width: 92px;
  text-align: center;
  white-space: pre;   /* preserves trailing spaces in the dot frames */
}
.seat__timer.is-urgent {
  color: #ffd9d9;
  border-color: var(--danger);
  background: rgba(80, 15, 15, 0.7);
  animation: timerPulse 0.8s ease-in-out infinite;
}
@keyframes timerPulse {
  0%,100% { transform: scale(1); }
  50%     { transform: scale(1.08); }
}

/* ===== Sit-out active button ===== */
.btn--sit-out-active {
  background: rgba(122, 245, 255, 0.18);
  border-color: #7af5ff;
  color: #7af5ff;
  font-weight: 700;
}

/* ===== + Bot picker modal ===== */
.modal__panel--bot-picker { width: min(720px, 96vw); }

/* Bot-picker actions relocated ABOVE the grid — a quick toolbar so Random /
   Fill / Cancel are one click away the moment the picker opens. Left-aligned
   (primary first), wraps on narrow screens, divider rule separates it from
   the character list below. */
.modal__actions--top {
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0 0 0.6rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid rgba(217,176,106,0.18);
}

/* Search bar above the grid — sticky-feeling, easy keyboard target. */
.bot-picker__search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0.4rem 0 0.55rem;
}
.bot-picker__search-input {
  flex: 1;
  padding: 0.45rem 0.6rem;
  font-size: 0.9rem;
  border: 1px solid var(--brass-dim, #6b5328);
  border-radius: 0.35rem;
  background: rgba(0, 0, 0, 0.25);
  color: inherit;
  outline: none;
}
.bot-picker__search-input:focus {
  border-color: var(--brass-bright, #d6b15c);
  background: rgba(0, 0, 0, 0.35);
  box-shadow: 0 0 0 2px rgba(214, 177, 92, 0.18);
}
.bot-picker__count {
  font-size: 0.75rem;
  color: var(--brass-bright, #d6b15c);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.bot-picker__empty {
  padding: 1.5rem 0.5rem;
  text-align: center;
  font-size: 0.85rem;
  opacity: 0.75;
  grid-column: 1 / -1;
}

.bot-picker__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 0.55rem;
  max-height: 60vh;
  overflow-y: auto;
  padding: 0.25rem 0.25rem 0.5rem 0;
  margin-bottom: 0.25rem;
}
.bot-picker__card {
  background: rgba(0,0,0,0.4);
  border: 1px solid rgba(217,176,106,0.22);
  border-radius: 10px;
  padding: 0.5rem 0.35rem;
  display: flex; flex-direction: column; align-items: center; gap: 0.25rem;
  cursor: pointer;
  transition: transform .12s, border-color .12s, background .12s;
  color: var(--ivory);
}
.bot-picker__card:hover {
  transform: translateY(-2px);
  border-color: var(--brass-bright);
  background: rgba(217,176,106,0.12);
}
.bot-picker__avatar {
  width: 48px; height: 48px;
  border-radius: 50%;
  background: rgba(0,0,0,0.5);
  border: 1px solid rgba(217,176,106,0.4);
  overflow: hidden;
}
.bot-picker__avatar svg, .bot-picker__avatar img { width: 100%; height: 100%; object-fit: cover; }
.bot-picker__nick { font-size: 0.78rem; font-weight: 600; }
.bot-picker__worth { font-size: 0.7rem; color: var(--brass-bright); font-variant-numeric: tabular-nums; }

/* ===== LOOT LORD ceremony ===== */
.lootlord-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex; align-items: center; justify-content: center;
}
.lootlord-overlay__backdrop {
  position: absolute; inset: 0;
  background: radial-gradient(ellipse at center, rgba(75, 50, 10, 0.7) 0%, rgba(0,0,0,0.92) 70%);
  backdrop-filter: blur(8px);
}
.lootlord-overlay__content {
  position: relative;
  text-align: center;
  color: var(--ivory);
  padding: 2rem 3rem;
  border: 2px solid var(--brass-bright);
  border-radius: 24px;
  background: radial-gradient(ellipse at center, rgba(40, 28, 10, 0.95), rgba(20, 12, 5, 0.97));
  box-shadow: 0 0 80px rgba(241, 207, 131, 0.5), 0 30px 80px rgba(0,0,0,0.8);
  animation: lootlordPop 0.6s cubic-bezier(.34,1.56,.64,1) both;
}
@keyframes lootlordPop {
  0% { transform: scale(0.4); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}
.lootlord-overlay__rays {
  position: absolute;
  inset: -100px;
  background: conic-gradient(from 0deg,
    transparent 0deg, rgba(241,207,131,0.18) 8deg, transparent 16deg,
    transparent 30deg, rgba(241,207,131,0.18) 38deg, transparent 46deg,
    transparent 60deg, rgba(241,207,131,0.18) 68deg, transparent 76deg,
    transparent 90deg, rgba(241,207,131,0.18) 98deg, transparent 106deg,
    transparent 120deg, rgba(241,207,131,0.18) 128deg, transparent 136deg,
    transparent 150deg, rgba(241,207,131,0.18) 158deg, transparent 166deg,
    transparent 180deg, rgba(241,207,131,0.18) 188deg, transparent 196deg,
    transparent 210deg, rgba(241,207,131,0.18) 218deg, transparent 226deg,
    transparent 240deg, rgba(241,207,131,0.18) 248deg, transparent 256deg,
    transparent 270deg, rgba(241,207,131,0.18) 278deg, transparent 286deg,
    transparent 300deg, rgba(241,207,131,0.18) 308deg, transparent 316deg,
    transparent 330deg, rgba(241,207,131,0.18) 338deg, transparent 346deg,
    transparent 360deg);
  animation: lootlordSpin 20s linear infinite;
  pointer-events: none;
  z-index: -1;
}
@keyframes lootlordSpin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.lootlord-overlay__pre {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.6rem;
  letter-spacing: 0.4em;
  color: var(--brass-bright);
  text-shadow: 0 0 12px rgba(241,207,131,0.6);
}
.lootlord-overlay__title {
  margin: 0.4rem 0 1.4rem;
  font-family: var(--font-display);
  font-size: 5.5rem;
  letter-spacing: 0.18em;
  color: var(--brass-bright);
  text-shadow:
    0 0 30px rgba(241,207,131,0.9),
    0 0 60px rgba(241,207,131,0.5),
    0 6px 16px rgba(0,0,0,0.8);
  background: linear-gradient(180deg, #fff5d2, var(--brass-bright), var(--brass));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.lootlord-overlay__portrait {
  width: 280px; height: 280px;
  margin: 0 auto 1rem;
  border-radius: 50%;
  border: 6px solid var(--brass-bright);
  overflow: hidden;
  box-shadow:
    0 0 50px rgba(241,207,131,0.7),
    0 0 100px rgba(241,207,131,0.4),
    inset 0 0 30px rgba(0,0,0,0.4);
  background: rgba(0,0,0,0.5);
  animation: lootlordGlow 2s ease-in-out infinite;
}
.lootlord-overlay__portrait img,
.lootlord-overlay__portrait svg { width: 100%; height: 100%; object-fit: cover; }
@keyframes lootlordGlow {
  0%,100% { box-shadow: 0 0 50px rgba(241,207,131,0.7), 0 0 100px rgba(241,207,131,0.4), inset 0 0 30px rgba(0,0,0,0.4); }
  50%     { box-shadow: 0 0 70px rgba(241,207,131,1.0), 0 0 140px rgba(241,207,131,0.6), inset 0 0 30px rgba(0,0,0,0.4); }
}
.lootlord-overlay__name {
  font-family: var(--font-display);
  font-size: 3rem;
  letter-spacing: 0.18em;
  color: var(--ivory);
  text-shadow: 0 0 12px rgba(241,207,131,0.5);
  margin-bottom: 0.4rem;
}
.lootlord-overlay__stats {
  font-size: 0.95rem;
  color: var(--ivory-dim);
  margin-bottom: 1.2rem;
}
.lootlord-overlay__countdown {
  font-size: 0.95rem;
  color: var(--brass-bright);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.lootlord-overlay__countdown span {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: #fff;
}

/* ===== Toast ===== */
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  padding: 0.7rem 1.1rem;
  background: rgba(15,25,18,0.95);
  border: 1px solid rgba(217,176,106,0.4);
  border-radius: var(--radius-btn);
  font-size: 0.9rem;
  box-shadow: var(--shadow-card);
  z-index: 50;
}
.toast.is-error { border-color: var(--danger); color: #ffd9d9; }

/* ===== Small screens ===== */
/* ===== Help modal ===== */
.modal__panel--help {
  width: min(680px, 96vw);
  max-height: 88vh;
  overflow-y: auto;
}
.help-modal__body {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin: 0.5rem 0 1rem;
}
.help-modal__body section h3 {
  margin: 0 0 0.35rem;
  font-family: var(--font-display);
  letter-spacing: 0.18em;
  color: var(--brass-bright);
  font-size: 0.9rem;
}
.help-modal__body dl {
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 0.6rem;
  font-size: 0.85rem;
}
.help-modal__body dt { grid-column: 1; }
.help-modal__body dd { grid-column: 2; margin: 0; color: var(--ivory-dim); }
.help-modal__rankings { list-style: none; counter-reset: rk; padding: 0; margin: 0; font-size: 0.85rem; }
.help-modal__rankings li { counter-increment: rk; padding-left: 1.6rem; position: relative; margin: 0 0 0.2rem; }
.help-modal__rankings li::before {
  content: counter(rk);
  position: absolute; left: 0;
  width: 1.2rem; text-align: center;
  color: var(--brass-bright); font-weight: 700;
}
.help-modal__rankings em { color: var(--ivory-dim); font-style: normal; margin-left: 0.4rem; }
.help-modal__flow { list-style: decimal inside; padding: 0; margin: 0; font-size: 0.85rem; }
.help-modal__flow li { margin: 0 0 0.2rem; }
.help-modal__tips { list-style: none; padding: 0; margin: 0; font-size: 0.85rem; }
.help-modal__tips li { padding-left: 1rem; position: relative; margin: 0 0 0.25rem; }
.help-modal__tips li::before { content: "→"; position: absolute; left: 0; color: var(--brass); }

/* ===== Tablet ===== */
@media (max-width: 1100px) {
  .help-panel { width: 200px; }
}

/* ===== Mobile ===== */
/* The "my hand" strip lives inside the action panel; hidden on desktop. */
.actpanel__myhand { display: none; }

@media (max-width: 720px) {
  /* Hide the side help panels — content moves into the Help modal. */
  .help-panel { display: none; }
  /* Topbar: drop brand text, tighten everything */
  .topbar { padding: 0.35rem 0.5rem; gap: 0.35rem; flex-wrap: wrap; position: relative; }
  .topbar__brand { display: none; }
  .topbar__clock { min-width: 110px; padding: 2px 8px; }
  .topbar__clock-digits svg { width: 16px; height: 28px; }
  .topbar__me { font-size: 0.75rem; gap: 0.3rem; flex-wrap: wrap; }
  .me-debt, .me-chips { font-size: 0.75rem; }
  .topbar__me .btn { padding: 4px 8px; font-size: 0.75rem; min-height: 32px; }

  /* ===== Topbar overflow menu (mobile) =====
     The management buttons (+Bot, Pick AI, Re-buy, Sit out, Switch,
     Leave, Reset) would otherwise wrap into 2-3 extra rows on a phone
     and eat the felt height. Collapsed into a slide-down panel
     anchored to the topbar's bottom edge so it stays reachable
     regardless of viewport width. The .≡ toggle button stays inline. */
  .topbar__menu-toggle { display: inline-flex; }
  .topbar__menu {
    display: none;
    position: absolute;
    top: 100%;
    right: 0.5rem;
    z-index: 70;
    flex-direction: column;
    align-items: stretch;
    gap: 0.3rem;
    padding: 0.5rem;
    background: linear-gradient(180deg, rgba(20,24,18,0.97), rgba(10,14,10,0.99));
    border: 1px solid rgba(217,176,106,0.4);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.7);
    min-width: 160px;
  }
  .topbar__menu.is-open { display: flex; }
  .topbar__menu .btn { width: 100%; min-height: 36px; text-align: left; }

  /* Felt: leave room for the fixed bottom action bar. */
  .felt { aspect-ratio: 1 / 1; }

  /* ===== Tiny seat cards (token + name ONLY on mobile) =====
     Everything else (chips, gear, current bet, hole cards, timer) is
     suppressed for opponent seats so the table shows who's there at a
     glance. The player's own chips + hole cards live in the bottom
     action bar instead. */
  /* Avatar +20% on mobile too (44 → 53); seat width + plate height
     bumped to accommodate so plates still don't overlap on phones. */
  .seat { width: 72px; max-height: 108px; }
  .seat__plate { padding: 3px 3px 4px; max-height: 108px; }
  .seat__avatar { width: 53px; height: 53px; }
  .seat__nick { font-size: 0.7rem; line-height: 1.1; }
  /* Hide secondary detail on every seat */
  .seat__chips,
  .seat__swords,
  .seat__bet,
  .seat__hole,
  .seat__waiting,
  .seat__afk-tag,
  .seat__leaving { display: none; }
  /* The gear strip is hover-only on desktop; on mobile (no real hover)
     suppress it entirely — players check gear via the leaderboard. */
  .seat:hover .seat__gear { display: none; }
  /* Keep the action timer on whichever seat is acting (so opponents
     can see whose turn it is) — others stay hidden. */
  .seat__timer { display: none; font-size: 0.62rem; min-width: 60px; padding: 1px 4px; }
  .seat.is-acting .seat__timer { display: inline-block; }
  /* Allinindicator stays inline on the nick because it's short */

  /* Pot: smaller display font */
  .pot--big { font-size: 1.4rem; padding: 0.3rem 0.8rem; }
  .board { gap: 0.3rem; min-height: 80px; }
  .card-svg { width: 50px; height: auto; }

  /* Chat log: shrink */
  .chat-panel { height: 80px; }
  .chat-panel__list { font-size: 0.76rem; padding: 0.25rem 0.6rem 0.3rem; }

  /* ===== Action panel → fixed bottom bar ===== */
  /* Sits ABOVE the chat panel (which is 80px tall on mobile) so the
     chat log stays visible — the actpanel bottom: 80px matches the
     chat panel's height exactly so they're flush. */
  .actpanel-host {
    position: fixed;
    left: 0; right: 0; bottom: 80px;
    top: auto;
    transform: none;
    width: 100%;
    z-index: 60;
    padding: 6px 8px;
    background: linear-gradient(180deg, rgba(0,0,0,0.55), rgba(0,0,0,0.92));
    border-top: 1px solid rgba(241,207,131,0.35);
    border-bottom: 1px solid rgba(241,207,131,0.18);
  }
  /* Chat panel keeps its z-index lower — it stays in flow at viewport
     bottom; the actpanel-host floats just above it. */
  .chat-panel { z-index: 5; }
  .actpanel {
    transform: none !important;     /* override drag offset on mobile */
    min-width: 0;
    width: 100%;
    margin: 0 auto;
    padding: 4px 6px 6px;
    gap: 4px;
    background: transparent;
    border: none;
    box-shadow: none;
  }
  /* Drag handle, bank/leaderboard toggles, and preset buttons are all
     hidden on mobile — too cramped. They remain available from the
     help/menu modal. */
  .actpanel__drag,
  .actpanel__presets,
  .actpanel__toggles,
  .actpanel__section { display: none; }

  /* Show the my-hand strip on mobile, above the action buttons. */
  .actpanel__myhand {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 2px 6px;
  }
  .actpanel__myhand-cards { display: flex; gap: 4px; }
  .actpanel__myhand-cards .card-svg { width: 44px; height: auto; }
  .actpanel__myhand-info {
    display: flex; flex-direction: column; align-items: flex-end; gap: 1px;
    font-size: 0.72rem; color: var(--ivory-dim);
  }
  .actpanel__myhand-chips { color: var(--brass-bright); font-weight: 600; }
  .actpanel__myhand-bet { color: var(--ivory-dim); }

  /* Buttons stay in a single row; raise amount + presets get the next row. */
  .actpanel__row { gap: 4px; }
  .actpanel__btn { flex: 1; min-height: 38px; font-size: 0.86rem; padding: 6px 4px; }
  .actpanel__amount { font-size: 0.85rem; min-height: 38px; }

  /* Roster picker grid: 3 wide on phones */
  .roster-section-grid { grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); }
  .roster-pick { padding: 0.5rem 0.4rem 0.5rem; }
  .roster-pick__avatar { width: 44px; height: 44px; }
  .roster-pick__nick { font-size: 0.78rem; }
  /* Avatar gallery in confirm screen */
  .avatar-grid { grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); }
}

/* ===== Very small (phones in portrait) ===== */
@media (max-width: 480px) {
  /* Stack topbar buttons; hide the less-critical ones behind the
     Help modal (they're still accessible from there in the future). */
  .topbar__me { font-size: 0.7rem; }
  .topbar__me .btn { padding: 3px 6px; font-size: 0.7rem; }
  /* Pot smaller still */
  .pot--big { font-size: 1.1rem; padding: 0.2rem 0.6rem; }
  .card-svg { width: 42px; height: auto; }
  /* Phone-portrait: avatar +20% (38 → 46), seat + plate scaled to match. */
  .seat { width: 62px; max-height: 98px; }
  .seat__avatar { width: 46px; height: 46px; }
  .seat__nick { font-size: 0.66rem; }
  /* Smaller hand cards in the bottom bar */
  .actpanel__myhand-cards .card-svg { width: 38px; height: auto; }
  .actpanel__btn { min-height: 34px; font-size: 0.8rem; }
  /* Tighten chat — and reposition the actpanel above it to match. */
  .chat-panel { height: 64px; }
  .actpanel-host { bottom: 64px; }
}
