/* ============================================================
   Chassis design system.
   Consumes tokens from /theme.css (runtime, settings-driven).
   Hand-authored — no build step, no framework.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }

/* The hidden attribute must win over any element's own display rule — without
   this, a class like .install-prompt { display: flex } silently overrides
   [hidden] and elements meant to be toggled from script show anyway. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--bg);
}

h1, h2, h3, h4 { font-family: var(--font-display); color: var(--ink); margin: 0 0 .5em; }
h1 { font-size: 22px; font-weight: 700; }
h2 { font-size: 18px; font-weight: 700; }
h3 { font-size: 15px; font-weight: 600; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); }

code, .mono { font-family: var(--font-mono); font-size: .92em; }

.dim { color: var(--dim); }

/* ---------- Shell layout ---------- */

.shell { display: flex; min-height: 100vh; }

.shell-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.content { flex: 1; padding: 24px; max-width: 1280px; width: 100%; }

/* The add-to-home-screen nudge. Quiet, dismissible, above the page content. */
.install-prompt {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 0 0 18px; padding: 12px 14px;
  background: var(--accent-soft); border: 1px solid var(--accent); border-radius: var(--radius);
}
.install-prompt-body { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 220px; }
.install-prompt-icon { font-size: 26px; line-height: 1; flex: none; }
.install-prompt-text { display: flex; flex-direction: column; gap: 2px; font-size: 14px; line-height: 1.45; }
.install-prompt-text .dim { font-size: 13px; }
.install-prompt-actions { display: flex; gap: 8px; flex: none; }

.legal-footer {
  padding: 16px 24px;
  font-size: 12px;
  color: var(--dim);
  border-top: 1px solid var(--line);
}

/* ---------- Sidebar ---------- */

.sidebar {
  width: 232px;
  flex-shrink: 0;
  background: var(--panel);
  border-right: 1px solid var(--line);
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.sidebar-brand { display: block; padding: 4px 10px; }

.brand-lockup { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); }
.brand-mark { display: inline-flex; color: var(--accent); }
.brand-mark svg { width: 28px; height: 28px; }
.brand-name { font-family: var(--font-display); font-weight: 800; font-size: 17px; letter-spacing: -.01em; }

.sidebar-nav { display: flex; flex-direction: column; gap: 2px; }

.nav-section {
  margin: 14px 10px 4px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--dim);
}

.nav-item {
  display: block;
  padding: 8px 10px;
  border-radius: calc(var(--radius) - 4px);
  color: var(--ink);
  font-weight: 500;
}
.nav-item:hover { background: var(--bg); color: var(--ink); }
.nav-item.active { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

/* ---------- Top bar ---------- */

.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 24px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 20;
}

.topbar-title { flex: 1; min-width: 0; }
.topbar-title h1 { margin: 0; font-size: 18px; }

.topbar-actions { display: flex; align-items: center; gap: 10px; }

.sidebar-toggle {
  display: none;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: calc(var(--radius) - 4px);
  padding: 6px 10px;
  font-size: 16px;
  cursor: pointer;
}

/* ---------- Avatar + dropdown ---------- */

.avatar-menu { position: relative; }

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-transform: uppercase;
}
.avatar:hover { background: var(--accent-hover); }
.avatar { position: relative; }

.bell {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--dim);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.bell:hover { color: var(--accent); border-color: var(--accent); }

.bell-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 2px solid var(--panel);
}

.dropdown {
  display: none;
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 230px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .10);
  padding: 6px;
  z-index: 40;
}
.avatar-menu.open .dropdown { display: block; }

.dropdown-header { padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; font-size: 13px; }
.dropdown-header .dim { font-size: 12px; }

.dropdown-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  border: none;
  background: none;
  border-radius: calc(var(--radius) - 6px);
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}
.dropdown-item:hover { background: var(--accent-soft); color: var(--accent); }

.dropdown-divider { height: 1px; background: var(--line); margin: 6px 4px; }

/* ---------- Modals ---------- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(17, 24, 39, .45);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 100;
  padding: 16px;
}
.modal-overlay.open { display: flex; }

.modal {
  background: var(--panel);
  border-radius: calc(var(--radius) + 4px);
  box-shadow: 0 20px 50px rgba(0, 0, 0, .25);
  max-width: 480px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  padding: 24px;
}

/* ---------- Banners & flashes ---------- */

