/* ---------- game page (lobby) ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--panel) 0%, var(--bg-2) 100%);
  box-shadow: 0 1px 0 rgba(230, 178, 60, 0.14);
}
.topbar .wordmark { font-size: 1.35rem; }
.icon-btn {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 10px;
  background: var(--panel);
  border: 1px solid var(--line);
  padding: 0;
  font-size: 1.1rem;
}
.icon-btn:hover { border-color: var(--gold); }

/* ══════════════════════════════════════════════════════════════════════
   Lobby — the waiting room (core/lobby.js)
   ══════════════════════════════════════════════════════════════════════
   Desktop: the invite card and the table rules on the left, the seats on the
   right, the start bar underneath. Phones: one column, with the start bar
   pinned to the bottom of the screen where a thumb can reach it. */
.lobby {
  max-width: 1040px;
  margin: 0 auto;
  padding: var(--sp-8) 1.25rem var(--sp-8);
}
.lobby-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr);
  grid-template-areas:
    "invite players"
    "rules  players";
  gap: var(--sp-5);
  align-items: start;
}
.lobby-invite  { grid-area: invite; }
.lobby-players { grid-area: players; }
.lobby-rules   { grid-area: rules; }

.lobby-card {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.025), transparent 40%), var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  box-shadow: var(--el-2);
  padding: var(--sp-6);
}
.lc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-bottom: var(--sp-4);
}
.lc-head h2 {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  margin: 0;
  font-family: var(--display);
  font-size: var(--fs-lg);
  font-weight: 600;
}
.lc-head-actions { display: flex; align-items: center; gap: var(--sp-2); position: relative; }
.lc-head-actions .btn-ghost, .lc-head-actions .btn-secondary { width: auto; }

/* ---- invite card ---- */
.lobby-eyebrow {
  margin: 0 0 var(--sp-1);
  color: var(--gold);
  font-size: var(--fs-sm);
  font-weight: 600;
}
.lobby-title {
  margin: 0 0 var(--sp-5);
  font-family: var(--display);
  font-size: var(--fs-2xl);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.15;
}
.code-block {
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r-lg);
  background: var(--bg);
  border: 1px dashed color-mix(in srgb, var(--gold) 40%, var(--line));
  text-align: center;
}
.code-label {
  display: block;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.code-block .code {
  font-family: var(--display);
  font-weight: 700;
  font-size: var(--fs-3xl);
  letter-spacing: 0.32em;
  padding-left: 0.32em;   /* balance the tracking after the last letter */
  color: var(--gold);
  line-height: 1.2;
}
.invite-actions {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2);
  margin-top: var(--sp-4);
}
.invite-actions .btn-secondary { width: 100%; padding-left: 0.5rem; padding-right: 0.5rem; text-decoration: none; }
.btn-whatsapp .ico { color: #25d366; }

/* ---- seats ---- */
.seat-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
  gap: var(--sp-3);
}
.seat-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-2) var(--sp-3);
  border-radius: var(--r-lg);
  background: var(--bg-2);
  border: 1px solid var(--line);
  text-align: center;
  min-width: 0;
}
.seat-tile.is-you { border-color: color-mix(in srgb, var(--gold) 40%, var(--line)); }
.seat-tile.offline .seat-av { filter: grayscale(0.7) brightness(0.7); }
.seat-av {
  position: relative;
  width: 56px; height: 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: #fff;
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 700;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  box-shadow: 0 0 0 3px var(--bg-2), 0 8px 18px -8px rgba(0, 0, 0, 0.7);
}
.seat-av .av-motif { width: 28px; height: 28px; stroke-width: 2.1; }
.seat-dot {
  position: absolute;
  right: 0; bottom: 1px;
  width: 13px; height: 13px;
  border-radius: 50%;
  background: var(--muted);
  box-shadow: 0 0 0 3px var(--bg-2);
}
.seat-dot.on { background: var(--success); }
.seat-name {
  max-width: 100%;
  font-weight: 600;
  font-size: 0.92rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.seat-tags { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.25rem; min-height: 18px; }
.seat-tags .badge .ico { width: 11px; height: 11px; margin-right: 0.2rem; stroke-width: 2.2; }
.seat-tile .kick-btn { position: absolute; top: 6px; right: 6px; }
.seat-tile.open {
  background: transparent;
  border-style: dashed;
  color: var(--muted);
}
.seat-tile.open .seat-av {
  background: transparent;
  box-shadow: none;
  border: 2px dashed var(--line);
  color: var(--muted);
}
.seat-tile.open .seat-av .ico { width: 22px; height: 22px; }
.seat-tile.open .seat-name { font-weight: 500; color: var(--muted); }

.lobby .meta {
  margin: var(--sp-4) 0 0;
  color: var(--muted);
  font-size: var(--fs-sm);
  text-align: center;
}

/* ---- table rules ---- */
.rules-summary {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--sp-2);
  margin: 0;
}
.rules-item {
  padding: var(--sp-3);
  border-radius: var(--r-md);
  background: var(--bg-2);
  border: 1px solid var(--line);
}
.rules-item dt { color: var(--muted); font-size: var(--fs-xs); line-height: 1.3; }
.rules-item dd {
  margin: 0.2rem 0 0;
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.rules-item dd.on { color: var(--success); }
.rules-item dd.off { color: var(--muted); }
.rules-editor-actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-4); }
.rules-editor-actions button { width: auto; }

