:root {
  /* Everything that sits above the footer offsets from this. */
  --footer-h: clamp(150px, 38dvh, 322px);
  --bg-dark: #0f1118;
  --bg-card: #1a1d29;
  --bg-elevated: #242938;
  --border-color: #343a4e;
  --accent-gold: #f59e0b;
  --accent-gold-glow: rgba(245, 158, 11, 0.4);
  --accent-red: #ef4444;
  --accent-blue: #3b82f6;
  --accent-green: #10b981;
  --accent-purple: #8b5cf6;
  --text-main: #f3f4f6;
  --text-muted: #9ca3af;
  /* Four families, and only these four. Cinzel for display, Nunito for
     everything read, system-ui as the fallback and sans-serif as the last
     resort. The printed card art is set in the fallback, which is what those
     SVGs have always rendered in. */
  --font-serif: 'Cinzel', serif;
  --font-sans: 'Nunito', system-ui, sans-serif;
  --font-card: system-ui, sans-serif;
  --tile-size: 140px;
  /* The landing's ground colour, also the outline drawn on everything sitting
     on it, so the art and the buttons share one ink. */
  --landing-ink: #131318;

  /* Minimalist in-game HUD: flat surfaces, one accent, no gradients or glows */
  --table-felt: #12141b;
  --hud-surface: #191c24;
  --hud-line: #2c313d;
  --accent: #f59e0b;
  --accent-hi: #fbbf24;
  --accent-ink: #12141b;
  --hp-red: #f87171;
  --reach-blue: #3b82f6;

  /* Playing-card footprint used by Keeypling and Item cards alike. */
  --card-w: 152px;
  --card-h: 220px;

  /* The log drawer's width, shared with the seats that move out from under it. */
  --log-w: 232px;
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

body {
  background-color: var(--bg-dark);
  color: var(--text-main);
  font-family: var(--font-sans);
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Header */
.app-header {
  background-color: var(--bg-card);
  border-bottom: 2px solid var(--border-color);
  padding: 12px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
  z-index: 100;
  flex-shrink: 0;
}

.logo-group {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo-icon {
  font-size: 1.8rem;
  filter: drop-shadow(0 0 8px var(--accent-gold));
}

.logo-title {
  font-family: var(--font-serif);
  font-size: 1.6rem;
  font-weight: 900;
  letter-spacing: 2px;
  color: #fbbf24;
  text-shadow: 0 2px 4px rgba(0,0,0,0.8);
}

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

.room-pill {
  background: #2e1065;
  border: 1px solid #7c3aed;
  color: #e9d5ff;
  padding: 6px 14px;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.9rem;
}

.room-pill strong {
  color: #fff;
  letter-spacing: 1px;
}

/* App Views */
.app-container {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}

.view {
  display: none !important;
  flex: 1;
  min-height: 0;
  width: 100%;
}

.view.active {
  display: flex !important;
  flex-direction: column;
}

/* Buttons & Inputs */
button {
  font-family: var(--font-sans);
  font-weight: 700;
  border-radius: 8px;
  cursor: pointer;
  border: none;
  transition: all 0.2s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.btn-primary {
  background: #d97706;
  border: 1px solid #b45309;
  color: #fff;
}
.btn-primary:hover:not(:disabled) {
  background: #b45309;
}

.btn-secondary {
  background: var(--bg-elevated);
  color: var(--text-main);
  border: 1px solid var(--border-color);
}
.btn-secondary:hover:not(:disabled) {
  background: #2d3345;
  border-color: #4b5563;
}

.btn-danger {
  background: #b91c1c;
  border: 1px solid #991b1b;
  color: #fff;
  padding: 8px 16px;
}
.btn-danger:hover:not(:disabled) {
  background: #991b1b;
}

.btn-ghost {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border-color);
  padding: 6px 14px;
}
.btn-ghost:hover {
  background: var(--bg-card);
  color: var(--text-main);
}

.btn-large {
  padding: 12px 24px;
  font-size: 1.1rem;
}

.btn-small {
  padding: 4px 10px;
  font-size: 0.85rem;
}

.btn-icon {
  background: transparent;
  color: inherit;
  font-size: 1.1rem;
  padding: 2px 6px;
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

input[type="text"] {
  background: var(--bg-dark);
  border: 1px solid var(--border-color);
  color: var(--text-main);
  padding: 10px 14px;
  border-radius: 6px;
  font-family: var(--font-sans);
  font-size: 1rem;
  outline: none;
  width: 100%;
}
input[type="text"]:focus {
  border-color: var(--accent-gold);
  box-shadow: 0 0 0 2px var(--accent-gold-glow);
}

/* Landing Page */
/*
 * Main menu.
 *
 * A quiet screen in the game's own colours: the title, your name, and a short
 * column of ways in. No panels and no coloured slabs — the menu is type on
 * stone, and the only colour is the gold the game already uses.
 */
#view-landing {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 28px 72px;
  background:
    radial-gradient(ellipse 90% 70% at 50% 38%, #1c1f29 0%, #0d0e13 62%, #08090c 100%);
}
/* Faint mortar lines under everything, so the menu reads as sitting on the
   dungeon wall rather than on a blank page. */
#view-landing::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.16;
  background-image:
    repeating-linear-gradient(0deg, transparent 0 47px, rgba(255, 255, 255, 0.055) 47px 48px),
    repeating-linear-gradient(90deg, transparent 0 95px, rgba(255, 255, 255, 0.045) 95px 96px);
  mask-image: radial-gradient(ellipse 70% 60% at 50% 45%, #000 10%, transparent 78%);
}

body.on-landing .app-header {
  display: none;
}

.menu-screen {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: center;
}

.menu-title {
  font-family: var(--font-serif);
  font-size: clamp(2.6rem, 6vw, 3.8rem);
  font-weight: 900;
  letter-spacing: 0.06em;
  color: var(--accent-gold);
  text-shadow: 0 3px 18px rgba(0, 0, 0, 0.85);
}
.menu-strap {
  margin-top: 10px;
  padding-bottom: 26px;
  border-bottom: 1px solid var(--hud-line);
  font-size: 0.86rem;
  letter-spacing: 0.05em;
  color: var(--text-muted);
}

.menu-field {
  display: flex;
  align-items: baseline;
  gap: 12px;
  padding: 22px 0 4px;
  text-align: left;
}
.menu-field label {
  flex: 0 0 auto;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.menu-field input {
  flex: 1;
  min-width: 0;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  padding: 6px 2px;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--hud-line);
  border-radius: 0;
  color: var(--text-main);
}
.menu-field input::placeholder {
  color: #565c6b;
  font-weight: 500;
}
.menu-field input:focus {
  outline: none;
  border-bottom-color: var(--accent-gold);
}

.menu-list {
  display: flex;
  flex-direction: column;
  padding-top: 20px;
}

.menu-item {
  position: relative;
  font-family: var(--font-serif);
  font-size: 1.18rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  padding: 11px 0;
  background: none;
  border: none;
  color: #c9cdd8;
  cursor: pointer;
  transition: color 120ms ease, letter-spacing 120ms ease;
}
/* The marker sits in reserved space, so nothing shifts when it appears. */
.menu-item::before {
  content: '\2023';
  position: absolute;
  left: 0;
  opacity: 0;
  color: var(--accent-gold);
  transition: opacity 120ms ease;
}
.menu-item:hover,
.menu-item:focus-visible {
  color: var(--accent-gold);
  letter-spacing: 0.1em;
  outline: none;
}
.menu-item:hover::before,
.menu-item:focus-visible::before {
  opacity: 1;
}

.menu-join[hidden] {
  display: none;
}
.menu-join {
  gap: 10px;
  padding-top: 16px;
  border-top: 1px solid var(--hud-line);
  margin-top: 14px;
}
.menu-join input {
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.menu-enter {
  flex: 0 0 auto;
  font-family: var(--font-serif);
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 6px 14px;
  background: transparent;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  color: var(--text-muted);
  cursor: pointer;
}
.menu-enter:hover {
  color: var(--accent-gold);
  border-color: var(--accent-gold);
}

.menu-version {
  position: absolute;
  left: 24px;
  bottom: 20px;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #4b5160;
}

/* Lobby Page */
#view-lobby {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 24px;
}

.lobby-layout {
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/*
 * The lobby screen.
 *
 * One viewport, three rows: a bar naming the room, the table of seats beside your
 * own two cards, and the host's controls along the bottom. Nothing here scrolls the
 * page — the seat list is the only part that may scroll, and only past six players,
 * which the game does not allow anyway.
 */
#view-lobby.view.active {
  padding: 0;
  overflow: hidden;
}
.lobby-screen {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  min-height: 0;
  gap: 10px;
  padding: 12px 16px 14px;
}

.lobby-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.lobby-bar h2 {
  font-family: var(--font-serif);
  font-size: 1.15rem;
  margin: 0;
}
.lobby-bar-left,
.lobby-bar-right {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.lobby-room-code {
  font-weight: 800;
  letter-spacing: 0.06em;
  color: var(--accent-gold);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 3px 10px;
  font-size: 0.82rem;
}
.lobby-bar-right input {
  width: 230px;
  max-width: 34vw;
  padding: 5px 8px;
  font-size: 0.76rem;
}

.lobby-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 34%);
  gap: 12px;
  flex: 1;
  min-height: 0;
}

.lobby-seats-panel,
.lobby-cards-panel {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.lobby-panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border-color);
}
.lobby-panel-hint {
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none;
}

/* Seat table: one row per player, the way a lobby list reads. */
.seat-table-head,
.lobby-seat-row {
  display: grid;
  grid-template-columns: 18px minmax(0, 1.5fr) minmax(0, 1.4fr) 92px auto;
  align-items: center;
  gap: 10px;
}
.seat-table-head {
  padding: 8px 4px 6px;
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.seat-table {
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow-y: auto;
  min-height: 0;
}
.lobby-seat-row {
  padding: 7px 4px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.02);
  font-size: 0.85rem;
}
.lobby-seat-row.is-you {
  border-color: var(--accent-gold);
  background: rgba(251, 191, 36, 0.08);
}
.lobby-seat-row.is-ready {
  border-color: #10b981;
}
.seat-swatch {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.5);
}
.seat-player-name {
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.seat-player-tag {
  color: var(--text-muted);
  font-weight: 700;
  font-size: 0.72rem;
  margin-left: 6px;
}
.seat-keeypling {
  color: var(--text-muted);
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.seat-keeypling strong {
  color: var(--accent-gold);
  font-weight: 700;
}
.seat-actions {
  display: flex;
  gap: 6px;
  justify-content: flex-end;
}
.seat-actions .btn-small {
  padding: 4px 10px;
  font-size: 0.72rem;
}

.lobby-watchers {
  flex-shrink: 0;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border-color);
  font-size: 0.76rem;
  color: var(--text-muted);
}
.lobby-watchers strong {
  color: #c7d2fe;
  font-weight: 700;
}

.lobby-foot {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0;
}
.lobby-foot .btn-large {
  margin-left: auto;
  padding: 10px 26px;
  font-size: 0.95rem;
}
.lobby-foot-note {
  color: var(--text-muted);
  font-size: 0.78rem;
}

/* The two dealt cards, side by side and sized to the room the panel has left. */
.lobby-cards-panel .my-dealt-cards-grid {
  flex: 1;
  min-height: 0;
  margin-top: 10px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  align-content: start;
  overflow: hidden;
}
.lobby-cards-panel .physical-dealt-wrapper {
  min-width: 0;
  width: 100%;
  max-width: none;
  gap: 5px;
}
.lobby-cards-panel .physical-keeypling-card {
  width: 100%;
  max-width: none;
}
.lobby-cards-panel .physical-keeypling-card:hover {
  transform: none;
}
/* An open seat, so the table reads as places waiting rather than a short list. */
.lobby-seat-row.is-open {
  border-style: dashed;
  border-color: var(--border-color);
  background: transparent;
  color: var(--text-muted);
  font-style: italic;
}
.lobby-cards-panel .dealt-badge {
  font-size: 0.6rem;
  padding: 2px 6px;
}
.lobby-cards-panel .btn-card-action {
  font-size: 0.7rem;
  padding: 5px 8px;
  white-space: normal;
  line-height: 1.15;
}

@media (max-width: 860px) {
  .lobby-body {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
  }
}

.lobby-header-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 20px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
}

.lobby-meta h2 {
  font-family: var(--font-serif);
  color: #fbbf24;
}
.lobby-meta p {
  color: var(--text-muted);
  font-size: 0.95rem;
}

.lobby-controls {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.share-box {
  background: var(--bg-dark);
  border: 1px solid var(--border-color);
  padding: 4px 10px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.85rem;
}

.share-box input {
  background: transparent;
  border: none;
  color: var(--accent-gold);
  width: 220px;
  padding: 4px;
}

.lobby-players-bar {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: 12px;
  padding: 16px 24px;
}

.player-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 10px;
}

.player-chip {
  background: var(--bg-elevated);
  border: 2px solid var(--border-color);
  padding: 8px 14px;
  border-radius: 30px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
}
.player-chip.is-you {
  border-color: var(--accent-gold);
  background: #382806;
}
/* A readied seat is legible at a glance from across the room. */
.player-chip.is-ready {
  border-color: #10b981;
}
.chip-ready-mark {
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(16, 185, 129, 0.18);
  border: 1px solid #10b981;
  color: #6ee7b7;
  white-space: nowrap;
}
.chip-ready-mark.is-waiting {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--border-color);
  color: var(--text-muted);
}