.maintenance-banner {
  padding: 10px 24px;
  font-size: 14px;
  font-weight: 500;
  text-align: center;
}
.maintenance-banner.tone-info { background: var(--accent-soft); color: var(--accent); }
.maintenance-banner.tone-warning { background: #FEF3C7; color: var(--warn); }
.maintenance-banner.tone-critical { background: #FEE2E2; color: var(--danger); }

.flash {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-radius: var(--radius);
  margin-bottom: 16px;
  font-size: 14px;
  border: 1px solid transparent;
}
.flash.tone-ok { background: #ECFDF5; color: var(--ok); border-color: #A7F3D0; }
.flash.tone-danger { background: #FEF2F2; color: var(--danger); border-color: #FECACA; }
.flash.tone-warn { background: #FFFBEB; color: var(--warn); border-color: #FDE68A; }
.flash.tone-info { background: var(--accent-soft); color: var(--accent); border-color: var(--line); }

.flash-dismiss { border: none; background: none; color: inherit; font-size: 18px; cursor: pointer; line-height: 1; }

/* ---------- Cards, panels ---------- */

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 20px;
}

.card + .card { margin-top: 16px; }
.grid > .card { margin-top: 0; } /* grid gap handles spacing — no stacked-card margin */
.grid { align-items: start; }

.card-title { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.card-title h2, .card-title h3 { margin: 0; }

.grid { display: grid; gap: 16px; }
.grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.grid.cols-4 { grid-template-columns: repeat(4, 1fr); }

.kpi { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.kpi .kpi-label { font-size: 12px; color: var(--dim); text-transform: uppercase; letter-spacing: .06em; }
.kpi .kpi-value { font-family: var(--font-display); font-size: 26px; font-weight: 800; }

/* ---- World map (super-admin structure visualiser) ---- */
.wm-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
.wm-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.wm-chip { background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 4px 12px; font-size: 13px; }
.wm-chip b { color: var(--accent); }

.wm-phase { border-left: 2px solid var(--accent); padding-left: 12px; margin-bottom: 4px; }
.wm-phase-h { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--accent); font-weight: 700; margin-bottom: 6px; }
.wm-flow { color: var(--dim); font-size: 12px; margin: 2px 0 10px 4px; }
.wm-seat { margin-bottom: 12px; }
.wm-seat-h { font-weight: 600; margin-bottom: 4px; }
.wm-opts { list-style: none; margin: 0; padding: 0; }
.wm-opts li { padding: 3px 0; font-size: 13px; }
.wm-opt-label { font-weight: 500; }
.wm-pill { display: inline-block; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; padding: 1px 7px; border-radius: 8px; margin-right: 5px; }
.wm-safe { background: var(--accent-soft); color: var(--accent); }
.wm-even { background: #FCEFDD; color: #9A5B10; }
.wm-long { background: #FBE4E4; color: #A5231C; }
.wm-tag { display: inline-block; font-size: 11px; color: var(--dim); border: 1px solid var(--line); border-radius: 6px; padding: 0 6px; margin-left: 5px; }
.wm-tag.wm-set { color: var(--accent); border-color: var(--accent); }
.wm-tag.wm-need { color: #9A5B10; border-color: #E7C79A; }
.wm-cards { margin: 5px 0 0; }
.wm-cardtag { display: inline-block; font-size: 12px; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 2px 8px; margin: 0 5px 5px 0; }
.wm-need2 { color: var(--dim); }

.wm-chain { display: grid; grid-template-columns: 1fr auto 1fr; gap: 10px; align-items: center; padding: 8px 0; border-top: 1px solid var(--line); }
.wm-chain:first-of-type { border-top: none; }
.wm-src { text-align: right; font-size: 12.5px; }
.wm-dst { font-size: 12.5px; }
.wm-mid { text-align: center; }
.wm-flagnode { display: inline-block; background: var(--accent-soft); color: var(--accent); font-weight: 700; font-size: 12.5px; border-radius: 999px; padding: 3px 12px; white-space: nowrap; }
.wm-chain.is-bad .wm-flagnode { background: #FBE4E4; color: #A5231C; }
.wm-chain.is-warn .wm-flagnode { background: #FCEFDD; color: #9A5B10; }
.wm-badge { font-size: 10px; margin-top: 3px; }
.wm-badge.bad { color: #A5231C; }
.wm-badge.warn { color: #9A5B10; }
.wm-warn { color: #A5231C; font-size: 12px; font-style: italic; }

.wm-cross { list-style: none; margin: 0; padding: 0; }
.wm-cross li { padding: 5px 0; border-top: 1px solid var(--line); font-size: 13px; }
.wm-cross li:first-child { border-top: none; }
.wm-links, .wm-cross .wm-links { color: var(--accent); font-weight: 600; margin: 0 4px; }

.wm-rounds, .wm-teams { list-style: none; margin: 0; padding: 0; }
.wm-rounds { display: flex; flex-wrap: wrap; gap: 6px; }
.wm-round { font-size: 12.5px; background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 3px 9px; }
.wm-round em { color: var(--accent); font-style: normal; }
.wm-teams li { padding: 6px 0; border-top: 1px solid var(--line); font-size: 13px; }
.wm-teams li:first-child { border-top: none; }

@media (max-width: 860px) {
  .wm-cols { grid-template-columns: 1fr; }
  .wm-chain { grid-template-columns: 1fr; gap: 3px; }
  .wm-src { text-align: left; }
}

/* ---- Playtest monitor ---- */
.pt-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.pt-cols { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; align-items: start; }
.pt-num { white-space: nowrap; }
.pt-bar { height: 7px; border-radius: 4px; background: var(--line); overflow: hidden; }
.pt-bar > span { display: block; height: 100%; background: var(--accent); border-radius: 4px; }
.pt-feed { list-style: none; margin: 0; padding: 0; }
.pt-feed li { padding: 9px 0; border-top: 1px solid var(--line); }
.pt-feed li:first-child { border-top: none; }
.pt-feed-line { font-size: 14px; }
.pt-rounds { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.pt-round-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; font-size: 14px; }
.pt-empty td { opacity: .55; }
@media (max-width: 860px) { .pt-cols { grid-template-columns: 1fr; } }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  border-radius: calc(var(--radius) - 2px);
  border: 1px solid transparent;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  background: var(--accent);
  color: var(--on-accent);
  transition: background .12s ease, transform .05s ease;
}
.btn:hover { background: var(--accent-hover); color: var(--on-accent); }
.btn:active { transform: translateY(1px); }

.btn.secondary { background: var(--panel); color: var(--ink); border-color: var(--line); }
.btn.secondary:hover { background: var(--bg); }

.btn.ghost { background: transparent; color: var(--accent); }
.btn.ghost:hover { background: var(--accent-soft); }

.btn.danger { background: var(--danger); }

.btn.sm { padding: 5px 10px; font-size: 13px; }

.btn[disabled] { opacity: .5; cursor: not-allowed; }

/* ---------- Forms ---------- */

.field { margin-bottom: 16px; }

.field label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 6px; }

.field .hint { font-size: 12px; color: var(--dim); margin-top: 4px; }
/* Plain descriptive text under a field. Distinct from .hint, which is the tooltip
   component (cursor: help + a data-hint bubble) and must not be borrowed for prose. */
.field-note { font-size: 12px; color: var(--dim); margin-top: 6px; line-height: 1.55; cursor: default; }

input[type="text"], input[type="email"], input[type="number"], input[type="password"],
input[type="url"], input[type="date"], select, textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) - 2px);
  font: inherit;
  font-size: 14px;
  color: var(--ink);
  background: var(--panel);
}
input:focus, select:focus, textarea:focus {
  outline: 2px solid var(--accent-soft);
  border-color: var(--accent);
}

.checkbox { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.checkbox input { width: auto; }

.code-input {
  font-family: var(--font-mono);
  font-size: 22px;
  letter-spacing: .45em;
  text-align: center;
}

/* ---------- Tables ---------- */

.table-wrap { overflow-x: auto; }

table.data {
  width: 100%;
  border-collapse: collapse;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: 14px;
}
table.data th {
  text-align: left;
  padding: 10px 14px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--dim);
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}
table.data td { padding: 10px 14px; border-bottom: 1px solid var(--line); }
table.data tr:last-child td { border-bottom: none; }
table.data tr:hover td { background: var(--bg); }

/* A seat cell that carries the role, the character in it, and the real player. */
table.data td.seat .seat-role { display: block; font-weight: 600; }
table.data td.seat .seat-sub { display: block; color: var(--dim); font-size: 12px; margin-top: 1px; }
.seat-player { color: var(--ink); font-weight: 600; }

/* ---------- Badges / pills ---------- */

.pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
}
.pill.ok { background: #ECFDF5; color: var(--ok); }
.pill.warn { background: #FFFBEB; color: var(--warn); }
.pill.danger { background: #FEF2F2; color: var(--danger); }
.pill.accent { background: var(--accent-soft); color: var(--accent); }
.pill.neutral { background: var(--bg); color: var(--dim); }

/* ---------- Auth screens ---------- */

.auth-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

.auth-box { width: 100%; max-width: 400px; }

.auth-brand { text-align: center; margin-bottom: 20px; }
.auth-brand .brand-lockup { justify-content: center; }

.auth-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: calc(var(--radius) + 4px);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .06);
  padding: 26px;
}

.auth-note {
  margin: 0 0 14px;
  padding: 10px 12px;
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--ink);
  font-size: 13px;
  line-height: 1.5;
}

.auth-split { min-height: 100vh; display: flex; }
.auth-split-brand {
  flex: 1;
  min-width: 0; /* let the panel be a true half — the wide card row bleeds, doesn't stretch it */
  background: var(--accent);
  color: var(--on-accent);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 48px;
  overflow: hidden; /* the seat-card row may bleed off the edge — never scroll the page */
}
.auth-split-brand h1 { color: var(--on-accent); font-size: 34px; }
/* The brand panel sits on the accent, so the logo must invert onto it — otherwise
   the mark (drawn in the accent colour) is invisible. And it is the hero of this
   page, so it is sized up well beyond the header lockup. */
.auth-split-brand .brand-lockup { color: var(--on-accent); gap: 16px; margin-bottom: 4px; }
.auth-split-brand .brand-mark { color: var(--on-accent); }
.auth-split-brand .brand-mark svg { width: 60px; height: 60px; }
.auth-split-brand .brand-name { font-size: 40px; letter-spacing: -.02em; }
/* The seat-card signature: a short overlapping row of the shelf's own cards, each
   in its sport's colours. Upright and equal-sized (not fanned), right card on top. */
/* Centred so the gap to the panel edge equals the gap to the middle divide, at any width. */
.auth-sports { display: flex; justify-content: center; margin-top: 44px; padding-top: 8px; max-width: 100%; }
.auth-sport-card {
  position: relative; /* so a hovered card's raised z-index actually sticks */
  width: 200px; flex: none;
  display: flex; flex-direction: column; gap: 14px;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: 18px;
  padding: 24px 26px 28px;
  box-shadow: 0 24px 48px rgba(0, 0, 0, .32);
  transition: transform .16s ease;
}
.auth-sport-card + .auth-sport-card { margin-left: -80px; }
.auth-sport-card:hover { transform: translateY(-12px); }
.auth-sport-icon { width: 44px; height: 44px; color: var(--accent); }
.auth-sport-icon svg { width: 100%; height: 100%; display: block; }
.auth-sport-name { font-family: var(--font-display); font-weight: 700; font-size: 18px; line-height: 1; white-space: nowrap; }
.auth-sport-disc { font-size: 12px; letter-spacing: .09em; text-transform: uppercase; color: var(--dim); white-space: nowrap; }
/* The full-size cards need a wide panel to sit inside the divide. Below that, step
   them down a size so the row still fits between the edge and the middle line. */
@media (max-width: 1439px) {
  .auth-sport-card { width: 150px; gap: 11px; border-radius: 14px; padding: 18px 20px 22px; box-shadow: 0 16px 34px rgba(0, 0, 0, .32); }
  .auth-sport-card + .auth-sport-card { margin-left: -58px; }
  .auth-sport-icon { width: 34px; height: 34px; }
  .auth-sport-name { font-size: 17px; }
  .auth-sport-disc { font-size: 11px; }
}
.auth-split-form {
  flex: 1; /* an even 50/50 split — the divide sits at the centre of the page */
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px; /* match the brand panel's padding so the split is exactly even */
  background: var(--bg);
}

/* ---------- Mobile footer bar ---------- */

.mobile-footer {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  background: var(--panel);
  border-top: 1px solid var(--line);
  z-index: 30;
  padding-bottom: env(safe-area-inset-bottom);
}

.mobile-footer-item {
  flex: 1;
  text-align: center;
  padding: 12px 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--dim);
}
.mobile-footer-item.active { color: var(--accent); }

body:has(.mobile-footer) .content { padding-bottom: 84px; }
body:has(.mobile-footer) .legal-footer { padding-bottom: 72px; }

/* ---------- Responsive ---------- */

@media (max-width: 900px) {
  .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 50;
    transform: translateX(-100%);
    transition: transform .18s ease;
    box-shadow: 0 0 40px rgba(0, 0, 0, .2);
  }
  body.sidebar-open .sidebar { transform: translateX(0); }
  .sidebar-toggle { display: inline-flex; }
  .grid.cols-2, .grid.cols-3, .grid.cols-4 { grid-template-columns: 1fr; }
  .auth-split { flex-direction: column; }
  .auth-split-form { width: 100%; }
  .auth-split-brand { padding: 40px 32px; }
  /* Tighter cards so the whole row fits a phone; any spill bleeds off, never scrolls. */
  .auth-sport-card { width: 104px; gap: 6px; padding: 11px 12px 12px; border-radius: 10px; }
  .auth-sport-card + .auth-sport-card { margin-left: -34px; }
  .auth-sport-icon { width: 22px; height: 22px; }
  .auth-sport-name { font-size: 15px; }
  .auth-sport-disc { font-size: 10px; }
}

/* ============================================================
   Product core: Parable
   ============================================================ */

/* ---------- Round-by-round score grid ---------- */
table.data th.rd,
table.data td.rd {
  width: 3.5rem;
  min-width: 3.5rem;
  text-align: center;
  padding-left: 6px;
  padding-right: 6px;
  font-variant-numeric: tabular-nums;
}
table.data th.rd { font-size: 11px; letter-spacing: .08em; }
table.data th.num,
table.data td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.data td.num.total { font-weight: 600; border-left: 1px solid var(--line); }
table.data th.num.total { border-left: 1px solid var(--line); }
table.data td.seat { white-space: nowrap; font-weight: 500; }
table.data th.pos,
table.data td.pos { width: 2.5rem; text-align: center; color: var(--dim); font-variant-numeric: tabular-nums; }

.score-up   { color: var(--ok); }
.score-down { color: var(--dim); }
.score-nil  { color: var(--dim); opacity: .55; }

.table-note { font-size: 13px; color: var(--dim); margin-top: 10px; }

/* ---------- The stage ----------
   A pack does not repaint the page. It renders inside a device, so its own
   world is a bounded object sitting on Parable's ground rather than a
   differently-coloured wall. On a phone the device IS the frame, so the
   bezel disappears and the pack goes full width. */
.stage-wrap { display: flex; flex-direction: column; align-items: center; }

.stage {
  width: 100%;
  max-width: 460px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 30px;
  padding: 12px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .05), 0 12px 32px rgba(0, 0, 0, .07);
}
.stage-screen {
  border-radius: 20px;
  overflow: hidden;
  background: var(--bg);
  border: 1px solid var(--line);
  /* `color` inherits as a COMPUTED value: body resolves var(--ink) against the
     platform tokens, and descendants inherit that literal. Re-declaring it here
     re-resolves against the pack's tokens, so text follows the stage. Without
     this, a dark pack renders dark ink on a dark panel. */
  color: var(--ink);
}
.stage-plaque {
  margin-top: 14px;
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--dim);
  text-align: center;
}

@media (max-width: 720px) {
  .stage { max-width: none; border: none; border-radius: 0; padding: 0; box-shadow: none; background: transparent; }
  .stage-screen { border-radius: 0; border-left: none; border-right: none; }
  .stage-plaque { display: none; }
}

/* ---------- Zebra striping for scan-across tables ----------
   Product tables are wide (a column per round), so the eye needs a rail to
   follow. Hover must stay distinguishable from the stripe, so it uses the
   accent tint rather than the same fill. */
table.data.striped tbody tr:nth-child(even) td { background: var(--bg); }
table.data.striped tbody tr:hover td { background: var(--accent-soft); }

/* ---------- Pills inside a pack's own presentation ----------
   The chassis status pills carry hardcoded light backgrounds, which is fine on
   paper and unreadable on a dark stage. Inside the stage they resolve from
   tokens instead, so a pack theme cannot produce pale-on-pale text. */
.stage-screen .pill.ok     { background: var(--accent-soft); color: var(--ok); }
.stage-screen .pill.warn   { background: var(--accent-soft); color: var(--warn); }
.stage-screen .pill.danger { background: var(--accent-soft); color: var(--danger); }
.stage-screen .pill.neutral { background: var(--bg); color: var(--dim); }

/* ---------- Choices: tap the card, not a radio ----------
   The radio stays in the DOM for form semantics and keyboard use, but is taken
   out of the visual language. Selection reads as a ring in the same colour as
   the commit button, so the thing you tapped and the thing you press next are
   obviously related. */
.choice {
  position: relative;
  display: block;
  background: var(--panel);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.choice input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}
.choice:hover { border-color: var(--dim); }
/* .is-selected is set by script and is the load-bearing one: :has() does not
   reliably invalidate style when `checked` is set as a property rather than an
   attribute, so it is kept only as progressive enhancement. */
.choice.is-selected {
  border-color: var(--accent);
  background: var(--accent-soft);
}
/* Progressive enhancement only, and kept in its OWN rule: an unsupported
   selector invalidates the entire selector list it sits in, which would take
   the class rule down with it. */
.choice:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.choice:has(input:focus-visible) {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.choice.is-locked {
  opacity: .45;
  cursor: not-allowed;
  background: transparent;
}
.choice.is-locked:hover { border-color: var(--line); }

.choice-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.choice-label { font-weight: 600; }
.choice-detail { display: block; margin-top: 6px; color: var(--dim); font-size: 14px; }
.choice-why { display: block; margin-top: 8px; color: var(--dim); font-size: 13px; font-style: italic; }

/* ---------- Commit: the thumb target ---------- */
.commit {
  width: 100%;
  justify-content: center;
  padding: 15px 16px;
  font-size: 15px;
  margin-top: 4px;
}
.commit[disabled] { opacity: .4; }

.leave {
  display: block;
  text-align: center;
  margin-top: 14px;
  color: var(--dim);
  font-size: 14px;
}
a.leave:hover { color: var(--ink); }

/* Quiet links keep the accent so they read as links, not disabled text. */
.leave a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.leave a:hover { color: var(--ink); }

/* ---------- The shelf ----------
   One card per season, each wearing its own pack's presentation. The shelf reads
   as a rack of different games rather than a list of rows, and the card is a
   small version of the stage it opens into — same tokens, same corner language —
   so selecting one feels like stepping into it rather than navigating away. */
.shelf { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }

.shelf-card {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 20px;
  padding: 20px;
  /* Same reason as .stage-screen: `color` inherits as a computed value, so it
     has to be re-resolved here or a dark pack renders dark ink on a dark card. */
  color: var(--ink);
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.shelf-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.shelf-title { margin: 0; font-size: 18px; color: var(--ink); }
.shelf-sub { margin: 2px 0 0; font-size: 13px; color: var(--dim); }

.shelf-meta { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px 16px; margin: 0; }
.shelf-meta div { margin: 0; }
.shelf-meta dt {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim);
}
.shelf-meta dd {
  margin: 2px 0 0; font-size: 15px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.shelf-meta .of { font-weight: 400; color: var(--dim); }

.shelf-seats { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.shelf-seats li {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; background: var(--panel); font-size: 14px;
}
.shelf-seats li:first-child { border-radius: 8px 8px 0 0; }
.shelf-seats li:last-child { border-radius: 0 0 8px 8px; }
.shelf-seats li:only-child { border-radius: 8px; }
.shelf-seat-role { font-weight: 600; }
/* The holder's name takes the slack so the play link or status stays pinned
   right. Each seat carries its own person, so two seats on one team read as two
   different people rather than the same name twice. */
.shelf-seat-team { color: var(--dim); flex: 1; }
.shelf-seat-go { color: var(--accent); font-weight: 600; }
.shelf-seat-done { color: var(--dim); font-size: 13px; }
/* The quieter sibling of "Play": you have played, but you can still revise. */
.shelf-seat-change { color: var(--accent); font-weight: 600; font-size: 13px; }

.shelf-foot { margin-top: auto; }
.shelf-waiting { margin: 0; font-size: 14px; color: var(--dim); }

/* A card opens into the stage. Where the browser supports it, the two are the
   same object moving; where it does not, it is an ordinary navigation. */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }

/* ---------- Hints ----------
   Shown on hover and on focus, so a keyboard reaches them and a tap on a phone
   opens them too — hover-only help is help that half the users never see. */
.hint { position: relative; cursor: help; }
.hint::after {
  content: attr(data-hint);
  position: absolute;
  /* Opens downward, not up. The pace pill sits at the top of a card on the top
     row of the shelf, and an upward tooltip slid straight under the sticky
     topbar — which wins the stacking contest because a hovered card is pinned at
     z-index 5 while the topbar sits at 20. Dropping the tooltip below the pill
     keeps it in the card body, clear of the header in every state. */
  top: calc(100% + 8px);
  right: 0;
  z-index: 30;
  width: max-content;
  max-width: 260px;
  padding: 10px 12px;
  background: var(--panel);
  color: var(--ink);
  border: 1px solid var(--border-strong, var(--line));
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, .18);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: 0;
  text-transform: none;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-3px);
  transition: opacity .12s ease, transform .12s ease, visibility .12s;
}
.shelf-card:hover { z-index: 5; }

.hint:hover::after,
.hint:focus-visible::after,
.hint:focus::after { opacity: 1; visibility: visible; transform: none; }
.hint:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 999px; }

@media (prefers-reduced-motion: reduce) { .hint::after { transition: none; } }

/* ---------- A finished season ----------
   Kept on the shelf rather than hidden: it is a keepsake, and the record is the
   point. Muted so it reads as history beside a live season without vanishing. */
.shelf-card.is-finished { opacity: .72; }
.shelf-card.is-finished:hover { opacity: 1; }
.shelf-card.is-finished .shelf-title { font-weight: 500; }

/* ---------- Sport marks ----------
   A ghosted line icon is the one thing that reliably does not work: strokes
   disappear before they stop being noticed, so the mark ends up illegible and
   still in the way. These four give it an actual job instead. */
/* No overflow clipping: a hint anchored inside the card has to be able to leave
   it. The spine rounds its own top corners instead of relying on the card to
   crop them. */
.shelf-card { position: relative; }

/* SPINE — the card is a box on a shelf, so it gets a spine. Full contrast,
   legible, and it names the sport rather than hinting at it. */
.sport-spine {
  display: flex; align-items: center; gap: 8px;
  margin: -20px -20px 4px; padding: 10px 20px;
  background: var(--accent-soft);
  border-bottom: 1px solid var(--line);
  border-radius: 19px 19px 0 0;   /* card radius less its 1px border */
  color: var(--accent);
}
.sport-spine-mark { width: 18px; height: 18px; flex: none; }
.sport-spine-mark svg { width: 100%; height: 100%; display: block; }
.sport-spine-name {
  font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
}

/* INLINE — smallest possible claim: a category marker beside the title. */
.sport-inline { width: 20px; height: 20px; flex: none; color: var(--accent); }
.sport-inline svg { width: 100%; height: 100%; display: block; }



/* The discipline sits under the sport: "MOTORSPORT · Single-seater". Generic by
   design — a real series name would be somebody else's trademark. */
.sport-spine-discipline {
  font-size: 11px; letter-spacing: .04em; opacity: .72; font-weight: 500;
}
.sport-spine-discipline::before { content: "·"; margin: 0 6px; opacity: .6; }

/* A compound question needs its parts labelled, or it reads as one long list. */
.question-label {
  margin: 18px 0 0; font-size: 13px; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--dim);
}

/* A notification list has to be able to run long without running off the screen. */
.dropdown-scroll { max-height: min(60vh, 420px); overflow-y: auto; overscroll-behavior: contain; }

/* ---- Season report -------------------------------------------------------
   The ending. A season used to stop rather than finish, so this screen exists
   to say plainly how it went - led by par, because that is the only thing the
   game scores. */

.report-verdict {
  font-size: 30px;
  font-weight: 640;
  letter-spacing: -.02em;
  line-height: 1.15;
  margin: 4px 0 0;
  text-wrap: balance;
}

.report-teams { list-style: none; margin: 4px 0 14px; padding: 0; display: grid; gap: 8px; }

.report-teams li {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: baseline;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}

.report-team-name  { font-weight: 600; }
.report-team-place { font-variant-numeric: tabular-nums; }
.report-team-points { color: var(--dim); font-variant-numeric: tabular-nums; font-size: 14px; }

.report-seat { padding: 14px 0; border-bottom: 1px solid var(--line); }
.report-seat:last-child { border-bottom: none; padding-bottom: 0; }
.report-seat p { margin: 0 0 6px; }

.report-seat-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 8px;
}