/* ---- start bar ---- */
.start-bar { margin-top: var(--sp-5); }
.start-bar-inner {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-3) var(--sp-3) var(--sp-5);
  border-radius: var(--r-xl);
  background: var(--panel);
  border: 1px solid var(--line);
  box-shadow: var(--el-2);
}
.start-bar .start-btn { width: auto; min-width: 220px; }
.start-bar .waiting {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  margin: 0;
  padding: var(--sp-2) 0;
}
.waiting-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--gold);
  animation: waiting-pulse 1.4s ease-in-out infinite;
}
@keyframes waiting-pulse { 0%, 100% { opacity: 0.35; transform: scale(0.85); } 50% { opacity: 1; transform: scale(1); } }

@media (max-width: 820px) {
  .lobby { padding: var(--sp-5) var(--sp-4) 7rem; }
  .lobby-grid {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "invite" "players" "rules";
    gap: var(--sp-4);
  }
  .lobby-card { padding: var(--sp-5); border-radius: var(--r-lg); }
  .lobby-title { font-size: var(--fs-xl); margin-bottom: var(--sp-4); }
  .code-block .code { font-size: 2.1rem; }
  .seat-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: var(--sp-2); }
  .seat-av { width: 48px; height: 48px; font-size: 1.15rem; }
  .seat-av .av-motif { width: 24px; height: 24px; }
  /* Pinned where a thumb can reach it, clear of the home indicator. */
  .start-bar {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    margin: 0;
    padding: var(--sp-3) var(--sp-3) calc(var(--sp-3) + env(safe-area-inset-bottom));
    background: linear-gradient(180deg, transparent, var(--bg) 35%);
  }
  .start-bar-inner { padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4); }
  .start-bar .start-btn { min-width: 0; flex: 1; }
}
@media (max-width: 480px) {
  /* Three equal buttons on a phone: icon over a one-line label, rather than
     labels wrapping onto two lines beside the icon. */
  .invite-actions .btn-secondary {
    flex-direction: column;
    gap: 0.2rem;
    min-height: 56px;
    font-size: var(--fs-xs);
    white-space: nowrap;
  }
}
@media (prefers-reduced-motion: reduce) {
  .waiting-dot { animation: none; }
}

/* Badges: small, sentence-case pills. They used to be all-caps with wide
   tracking, which made five of them in one row read like shouting. */