.section-title-box {
  margin-bottom: 16px;
}
.section-title-box h3 {
  font-family: var(--font-serif);
  color: #fff;
  font-size: 1.25rem;
  margin-bottom: 4px;
}
.section-sub-desc {
  color: var(--text-muted);
  font-size: 0.9rem;
  line-height: 1.4;
}

.my-dealt-cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 20px;
  margin-top: 14px;
}

.dealt-card {
  background: var(--bg-elevated);
  border: 2px solid var(--border-color);
  border-radius: 14px;
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4);
  transition: all 0.2s ease;
}

.dealt-card.is-primary {
  border-color: #f59e0b;
  background: var(--bg-elevated);
}

.dealt-card.is-reserve {
  border-color: #6366f1;
  background: var(--bg-elevated);
}

.dealt-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  font-weight: 800;
  padding: 4px 10px;
  border-radius: 9999px;
  width: fit-content;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.dealt-badge.badge-primary {
  background: #78350f;
  border: 1px solid #f59e0b;
  color: #fef08a;
}

.dealt-badge.badge-reserve {
  background: #312e81;
  border: 1px solid #818cf8;
  color: #e0e7ff;
}

.char-card {
  background: var(--bg-card);
  border: 2px solid var(--border-color);
  border-radius: 12px;
  padding: 16px;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  flex-direction: column;
  gap: 10px;
  position: relative;
}

/* Authentic Physical Board Game Cards */
.my-dealt-cards-grid {
  display: flex;
  gap: 24px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 16px;
}

.physical-dealt-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  max-width: 280px;
  width: 100%;
}

.physical-keeypling-card {
  width: 100%;
  max-width: 270px;
  font-family: var(--font-sans);
  user-select: none;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.physical-keeypling-card:hover {
  transform: translateY(-4px);
}

.card-outer-frame {
  background: #50545f;
  border: 3px solid #363940;
  border-radius: 18px;
  padding: 8px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255,255,255,0.15);
  display: flex;
  flex-direction: column;
  position: relative;
}

/* 3 Iconic Hanging Top Notches */
.card-notches-row {
  display: flex;
  justify-content: space-around;
  padding: 0 12px;
  margin-bottom: -8px;
  z-index: 10;
  position: relative;
}

.card-notch {
  background: #ffffff;
  border: 2px solid #2d3036;
  border-top: none;
  border-radius: 0 0 10px 10px;
  width: 44px;
  height: 48px;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* The tab hangs off the top edge, so the label needs its own headroom, and the
     value needs the same clearance under it. */
  justify-content: center;
  gap: 2px;
  padding: 5px 0 6px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.25);
}

.notch-label {
  font-size: 0.65rem;
  font-weight: 900;
  letter-spacing: 0.5px;
  line-height: 1;
}