.report-seat-role { font-weight: 640; font-size: 17px; }

.report-seat-score {
  font-family: var(--font-mono);
  font-size: 26px;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}

/* Best / worst / finish as a compact scannable strip rather than three sentences
   and three "Read it back" links. The round is the link; the signed delta wears
   the colour, so the eye can read the season without reading paragraphs. */
.report-seat-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  margin-top: 2px;
  font-size: 14px;
  color: var(--dim);
}
.report-seat-stats .stat { display: inline-flex; align-items: baseline; gap: 7px; }
.report-seat-stats .stat b {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--ink);
}
.report-seat-stats .stat b.score-up { color: var(--ok); }
.report-seat-stats .stat b.score-down { color: var(--dim); }
.report-seat-stats a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--line);
}
.report-seat-stats a:hover { color: var(--accent); text-decoration-color: var(--accent); }

/* Your own row, so the table can be scanned for yourself at a glance. */
table.data tr.is-me td { font-weight: 640; }

@media (max-width: 560px) {
  .report-verdict { font-size: 24px; }
  .report-teams li { grid-template-columns: 1fr auto; }
  .report-team-points { grid-column: 2; }
}

/* ---- The par illustration --------------------------------------------------
   A row of finishing positions with the autopilot (par) box and the actual
   finish marked. The gap between the two boxes is the score, read at a glance —
   the picture that made par land in the player guide. Pack-themed via tokens, so
   it works on the light platform chrome and inside a dark stage alike. */