.badge {
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-2xs);
  font-weight: 650;
  letter-spacing: 0.01em;
  line-height: 1.5;
  padding: 0.05rem 0.5rem;
  border-radius: var(--r-pill);
  white-space: nowrap;
}
.badge.host { background: color-mix(in srgb, var(--gold) 18%, transparent); color: var(--gold); box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold) 45%, transparent) inset; }
.badge.you  { background: var(--panel-2); color: var(--muted); }
.badge.next-turn { background: transparent; color: var(--gold); box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold) 55%, transparent) inset; }
.badge.turn-now { background: var(--accent); color: #fff; }

/* ---- Add bot ----------------------------------------------------------
   Sits above Start in the same row. Deliberately a ghost button next to the
   filled Start: seating a bot is optional setup, and two loud buttons would
   make the host choose between them instead of reading Start as the way on.
   The picker reuses the theme dropdown's shape (see themes.css) rather than
   inventing a second popover style for the same "pick one of a few" job. */
.add-bot-wrap {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 0.6rem;
}
.add-bot-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  width: auto;
  flex: 0 0 auto;
  padding: 0.45rem 0.8rem;
  font-size: 0.88rem;
}
.add-bot-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.add-bot-note {
  color: var(--muted);
  font-size: 0.8rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bot-picker {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 0.4rem;
  display: flex;
  flex-direction: column;
  gap: 4px;
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.6);
  z-index: 80;
  width: 200px;
}
/* Opens upward: the row sits at the bottom of the lobby card, so a downward
   menu would fall off the card on a phone. */
.bot-opt {
  width: 100%;
  border: none;
  background: transparent;
  color: var(--text);
  font-family: var(--body);
  font-size: 0.88rem;
  padding: 0.5rem 0.6rem;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  text-align: left;
  transition: background 0.12s ease;
}
.bot-opt:hover { background: rgba(255, 255, 255, 0.08); }
.bot-face { display: inline-flex; color: var(--muted); }
.bot-name { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bot-seated {
  flex: 0 0 auto;
  color: var(--muted);
  font-size: 0.72rem;
}
.waiting {
  text-align: center;
  color: var(--muted);
  font-size: 0.92rem;
}

/* placeholder shown after start (until Phase 1) */
.placeholder {
  text-align: center;
  padding: 3rem 1rem;
  color: var(--muted);
}
.placeholder h2 {
  font-family: var(--display);
  color: var(--text);
}

/* ---------- modal ----------
   One dialog style for the whole app: dimmed, slightly blurred backdrop; a
   panel that rises in; a footer row (.close-row) with actions on the right. */
.modal-backdrop {
  position: fixed; inset: 0;
  background: rgba(6, 8, 9, 0.66);
  -webkit-backdrop-filter: blur(3px);
          backdrop-filter: blur(3px);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  z-index: var(--z-modal);
}
.modal-backdrop.open { display: flex; animation: modal-fade var(--dur) ease-out; }
.modal-backdrop.open > .modal,
.modal-backdrop.open > .winner-panel { animation: modal-rise var(--dur-slow) var(--ease-out); }
@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-rise { from { opacity: 0; transform: translateY(10px) scale(0.985); } to { opacity: 1; transform: none; } }
.modal {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  max-width: 540px;
  width: 100%;
  max-height: 84vh;
  overflow-y: auto;
  padding: var(--sp-6);
  box-shadow: var(--el-3);
}
.modal h2 { font-family: var(--display); font-size: var(--fs-xl); font-weight: 600; letter-spacing: -0.005em; margin-top: 0; }
.modal h3 {
  font-family: var(--display);
  font-size: 0.95rem;
  margin: 1.1rem 0 0.3rem;
  color: var(--gold);
}
.modal p, .modal li { font-size: 0.9rem; color: var(--text); }
.modal ul { padding-left: 1.1rem; }
.modal .close-row {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-6);
}
.modal .close-row button { width: auto; padding-left: 1.2rem; padding-right: 1.2rem; }