.notch-atk .notch-label { color: #dc2626; }
.notch-def .notch-label { color: #2563eb; }
.notch-spd .notch-label { color: #374151; }
.notch-assist .notch-label { color: #059669; }

.notch-val {
  font-size: 1.15rem;
  font-weight: 900;
  color: #111827;
  line-height: 1.1;
  margin-top: 1px;
}

.notch-empty {
  visibility: hidden;
  pointer-events: none;
}

/* Inner Colored Art Body */
.card-inner-art {
  border-radius: 14px;
  height: 190px;
  border: 2px solid #2d3036;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Art sits on the middle of the colour block; the name pill is lifted out of
     the flow so it cannot push the character off centre. */
  justify-content: center;
  padding: 10px 8px 8px 8px;
}

.art-svg-wrapper {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  z-index: 2;
}

.keeyp-art-svg {
  width: 100px;
  height: 100px;
}

.card-name-pill {
  position: absolute;
  left: 50%;
  bottom: 6px;
  transform: translateX(-50%);
  background: #ffffff;
  border: 2.5px solid #1e293b;
  border-radius: 9999px;
  padding: 3px 18px;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.35);
  z-index: 3;
  margin-bottom: 0;
}

.card-name-pill span {
  font-family: var(--font-sans);
  font-size: 0.92rem;
  font-weight: 900;
  letter-spacing: 1.2px;
  color: #0f172a;
}

/* Lower Ability Box */
.card-ability-container {
  background: #252830;
  border-radius: 8px;
  padding: 8px 10px;
  margin-top: 8px;
  border: 1px solid #3d414a;
  min-height: 52px;
  display: flex;
  align-items: center;
}

.card-ability-text {
  color: #f1f5f9;
  font-size: 0.74rem;
  line-height: 1.35;
}

.card-ability-text b {
  color: #facc15;
}

.ability-uses-tag {
  color: #38bdf8;
  font-weight: 800;
}

/* Authentic Face-Down Card Back */
.physical-card-back {
  width: 100%;
  max-width: 270px;
  user-select: none;
}

.back-frame {
  height: 290px;
  position: relative;
  overflow: hidden;
  justify-content: center;
  align-items: center;
}

.quadrant-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  width: 100%;
  height: 100%;
  border-radius: 12px;
  overflow: hidden;
  border: 2px solid #2d3036;
}

.quad-pink { background: #e11d48; }
.quad-blue { background: #0284c7; }
.quad-yellow { background: #eab308; }
.quad-green { background: #16a34a; }

.back-center-pill {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #ffffff;
  border: 2.5px solid #1e293b;
  border-radius: 9999px;
  padding: 6px 18px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  z-index: 5;
}

.back-center-pill span {
  font-family: var(--font-sans);
  font-weight: 900;
  font-size: 0.85rem;
  letter-spacing: 1.5px;
  color: #0f172a;
}

/* Compact Tabletop Card System (126px x 154px - authentic playing card aspect ratio) */
.physical-keeypling-card.compact,
.physical-item-card.compact,
.physical-card-back.compact {
  width: var(--card-w);
  height: var(--card-h);
  max-width: var(--card-w);
  max-height: var(--card-h);
  zoom: var(--card-scale, 1);
  box-sizing: border-box;
  font-family: var(--font-sans);
  user-select: none;
  flex-shrink: 0;
}

.physical-keeypling-card.compact .card-outer-frame,
.physical-card-back.compact .card-outer-frame {
  width: var(--card-w);
  height: var(--card-h);
  max-width: var(--card-w);
  max-height: var(--card-h);
  border-radius: 9px;
  padding: 4px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border: 2px solid #282b32;
  background: #464a55;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.15);
  position: relative;
}

.physical-keeypling-card.compact .card-notches-row {
  display: flex;
  justify-content: space-around;
  padding: 0 1px;
  margin-top: 0;
  margin-bottom: 2px;
  height: 28px;
  z-index: 10;
}

.physical-keeypling-card.compact .card-notch {
  width: 32px;
  height: 28px;
  border-radius: 0 0 5px 5px;
  border: 1.5px solid #282b32;
  border-top: none;
  background: #ffffff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  padding: 3px 0 4px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.physical-keeypling-card.compact .notch-label {
  font-size: 0.56rem;
  font-weight: 900;
  line-height: 1;
  letter-spacing: 0.3px;
}

.physical-keeypling-card.compact .notch-val {
  font-size: 0.86rem;
  font-weight: 900;
  line-height: 1;
  margin-top: 1px;
}

.physical-keeypling-card.compact .card-inner-art {
  height: 88px;
  min-height: 88px;
  max-height: 88px;
  border-radius: 6px;
  border: 1.5px solid #282b32;
  padding: 2px 3px 2px 3px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.physical-keeypling-card.compact .art-svg-wrapper {
  flex: 0 0 auto;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 0;
  z-index: 2;
}

.physical-keeypling-card.compact .keeyp-art-svg {
  width: 46px;
  height: 46px;
}

.physical-keeypling-card.compact .card-name-pill {
  background: #ffffff;
  border: 1.5px solid #1e293b;
  border-radius: 9999px;
  padding: 1px 6px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.35);
  z-index: 3;
  bottom: 3px;
  margin-bottom: 0;
  white-space: nowrap;
  max-width: 95%;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: center;
}

.physical-keeypling-card.compact .card-name-pill span {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 900;
  letter-spacing: 0.4px;
  color: #0f172a;
  line-height: 1.1;
  display: block;
}

.physical-keeypling-card.compact .card-ability-container {
  background: #1e222b;
  border-radius: 5px;
  padding: 2px 4px;
  margin-top: 2px;
  border: 1px solid #333c4d;
  flex: 1 1 auto;
  min-height: 0;
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  overflow: hidden;
}

.physical-keeypling-card.compact .card-ability-text {
  color: #f1f5f9;
  font-size: 0.7rem;
  line-height: 1.25;
  overflow: hidden;
  margin: 0;
}

/* Compact Face-Down Card Back */
.physical-card-back.compact .back-frame {
  height: 154px;
  max-height: 154px;
  padding: 4px;
  box-sizing: border-box;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  overflow: hidden;
}

.physical-card-back.compact .quadrant-grid {
  border-radius: 6px;
  border: 1.5px solid #282b32;
  width: 100%;
  height: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  overflow: hidden;
}

.physical-card-back.compact .back-center-pill {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #ffffff;
  border: 2px solid #1e293b;
  border-radius: 9999px;
  padding: 2px 7px;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.6);
  white-space: nowrap;
  z-index: 5;
}

.physical-card-back.compact .back-center-pill span {
  font-family: var(--font-sans);
  font-weight: 900;
  font-size: 0.56rem;
  letter-spacing: 0.5px;
  color: #0f172a;
}

/* Miniature Die SVG */
.keeyp-die-svg {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.5));
}

.btn-card-action {
  width: 100%;
  padding: 10px 16px;
  font-size: 0.9rem;
}

/* Tabletop Board Game Layout */
#view-game {
  flex: 1;
  min-height: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  background: var(--table-felt);
  user-select: none;
}

/* Top Bar: room, turn state, match controls. No player list here. */
.game-top-bar {
  height: 52px;
  background: var(--hud-surface);
  border-bottom: 1px solid var(--hud-line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 14px;
  gap: 16px;
  z-index: 60;
  flex-shrink: 0;
}

.top-bar-left,
.top-bar-right {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.top-bar-center {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex: 1 1 auto;
  min-width: 0;
}

.top-room-pill {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 10px;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  cursor: pointer;
}
.top-room-pill:hover {
  border-color: var(--accent);
}
.room-pill-label {
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.room-pill-code {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--text-main);
}

.turn-indicator {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 12px;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  min-width: 0;
}
.turn-indicator.is-my-turn {
  border-color: var(--accent);
}
.turn-indicator #turn-avatar {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.turn-title {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-main);
  white-space: nowrap;
}
.turn-sub {
  font-size: 0.7rem;
  color: var(--text-muted);
  white-space: nowrap;
}

/* The lobby, seen by someone without a seat. */
.spectator-invite {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 28px 20px;
  text-align: center;
  color: var(--text-muted);
  border: 1px dashed var(--border-color);
  border-radius: 12px;
  max-width: 460px;
  margin: 0 auto;
}
.spectator-invite p {
  margin: 0;
  font-size: 0.9rem;
}

/* Says who is watching without a seat, and tells a watcher that is them. */
.watching-pill {
  display: flex;
  align-items: center;
  padding: 5px 12px;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--text-muted);
  white-space: nowrap;
}
.watching-pill.is-me {
  border-color: #a5b4fc;
  color: #c7d2fe;
}

/* Host's turn clock, in the same HUD frame as the turn and Key readouts. */
.turn-clock {
  display: flex;
  align-items: center;
  padding: 5px 12px;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-main);
  white-space: nowrap;
}
/* Last ten seconds: the frame warms up rather than shouting. */
.turn-clock.is-low {
  border-color: var(--accent);
  color: var(--accent);
}
.turn-clock.is-out {
  border-color: var(--hp-red);
  color: var(--hp-red);
}

.host-setting {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.78rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.host-setting-select {
  background: var(--bg-dark);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  color: var(--text-main);
  padding: 5px 8px;
  font: inherit;
  font-weight: 700;
}
.host-setting-select:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.key-status-tracker {
  display: flex;
  align-items: center;
  padding: 5px 12px;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  font-size: 0.75rem;
  color: var(--text-muted);
  white-space: nowrap;
}
.key-status-tracker.key-live {
  border-color: var(--accent);
  color: var(--accent);
}

.btn-hud {
  padding: 6px 12px;
  font-size: 0.78rem;
  font-weight: 700;
  font-family: inherit;
  border-radius: 4px;
  background: transparent;
  border: 1px solid var(--hud-line);
  color: var(--text-main);
  cursor: pointer;
}
.btn-hud:hover:not(:disabled) {
  border-color: var(--accent);
}
.btn-hud:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.btn-hud-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.btn-hud-primary:hover:not(:disabled) {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
}

.hud-zoom-group {
  display: flex;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  overflow: hidden;
}
.hud-zoom-group .btn-icon-hud {
  border: none;
  border-right: 1px solid var(--hud-line);
  border-radius: 0;
}
.hud-zoom-group .btn-icon-hud:last-child {
  border-right: none;
}

.btn-icon-hud {
  min-width: 30px;
  height: 30px;
  padding: 0 8px;
  font-size: 0.78rem;
  font-weight: 700;
  font-family: inherit;
  background: transparent;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  color: var(--text-muted);
  cursor: pointer;
}
.btn-icon-hud:hover {
  color: var(--text-main);
  border-color: var(--accent);
}

/* Player Seats: one column down the left of the table, in seat order.
   Never scrolls. */
.seat-ring {
  position: absolute;
  top: 12px;
  left: 24px;
  bottom: calc(var(--footer-h) + 12px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  pointer-events: none;
  z-index: 40;
}

.player-seat {
  pointer-events: auto;
  width: 146px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 7px 9px;
  background: var(--hud-surface);
  border: 1px solid var(--hud-line);
  border-radius: 4px;
}
.player-seat.is-active-turn {
  border-color: var(--accent);
}
.player-seat.is-me .seat-name {
  color: var(--accent);
}
.player-seat.is-eliminated {
  opacity: 0.4;
}

.seat-row {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.seat-avatar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.seat-name {
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--text-main);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.seat-sub {
  font-size: 0.68rem;
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.seat-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.68rem;
  color: var(--text-muted);
}
.seat-hp {
  font-weight: 700;
  color: var(--hp-red);
}
/* Where this seat sits in the turn order rolled at the start of the match. */
.seat-order {
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
}
/* The Key rides beside its carrier's name, sized to the text around it. */
.seat-key-mark {
  width: 0.95em;
  height: 0.95em;
  vertical-align: -0.14em;
  margin-left: 5px;
  filter: drop-shadow(0 0 4px rgba(251, 191, 36, 0.55));
}
.btn-seat-play {
  margin-top: 2px;
  padding: 2px 0;
  font-size: 0.66rem;
  font-weight: 700;
  font-family: inherit;
  background: transparent;
  border: 1px solid var(--hud-line);
  border-radius: 3px;
  color: var(--text-muted);
  cursor: pointer;
}
.btn-seat-play:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* Non-blocking rule notices */
.toast-stack {
  position: absolute;
  bottom: calc(var(--footer-h) + 20px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  z-index: 200;
  pointer-events: none;
}
.toast {
  padding: 8px 16px;
  background: var(--hud-surface);
  border: 1px solid var(--hud-line);
  border-left: 3px solid var(--accent);
  border-radius: 4px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-main);
  max-width: 460px;
  opacity: 1;
  transition: opacity 0.25s ease;
}
.toast.is-leaving {
  opacity: 0;
}
.game-arena {
  flex: 1;
  min-height: 0;
  display: flex;
  position: relative;
  overflow: hidden;
  background: var(--table-felt);
}

/* Dungeon 2D Viewport */
.dungeon-viewport {
  flex: 1;
  min-height: 0;
  min-width: 0;
  height: 100%;
  overflow: hidden;
  position: relative;
  cursor: grab;
  user-select: none;
}
.dungeon-viewport:active {
  cursor: grabbing;
}

.dungeon-grid {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  transform-origin: 0 0;
  transition: transform 0.15s ease-out;
}

/* Dungeon Tiles */
.tile-node {
  position: absolute;
  width: var(--tile-size);
  height: var(--tile-size);
  background: #1c1f27;
  /* No border: the card art draws its own edge, and a border here would stack
     with the neighbour's into a seam between tiles. State highlights use an
     inset ring, which paints inside the tile instead of between two. */
  border: none;
  border-radius: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: default;
}

.tile-art-wrapper {
  width: 100%;
  height: 100%;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s ease;
}

.tile-art-svg {
  width: 100%;
  height: 100%;
  display: block;
}



/* Movement range, drawn like a tactics grid: the whole reachable area is shaded
   one colour, and hovering a destination traces the route to it. No pulsing. */
.tile-node.valid-move {
  cursor: pointer;
}

/* A line of sight, drawn the way the reachable range is: a field over the
   chambers the ability can run down. Amber rather than blue, because it is a
   line of attack and not somewhere to walk. */
.sight-field {
  position: absolute;
  inset: 0;
  background: rgba(251, 191, 36, 0.16);
  box-shadow: inset 0 0 0 2px rgba(251, 191, 36, 0.4);
  pointer-events: none;
  z-index: 5; /* under the move field, which the player can actually walk */
}

/* The chamber at the end of a line, holding whoever can be aimed at. */
.tile-node.sight-target .sight-field {
  background: rgba(251, 191, 36, 0.3);
  box-shadow: inset 0 0 0 3px rgba(251, 191, 36, 0.85);
}

/* How much range adds to the attack, for Blue Jazz. */
.tile-node.sight-target .sight-field::after {
  content: attr(data-range);
  position: absolute;
  top: 4px;
  right: 5px;
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.04em;
  color: #1c1608;
  background: rgba(251, 191, 36, 0.92);
  border-radius: 3px;
  padding: 1px 4px;
}

.move-field {
  position: absolute;
  inset: 0;
  background: rgba(59, 130, 246, 0.28);
  box-shadow: inset 0 0 0 2px rgba(96, 165, 250, 0.55);
  pointer-events: none;
  z-index: 6; /* over the tile art, under pawns (12) and the label (10) */
}
.tile-node.valid-move:hover .move-field {
  background: rgba(96, 165, 250, 0.42);
}

/* A chamber an ability is being aimed at. Orange rather than the blue of walking,
   because it is somewhere the card sends you, not somewhere you can step. The
   board is the menu: no coordinates are printed anywhere. */
.tile-node.ability-target {
  cursor: pointer;
}
.ability-field {
  position: absolute;
  inset: 0;
  background: rgba(245, 158, 11, 0.3);
  box-shadow: inset 0 0 0 3px var(--accent-hi);
  pointer-events: none;
  z-index: 7; /* over the move field, under pawns (12) and the label (10) */
  animation: ability-target-pulse 1.25s ease-in-out infinite;
}
.tile-node.ability-target:hover .ability-field {
  background: rgba(251, 191, 36, 0.5);
  animation: none;
}
@keyframes ability-target-pulse {
  0%, 100% { background: rgba(245, 158, 11, 0.22); }
  50% { background: rgba(245, 158, 11, 0.42); }
}

/* The bar says what is being aimed; the chambers themselves say where. */
.ability-pick-hint {
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--text-muted);
  align-self: center;
}

/* Tiles along the previewed route read brighter than the rest of the field. */
.tile-node.on-path .move-field {
  background: rgba(96, 165, 250, 0.45);
  box-shadow: inset 0 0 0 2px rgba(191, 219, 254, 0.75);
}
.tile-node.is-path-target {
  box-shadow: inset 0 0 0 2px #dbeafe;
}
.tile-node.is-path-target .move-field {
  background: rgba(147, 197, 253, 0.55);
}

/* The route reads as one continuous arrow: half-length stubs meet at each tile
   centre so neighbours join into an unbroken line, with a single head at the end. */
.path-stub {
  position: absolute;
  background: #eff6ff;
  opacity: 0.9;
  pointer-events: none;
  z-index: 8;
}
/* Each stub runs from the named edge to the centre of the tile. */
.path-stub-n { left: 50%; top: 0; width: 12px; height: 50%; margin-left: -6px; }
.path-stub-s { left: 50%; bottom: 0; width: 12px; height: 50%; margin-left: -6px; }
.path-stub-w { top: 50%; left: 0; height: 12px; width: 50%; margin-top: -6px; }
.path-stub-e { top: 50%; right: 0; height: 12px; width: 50%; margin-top: -6px; }

.path-head {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
  z-index: 9;
}
/* Solid triangle pointing the way the Keeypling arrives. */
.path-head.path-n {
  margin: -30px 0 0 -17px;
  border-left: 17px solid transparent;
  border-right: 17px solid transparent;
  border-bottom: 24px solid #eff6ff;
}
.path-head.path-s {
  margin: 6px 0 0 -17px;
  border-left: 17px solid transparent;
  border-right: 17px solid transparent;
  border-top: 24px solid #eff6ff;
}
.path-head.path-e {
  margin: -17px 0 0 6px;
  border-top: 17px solid transparent;
  border-bottom: 17px solid transparent;
  border-left: 24px solid #eff6ff;
}
.path-head.path-w {
  margin: -17px 0 0 -30px;
  border-top: 17px solid transparent;
  border-bottom: 17px solid transparent;
  border-right: 24px solid #eff6ff;
}
.path-head.path-warp {
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  background: #eff6ff;
}

/* Movement cost, revealed only for the space under the cursor. */
.move-cost {
  position: absolute;
  top: 4px;
  right: 4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 3px;
  background: #0b1220;
  border: 1px solid rgba(191, 219, 254, 0.8);
  color: #eff6ff;
  font-size: 0.62rem;
  font-weight: 800;
  line-height: 16px;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  z-index: 14;
}
.tile-node.valid-move:hover .move-cost,
.tile-node.is-path-target .move-cost {
  opacity: 1;
}

/* Whose turn it is, marked on the board itself. */
.board-token.is-active-turn {
  border-color: #fde68a;
  box-shadow: 0 0 0 3px rgba(253, 230, 138, 0.45);
  z-index: 13;
}
/* Turn marker sits with the name in the seat list, where names are read. */
.seat-turn-caret {
  flex-shrink: 0;
  color: var(--accent);
  font-size: 0.7rem;
  line-height: 1;
}

.tile-explorable {
  position: absolute;
  width: var(--tile-size);
  height: var(--tile-size);
  border: 2px dashed var(--reach-blue);
  border-radius: 0;
  background: rgba(59, 130, 246, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--reach-blue);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.tile-explorable:hover {
  background: rgba(59, 130, 246, 0.22);
  border-color: #93c5fd;
  color: #dbeafe;
}

/* Pending Tile Placement Preview directly on Board */
.tile-node.pending-placement {
  box-shadow: inset 0 0 0 2px var(--accent);
  z-index: 25;
  cursor: pointer;
}
.tile-node.pending-placement .pending-pill {
  background: #facc15 !important;
  color: #0f172a !important;
  font-weight: 900 !important;
  border: 1px solid #ca8a04 !important;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.passage-indicator.passage-pending {
  background: #facc15 !important;
  box-shadow: 0 0 12px #facc15 !important;
}

.tile-icon {
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #f1f5f9;
  text-transform: uppercase;
  background: rgba(0, 0, 0, 0.3);
  padding: 2px 5px;
  border-radius: 4px;
}
.tile-label {
  font-size: 0.68rem;
  font-weight: 700;
  color: #cbd5e1;
  text-align: center;
  margin-top: 2px;
}

/* Passage Openings on Tile (Matches 50px Roadway) */
/* Only the chamber being placed carries these, so they can glow. */
.passage-indicator {
  position: absolute;
  background: #cbd5e1;
  box-shadow: 0 0 6px rgba(203, 213, 225, 0.6);
  border-radius: 2px;
  z-index: 5;
}
.passage-n { top: -2px; left: calc(50% - 24px); width: 48px; height: 4px; }
.passage-e { right: -2px; top: calc(50% - 24px); width: 4px; height: 48px; }
.passage-s { bottom: -2px; left: calc(50% - 24px); width: 48px; height: 4px; }
.passage-w { left: -2px; top: calc(50% - 24px); width: 4px; height: 48px; }

/* Player Tokens on Board */
/* Pawns sit in the middle of the chamber, where the eye goes first, and every
   one on the tile is drawn. Past four they wrap onto a second line and shrink,
   so a full six-player pile still fits inside 140px with nothing hidden. */
.players-on-tile {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  gap: 3px;
  /* An explicit width, not a max: the box is anchored from its left edge, so
     shrink-to-fit would only offer it the half-tile to the right of centre and
     the row would wrap two-wide instead of four. */
  width: calc(var(--tile-size) - 12px);
  z-index: 12;
}
.players-on-tile.is-crowded {
  gap: 2px;
}
.players-on-tile.is-crowded .board-token {
  width: 25px;
  height: 25px;
}

.board-token {
  width: 29px;
  height: 29px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.95rem;
  border: 2px solid #0f1118;
  overflow: hidden;
}
.board-token.has-key {
  border-color: var(--accent);
}

body.in-game .app-header {
  display: none !important;
}

.top-room-pill {
  background: #1e2430;
  border: 1px solid #374151;
  padding: 3px 10px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.8rem;
  cursor: pointer;
  transition: all 0.2s;
}
.top-room-pill:hover {
  background: #283142;
  border-color: #fbbf24;
}

/* Bottom Tabletop Dashboard */
.game-bottom-bar {
  /* The station floats over the arena rather than taking a slice out of it, so
     the dungeon can be panned under it instead of disappearing behind a wall.
     Everything in here paints its own background; the bar itself has none. */
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* Short laptop viewports need a bigger share of the screen here, or the cards
     scale down to unreadable. The board scales itself to whatever is left. */
  height: var(--footer-h);
  background: transparent;
  border-top: none;
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  padding: 6px 14px;
  gap: 14px;
  z-index: 50;
  /* The bar floats over the board, and most of it is empty air: the gap above
     the cards, the blank middle beside the hand. None of that may swallow a
     click meant for the chamber underneath, so the bar and its columns are
     transparent to the pointer and only the painted parts take clicks back. */
  pointer-events: none;
}
.game-bottom-bar > * {
  pointer-events: none;
}
.game-bottom-bar .hp-die-container,
.game-bottom-bar .bottom-cards-cluster,
.game-bottom-bar .inv-title-row,
.game-bottom-bar .discard-banner,
.game-bottom-bar .poker-card-wrapper,
.game-bottom-bar .decks-row {
  pointer-events: auto;
}
/* The header rows are full-width strips holding a small label at one end, so
   they stay transparent and only what is painted in them takes a click. */
.game-bottom-bar .keeypling-station-header,
.game-bottom-bar .inventory-station-header,
.game-bottom-bar .poker-hand-fanout {
  pointer-events: none;
}

/* Bottom Left: Keeypling Station */
.bottom-keeypling-station {
  width: 400px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: none;
  border: none;
  border-radius: 0;
  /* 14px of footer padding plus 4px here puts the card edge 18px in, the same
     inset the End Turn button keeps on the right. */
  padding: 8px 12px 8px 4px;
  position: relative;
}
.bottom-keeypling-station .bottom-cards-cluster {
  justify-content: flex-start;
}
.keeypling-station-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2px;
}
.hp-die-container {
  display: flex;
  align-items: center;
  justify-content: center;
}
.bottom-cards-cluster {
  display: flex;
  gap: 10px;
  flex: 1;
  min-height: 0;
  align-items: flex-start;
  justify-content: center;
}
.primary-card-slot {
  width: 158px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}
.backup-card-slot {
  width: 158px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}
.slot-badge {
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  padding: 1px 6px;
  border-radius: 3px;
  margin-bottom: 2px;
  text-transform: uppercase;
  white-space: nowrap;
  line-height: 1.3;
  background: transparent;
}
.slot-badge.active-badge {
  color: var(--accent);
  border: 1px solid var(--accent);
}
.slot-badge.reserve-badge-tag {
  color: var(--text-muted);
  border: 1px solid var(--hud-line);
}
.primary-card-slot #my-physical-card-container,
.backup-card-slot #reserve-card-container {
  width: calc(var(--card-w) * var(--card-scale, 1));
  height: calc(var(--card-h) * var(--card-scale, 1));
  overflow: visible;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: none;
}

/* Bottom Center: Poker Fanout Inventory */
.bottom-inventory-station {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: none;
  border: none;
  border-radius: 0;
  padding: 8px 12px;
  position: relative;
}
.inventory-station-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2px;
}
.inv-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.inv-title {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.inv-count-pill {
  font-size: 0.68rem;
  font-weight: 700;
  background: transparent;
  border: 1px solid var(--hud-line);
  color: var(--text-muted);
  padding: 1px 7px;
  border-radius: 3px;
}
.discard-banner {
  background: transparent;
  color: var(--hp-red);
  font-size: 0.7rem;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 3px;
  border: 1px solid var(--hp-red);
}

.poker-hand-fanout {
  flex: 1;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  position: relative;
  width: 100%;
  height: 170px;
}
/* Individual Poker Fanout Item Card */
.poker-card-wrapper {
  position: absolute;
  /* Rotation pivots on the bottom centre, so the fanned cards swing their lower
     corners down; this offset keeps them inside the footer. */
  bottom: 26px;
  width: calc(var(--card-w) * var(--card-scale, 1));
  height: calc(var(--card-h) * var(--card-scale, 1));
  cursor: pointer;
  transform-origin: 50% 100%;
  /* Transform carries the whole fan layout, so hover animates in one property. */
  transition: transform 0.22s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.22s;
}
/* The card that pushed the hand over its limit, called out so the choice about
   which one to put back is made with it in view rather than hidden. */
.poker-card-wrapper.is-just-drawn .physical-item-card {
  box-shadow: 0 0 0 3px var(--accent-hi), 0 10px 26px rgba(0, 0, 0, 0.6);
}
.just-drawn-tag {
  position: absolute;
  top: -11px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 2px 9px;
  border-radius: 9999px;
  background: var(--accent-hi);
  color: var(--accent-ink);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  pointer-events: none;
  z-index: 2;
}
.poker-card-wrapper.is-lifted {
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.95), 0 0 14px rgba(251, 191, 36, 0.5);
}
.poker-card-wrapper .physical-item-card {
  width: var(--card-w);
  height: var(--card-h);
  transform: none;
}
.poker-card-actions {
  position: absolute;
  bottom: 6px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 4px;
  z-index: 20;
  opacity: 0;
  transition: opacity 0.2s;
  pointer-events: none;
}
.poker-card-actions button {
  font-size: 0.65rem;
  padding: 2px 8px;
  font-weight: 800;
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.8);
}
.poker-card-wrapper:hover .poker-card-actions,
.poker-card-wrapper.hovered .poker-card-actions {
  opacity: 1;
  pointer-events: auto;
}