.par-pips { display: flex; gap: 4px; margin: 14px 0 8px; }
.par-pips .pip {
  flex: 1; min-width: 0; height: 34px; border-radius: 6px;
  background: var(--panel); border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 13px; color: var(--dim);
  font-variant-numeric: tabular-nums;
}
/* The counterfactual: a dashed ghost of a box — where you would have drifted. */
.par-pips .pip.par { background: var(--accent-soft); border: 1px dashed var(--accent); color: var(--ink); font-weight: 600; }
/* Where you actually finished: solid, yours. */
.par-pips .pip.you { background: var(--accent); border: 1px solid var(--accent); color: var(--on-accent); font-weight: 700; }
/* The run of places skipped between the anchors and your neighbourhood. Narrow, so
   the real boxes keep the width rather than stretching across the whole grid. */
.par-pips .pip-gap {
  flex: 0 0 auto; display: flex; align-items: flex-end; justify-content: center;
  padding: 0 2px; color: var(--dim); font-size: 15px; letter-spacing: 1px;
}

.par-legend { display: flex; gap: 18px; flex-wrap: wrap; font-size: 13px; color: var(--dim); }
.par-legend span { display: inline-flex; align-items: center; gap: 8px; }
.par-legend strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.par-legend i { width: 14px; height: 14px; border-radius: 4px; display: inline-block; flex: none; }
.par-legend .sw-par { background: var(--accent-soft); border: 1px dashed var(--accent); }
.par-legend .sw-you { background: var(--accent); border: 1px solid var(--accent); }