/* A labelled number field with a unit (spectator admit's penalty). */
.admit-modal { max-width: 440px; }
.field-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin: var(--sp-5) 0 0;
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  text-transform: none;
  letter-spacing: 0;
  font-size: inherit;
  color: var(--text);
}
.field-row-text { display: flex; flex-direction: column; }
.field-row-text strong { font-size: 0.92rem; font-weight: 600; }
.field-row-text small { font-size: var(--fs-xs); color: var(--muted); }
.field-suffix { display: inline-flex; align-items: center; gap: 0.35rem; color: var(--muted); font-weight: 600; }
.field-suffix input { width: 72px; text-align: right; padding: 0.5rem 0.6rem; }

/* SS.confirm() (core/dialog.js) — replaces the browser's confirm() box. */
.confirm-modal { max-width: 400px; }
.confirm-modal h2 { margin-bottom: var(--sp-2); }
.confirm-modal p { color: var(--muted); margin: 0; line-height: 1.5; }
@media (prefers-reduced-motion: reduce) {
  .modal-backdrop.open, .modal-backdrop.open > .modal, .modal-backdrop.open > .winner-panel { animation: none; }
}

/* ---------- dialog header + language toggle (rules, install) ---------- */
.dialog-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line);
}
.dialog-head h2 { margin: 0; }
.lang-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 9px;
}
.lang-btn {
  padding: 0.3rem 0.7rem;
  background: transparent;
  border-radius: 6px;
  color: var(--muted);
  font-size: 0.8rem;
  font-weight: 700;
}
.lang-btn:hover { color: var(--text); }
.lang-btn.active { background: var(--panel-2); color: var(--text); }

/* ── Install modal extras (driven by core/install.js) ─────────────────── */
/* The attribute alone loses to any display rule, so make it decisive here. */
#install-modal [hidden] { display: none !important; }

#install-now-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding-bottom: 1rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid var(--line);
}
#install-now-btn {
  width: auto;
  padding: 0.7rem 2.2rem;
  font-size: 1rem;
}
.install-now-hint {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
}
.install-done-note {
  margin: 0 0 1rem;
  padding: 0.7rem 0.9rem;
  border-radius: 10px;
  background: rgba(87, 217, 138, 0.12);
  border: 1px solid rgba(87, 217, 138, 0.35);
  font-size: 0.88rem;
}
.install-manual-intro {
  margin: 0 0 0.6rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted);
}

/* ---------- toast ----------
   Neutral by default; red only for errors (core/socket.js showToast kind). */
#toast {
  position: fixed;
  left: 50%;
  bottom: calc(1.5rem + env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(1rem);
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  max-width: min(92vw, 440px);
  background: #2c3033;
  color: var(--text);
  border: 1px solid #3f4448;
  padding: 0.7rem 1rem 0.7rem 0.85rem;
  border-radius: 12px;
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.35;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.22s cubic-bezier(0.32, 0.72, 0, 1);
  z-index: 100;
  box-shadow: 0 16px 40px -12px rgba(0, 0, 0, 0.75);
}
#toast .ico { width: 18px; height: 18px; color: var(--muted); }
#toast.toast-success .ico { color: var(--turn); }
#toast.toast-error {
  background: #3a1f1b;
  border-color: rgba(232, 89, 63, 0.55);
}
#toast.toast-error .ico { color: #ff8a73; }
#toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
/* At a table on a phone the bottom of the screen is your hand and the betting
   buttons, so toasts drop in from under the topbar instead of covering them. */
@media (max-width: 600px) {
  body.room-page #toast {
    top: calc(72px + env(safe-area-inset-top));
    bottom: auto;
    transform: translateX(-50%) translateY(-0.75rem);
    max-width: calc(100vw - 2rem);
    padding: 0.5rem 0.8rem 0.5rem 0.7rem;
    font-size: 0.82rem;
    white-space: nowrap;
  }
  body.room-page #toast .toast-text { overflow: hidden; text-overflow: ellipsis; }
  body.room-page #toast.show { transform: translateX(-50%) translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ---------- topbar extras ---------- */