/* Bottom Right: Decks Station */
.bottom-decks-station {
  width: 214px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: none;
  border: none;
  border-radius: 0;
  padding: 8px 10px;
  justify-content: center;
  align-items: center;
}
.decks-row {
  display: flex;
  gap: 14px;
  align-items: center;
  justify-content: center;
}
.deck-container {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.tabletop-deck-wrapper {
  position: relative;
  cursor: pointer;
  user-select: none;
  transition: transform 0.2s ease;
}
.tabletop-deck-wrapper:hover {
  transform: translateY(-3px);
}
.tabletop-deck-wrapper:hover {
  transform: translateY(-4px);
}
.deck-shadow-stack {
  position: absolute;
  inset: 0;
  border-radius: 8px;
  /* Stacked card edges, each one a little darker as it recedes. */
  box-shadow:
    0 3px 0 #39404e, 0 6px 0 #2b313d, 0 9px 0 #232832,
    0 12px 0 #1a1e26, 0 15px 0 #14171e,
    0 22px 26px rgba(0, 0, 0, 0.75);
  pointer-events: none;
}
.deck-card-top {
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  background: #1e222a;
  border: 1px solid #4a5262;
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, 0.08), inset 0 -3px 6px rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}
.square-deck-card {
  width: 65px;
  height: 65px;
}
.rect-deck-card {
  width: 65px;
  height: 88px;
}
.deck-top-svg {
  width: 100%;
  height: 100%;
  display: block;
}
.deck-center-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: rgba(15, 23, 42, 0.88);
  border: 1px solid #fbbf24;
  border-radius: 4px;
  padding: 1px 6px;
  font-family: var(--font-serif);
  font-size: 0.65rem;
  font-weight: 900;
  letter-spacing: 1px;
  color: #fbbf24;
  pointer-events: none;
}
.deck-center-label.treasure-label {
  border-color: #f59e0b;
  color: #fef08a;
}
.deck-count-pill {
  position: absolute;
  top: 3px;
  right: 3px;
  background: var(--table-felt);
  border: 1px solid var(--hud-line);
  color: var(--text-main);
  font-size: 0.65rem;
  font-weight: 700;
  padding: 1px 5px;
  border-radius: 3px;
}
.deck-title-label {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--text-muted);
  margin-top: 6px;
  text-align: center;
  white-space: nowrap;
}