/* ---- Hosting: the host form, the lobby, the dashboard home -----------------
   All built from the same tokens as the rest of the app; the lobby wears the
   pack's presentation like a shelf card so it reads as a way into that world. */

/* Dashboard tiles: play, or host. */
.home-cta { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-bottom: 16px; }
.home-tile {
  display: flex; flex-direction: column; gap: 4px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 20px; color: var(--ink);
}
.home-tile:hover { border-color: var(--accent); color: var(--ink); }
.home-tile.accent { background: var(--accent-soft); border-color: transparent; }
.home-tile-k { font-size: 13px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--dim); }
.home-tile.accent .home-tile-k { color: var(--accent); }
.home-tile-v { font-family: var(--font-display); font-size: 34px; font-weight: 800; line-height: 1; }
.home-tile.accent .home-tile-v { color: var(--accent); }
.home-tile-note { font-size: 13px; color: var(--dim); }

/* Hosted-games list. */
.host-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.host-list li {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.host-list li:first-child { border-top: none; }
.host-list-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.host-list-name { font-weight: 600; }
.host-list-sub { font-size: 13px; }

/* Your turn — the seats waiting on a call, the top of the dashboard. */
.waiting-card { border-color: var(--accent); }
.turn-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.turn-list li {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.turn-list li:first-child { border-top: none; }
.turn-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.turn-role { font-weight: 600; }
.turn-sub { font-size: 13px; }

/* Host form. */
.host-wrap { max-width: 780px; }
.hosted-list { list-style: none; margin: 0; padding: 0; }
.hosted-list li {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.hosted-list li:first-child { border-top: none; }
.hosted-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.hosted-name { font-weight: 600; }
.hosted-meta { font-size: 13px; display: flex; align-items: center; gap: 6px; }
.pick-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.pace-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.pick { position: relative; display: block; cursor: pointer; }
.pick input { position: absolute; opacity: 0; pointer-events: none; }
.pick-body {
  display: flex; flex-direction: column; gap: 5px; height: 100%;
  border: 1.5px solid var(--line); border-radius: var(--radius);
  padding: 14px 15px; background: var(--panel); transition: border-color .12s ease, background .12s ease;
}
.pick input:checked + .pick-body { border-color: var(--accent); background: var(--accent-soft); }
.pick input:focus-visible + .pick-body { outline: 2px solid var(--accent); outline-offset: 2px; }
.pick-head { display: flex; align-items: center; gap: 7px; }
.pick-icon { width: 18px; height: 18px; color: var(--accent); flex: none; }
.pick-icon svg { width: 100%; height: 100%; }
.pick-sport { font-size: 11px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--dim); }
.pick-disc { letter-spacing: .02em; }
.pick-name { font-weight: 700; font-size: 16px; letter-spacing: -.01em; }
.pick-meta { font-size: 12.5px; color: var(--dim); line-height: 1.4; }
.pick-seats { font-size: 12px; color: var(--dim); }
.pick.pace .pick-body { gap: 6px; }

/* Lobby. */
.lobby { max-width: 820px; color: var(--ink); }
.lobby > .card { background: var(--panel); border-color: var(--line); }
.lobby .card + .card { margin-top: 16px; }
.lobby-headrow { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.lobby-meta { display: flex; gap: 28px; margin: 16px 0 0; }
.lobby-meta dt { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--dim); }
.lobby-meta dd { margin: 3px 0 0; font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; }

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

.invite-share { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.invite-tones { display: flex; gap: 4px; }
.invite-tone {
  border: 1px solid var(--line); background: var(--bg); color: var(--dim);
  padding: 5px 12px; border-radius: 999px; font-size: 13px; cursor: pointer;
}
.invite-tone.is-on { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.invite-message {
  width: 100%; min-height: 116px; resize: vertical; box-sizing: border-box;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg); color: var(--ink); font: inherit; font-size: 13px; line-height: 1.5;
}
.invite-row input {
  flex: 1; min-width: 0; font-family: var(--font-mono); font-size: 13px;
  padding: 9px 12px; border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px);
  background: var(--bg); color: var(--ink);
}

.lobby-teams { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.lobby-team { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
/* Clear the sticky header when a seat click jumps to the join card, so its
   "Take a seat" heading is not tucked out of sight under the top bar. */
#join { scroll-margin-top: 84px; }

/* The instruction that appears once a signed-out visitor picks a seat. Loud
   enough to read as "your move", not another line of grey helper text. */
.join-picked {
  margin: 0 0 12px; padding: 11px 13px;
  background: var(--accent-soft); color: var(--ink);
  border: 1px solid var(--accent); border-radius: var(--radius);
  font-size: 14px; line-height: 1.5;
}

/* A brief ring so the eye lands on the card the scroll just brought into view. */
@keyframes joinFlash {
  0%   { box-shadow: 0 0 0 0 var(--accent); }
  100% { box-shadow: 0 0 0 6px transparent; }
}
.join-flash { animation: joinFlash 1s ease-out 1; }
@media (prefers-reduced-motion: reduce) { .join-flash { animation: none; } }

.lobby-team-name {
  display: flex; align-items: center; gap: 8px;
  font-weight: 700; padding: 10px 14px; background: var(--panel); color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.team-swatch {
  display: inline-block; width: 12px; height: 12px; border-radius: 3px; flex: none;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .18);
}
.lobby-seats { list-style: none; margin: 0; padding: 0; }
.lobby-seats li {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 14px; border-top: 1px solid var(--line); font-size: 14px; min-height: 46px;
}
.lobby-seats li:first-child { border-top: none; }
.lobby-seats li.is-mine { background: var(--accent-soft); }
.lobby-seat-who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.lobby-seat-role { font-weight: 600; }
.lobby-seat-char { color: var(--dim); font-size: 13px; }
.lobby-seat-status { color: var(--dim); font-size: 13px; flex: none; }
.lobby-seat-status.is-mine-tag { color: var(--accent); font-weight: 600; }
.lobby-seat-player { color: var(--ink); font-weight: 600; }
.lobby-seat-taken { display: flex; align-items: center; gap: 8px; flex: none; }
.seat-release { display: inline; margin: 0; }
.btn.xs { padding: 2px 7px; font-size: 12px; line-height: 1.4; }
.lobby-actions { display: flex; flex-direction: column; align-items: flex-start; }

/* "You're in" — a quiet, reassuring banner while the season waits to start. */
.lobby-in-banner { border-left: 3px solid var(--accent); background: var(--accent-soft); }

/* Host tools: the seat-limit selector and the reset, sat one below the other. */
.lobby-host-tools .host-tool-row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0;
}
.lobby-host-tools .host-tool-row select { width: auto; min-width: 160px; }

/* "Bring people you've played with" — a tappable roster of past co-players. */
.playmate-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.playmate {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  padding: 7px 12px; border: 1px solid var(--line); border-radius: 999px; font-size: 14px;
}
.playmate:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.playmate input { margin: 0; }

.waiting-list { list-style: none; margin: 0; padding: 0; }
.waiting-list li { padding: 8px 0; border-top: 1px solid var(--line); }
.waiting-list li:first-child { border-top: none; }
.waiting-role { font-weight: 600; }

@media (max-width: 560px) {
  .home-cta { grid-template-columns: 1fr; }
  .lobby-meta { gap: 20px; }
}

/* ---- Studio: the team-name editor grid ---- */
.team-edit-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.team-edit input {
  width: 100%; padding: 10px 12px; font-size: 15px; font-weight: 600;
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px);
  background: var(--panel); color: var(--ink);
}
.team-edit input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }

/* ---- Studio: the roster editor (teams + the people in each seat) ---- */
.build-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; max-width: 640px; }