/* Controls stay on ONE line at every width; they compact rather than wrap. */
.topbar-right { position: relative; display: flex; align-items: center; gap: 0.55rem; flex-wrap: nowrap; }
/* Desktop: actions inline, hamburger hidden. (Mobile overrides in reactions.css.) */
.topbar-actions {
  display: flex; align-items: center; gap: 0.4rem;
  background: rgba(0, 0, 0, 0.18);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.3rem;
}
.topbar-menu-btn { display: none; }
.topbar-divider { width: 1px; height: 22px; background: var(--line); margin: 0 0.15rem; flex: none; }
/* Blend the mute icon into the toolbar pill instead of stacking its own
   panel+border on top of the pill's — the pill already reads as a control
   group. */
.topbar-actions .icon-btn { background: transparent; border: none; }
.topbar-actions .icon-btn:hover { background: rgba(255, 255, 255, 0.08); }

/* per-game brand (card emblem + name), accent supplied inline by branding.html */
.game-brand { min-width: 0; }
.game-brand .brand-link {
  text-decoration: none; color: inherit;
  display: inline-flex; align-items: center; gap: 0.5rem; min-width: 0;
}
.brand-name {
  font-family: var(--display); font-weight: 700; font-size: 1.2rem;
  letter-spacing: 0.02em; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.brand-symbol {
  flex: none; height: 34px; width: auto; display: block;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.4));
}
.round-chip {
  font-family: var(--display);
  font-weight: 600;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--gold);
  border: 1px solid rgba(230, 178, 60, 0.4);
  background: rgba(230, 178, 60, 0.07);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
}

.tab-count {
  font-size: 0.72rem; min-width: 22px; height: 22px; padding: 0 0.4rem;
  border-radius: 999px; background: var(--panel-2); color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--body); font-weight: 600;
}

/* ---------- lobby: reusable settings panel (all games share this) ---------- */
.settings-note { color: var(--muted); font-size: 0.8rem; margin: 0 0 0.95rem; }
.rules-summary + .settings-note { margin: var(--sp-3) 0 0; }
.lobby-settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.65rem 0.85rem;
}
.set-item {
  display: flex; flex-direction: column; gap: 0.3rem;
  margin: 0; text-transform: none;
}
.set-label {
  font-size: 0.72rem; color: var(--muted);
  text-transform: none; letter-spacing: 0; margin: 0;
}
.set-item input {
  width: 100%; background: var(--bg); border: 1px solid var(--line);
  border-radius: 8px; padding: 0.45rem 0.55rem; color: var(--text);
  font: inherit; font-size: 0.95rem;
}
.set-val { font-family: var(--display); font-weight: 600; color: var(--text); font-size: 1rem; }
/* Host's "Shuffle seats" option (core/lobby.js), next to Start game and in the
   Super Seven round summary next to Next round. */
.shuffle-opt {
  display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer;
  font-size: 0.82rem; color: var(--muted); user-select: none; margin-right: auto;
  /* Inside a modal footer it would otherwise inherit label caps/tracking. */
  text-transform: none; letter-spacing: 0; font-weight: 500;
}
.shuffle-opt > span { display: inline-flex; align-items: center; gap: 0.35rem; }
.shuffle-opt .switch { width: 38px; height: 22px; }
.shuffle-opt .switch::after { width: 14px; height: 14px; }
.shuffle-opt .switch:checked::after { transform: translateX(16px); }
.shuffle-opt:hover { color: var(--text); }
/* On/off settings ({type: "toggle"} in core/lobby.js): a switch for the host. */
.set-item.set-toggle { cursor: pointer; }
/* Two classes, so it outranks `.set-item input` (the number boxes' full-width rule). */
.set-item .set-switch {
  appearance: none; -webkit-appearance: none; margin: 0.15rem 0 0; padding: 0;
  width: 44px; height: 24px; flex: 0 0 auto; border-radius: 999px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line);
  position: relative; transition: background 0.15s, border-color 0.15s;
}
.set-item .set-switch::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--muted); transition: transform 0.15s, background 0.15s;
}
.set-item .set-switch:checked { background: color-mix(in srgb, var(--gold) 35%, transparent); border-color: var(--gold); }
.set-item .set-switch:checked::after { transform: translateX(20px); background: var(--gold); }
.set-item .set-switch:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.set-save { margin-top: 1rem; width: auto; padding: 0.5rem 1.1rem; }