/* Slide-over Dungeon Action Log Drawer */
.dungeon-log-drawer {
  position: absolute;
  top: 52px;
  right: 0;
  bottom: var(--footer-h);
  width: var(--log-w);
  background: rgba(17, 21, 30, 0.96);
  backdrop-filter: blur(10px);
  border-left: 2px solid #333d4f;
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.75);
  display: flex;
  flex-direction: column;
  z-index: 80;
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.dungeon-log-drawer.hidden {
  transform: translateX(100%);
  pointer-events: none;
}
.drawer-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid #2d3444;
}
.drawer-header h4 {
  margin: 0;
  font-family: var(--font-serif);
  color: #fbbf24;
  font-size: 0.9rem;
}
.btn-close-drawer {
  background: transparent;
  border: none;
  color: #94a3b8;
  font-size: 1.3rem;
  cursor: pointer;
}
.btn-close-drawer:hover {
  color: #fff;
}
.action-log-drawer-body {
  flex: 1;
  overflow-y: auto;
  padding: 10px 14px;
  display: flex;
  flex-direction: column-reverse;
  gap: 6px;
  font-size: 0.78rem;
  line-height: 1.4;
}

.log-item {
  background: var(--bg-dark);
  padding: 4px 8px;
  border-radius: 4px;
  border-left: 3px solid #4b5563;
}
.log-item.move { border-left-color: #3b82f6; }
.log-item.tile { border-left-color: #eab308; }
.log-item.item { border-left-color: #10b981; }
.log-item.combat { border-left-color: #ef4444; }
.log-item.win { border-left-color: #a855f7; }

/* Floating Placement Bar */
.placement-bar {
  position: absolute;
  bottom: calc(var(--footer-h) + 10px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--hud-surface);
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 10px 18px;
  display: flex;
  align-items: center;
  gap: 16px;
  z-index: 70;
}

.placement-preview {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tile-mini-preview {
  width: 44px;
  height: 44px;
  background: #334155;
  border: 2px solid #cbd5e1;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
}

.placement-preview {
  display: flex;
  align-items: center;
  gap: 12px;
}

.tile-mini-preview {
  width: 44px;
  height: 44px;
  background: #334155;
  border: 2px solid #cbd5e1;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
}

/* Modals */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.8);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
}

.modal-dialog {
  background: var(--bg-card);
  border: 2px solid var(--border-color);
  border-radius: 16px;
  max-width: 580px;
  width: 90%;
  max-height: 90vh;
  max-height: 90dvh;
  overflow-y: auto;
  padding: 28px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.9);
}

/* ── The parley table ──────────────────────────────────────────────────────
   The fight is settled the way terms are settled: two sides seated across a
   balance, each with a card face down in front of them. Carved bronze frame,
   vellum ground, inscriptional capitals, and a beam that leans toward whoever
   is winning. Everything here is scoped to .parley so the rest of the game's
   flat dark HUD is untouched. */
.parley {
  --vellum: #d9c7a1;
  --vellum-deep: #c3ab80;
  --vellum-shadow: rgba(64, 44, 18, 0.28);
  --ink: #2b1e0f;
  --ink-soft: #6b5636;
  --oak: #17110a;
  --bronze: #9c7735;
  --bronze-hi: #e3c07a;
  --oxide: #7d2a17;
  --verdigris: #2c5a51;

  position: relative;
  max-width: 780px;
  padding: 0;
  border: 2px solid var(--bronze);
  border-radius: 3px;
  color: var(--ink);
  font-family: var(--font-sans);
  /* Vellum: a warm sheet, darker at the edges where it has been handled, with
     a faint mottle standing in for the grain. */
  background:
    radial-gradient(circle at 22% 18%, rgba(120, 90, 40, 0.06) 0 12px, transparent 13px),
    radial-gradient(circle at 74% 62%, rgba(120, 90, 40, 0.05) 0 18px, transparent 19px),
    radial-gradient(circle at 46% 88%, rgba(120, 90, 40, 0.05) 0 14px, transparent 15px),
    radial-gradient(120% 90% at 50% 0%, rgba(255, 244, 214, 0.55), transparent 60%),
    radial-gradient(80% 60% at 18% 100%, var(--vellum-shadow), transparent 70%),
    linear-gradient(180deg, var(--vellum), var(--vellum-deep));
  box-shadow:
    inset 0 0 0 13px var(--oak),
    inset 0 0 0 14px var(--bronze),
    inset 0 0 46px rgba(90, 62, 26, 0.32),
    0 26px 60px rgba(0, 0, 0, 0.85);
}

/* Four bronze studs where the frame is pinned to the board. */
.parley::before {
  content: '';
  position: absolute;
  inset: 3px;
  pointer-events: none;
  background-image:
    radial-gradient(circle, var(--bronze-hi) 0 2px, #6d4f20 3px, transparent 4px),
    radial-gradient(circle, var(--bronze-hi) 0 2px, #6d4f20 3px, transparent 4px),
    radial-gradient(circle, var(--bronze-hi) 0 2px, #6d4f20 3px, transparent 4px),
    radial-gradient(circle, var(--bronze-hi) 0 2px, #6d4f20 3px, transparent 4px);
  background-size: 12px 12px;
  background-repeat: no-repeat;
  background-position: left top, right top, left bottom, right bottom;
}

.parley-head {
  padding: 26px 30px 14px;
  text-align: center;
}

.combat-banner {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  font-weight: 900;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-transform: uppercase;
  color: var(--oxide);
  text-shadow: 0 1px 0 rgba(255, 246, 219, 0.7);
}

.parley-subhead {
  margin-top: 8px;
  font-size: 0.8rem;
  font-style: italic;
  color: var(--ink-soft);
}
/* The rule under the title is drawn as an inlaid bronze band, the way the
   frame is, rather than as another border. */
.parley-subhead::after {
  content: '';
  display: block;
  width: 220px;
  max-width: 70%;
  height: 3px;
  margin: 12px auto 0;
  background: linear-gradient(90deg, transparent, var(--bronze) 18%, var(--bronze-hi) 50%, var(--bronze) 82%, transparent);
}

.combatants-row {
  display: grid;
  grid-template-columns: 1fr 96px 1fr;
  align-items: stretch;
  gap: 14px;
  padding: 4px 26px 18px;
}

/* Each side sits on its own sunken vellum panel, headed by a coloured band:
   oxide red for the one swinging, verdigris for the one holding. */
.combatant-box {
  position: relative;
  padding: 0 16px 16px;
  text-align: center;
  border: 1px solid var(--bronze);
  border-radius: 2px;
  background: linear-gradient(180deg, rgba(255, 249, 228, 0.5), rgba(150, 118, 66, 0.16));
  box-shadow: inset 0 1px 0 rgba(255, 250, 232, 0.6), inset 0 -14px 26px rgba(94, 66, 28, 0.14);
}
.combatant-box.attacker { --side: var(--oxide); }
.combatant-box.defender { --side: var(--verdigris); }

.combatant-role {
  margin: 0 -16px 14px;
  padding: 6px 0 5px;
  font-family: var(--font-serif);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  text-transform: uppercase;
  color: #f4e6c6;
  background: var(--side);
  box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.35), 0 1px 0 var(--bronze);
}

/* Portrait medallion: the Keeypling set in a bronze coin. */
.parley-portrait {
  width: 66px;
  height: 66px;
  margin: 0 auto 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle at 34% 28%, var(--bronze-hi), var(--bronze) 58%, #6d4f20);
  box-shadow: inset 0 2px 4px rgba(255, 240, 200, 0.5), inset 0 -3px 6px rgba(0, 0, 0, 0.45), 0 2px 6px rgba(40, 26, 8, 0.5);
}

.combatant-avatar {
  font-size: 2rem;
  line-height: 1;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
}

.combatant-box h3 {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
}

/* Engraved plate for the printed stat. */
.stat-box {
  margin: 8px 0 12px;
  padding: 5px 8px;
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  border-top: 1px solid rgba(120, 92, 44, 0.45);
  border-bottom: 1px solid rgba(120, 92, 44, 0.45);
}

.parley-slot-label {
  display: block;
  font-size: 0.68rem;
  font-style: italic;
  color: var(--ink-soft);
  margin-bottom: 4px;
}

.combat-item-select {
  width: 100%;
  padding: 6px 8px;
  font-family: inherit;
  font-size: 0.78rem;
  color: var(--ink);
  background: rgba(255, 250, 232, 0.72);
  border: 1px solid var(--bronze);
  border-radius: 2px;
  box-shadow: inset 0 1px 3px rgba(90, 62, 26, 0.3);
}
.combat-item-select:disabled {
  color: var(--ink-soft);
  background: rgba(163, 137, 88, 0.28);
}

.parley .btn-lock-card {
  margin-top: 7px;
  padding: 6px 8px;
  font-family: var(--font-serif);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #f6ead0;
  border: 1px solid #6d4f20;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--bronze-hi), var(--bronze) 45%, #74551f);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.6), 0 1px 2px rgba(40, 26, 8, 0.5);
  text-shadow: 0 1px 1px rgba(45, 30, 8, 0.55);
  cursor: pointer;
}
.parley .btn-lock-card:hover:not(:disabled) {
  background: linear-gradient(180deg, #f0d194, var(--bronze-hi) 45%, var(--bronze));
  color: #2b1e0f;
}
.parley .btn-lock-card:disabled {
  opacity: 1;
  color: var(--ink-soft);
  background: rgba(163, 137, 88, 0.3);
  border-color: rgba(109, 79, 32, 0.5);
  box-shadow: none;
  text-shadow: none;
  cursor: not-allowed;
}

/* A card that is down gets a wax mark beside the word, so the state reads at
   a glance from across the table. */
.parley .card-state {
  margin-top: 6px;
  font-size: 0.68rem;
  font-style: italic;
  font-weight: 400;
  color: var(--ink-soft);
}
.parley .card-state.is-ready {
  font-style: normal;
  font-weight: 700;
  color: var(--oxide);
}
.parley .card-state.is-ready::before {
  content: '';
  display: inline-block;
  width: 9px;
  height: 9px;
  margin-right: 6px;
  border-radius: 50%;
  vertical-align: -1px;
  background: radial-gradient(circle at 35% 30%, #b8391f, #6d1f11);
  box-shadow: 0 1px 2px rgba(50, 14, 6, 0.6);
}

.parley-tally {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 3px double rgba(120, 92, 44, 0.5);
}
.parley-tally-label {
  display: block;
  font-size: 0.66rem;
  font-style: italic;
  color: var(--ink-soft);
}
.combat-total {
  font-family: var(--font-serif);
  font-size: 2rem;
  font-weight: 900;
  line-height: 1.1;
  color: var(--side, var(--ink));
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 0 rgba(255, 246, 219, 0.8);
}

/* The balance between them. --tilt is set from the two totals, so the beam
   leans toward whoever is ahead and levels off when they are even. */
.combat-vs {
  position: relative;
  align-self: center;
  height: 108px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding-bottom: 4px;
}

/* The seam down the middle of the table the two sides are seated across. */
.combat-vs::before {
  content: '';
  position: absolute;
  top: -14px;
  bottom: -14px;
  left: 50%;
  width: 1px;
  background: linear-gradient(180deg, transparent, rgba(120, 92, 44, 0.55) 22%, rgba(120, 92, 44, 0.55) 78%, transparent);
}

.scales-beam {
  position: absolute;
  top: 22px;
  left: 4px;
  right: 4px;
  height: 3px;
  border-radius: 2px;
  background: linear-gradient(90deg, #6d4f20, var(--bronze-hi) 50%, #6d4f20);
  transform: rotate(var(--tilt, 0deg));
  transition: transform 420ms cubic-bezier(0.34, 1.2, 0.64, 1);
}
.scales-pan {
  position: absolute;
  top: 3px;
  width: 26px;
  height: 26px;
  border-radius: 0 0 13px 13px;
  border: 1px solid #6d4f20;
  border-top: none;
  background: linear-gradient(180deg, rgba(227, 192, 122, 0.9), rgba(124, 92, 38, 0.9));
}
.scales-pan.is-left { left: -6px; }
.scales-pan.is-right { right: -6px; }
/* The chains the pans hang on. */
.scales-pan::before {
  content: '';
  position: absolute;
  left: 50%;
  top: -3px;
  width: 1px;
  height: 3px;
  background: #6d4f20;
}

.scales-post {
  width: 5px;
  height: 62px;
  margin-bottom: 6px;
  border-radius: 1px;
  background: linear-gradient(90deg, #6d4f20, var(--bronze-hi), #6d4f20);
}
.scales-post::after {
  content: '';
  display: block;
  width: 46px;
  height: 6px;
  margin: 58px 0 0 -20px;
  border-radius: 2px;
  background: linear-gradient(180deg, var(--bronze), #5e441c);
}

.scales-word {
  font-family: var(--font-serif);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* The defender is being attacked on someone else's turn, so the option to
   leave has to announce itself rather than sit in a quiet button. */
.combat-offer {
  color: var(--oxide);
  font-weight: 900;
}

.combat-result-message {
  margin: 0 26px 18px;
  padding: 11px 14px;
  text-align: center;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-soft);
  background: rgba(255, 249, 228, 0.45);
  border-top: 1px solid rgba(120, 92, 44, 0.45);
  border-bottom: 1px solid rgba(120, 92, 44, 0.45);
  min-height: 44px;
}

.modal-footer {
  display: flex;
  justify-content: center;
  gap: 12px;
}

.victory-modal {
  text-align: center;
}
.victory-trophy {
  font-size: 4rem;
  margin-bottom: 12px;
}
.victory-modal h2 {
  font-family: var(--font-serif);
  color: #fbbf24;
  font-size: 2rem;
  margin-bottom: 8px;
}
.winner-display {
  margin: 20px 0;
}
.winner-avatar {
  font-size: 3.5rem;
}

.rules-modal {
  max-width: 680px;
  max-height: 85vh;
  overflow-y: auto;
}
.rules-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}
.rules-header h2 {
  font-family: var(--font-serif);
  color: #fbbf24;
}
.btn-close {
  background: transparent;
  color: var(--text-muted);
  font-size: 1.6rem;
}
.rules-body h3 {
  color: #fff;
  margin: 14px 0 6px;
  font-size: 1.1rem;
}
.rules-body p, .rules-body li {
  color: #cbd5e1;
  line-height: 1.6;
  font-size: 0.95rem;
}
.rules-body ul, .rules-body ol {
  padding-left: 20px;
  margin-bottom: 10px;
}

.discard-banner {
  background: #451a03;
  border: 1px solid #f59e0b;
  color: #fef08a;
  padding: 10px 16px;
  border-radius: 8px;
  margin-bottom: 12px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 700;
  font-size: 0.9rem;
}

.hidden {
  display: none !important;
}

@media (max-width: 840px) {
  .landing-forms {
    grid-template-columns: 1fr;
  }
  .divider-or {
    text-align: center;
  }
  .game-hud {
    padding: 8px 14px;
    flex-wrap: wrap;
    gap: 8px;
  }
  .game-arena {
    flex-direction: column;
  }
  .game-sidebar {
    width: 100%;
    max-width: 100%;
    height: 240px;
    flex-shrink: 0;
    border-left: none;
    border-top: 2px solid var(--border-color);
  }
}

/* =========================================================
   Monopoly 3D White Dice Roll Animation & Tray
   ========================================================= */
.dice-roll-backdrop {
  z-index: 9999;
  background: rgba(10, 14, 23, 0.82);
  backdrop-filter: blur(8px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.dice-roll-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: auto;
}

.dice-roll-tray {
  background: radial-gradient(circle at 50% 30%, #1e293b 0%, #0f172a 100%);
  border: 3px solid #475569;
  border-radius: 28px;
  padding: 36px 52px 28px 52px;
  box-shadow: 0 25px 60px rgba(0, 0, 0, 0.85), 0 0 40px rgba(59, 130, 246, 0.25);
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  cursor: pointer;
  animation: pop-modal 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.dice-roll-scene {
  width: 150px;
  height: 150px;
  /* A 70px cube under 800px of perspective is nearly orthographic, so the side
     faces never foreshorten and the die reads as a flat tile. */
  perspective: 380px;
  perspective-origin: 50% 42%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  margin-bottom: 20px;
}

/* The falling half: gravity only, no rotation and no scale. */
.dice-drop {
  transform-style: preserve-3d;
}

.dice-drop.is-rolling {
  animation: dice-drop 1.15s forwards;
}

/* White Monopoly Cube */
.monopoly-cube {
  width: 70px;
  height: 70px;
  position: relative;
  transform-style: preserve-3d;
}

/* One spin, always the same way round, decelerating onto the rolled face.
   The old keyframes overshot the target and then rotated backwards into it,
   which is what read as wrong. */
.monopoly-cube.is-rolling {
  animation: dice-spin 1.15s cubic-bezier(0.14, 0.8, 0.2, 1) forwards;
}

.cube-face {
  position: absolute;
  width: 70px;
  height: 70px;
  background: radial-gradient(circle at 35% 35%, #ffffff 0%, #f1f5f9 65%, #e2e8f0 100%);
  border: 2px solid #cbd5e1;
  /* Barely rounded. At 14px the faces read as separate rounded tiles floating
     apart rather than one solid cube. */
  border-radius: 7px;
  box-shadow: inset 0 2px 4px rgba(255, 255, 255, 0.95), inset 0 -3px 6px rgba(0, 0, 0, 0.15), 0 6px 14px rgba(0, 0, 0, 0.25);
  box-sizing: border-box;
  padding: 8px;
  backface-visibility: hidden;
}

/* Indented Black Pips */
.pip {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #334155 0%, #0f172a 75%, #000000 100%);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.9), 0 1px 1px rgba(255, 255, 255, 0.8);
  flex-shrink: 0;
}

.pip-row {
  display: flex;
  justify-content: space-between;
  width: 100%;
}

.pip-col {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
}

/* Face Placements (35px = half of 70px) */
.face-1 { transform: rotateY(0deg) translateZ(35px); display: flex; align-items: center; justify-content: center; }
.face-6 { transform: rotateY(180deg) translateZ(35px); display: flex; justify-content: space-between; }
.face-2 { transform: rotateY(90deg) translateZ(35px); display: flex; flex-direction: column; justify-content: space-between; }
.face-2 .pip-tl { align-self: flex-start; }
.face-2 .pip-br { align-self: flex-end; }
.face-5 { transform: rotateY(-90deg) translateZ(35px); display: flex; flex-direction: column; justify-content: space-between; align-items: center; }
.face-3 { transform: rotateX(90deg) translateZ(35px); display: flex; flex-direction: column; justify-content: space-between; }
.face-3 .pip-tl { align-self: flex-start; }
.face-3 .pip-center { align-self: center; }
.face-3 .pip-br { align-self: flex-end; }
.face-4 { transform: rotateX(-90deg) translateZ(35px); display: flex; flex-direction: column; justify-content: space-between; }

/* A real die is lit from one side, so the faces cannot all be the same white
   or the cube reads flat whenever one turns edge-on. */
.face-2, .face-5 { filter: brightness(0.88); }
.face-3 { filter: brightness(1.04); }
.face-4 { filter: brightness(0.78); }
.face-6 { filter: brightness(0.94); }

/* Floor Shadow under Die */
.dice-shadow {
  position: absolute;
  bottom: 0px;
  width: 70px;
  height: 18px;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, 0.65) 0%, rgba(0, 0, 0, 0) 72%);
  border-radius: 50%;
  pointer-events: none;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.dice-drop.is-rolling ~ .dice-shadow {
  animation: dice-shadow-bounce 1.15s linear forwards;
}

/* Result Card */
.dice-result-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 6px;
}

.dice-roll-reason {
  font-size: 0.75rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: #94a3b8;
}

.dice-roll-announcement {
  font-size: 1.35rem;
  font-weight: 900;
  color: #fbbf24;
  text-shadow: 0 0 10px rgba(251, 191, 36, 0.4);
}

.dice-roll-hint {
  font-size: 0.7rem;
  color: #64748b;
  margin-top: 4px;
}

@keyframes dice-spin {
  from { transform: rotateX(0deg) rotateY(0deg); }
  to   { transform: var(--target-dice-rotation); }
}

/* Two decaying bounces. Each fall accelerates and each rise slows, so the die
   hangs at the top of a bounce the way a thrown die does. */
@keyframes dice-drop {
  0%   { transform: translateY(-115px); animation-timing-function: cubic-bezier(0.45, 0, 1, 1); }
  36%  { transform: translateY(0);      animation-timing-function: cubic-bezier(0, 0, 0.45, 1); }
  50%  { transform: translateY(-28px);  animation-timing-function: cubic-bezier(0.45, 0, 1, 1); }
  66%  { transform: translateY(0);      animation-timing-function: cubic-bezier(0, 0, 0.45, 1); }
  76%  { transform: translateY(-8px);   animation-timing-function: cubic-bezier(0.45, 0, 1, 1); }
  86%, 100% { transform: translateY(0); }
}

/* Surprise Baby Bomb Announcement & Explosion Animation */
.bomb-backdrop {
  z-index: 9999;
  background: rgba(10, 10, 15, 0.96);
  display: flex;
  align-items: center;
  justify-content: center;
}

.bomb-stage {
  max-width: 440px;
  width: 90%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  position: relative;
}

.bomb-hazard-header {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 8px;
}

.hazard-stripe {
  flex: 1;
  height: 12px;
  background: repeating-linear-gradient(
    -45deg,
    #f59e0b,
    #f59e0b 10px,
    #18181b 10px,
    #18181b 20px
  );
  border-radius: 4px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.6);
}

.hazard-badge {
  font-family: var(--font-serif);
  font-size: 0.90rem;
  font-weight: 900;
  letter-spacing: 1.5px;
  color: #fbbf24;
  text-shadow: 0 0 12px rgba(251, 191, 36, 0.6);
  white-space: nowrap;
}

.bomb-player-banner {
  font-family: var(--font-serif);
  font-size: 1.25rem;
  font-weight: 900;
  letter-spacing: 1px;
  color: #ffffff;
  text-align: center;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.9);
}

.bomb-player-highlight {
  color: var(--accent);
}

.bomb-presentation-area {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 4px 0;
  position: relative;
}

.bomb-card-frame {
  width: 160px;
  height: 160px;
  border-radius: 10px;
  background: #181b22;
  border: 1px solid var(--hud-line);
  position: relative;
  overflow: hidden;
}

.bomb-card-art {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.bomb-card-art svg {
  width: 100%;
  height: 100%;
  display: block;
}

.bomb-effect-panel {
  width: 100%;
  background: var(--hud-surface);
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  padding: 14px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  text-align: center;
}

.bomb-effect-title {
  font-size: 0.82rem;
  font-weight: 900;
  letter-spacing: 1px;
  color: #f87171;
  text-transform: uppercase;
}

.bomb-effect-body {
  font-size: 0.9rem;
  line-height: 1.4;
  color: var(--text-main);
}

.bomb-effect-body b {
  color: #f87171;
  font-size: 0.96rem;
}

.bomb-discard-note {
  font-size: 0.72rem;
  color: #94a3b8;
  display: block;
  margin-top: 4px;
}

.bomb-dismiss-row {
  margin-top: 4px;
  width: 100%;
  display: flex;
  justify-content: center;
}

/* The notice closes itself. A bar shows how long is left, so the modal going
   away reads as the timer running out rather than as something going wrong,
   and clicking the backdrop still takes it away early. */
.bomb-autoclose {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  width: 190px;
  padding-top: 4px;
}
.bomb-autoclose-text {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.bomb-autoclose-bar {
  width: 100%;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.12);
  overflow: hidden;
}
.bomb-autoclose-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: #ef4444;
  transform-origin: left center;
}
.bomb-autoclose-fill.is-running {
  animation: bomb-autoclose-drain 3s linear forwards;
}
@keyframes bomb-autoclose-drain {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}

/* Keyframes */
@keyframes dice-shadow-bounce {
  0%   { transform: scale(0.5); opacity: 0.15; }
  36%  { transform: scale(1.06); opacity: 0.8; }
  50%  { transform: scale(0.82); opacity: 0.42; }
  66%  { transform: scale(1.02); opacity: 0.74; }
  76%  { transform: scale(0.93); opacity: 0.58; }
  86%, 100% { transform: scale(1); opacity: 0.7; }
}

/* Nobody needs a die thrown at them. */
@media (prefers-reduced-motion: reduce) {
  .dice-drop.is-rolling { animation: none; }
  .monopoly-cube.is-rolling { animation: none; transform: var(--target-dice-rotation); }
  .monopoly-cube.is-rolling ~ .dice-shadow,
  .dice-drop.is-rolling ~ .dice-shadow { animation: none; }
}


/* A seat whose player closed their tab. Hotseat never shows this. */
.player-seat.is-disconnected {
  opacity: 0.55;
  border-style: dashed;
}
.seat-away {
  font-weight: 700;
  color: var(--hp-red);
}

/* Bouncer's Knockback destination picker inside the combat modal */
.knockback-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 0.78rem;
  color: var(--text-muted);
}
.knockback-row select {
  max-width: 260px;
}

/* Big Look's Keeyp Sight tile picker */
.tile-choice-options {
  display: flex;
  gap: 12px;
  align-items: center;
}
.tile-choice-option {
  width: 84px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 6px;
  border: 1px solid var(--hud-line);
  border-radius: 4px;
  background: transparent;
  color: var(--text-main);
  font-family: inherit;
  font-size: 0.62rem;
  font-weight: 700;
  cursor: pointer;
}
.tile-choice-option:hover {
  border-color: var(--accent);
}
.tile-choice-art {
  width: 56px;
  height: 56px;
  overflow: hidden;
  border-radius: 3px;
}
.tile-choice-art svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Surprise tile notice: acknowledged per player, never blocks the match */
.bomb-dismiss-note {
  margin-top: 8px;
  font-size: 0.7rem;
  color: var(--text-muted);
  text-align: center;
}

/* End Turn calls for attention once the player has no moves or chambers left. */
.btn-hud.is-urgent {
  background: var(--accent);
  border-color: var(--accent-hi);
  color: var(--accent-ink);
  box-shadow: 0 0 0 2px rgba(251, 191, 36, 0.35), 0 0 14px rgba(251, 191, 36, 0.55);
}

/* Combat: each side arms a card face down before anything is revealed */
.btn-lock-card {
  width: 100%;
  margin-top: 5px;
  padding: 4px 6px;
  font-size: 0.68rem;
  font-weight: 700;
  font-family: inherit;
  background: transparent;
  border: 1px solid var(--hud-line);
  border-radius: 3px;
  color: var(--text-main);
  cursor: pointer;
}
.btn-lock-card:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.btn-lock-card:disabled { opacity: 0.4; cursor: not-allowed; }
.card-state {
  margin-top: 4px;
  font-size: 0.66rem;
  font-weight: 700;
  text-align: center;
  color: var(--text-muted);
  min-height: 14px;
}
.card-state.is-ready { color: var(--accent); }

/* Placement controls float beside the chamber being placed */
.tile-placement-controls {
  position: absolute;
  z-index: 80;
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 7px 9px;
  background: var(--hud-surface);
  border: 1px solid var(--accent);
  border-radius: 4px;
  pointer-events: auto;
}
.placing-name {
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  text-align: center;
}
.placing-buttons { display: flex; gap: 5px; }
.btn-place {
  padding: 5px 10px;
  font-size: 0.72rem;
  font-weight: 700;
  font-family: inherit;
  background: transparent;
  border: 1px solid var(--hud-line);
  border-radius: 3px;
  color: var(--text-main);
  cursor: pointer;
  white-space: nowrap;
}
.btn-place:hover:not(:disabled) { border-color: var(--accent); }
.btn-place:disabled { opacity: 0.4; cursor: not-allowed; }
.btn-place-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
.btn-place-primary:hover { background: var(--accent-hi); border-color: var(--accent-hi); }

/* A card dealt from the tile deck onto the board */
.dealt-tile-card {
  position: fixed;
  z-index: 300;
  border-radius: 4px;
  overflow: hidden;
  border: 2px solid var(--accent);
  background: #1c1f27;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.7);
  pointer-events: none;
  transform-origin: center center;
  transition: transform 620ms cubic-bezier(0.22, 0.68, 0.32, 1), opacity 200ms ease 520ms;
}
.dealt-tile-card svg { width: 100%; height: 100%; display: block; }
.dealt-tile-card .deal-back {
  width: 100%;
  height: 100%;
  background: repeating-linear-gradient(45deg, #3b2f14 0 6px, #2a220f 6px 12px);
}

/* Whose turn it is, stated plainly in the top bar */
.turn-indicator .turn-title {
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.02em;
}
.turn-indicator.is-my-seat {
  background: rgba(245, 158, 11, 0.12);
  border-color: var(--accent);
}
.turn-indicator.is-my-seat .turn-title {
  color: var(--accent);
  letter-spacing: 0.08em;
}

/* Enlarged Keeypling card, for reading stats and ability text */
.card-zoom-backdrop { cursor: zoom-out; }
.card-zoom-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.card-zoom-role {
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.card-zoom-hint {
  font-size: 0.72rem;
  color: var(--text-muted);
}
/* The card is built at a fixed pixel size, so scale the whole thing up. */
.card-zoom-body .physical-keeypling-card.compact {
  zoom: 2.4;
}
.card-zoom-body .physical-keeypling-card.compact .card-ability-text {
  -webkit-line-clamp: unset;
  overflow: visible;
}
/* Station cards invite the click that opens that view. */
#my-physical-card-container,
#reserve-card-container {
  cursor: zoom-in;
}

/* End Turn parked in the board's bottom-right corner, always in the same place */
.corner-actions {
  position: absolute;
  right: 18px;
  bottom: 18px;
  z-index: 70;
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.corner-actions .btn-end-turn-corner.hidden {
  display: none;
}
.btn-end-turn-corner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 132px;
  padding: 10px 18px;
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 800;
  letter-spacing: 0.04em;
  background: var(--hud-surface);
  border: 1px solid var(--hud-line);
  border-radius: 5px;
  color: var(--text-main);
  cursor: pointer;
}
.btn-end-turn-corner:hover:not(:disabled) { border-color: var(--accent); }
.btn-end-turn-corner:disabled { opacity: 0.35; cursor: not-allowed; }
.end-turn-sub {
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--text-muted);
}
/* Nothing left to do, so the button asks for the click. */
.btn-end-turn-corner.is-urgent {
  background: var(--accent);
  border-color: var(--accent-hi);
  color: var(--accent-ink);
  animation: end-turn-pulse 1.5s ease-in-out infinite;
}
.btn-end-turn-corner.is-urgent .end-turn-sub { color: rgba(18, 20, 27, 0.75); }
@keyframes end-turn-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(251, 191, 36, 0.55), 0 0 12px rgba(251, 191, 36, 0.4); }
  50% { box-shadow: 0 0 0 8px rgba(251, 191, 36, 0), 0 0 22px rgba(251, 191, 36, 0.75); }
}

.action-log-drawer-body { font-size: 0.68rem; }
.log-item { font-size: 0.68rem; line-height: 1.3; padding: 5px 7px; }
.drawer-header h4 { font-size: 0.8rem; }

/* Player pieces: plain coloured figures, as in the box */
.player-piece-svg { width: 100%; height: 100%; display: block; }
.board-token {
  background: transparent !important;
  border-color: transparent;
  border-radius: 4px;
  overflow: visible;
}
.board-token.is-active-turn { border-color: #fde68a; }
.seat-avatar { background: transparent !important; }

/* Laptop-height screens: the cards need a bigger slice or they shrink past
   reading size, and the board simply scales into whatever is left. */
@media (max-height: 760px) {
  :root {
    --footer-h: clamp(150px, 46dvh, 322px);
  }
}

/* Seats read as openable, because they are: the card behind them zooms. */
.player-seat.seat-openable {
  cursor: pointer;
}
.player-seat.seat-openable:hover {
  border-color: var(--accent);
}

/* A fallen Keeypling stays on the table, struck through, so the player can still
   read what they lost. */
.card-slot-dead {
  position: relative;
}
.card-slot-dead .physical-keeypling-card {
  opacity: 0.4;
  filter: grayscale(0.9);
}
.card-slot-dead::before,
.card-slot-dead::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  /* Corner to corner on the printed card's 152x220 footprint. */
  width: 176%;
  height: 3px;
  background: #ef4444;
  border-radius: 2px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.85);
  pointer-events: none;
  z-index: 5;
}
.card-slot-dead::before { transform: translate(-50%, -50%) rotate(55deg); }
.card-slot-dead::after { transform: translate(-50%, -50%) rotate(-55deg); }
.slot-badge.dead-badge {
  color: #ef4444;
  border: 1px solid #ef4444;
}

/* The item cards are single authored SVGs of the printed card, so the card box
   only has to give one the room to fill. */
.physical-item-card.compact {
  display: flex;
  align-items: center;
  justify-content: center;
}

.physical-item-card .item-card-svg {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.5));
}

/* Blown up, the card is readable: its info line is printed at card scale. */
.card-zoom-body .physical-item-card.compact {
  zoom: 2.4;
}

/* The Keeypling cards are single authored SVGs of the printed card, so the card box
   only has to give one the room to fill. */
.physical-keeypling-card.compact {
  display: flex;
  align-items: center;
  justify-content: center;
}

.physical-keeypling-card .keeypling-card-svg {
  width: 100%;
  height: 100%;
  display: block;
  filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.5));
}


/* What the battle did. Both sides' sums, then the consequences in order:
   damage, whether a Keeypling fell, where the Key ended up. */
.combat-outcome {
  background: var(--bg-dark);
  border: 1px solid var(--border-color);
  border-radius: 10px;
  padding: 14px 16px 12px;
  margin-bottom: 20px;
}

.outcome-head {
  font-size: 0.7rem;
  font-weight: 900;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 10px;
}

.outcome-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 10px;
}

.outcome-side {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 8px 10px;
  min-width: 0;
}

/* Only the winning side is lifted, so which one it is reads without counting. */
.outcome-side.is-winner {
  border-color: #38bdf8;
  background: rgba(56, 189, 248, 0.08);
}

.outcome-who {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-weight: 900;
  margin-bottom: 4px;
}

.outcome-flag {
  margin-left: auto;
  font-size: 0.6rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  color: #38bdf8;
}

.outcome-sum {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
}

.outcome-base { color: var(--text-muted); }
.outcome-op { color: var(--text-muted); opacity: 0.6; }
.outcome-card { color: #facc15; font-weight: 700; }
.outcome-card.is-none { color: var(--text-muted); font-weight: 400; font-style: italic; }
.outcome-total { font-weight: 900; font-size: 1rem; margin-left: auto; }

.outcome-vs {
  font-size: 0.7rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}

.outcome-lines {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 0.85rem;
  line-height: 1.45;
}

.outcome-hp {
  font-variant-numeric: tabular-nums;
  font-weight: 900;
  color: #f87171;
}

.outcome-lines .is-grave { color: #f87171; }
.outcome-lines .is-key { color: #facc15; }


/* ── Parley table, continued: the record of the fight and the seals ──────── */

/* What the battle did, written up on the same vellum. */
.parley .combat-outcome {
  margin: 0 26px 18px;
  padding: 14px 16px 13px;
  border: 1px solid var(--bronze);
  border-radius: 2px;
  background: rgba(255, 249, 228, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 250, 232, 0.6);
}
.parley .outcome-head {
  font-family: var(--font-serif);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 11px;
}
.parley .outcome-side {
  border: 1px solid rgba(120, 92, 44, 0.55);
  border-radius: 2px;
  padding: 8px 10px;
  background: rgba(255, 250, 232, 0.35);
}
.parley .outcome-side.is-winner {
  border-color: var(--oxide);
  background: rgba(125, 42, 23, 0.1);
  box-shadow: inset 0 0 0 1px rgba(125, 42, 23, 0.25);
}
.parley .outcome-who { color: var(--ink); }
.parley .outcome-flag {
  font-family: var(--font-serif);
  font-size: 0.58rem;
  letter-spacing: 0.14em;
  color: var(--oxide);
}
.parley .outcome-base,
.parley .outcome-op,
.parley .outcome-vs { color: var(--ink-soft); }
.parley .outcome-card { color: #8a5a12; }
.parley .outcome-card.is-none { color: var(--ink-soft); }
.parley .outcome-total { color: var(--ink); font-family: var(--font-serif); }
.parley .outcome-lines { color: var(--ink); }
.parley .outcome-hp,
.parley .outcome-lines .is-grave { color: var(--oxide); }
.parley .outcome-lines .is-key { color: #8a5a12; }

/* The seals along the bottom: bronze plaques, and wax red for the one that
   ends the fight. */
.parley .modal-footer {
  gap: 10px;
  flex-wrap: wrap;
  padding: 0 26px 24px;
}
.parley .modal-footer button {
  font-family: var(--font-serif);
  font-weight: 700;
  letter-spacing: 0.1em;
  border-radius: 2px;
  text-shadow: 0 1px 1px rgba(45, 30, 8, 0.5);
}
.parley .modal-footer .btn-secondary {
  color: #f6ead0;
  border: 1px solid #6d4f20;
  background: linear-gradient(180deg, var(--bronze-hi), var(--bronze) 45%, #74551f);
  box-shadow: inset 0 1px 0 rgba(255, 245, 214, 0.55), 0 2px 3px rgba(40, 26, 8, 0.45);
}
.parley .modal-footer .btn-secondary:hover:not(:disabled) {
  background: linear-gradient(180deg, #f0d194, var(--bronze-hi) 45%, var(--bronze));
  border-color: #6d4f20;
  color: #2b1e0f;
}
.parley .modal-footer .btn-primary {
  color: #f7e3c4;
  border: 1px solid #4d1409;
  background: linear-gradient(180deg, #a13a22, var(--oxide) 55%, #611c0f);
  box-shadow: inset 0 1px 0 rgba(255, 206, 170, 0.35), 0 2px 4px rgba(40, 12, 4, 0.5);
}
.parley .modal-footer .btn-primary:hover:not(:disabled) {
  background: linear-gradient(180deg, #b8452a, #8a2f1a 55%, var(--oxide));
}
.parley .modal-footer button:disabled {
  color: var(--ink-soft);
  background: rgba(163, 137, 88, 0.32);
  border-color: rgba(109, 79, 32, 0.55);
  box-shadow: none;
  text-shadow: none;
  opacity: 1;
}

.parley :focus-visible {
  outline: 2px solid var(--oxide);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .parley .scales-beam { transition: none; }
}

/* On a phone the two sides stack, and the balance lies across the middle of
   the table rather than standing between them. */
@media (max-width: 680px) {
  .parley .combatants-row {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 4px 16px 16px;
  }
  .parley .combat-vs {
    height: 46px;
    justify-content: center;
    padding-bottom: 0;
  }
  .parley .scales-beam { top: 12px; left: 28%; right: 28%; }
  .parley .scales-post { display: none; }
  .parley .scales-word { margin-top: 22px; }
  .parley-head { padding: 20px 18px 12px; }
  .parley .combat-result-message,
  .parley .combat-outcome { margin-inline: 16px; }
  .parley .modal-footer { padding: 0 16px 18px; }
}

/* Background music control: a button in the top right of the lobby and of the
   game HUD, with the level on a slider behind it. Kept out of the header row
   until it is opened, so the row does not grow a permanent slider. */
.music-control {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}
.btn-music.is-open {
  color: var(--accent-hi);
  border-color: var(--accent);
}
.btn-music.is-off {
  opacity: 0.55;
}
.music-popover {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 220;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  background: var(--hud-surface);
  border: 1px solid var(--hud-line);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}
.music-popover[hidden] {
  display: none;
}
.music-popover-label {
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-muted);
}
.music-value {
  font-size: 0.68rem;
  font-weight: 700;
  color: var(--text-muted);
  /* Three digits wide, so the popover does not jump as the number changes. */
  min-width: 34px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.music-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 120px;
  height: 4px;
  background: var(--hud-line);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}
.music-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
  cursor: pointer;
}
.music-slider::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: none;
  cursor: pointer;
}
.music-slider:focus-visible {
  box-shadow: 0 0 0 2px var(--accent-hi);
}