.import-json {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 150px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg); color: var(--ink); font-family: var(--font-mono); font-size: 12px; line-height: 1.5;
}
.import-errors {
  margin-top: 14px; padding: 12px 14px; border-radius: var(--radius);
  background: color-mix(in srgb, var(--danger) 12%, transparent); border: 1px solid var(--danger);
  font-size: 13px;
}
.import-errors ul { margin: 6px 0 0; padding-left: 18px; }
.import-errors li { margin: 2px 0; }

.vocab-grid { display: flex; flex-direction: column; gap: 10px; max-width: 640px; }
.vocab-row { display: grid; grid-template-columns: 1fr 130px 130px; gap: 10px; align-items: center; }
.vocab-label { display: flex; flex-direction: column; gap: 1px; font-size: 13px; line-height: 1.4; }
.vocab-label .dim { font-size: 12px; }
.vocab-row input { padding: 8px 10px; border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--bg); color: var(--ink); font-size: 14px; min-width: 0; }
@media (max-width: 560px) { .vocab-row { grid-template-columns: 1fr 1fr; } .vocab-row .vocab-label { grid-column: span 2; } }
.team-card { border: 1px solid var(--line); border-left: 5px solid var(--team-accent, var(--line)); border-radius: var(--radius); padding: 14px; margin-bottom: 10px; background: var(--panel); }
.team-card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
/* The team's colour: a swatch that tints the card's edge live as you pick. */
.team-accent {
  flex: none; width: 34px; height: 34px; padding: 3px; cursor: pointer;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg);
}
.team-accent::-webkit-color-swatch-wrapper { padding: 0; }
.team-accent::-webkit-color-swatch { border: none; border-radius: 5px; }
.team-accent::-moz-color-swatch { border: none; border-radius: 5px; }
/* Strength: a five-dot meter that fills in the team's own colour, plus the tier name. */
.team-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 22px; margin: 0 0 14px; }
.strength { display: inline-flex; align-items: center; gap: 10px; }
.strength-cap { font-size: 11px; font-weight: 600; color: var(--dim); text-transform: uppercase; letter-spacing: .07em; }
.strength-dots { display: inline-flex; gap: 5px; }
.strength-dot { position: relative; cursor: pointer; line-height: 0; }
.strength-dot input { position: absolute; opacity: 0; width: 0; height: 0; }
.strength-dot .dot { display: block; width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line); background: transparent; }
.strength-dot.is-on .dot { background: var(--team-accent, var(--accent)); border-color: var(--team-accent, var(--accent)); }
.strength-dot input:focus-visible + .dot { outline: 2px solid var(--accent); outline-offset: 2px; }
.strength-name { font-size: 13px; font-weight: 600; color: var(--ink); min-width: 66px; }
.team-even { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--dim); cursor: pointer; white-space: nowrap; }