/* The landing page's picker, actions and join row live in home.css. */

/* ══════════════════════════════════════════════════════════════════════
   Join screen for a shared room link (partials/join_gate.html)
   ══════════════════════════════════════════════════════════════════════
   Covers the room until the visitor is seated, so they never see a lobby
   they are not part of. Above dialogs and the floating buttons, below toasts
   (a refusal such as "table is full" must still be readable). */
.join-gate {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-toast) - 1);
  display: grid;
  place-items: center;
  overflow-y: auto;
  padding: var(--sp-6) var(--sp-4) calc(var(--sp-6) + env(safe-area-inset-bottom));
  background:
    radial-gradient(70% 55% at 85% 0%, rgba(230, 178, 60, 0.08) 0%, transparent 60%),
    radial-gradient(90% 70% at 10% -10%, rgba(63, 158, 100, 0.12) 0%, transparent 65%),
    var(--bg);
}
.join-gate[hidden] { display: none; }
body.gated { overflow: hidden; }
.join-gate-card {
  width: 100%;
  max-width: 420px;
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
  border-radius: var(--r-xl);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.03), transparent 40%), var(--panel);
  border: 1px solid var(--line);
  box-shadow: var(--el-3);
  text-align: center;
  animation: modal-rise var(--dur-slow) var(--ease-out);
}
.jg-symbol { height: 60px; width: auto; filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.55)); }
.jg-eyebrow { margin: var(--sp-4) 0 var(--sp-1); color: var(--gold); font-size: var(--fs-sm); font-weight: 600; }
.jg-title {
  margin: 0;
  font-family: var(--display);
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
}
.jg-sub { margin: var(--sp-2) 0 var(--sp-6); color: var(--muted); font-size: var(--fs-sm); line-height: 1.6; }
.jg-sub b { color: var(--text); font-weight: 600; }
.jg-note { color: var(--warning); }
.join-gate-card label { text-align: left; }
.join-gate-card input[type="text"] { height: 48px; font-size: 1.05rem; }
.jg-av-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: var(--sp-5) 0 var(--sp-2);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.jg-av-head small { text-transform: none; letter-spacing: 0; opacity: 0.8; }
.jg-avatars {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(38px, 1fr));
  gap: var(--sp-2);
  margin-bottom: var(--sp-6);
}
.jg-av {
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  padding: 0;
  border-radius: 50%;
  background: var(--panel-2);
  border: 2px solid transparent;
  color: var(--text);
  font-family: var(--display);
  font-size: 0.95rem;
  font-weight: 700;
}
.jg-av .av-motif { width: 18px; height: 18px; stroke-width: 2; }
.jg-av:hover { border-color: var(--line); }
.jg-av.selected { border-color: var(--gold); color: var(--gold); background: color-mix(in srgb, var(--gold) 16%, var(--panel-2)); }
.join-gate-card .btn-primary { width: 100%; }
.jg-home {
  display: inline-block;
  margin-top: var(--sp-4);
  color: var(--muted);
  font-size: var(--fs-sm);
  text-decoration: none;
}
.jg-home:hover { color: var(--text); }
@media (prefers-reduced-motion: reduce) { .join-gate-card { animation: none; } }