/* Venues & the calendar. */
/* A venue reads as a headline and a line of colour: number, name and character on
   the top row, and the player-facing note spanning underneath where it has room. */
.venue-row {
  display: grid;
  grid-template-columns: auto minmax(150px, 1fr) auto auto;
  grid-template-areas:
    "num  name wear remove"
    "note note note      note";
  align-items: center;
  gap: 8px 10px;
  padding: 10px 0;
}
/* A round is five things on one line — number, venue, label, which question it asks,
   and its controls — so it reads as a single row rather than wrapping into three. */
.round-row { display: grid; grid-template-columns: auto minmax(130px, 1fr) minmax(110px, 1fr) auto auto; align-items: center; gap: 10px; padding: 8px 0; }
.venue-row + .venue-row, .round-row + .round-row { border-top: 1px solid var(--line); }
.venue-row input, .venue-row select, .round-row input, .round-row select {
  padding: 8px 11px; font-size: 14px; border: 1px solid var(--line);
  border-radius: calc(var(--radius) - 2px); background: var(--bg); color: var(--ink);
}
.venue-row input:focus-visible, .venue-row select:focus-visible,
.round-row input:focus-visible, .round-row select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.venue-num { grid-area: num; }
.venue-name { grid-area: name; width: 100%; min-width: 0; font-weight: 600; }
.venue-wear { grid-area: wear; }
.venue-row .team-remove { grid-area: remove; }
.venue-note { grid-area: note; width: 100%; min-width: 0; }
.round-num, .venue-num {
  flex: none; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--accent-soft); color: var(--accent); font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.round-venue, .round-label, .round-set { min-width: 0; width: 100%; }
.round-actions { display: inline-flex; gap: 4px; }
.btn-icon {
  width: 30px; height: 30px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 7px; background: var(--panel); color: var(--dim); cursor: pointer; font-size: 15px; line-height: 1;
}
.btn-icon:hover { border-color: var(--accent); color: var(--accent); }
.btn-icon.is-danger:hover { border-color: var(--danger); color: var(--danger); }

/* The studio's tabs: one step of world-building at a time. */
.build-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin: 0 0 18px; border-bottom: 1px solid var(--line); padding-bottom: 0; }
.build-tab {
  appearance: none; border: 1px solid transparent; border-bottom: none; background: transparent;
  padding: 9px 15px; font-size: 14px; font-weight: 600; color: var(--dim); cursor: pointer;
  border-radius: 8px 8px 0 0; margin-bottom: -1px; white-space: nowrap;
}
.build-tab:hover { color: var(--ink); background: var(--bg); }
.build-tab.is-on { color: var(--accent); background: var(--panel); border-color: var(--line); border-bottom: 1px solid var(--panel); }
.build-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.tab-panel { display: none; }
.tab-panel.is-on { display: block; }

@media (max-width: 760px) {
  .round-row { grid-template-columns: auto 1fr auto; }
  .round-label, .round-set { grid-column: 2 / 3; }
}

@media (max-width: 620px) {
  .venue-row {
    grid-template-columns: auto 1fr;
    grid-template-areas: "num name" "wear remove" "note note";
  }
  .venue-row .team-remove { justify-self: start; }
}

/* The decisions editor: each role's choices, their words and their character. */
.question-block { padding: 14px 0; }
.question-block + .question-block { border-top: 1px solid var(--line); }
.question-role { font-weight: 700; font-size: 15px; margin-bottom: 8px; }
/* A role's question sets, and the parts within one. */
.qset { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; margin: 0 0 10px; background: var(--bg); }
.qset-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
.qset-name { font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--dim); }
.qset-name code { font-family: var(--font-mono, ui-monospace, monospace); text-transform: none; letter-spacing: 0; color: var(--accent); background: var(--accent-soft); padding: 1px 6px; border-radius: 5px; }
.qpart { padding: 8px 0; }
.qpart + .qpart { border-top: 1px dashed var(--line); margin-top: 6px; }
.qpart-head { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }
.qpart-label {
  flex: 1; min-width: 0; padding: 7px 11px; font-size: 13px; font-weight: 600;
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--panel); color: var(--ink);
}
.qpart-label:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.qset-add { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.new-set-name {
  padding: 7px 11px; font-size: 13px; min-width: 220px;
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--bg); color: var(--ink);
}


.option-row { display: flex; align-items: flex-start; gap: 12px; padding: 6px 0; }
/* A consecutive number per choice, matching the calendar's round markers. */
.option-num {
  flex: none; width: 24px; height: 24px; margin-top: 5px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--accent-soft); color: var(--accent);
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
/* Event cards carry no numbers, so a rule keeps their choices apart. */
#events-form .option-row + .option-row { border-top: 1px solid var(--line); margin-top: 2px; padding-top: 10px; }
.option-words { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.option-words input {
  width: 100%; padding: 8px 11px; font-size: 14px; border: 1px solid var(--line);
  border-radius: calc(var(--radius) - 2px); background: var(--bg); color: var(--ink);
}
.option-words input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.option-label { font-weight: 600; }
.risk-seg { display: inline-flex; flex: none; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; align-self: center; }
.risk-opt { position: relative; cursor: pointer; }
.risk-opt + .risk-opt { border-left: 1px solid var(--line); }
.risk-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.risk-opt span { display: block; padding: 7px 13px; font-size: 13px; font-weight: 600; color: var(--dim); white-space: nowrap; }
.risk-opt.is-on span { background: var(--accent-soft); color: var(--accent); }
.risk-opt input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: -2px; }

/* Story coverage: how many twists each role can meet in a season. */
.cover-row { display: flex; align-items: center; gap: 12px; padding: 7px 0; }
.cover-row + .cover-row { border-top: 1px solid var(--line); }
.cover-role { flex: 0 0 150px; font-weight: 600; font-size: 14px; }
.cover-bar { display: inline-flex; gap: 3px; flex: 1; min-width: 0; }
.cover-bar i { width: 12px; height: 12px; border-radius: 3px; background: var(--accent); flex: none; }
.cover-num { flex: none; font-size: 13px; color: var(--ink); font-variant-numeric: tabular-nums; }
.cover-row.is-dead .cover-role { color: var(--danger); }

/* The flags panel: the consequence web at a glance. */
.flag-badges { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* Theme-safe callouts: the ground stays the app's, severity is carried by the colour. */
.flag-callout {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  margin: 0 0 12px; padding: 10px 12px; font-size: 13px; line-height: 1.6;
  background: var(--bg); border-left: 3px solid currentColor; border-radius: 0 calc(var(--radius) - 2px) calc(var(--radius) - 2px) 0;
}
.flag-callout.is-dead { color: var(--danger); }
.flag-callout.is-idle { color: var(--warn); }
.flag-callout strong { font-weight: 700; }
.flag-callout code {
  font-family: var(--font-mono, ui-monospace, monospace); font-size: 12px;
  padding: 2px 7px; border-radius: 5px; background: var(--panel); color: var(--ink);
}

.flag-row { display: flex; align-items: flex-start; gap: 14px; padding: 10px 0; }
.flag-row + .flag-row { border-top: 1px solid var(--line); }
.flag-name {
  flex: none; min-width: 170px; font-family: var(--font-mono, ui-monospace, monospace); font-size: 13px;
  font-weight: 600; color: var(--accent); background: var(--accent-soft); padding: 4px 9px; border-radius: 6px;
}
.flag-uses { flex: 1; min-width: 0; font-size: 13px; line-height: 1.55; color: var(--ink); }
.flag-k { display: inline-block; min-width: 52px; font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--dim); }
.flag-warn { color: var(--danger); font-weight: 600; margin-top: 2px; }
.flag-note { color: var(--dim); margin-top: 2px; }
.flag-row.is-dead .flag-name { color: var(--danger); background: transparent; box-shadow: inset 0 0 0 1px var(--danger); }
.flag-row.is-idle .flag-name { color: var(--dim); background: var(--bg); box-shadow: inset 0 0 0 1px var(--line); }

/* Event cards: the narrative one-offs and their flag wiring. */
.event-card { border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; margin-bottom: 12px; background: var(--panel); }
.event-card:has(.team-remove input:checked) { opacity: .5; }
.event-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.event-title {
  flex: 1; min-width: 0; padding: 9px 12px; font-size: 15px; font-weight: 700;
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--bg); color: var(--ink);
}
.event-body {
  width: 100%; padding: 9px 12px; font-size: 14px; line-height: 1.5; resize: vertical;
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--bg); color: var(--ink);
  font-family: inherit; margin-bottom: 10px;
}
.event-meta { display: flex; flex-wrap: wrap; gap: 10px 14px; margin-bottom: 8px; }
.event-f { display: inline-flex; flex-direction: column; gap: 4px; font-size: 11px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--dim); }
.event-f.grow { flex: 1 1 180px; min-width: 150px; }
.event-f input, .event-f select {
  padding: 7px 10px; font-size: 14px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--ink);
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--bg);
}
.event-f input[type="number"] { width: 84px; }
.event-title:focus-visible, .event-body:focus-visible,
.event-f input:focus-visible, .event-f select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.option-extras { display: flex; flex-wrap: wrap; gap: 8px 14px; }
.team-name {
  flex: 1; min-width: 0; max-width: 420px; padding: 9px 12px; font-size: 16px; font-weight: 700;
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 2px); background: var(--bg); color: var(--ink);
}
.team-name:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.team-remove { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--dim); white-space: nowrap; cursor: pointer; }

/* The line-up: the shared seat and each car sit side by side as columns, so a
   two-car team fills the row instead of stacking down the left. Within a column
   the seats pack; a single-car sport is one column that wraps its whole squad. */
/* One column per unit — the shared seat plus each car — so the row fills the card
   evenly however the team is shaped, rather than leaving a ragged gap on the right. */
.roster-units { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 16px 24px; align-items: start; }
.roster-unit { min-width: 0; }
.roster-unit .lobby-car-name { padding: 0 0 7px; }
.team-people { display: flex; flex-wrap: wrap; gap: 10px 14px; }
/* When a team is more than one unit — a shared seat and cars — each unit is a slim
   column with its seats stacked, so Shared / Car 1 / Car 2 sit across the row. A
   single-unit team (a whole squad on one car) keeps wrapping instead. */
.roster-units.is-columns .team-people { flex-direction: column; gap: 8px; }
.roster-units.is-columns .person { width: 100%; }
.person { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--dim); width: 168px; max-width: 100%; }
.person span { font-weight: 600; letter-spacing: .02em; }
.person input {
  padding: 8px 10px; font-size: 14px; color: var(--ink);
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 3px); background: var(--bg);
}
.person input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
/* A team flagged for removal dims so it reads as on its way out. */
.team-card:has(.team-remove input:checked) { opacity: .5; }

@media (max-width: 560px) { .build-cols { grid-template-columns: 1fr; } }

/* Studio: a row of management actions (each is its own little form). */
.manage-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.manage-actions form { margin: 0; }

/* Studio/lobby: a car sub-heading within a two-car team, and the car tag on a
   shelf seat row. Absent for one-car sports, where team and car are the same. */
.lobby-car-name { font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--dim); padding: 8px 14px 4px; }
.shelf-seat-car { color: var(--dim); font-weight: 400; }

/* Studio: the shared-seats checklist in the team-structure control. */
.shared-seats { display: flex; flex-wrap: wrap; gap: 8px 18px; }

/* Studio: the role editor rows. */
.role-row { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-top: 1px solid var(--line); }
.role-row:first-child { border-top: none; }
.role-label { flex: 1; min-width: 0; padding: 8px 11px; font-size: 15px; font-weight: 600;
  border: 1px solid var(--line); border-radius: calc(var(--radius) - 3px); background: var(--bg); color: var(--ink); }
.role-phase { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--dim); white-space: nowrap; }
.role-phase select { padding: 5px 6px; border: 1px solid var(--line); border-radius: 6px; background: var(--panel); color: var(--ink); }
