/* Match Loop — app shell styles
   Original design system. Mobile-first. Dark navy + lime accent.
*/

:root {
  --bg: #0a1020;
  --bg-elev: #121a2e;
  --surface: #1a2440;
  --surface-2: #222e4f;
  --border: #2a3760;
  --border-soft: #1f2a4a;
  --text: #eef2fb;
  --text-dim: #aab4ce;
  --text-mute: #7585a3;
  --accent: #1668F0;
  --accent-2: #0CCB88;
  --accent-ink: #ffffff;
  --danger: #ff7a8c;
  --warn: #ffcc66;
  --ok: #2FD165;
  --info: #3B86F7;

  /* matchloop brand palette — exact values pulled from matchloop.app CSS.
     blue→sky→teal→green→lime loop, violet on the cool end. */
  --blue: #1668F0;
  --sky: #089DED;
  --teal: #0CCB88;
  --green: #2FD165;
  --lime: #C6EE1D;
  --violet: #6246EC;
  --ink: #0E1726;
  --slate: #5B6577;
  --mist: #F4F7FB;
  --line: #E6ECF4;
  /* Signature blue→green gradient for primary actions + brand moments. */
  --brand-grad: linear-gradient(100deg, #1668F0 0%, #0CCB88 60%, #2FD165 100%);
  /* Full landing "loop" gradient for hero/brand accents. */
  --brand-loop: linear-gradient(100deg, #6246EC, #1668F0 28%, #089DED 48%, #0CCB88 70%, #2FD165 84%, #C6EE1D);
  --brand-soft: linear-gradient(135deg, rgba(22,104,240,0.12), rgba(12,203,136,0.12) 60%, rgba(198,238,29,0.12));

  --radius-sm: 8px;
  --radius: 14px;
  --radius-lg: 20px;
  --radius-xl: 28px;

  --shadow-card: 0 1px 0 rgba(255,255,255,0.03) inset, 0 8px 24px rgba(0,0,0,0.25);
  --shadow-pop: 0 12px 40px rgba(0,0,0,0.5);
  --shadow-soft: 0 10px 30px rgba(0,0,0,0.35);

  --pad: 16px;
  --gap: 12px;

  --font-sans: 'Outfit', 'Manrope', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'Sora', 'Outfit', ui-sans-serif, system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
}

/* Brand display font (Sora) for prominent headings. */
.topbar .title,
.hero .name,
.section h2,
.brand-name { font-family: var(--font-display); }

[data-density="compact"] {
  --pad: 12px;
  --gap: 8px;
  --radius: 12px;
  --radius-lg: 16px;
}

/* Light is the default brand look — bright, airy, blue→green.
   Palette pulled from matchloop.app (mist bg, white cards, ink text,
   slate muted, line borders, blue accent, brand green for "ok"). */
[data-theme="light"] {
  --bg: #F4F7FB;          /* mist */
  --bg-elev: #ffffff;
  --surface: #ffffff;
  --surface-2: #EFF3F9;
  --border: #E6ECF4;      /* line */
  --border-soft: #EEF2F8;
  --text: #0E1726;        /* ink */
  --text-dim: #5B6577;    /* slate */
  --text-mute: #97A1B2;
  --accent: #1668F0;      /* blue */
  --accent-2: #0CCB88;    /* teal */
  --accent-ink: #ffffff;
  --ok: #17B267;          /* brand green, deepened for text legibility on white */
  --warn: #E8912A;
  --danger: #E5544B;
  --info: #1668F0;
  /* Layered, brand-tinted depth so cards lift off the mist instead of
     reading as flat white rectangles. */
  --shadow-card: 0 1px 2px rgba(14,23,38,0.05), 0 10px 28px rgba(22,40,80,0.09);
  --shadow-soft: 0 2px 6px rgba(14,23,38,0.06), 0 18px 40px rgba(22,40,80,0.14);
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100%;
}
body {
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(22,104,240,0.10), transparent 60%),
    radial-gradient(800px 600px at -10% 100%, rgba(12,203,136,0.08), transparent 60%),
    var(--bg);
  min-height: 100vh;
}
/* Light (default) — soft blue→green wash for the airy brand feel. */
[data-theme="light"] body {
  background:
    radial-gradient(900px 520px at 82% -12%, rgba(22,104,240,0.10), transparent 60%),
    radial-gradient(760px 520px at -12% 108%, rgba(12,203,136,0.10), transparent 60%),
    var(--bg);
}

button { font-family: inherit; cursor: pointer; }
input, textarea, select { font-family: inherit; color: inherit; }

/* layout: mobile-first single column up to 720 then desktop framed
   The "app" sits in a phone-shaped column on desktop so it stays mobile-first,
   while taking the full viewport on actual phones. */

.app-root {
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.app-frame {
  width: 100%;
  max-width: 100%;
  min-height: 100vh;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}

/* [bottomnav-fix] On mobile, give the frame a DEFINITE viewport height so the
   inner .scroll (flex:1, overflow-y:auto) scrolls internally and the sibling
   .bottomnav stays pinned to the bottom of the viewport on every screen.
   With the base min-height:100vh (a floor, not a fixed height), tall content
   grew the frame past the viewport, the page scrolled, and the nav dropped
   below the fold. 100dvh tracks the real visible viewport on iOS; min-height:0
   removes the 100vh floor so content can never push the frame taller. Desktop
   (>=880px) keeps its own phone-frame sizing; safe-area padding is untouched. */
@media (max-width: 879px) {
  .app-frame {
    height: 100dvh;
    min-height: 0;
  }
  /* [guest-scroll] The PUBLIC guest response page (real opponents, mobile Safari)
     has NO pinned .bottomnav — its "Send response" button is inline at the end of
     the form. So it must NOT inherit the captain app's fixed 100dvh + overflow:hidden
     frame, which CLIPS the form's bottom (Send button unreachable) — worse under
     Safari's collapsing URL bar. Let the guest page flow as a normal scrolling
     document sized by dvh (not the 100vh trap) with safe-area padding, so the whole
     form incl. Send stays visible + tappable. */
  .app-frame.guest-flow {
    height: auto;
    min-height: 100dvh;
    overflow: visible;
    padding-bottom: calc(28px + env(safe-area-inset-bottom));
  }
}

/* on desktop, show a phone-shaped column for the captain & player roles */
@media (min-width: 880px) {
  .app-root {
    padding: 32px 16px 80px;
    background:
      radial-gradient(900px 600px at 85% -5%, rgba(22,104,240,0.14), transparent 60%),
      radial-gradient(800px 600px at 0% 105%, rgba(12,203,136,0.14), transparent 60%),
      linear-gradient(180deg, #EAF1FB 0%, #EAF7F1 100%);
  }
  .app-root .app-frame[data-role="captain"],
  .app-root .app-frame[data-role="player"] {
    max-width: 440px;
    border-radius: 28px;
    border: 1px solid var(--border-soft);
    box-shadow: 0 30px 80px rgba(22,40,80,0.18), 0 0 0 1px rgba(255,255,255,0.6) inset;
    margin: 0 auto;
    min-height: 880px;
    max-height: calc(100vh - 64px);
  }
}

/* Role switcher (devtool, persistent above app) */
.role-switcher {
  position: fixed;
  /* [safe-area] Clear the notch on notched iOS (dev "View as" control). */
  top: calc(12px + env(safe-area-inset-top));
  left: 50%;
  transform: translateX(-50%);
  background: rgba(20, 28, 56, 0.85);
  backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px;
  display: flex;
  gap: 2px;
  z-index: 40;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.role-switcher button {
  background: transparent;
  border: 0;
  color: var(--text-dim);
  padding: 6px 12px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.role-switcher button.active {
  background: var(--accent);
  color: var(--accent-ink);
}

/* Top bar */
.topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  /* [safe-area] Pad the top header below the notch/status bar on notched iOS.
     env() resolves to 0 on desktop/non-notched, so layout there is unchanged. */
  padding: calc(18px + env(safe-area-inset-top)) var(--pad) 14px;
  border-bottom: 1px solid var(--border-soft);
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--bg);
}
.topbar .back {
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--text);
}
.topbar .title {
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
  flex: 1;
}
.topbar .sub {
  font-size: 12px;
  color: var(--text-mute);
  font-weight: 500;
  margin-top: 2px;
}
.topbar .action {
  background: transparent;
  border: 0;
  color: var(--accent);
  font-weight: 700;
  font-size: 14px;
  padding: 8px 4px;
}

/* Scrolling content area */
.scroll {
  flex: 1;
  overflow-y: auto;
  padding-bottom: 120px;
  -webkit-overflow-scrolling: touch;
}

/* Bottom nav (captain/player) */
.bottomnav {
  position: sticky;
  bottom: 0;
  background: linear-gradient(180deg, color-mix(in oklab, var(--bg) 0%, transparent) 0%, var(--bg) 30%);
  padding: 16px var(--pad) calc(16px + env(safe-area-inset-bottom));
  display: flex;
  gap: 8px;
  z-index: 5;
}
.bottomnav .nav-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: transparent;
  border: 0;
  color: var(--text-mute);
  font-size: 11px;
  font-weight: 600;
  padding: 8px 0;
}
.bottomnav .nav-item.active { color: var(--accent); }

/* Buttons */
.btn {
  border: 0;
  background: var(--brand-grad);
  color: #ffffff;
  font-weight: 700;
  font-size: 15px;
  padding: 14px 20px;
  border-radius: 999px;
  letter-spacing: -0.005em;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: transform 0.06s ease, opacity 0.15s ease, filter 0.15s ease;
}
.btn:hover { filter: brightness(1.06) saturate(1.04); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn.block { width: 100%; }
.btn.secondary {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
}
.btn.secondary:hover { background: var(--surface-2); }
.btn.ghost {
  background: transparent;
  color: var(--text-dim);
}
.btn.ghost:hover { color: var(--text); }
.btn.danger {
  background: transparent;
  color: var(--danger);
  border: 1px solid color-mix(in oklab, var(--danger) 30%, transparent);
}
.btn.sm { font-size: 13px; padding: 8px 14px; }

/* Cards */
.card {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: var(--pad);
  box-shadow: var(--shadow-card);
}
.card.tight { padding: 12px; }
.card.flat { box-shadow: none; }

.section {
  padding: 20px var(--pad);
}
.section .label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mute);
  margin-bottom: 10px;
}
.section h2 {
  margin: 0 0 14px;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.015em;
}
.stack { display: flex; flex-direction: column; gap: var(--gap); }
.row { display: flex; gap: var(--gap); align-items: center; }
.row.between { justify-content: space-between; }

/* Pills / badges */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  color: var(--text-dim);
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}
.pill .dot { width: 6px; height: 6px; border-radius: 999px; background: currentColor; }
.pill.accent { background: color-mix(in oklab, var(--accent) 18%, transparent); color: var(--accent); border-color: color-mix(in oklab, var(--accent) 30%, transparent); }
.pill.warn { color: var(--warn); border-color: color-mix(in oklab, var(--warn) 35%, transparent); background: color-mix(in oklab, var(--warn) 14%, transparent); }
.pill.ok { color: var(--ok); border-color: color-mix(in oklab, var(--ok) 35%, transparent); background: color-mix(in oklab, var(--ok) 12%, transparent); }
.pill.danger { color: var(--danger); border-color: color-mix(in oklab, var(--danger) 35%, transparent); background: color-mix(in oklab, var(--danger) 12%, transparent); }
.pill.muted { background: transparent; }

/* Match card */
.match-card {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: left;
  width: 100%;
  color: var(--text);
  transition: border-color 0.15s ease, transform 0.06s ease;
}
.match-card:hover { border-color: var(--border); }
.match-card:active { transform: scale(0.998); }
.match-card .title { font-weight: 700; font-size: 16px; letter-spacing: -0.01em; }
.match-card .meta { color: var(--text-dim); font-size: 13px; }
.match-card .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }

/* Date option chips */
.date-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
}
.date-opt {
  text-align: left;
  background: var(--surface);
  border: 1.5px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--text);
  transition: border-color 0.15s, background 0.15s;
  position: relative;
}
.date-opt:hover { border-color: var(--border); }
.date-opt.selected {
  border-color: var(--accent);
  background: color-mix(in oklab, var(--accent) 8%, var(--surface));
}
.date-opt.selected::after {
  content: '';
  position: absolute;
  top: 8px;
  right: 8px;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  background: var(--accent);
  background-image: linear-gradient(135deg, transparent 35%, var(--accent-ink) 35% 45%, transparent 45%, transparent 55%, var(--accent-ink) 55% 65%, transparent 65%);
}
.date-opt .dow { font-size: 11px; color: var(--text-mute); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; }
.date-opt .day { font-size: 22px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; }
.date-opt .time { font-size: 13px; color: var(--text-dim); font-weight: 600; }
.date-opt .courts { font-size: 11px; color: var(--text-mute); margin-top: 2px; font-family: var(--font-mono); }

/* Inputs */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.field > label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--text-mute);
  text-transform: uppercase;
}
.input, .textarea, .select {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--text);
  border-radius: var(--radius);
  padding: 12px 14px;
  /* 16px min so iOS/WKWebView never auto-zooms the page on input focus. */
  font-size: 16px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s;
  width: 100%;
}
.input:focus, .textarea:focus, .select:focus {
  border-color: var(--accent);
}
.textarea { min-height: 80px; resize: vertical; }

/* Scrolling time picker — hide native scrollbar on webkit so the wheel
   reads cleanly. Firefox + IE handled inline via scrollbar-width/msOverflowStyle. */
.time-wheel-scroller::-webkit-scrollbar { display: none; }

/* Loading spinner */
.spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 999px;
  animation: spin 0.7s linear infinite;
  vertical-align: -2px;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Player roster row */
.player-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-soft);
}
.player-row:last-child { border-bottom: 0; }
.avatar {
  width: 36px; height: 36px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-dim);
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.player-row .name { font-weight: 600; flex: 1; font-size: 14px; }
.player-row .status { font-size: 11px; color: var(--text-mute); }

/* Tally bar */
.tally {
  display: flex;
  height: 8px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
}
.tally span { display: block; height: 100%; }
.tally .seg-yes { background: var(--accent); }
.tally .seg-mb { background: var(--warn); }
.tally .seg-no { background: var(--danger); }

/* Stat grid (used in rules details) */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}
.stat {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 14px 16px;
}
.stat .v { font-size: 24px; font-weight: 800; letter-spacing: -0.02em; }
.stat .k { font-size: 11px; color: var(--text-mute); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; margin-top: 4px; }

/* Toast */
.toast {
  position: fixed;
  left: 50%;
  /* [safe-area] Keep the toast clear of the home indicator on notched iOS. */
  bottom: calc(32px + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  background: var(--accent);
  color: var(--accent-ink);
  font-weight: 700;
  padding: 12px 20px;
  border-radius: 999px;
  z-index: 60;
  box-shadow: 0 12px 30px rgba(0,0,0,0.35);
  display: flex;
  align-items: center;
  gap: 8px;
  animation: toastIn 0.3s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes toastIn {
  from { opacity: 0; transform: translate(-50%, 20px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}

/* Logo */
.logo-mark {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--accent);
  display: grid;
  place-items: center;
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}
.logo-mark::before, .logo-mark::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid var(--accent-ink);
  border-color: var(--accent-ink) transparent transparent var(--accent-ink);
  transform: rotate(-25deg);
  opacity: 0.85;
}
.logo-mark::after {
  transform: rotate(155deg);
}
.brand-row { display: flex; align-items: center; gap: 10px; }
.brand-row .brand-dark { display: inline-flex; align-items: center; gap: 10px; }
.brand-name { font-weight: 800; letter-spacing: -0.02em; font-size: 17px; }
.brand-name b { color: var(--accent); font-weight: 800; }

/* Lock the logo to its native colors. The PNG has the metallic infinity +
   navy ground + lime tennis ball + lime wordmark accent baked in — we want
   the browser to render those pixels exactly, with no filter/invert/blend
   side effects from ancestor styles, and with a high-quality downscale so
   the navy strokes don't dissolve into the highlights at small sizes. */
.brand-mark {
  filter: none !important;
  -webkit-filter: none !important;
  mix-blend-mode: normal !important;
  opacity: 1 !important;
  display: block;
  /* Use the browser's smooth high-quality downscaler. The old
     -webkit-optimize-contrast value sharpened/crunched the gradient PNG and
     made it read cheap; "auto" matches how matchloop.app renders the same
     logo.png (height:40px, width:auto) — crisp at any size below source. */
  image-rendering: auto;
  forced-color-adjust: none;
  print-color-adjust: exact;
  -webkit-print-color-adjust: exact;
}

/* Swap brand mark by theme — light mode uses the raster logo (with "match loop" wordmark baked in),
   dark mode uses the SVG + neon wordmark for contrast. */
[data-theme="light"] .brand-row .brand-dark { display: none !important; }
[data-theme="light"] .brand-row .brand-light { display: inline-block !important; }

/* Hero header (captain dash) */
.hero {
  padding: 24px var(--pad) 20px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.hero .greeting {
  font-size: 13px;
  color: var(--text-mute);
  font-weight: 600;
  letter-spacing: 0.01em;
}
.hero .name {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.02em;
}

/* Alert/banner */
.banner {
  background: linear-gradient(180deg, color-mix(in oklab, var(--accent) 18%, transparent), color-mix(in oklab, var(--accent) 6%, transparent));
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.banner.warn {
  background: linear-gradient(180deg, color-mix(in oklab, var(--warn) 18%, transparent), color-mix(in oklab, var(--warn) 6%, transparent));
  border-color: color-mix(in oklab, var(--warn) 35%, transparent);
}
.banner .icon-wrap {
  width: 36px; height: 36px;
  border-radius: 10px;
  background: var(--accent);
  color: var(--accent-ink);
  display: grid; place-items: center;
  flex-shrink: 0;
}
.banner.warn .icon-wrap { background: var(--warn); color: #2a1a00; }
.banner .ttl { font-weight: 700; font-size: 14px; margin-bottom: 2px; }
.banner .body { font-size: 13px; color: var(--text-dim); line-height: 1.45; }

/* slot row in confirm view */
.slot-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-soft);
}
.slot-row:last-child { border-bottom: 0; }
.slot-row .when { flex: 1; }
.slot-row .when b { display: block; font-size: 14px; font-weight: 700; }
.slot-row .when span { font-size: 12px; color: var(--text-mute); }
.slot-row .count {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-dim);
}

/* response squares
   -----------------------------------------------------------------
   The poll grid lives inside a `.resp-grid-scroll` wrapper so that
   when there are 4+ proposed makeup dates the date columns scroll
   horizontally instead of overflowing off-screen. Each row sets its
   own `--date-cols` inline so the header + all player rows share the
   exact same column template and stay aligned while scrolling.

   The player name column is sticky-left so it stays readable while
   the captain scrolls dates on mobile.
   ----------------------------------------------------------------- */
.resp-grid-scroll {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  /* keep a hint of the next date visible so users notice the scroll */
  scroll-padding-right: 24px;
}
.resp-grid-scroll::-webkit-scrollbar { height: 6px; }
.resp-grid-scroll::-webkit-scrollbar-thumb {
  background: var(--border-soft);
  border-radius: 999px;
}
.resp-grid-scroll::-webkit-scrollbar-track { background: transparent; }

.resp-grid {
  display: grid;
  /* [makeup-partial] Fluid columns so the grid FITS its container — the 440px
     desktop app frame AND a ~360px phone alike — instead of forcing
     `max-content` width and horizontal-scrolling (which then tripped the
     narrow-width media queries and made the phone render diverge from desktop).
     Date columns share the leftover space equally; the name column keeps a
     readable minimum but can shrink. The `.resp-grid-scroll` wrapper still
     allows scroll as a last resort if a captain ever proposes many dates on a
     very small screen, but the common case no longer scrolls. */
  grid-template-columns:
    [name] minmax(72px, 1.4fr)
    [dates] repeat(var(--date-cols, 3), minmax(0, 1fr));
  gap: 6px 8px;
  align-items: center;
  width: 100%;
}
.resp-grid .name-cell {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
  /* fade-out to hint at scrollable content beneath */
  padding-right: 8px;
  min-width: 0;
}
/* On player rows the sticky name cell needs to cover the row border
   peek-through cleanly. The card bg is --surface so this matches. */
.resp-grid .name-cell .name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.resp-grid .name { font-size: 13px; font-weight: 600; }
.resp-grid .cell {
  width: 28px; height: 28px;
  /* Fixed-size pill centered in its (now fluid) column so rows stay aligned. */
  justify-self: center;
  border-radius: 8px;
  display: grid; place-items: center;
  font-size: 11px;
  font-weight: 700;
  border: 1px solid var(--border-soft);
  background: var(--surface-2);
  color: var(--text-mute);
}
/* [makeup-partial] On very narrow phones with several proposed dates, shrink
   the cells/gap a touch so the fluid columns still hold a centered pill without
   forcing a horizontal scroll — keeping the phone render matched to desktop. */
@media (max-width: 380px) {
  .resp-grid { column-gap: 5px; }
  .resp-grid .cell { width: 24px; height: 24px; font-size: 10px; }
}
.resp-grid .cell.yes { background: color-mix(in oklab, var(--accent) 25%, var(--surface)); color: var(--accent); border-color: color-mix(in oklab, var(--accent) 40%, transparent); }
.resp-grid .cell.no { background: color-mix(in oklab, var(--danger) 18%, var(--surface)); color: var(--danger); border-color: color-mix(in oklab, var(--danger) 30%, transparent); }
.resp-grid .cell.mb { background: color-mix(in oklab, var(--warn) 18%, var(--surface)); color: var(--warn); border-color: color-mix(in oklab, var(--warn) 30%, transparent); }
/* Button form of cell (captain-tappable in poll grid) — match div styling */
button.cell {
  font: inherit; font-size: 11px; font-weight: 700;
  padding: 0; margin: 0; line-height: 1;
  transition: transform 80ms ease, box-shadow 120ms ease;
}
button.cell:hover { transform: translateY(-1px); box-shadow: 0 2px 6px color-mix(in oklab, var(--text) 12%, transparent); }
button.cell:active { transform: translateY(0); }
button.cell:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Hide scrollbar on mobile */
.scroll::-webkit-scrollbar { display: none; }
.scroll { scrollbar-width: none; }

/* utilities */
.muted { color: var(--text-mute); }
.dim { color: var(--text-dim); }
.mono { font-family: var(--font-mono); }
.tnum { font-variant-numeric: tabular-nums; }
.hr { height: 1px; background: var(--border-soft); border: 0; margin: 8px 0; }

/* Skeleton tennis-ball icon (svg currentColor) */
.skel-icon { width: 1em; height: 1em; flex-shrink: 0; }

/* =====================================================================
   DEMO-MODE BAR — persistent across all screens in the prototype build.
   Lets reviewers jump between Sign Up / Captain / Player / Opponent
   Captain without losing context or having to refresh. Production build
   strips both this CSS block and the React component that renders it.
   ===================================================================== */
.demo-bar {
  position: sticky;
  top: 0;
  z-index: 60;
  /* [safe-area] Clear the notch on notched iOS (demo-mode banner). */
  padding-top: env(safe-area-inset-top);
  background: color-mix(in oklab, var(--info) 14%, var(--bg) 86%);
  border-bottom: 1px solid color-mix(in oklab, var(--info) 28%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.demo-bar-inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 7px 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}
.demo-bar-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--info) 75%, var(--text) 25%);
  white-space: nowrap;
}
.demo-bar-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--info);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--info) 25%, transparent);
  animation: demo-pulse 2.4s ease-in-out infinite;
}
@keyframes demo-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}
.demo-pill {
  display: inline-flex;
  align-items: stretch;
  gap: 2px;
  padding: 3px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.02) inset;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
}
.demo-pill::-webkit-scrollbar { display: none; }
.demo-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  color: var(--text-mute);
  padding: 7px 12px;
  border-radius: 999px;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  transition: color 0.15s, background 0.15s, transform 0.06s;
}
.demo-opt:hover:not(.active) { color: var(--text); background: var(--surface-2); }
.demo-opt:active { transform: scale(0.97); }
.demo-opt.active {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 1px 6px color-mix(in oklab, var(--accent) 30%, transparent);
}
.demo-opt .demo-opt-label { display: inline-block; }
@media (max-width: 540px) {
  .demo-bar-inner { padding: 6px 8px; gap: 8px; }
  .demo-bar-tag { font-size: 9px; letter-spacing: 0.1em; }
  .demo-opt { padding: 6px 10px; font-size: 11px; }
}

/* =====================================================================
   View-as toggle (Captain / Player demo switcher)
   Sits above the app frame as a thin centered pill. Subtle on purpose —
   it's a dev/demo affordance, not part of the product chrome.
   ===================================================================== */
.viewas-bar {
  display: flex;
  justify-content: center;
  padding: 10px var(--pad) 8px;
  background: var(--bg);
}
@media (min-width: 880px) {
  .viewas-bar {
    padding: 0 0 12px;
    background: transparent;
  }
}
.viewas-pill {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  background: color-mix(in oklab, var(--surface) 90%, var(--bg));
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.02) inset;
}
.viewas-opt {
  background: transparent;
  border: 0;
  color: var(--text-mute);
  padding: 6px 16px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, transform 0.06s;
  min-width: 80px;
}
.viewas-opt:hover:not(.active) { color: var(--text); }
.viewas-opt:active { transform: scale(0.98); }
.viewas-opt.active {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 1px 6px color-mix(in oklab, var(--accent) 30%, transparent);
}
.viewas-reset {
  width: 24px;
  height: 24px;
  margin-left: 4px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 0;
  color: var(--text-mute);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: color 0.15s, background 0.15s;
}
.viewas-reset:hover { color: var(--text); background: var(--surface); }

.matchday-panel {
  background:
    linear-gradient(180deg, color-mix(in oklab, var(--accent) 18%, var(--surface)) 0%, var(--surface) 80%);
  border: 1px solid color-mix(in oklab, var(--accent) 45%, var(--border-soft));
  border-radius: var(--radius-lg);
  padding: 16px;
  margin: 16px var(--pad) 0;
  position: relative;
  overflow: hidden;
}
.matchday-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  background:
    radial-gradient(400px 200px at 90% -20%, color-mix(in oklab, var(--accent) 35%, transparent), transparent 60%);
  pointer-events: none;
}
.matchday-header {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  position: relative;
}
.matchday-pulse {
  width: 12px;
  height: 12px;
  border-radius: 999px;
  background: var(--accent);
  margin-top: 6px;
  box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 60%, transparent);
  animation: mdpulse 2s ease-out infinite;
  flex-shrink: 0;
}
@keyframes mdpulse {
  0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 70%, transparent); }
  70% { box-shadow: 0 0 0 14px color-mix(in oklab, var(--accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--accent) 0%, transparent); }
}
.matchday-eyebrow {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.matchday-title {
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.015em;
  margin-top: 2px;
  color: var(--text);
}
.matchday-meta {
  color: var(--text-dim);
  font-size: 12px;
  margin-top: 2px;
}

/* arrival progress */
.matchday-progress {
  margin-top: 14px;
  position: relative;
}
.matchday-progress-track {
  height: 6px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  overflow: hidden;
  position: relative;
  display: flex;
}
.matchday-progress-fill {
  height: 100%;
  background: var(--accent);
  transition: width 0.4s ease;
}
.matchday-progress-eta {
  height: 100%;
  background: var(--warn);
  opacity: 0.7;
  transition: width 0.4s ease;
}
.matchday-progress-row {
  display: flex;
  gap: 8px;
  margin-top: 6px;
  font-size: 11px;
  font-weight: 700;
  color: var(--text);
}
.matchday-progress-row b { color: var(--text); }
.matchday-progress-row .warn { color: var(--warn); }
.matchday-progress-row .danger { color: var(--danger); }
.matchday-progress-row .muted { color: var(--text-mute); }

/* arrival roster strip */
.matchday-roster {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 12px;
  cursor: pointer;
}
.matchday-roster-more {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
}
.matchday-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px 3px 3px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  position: relative;
}
.matchday-chip .matchday-chip-name { white-space: nowrap; }
.matchday-chip .matchday-chip-mark {
  width: 14px;
  height: 14px;
  display: grid;
  place-items: center;
  border-radius: 999px;
}
.matchday-chip.arr-arrived {
  background: color-mix(in oklab, var(--accent) 18%, var(--surface));
  border-color: color-mix(in oklab, var(--accent) 35%, transparent);
  color: var(--accent);
}
.matchday-chip.arr-arrived .matchday-chip-mark { background: var(--accent); color: var(--accent-ink); }
.matchday-chip.arr-eta {
  background: color-mix(in oklab, var(--warn) 16%, var(--surface));
  border-color: color-mix(in oklab, var(--warn) 35%, transparent);
  color: var(--warn);
}
.matchday-chip.arr-eta .matchday-chip-mark { background: var(--warn); color: #2a1a00; }
.matchday-chip.arr-no-show {
  background: color-mix(in oklab, var(--danger) 14%, var(--surface));
  border-color: color-mix(in oklab, var(--danger) 35%, transparent);
  color: var(--danger);
}
.matchday-chip.arr-no-show .matchday-chip-mark { background: var(--danger); color: white; }

/* matchday quick actions */
.matchday-actions {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-top: 14px;
  position: relative;
}
.matchday-action {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  border-radius: var(--radius);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--text);
  font-weight: 700;
  font-size: 13px;
  text-align: left;
  transition: border-color 0.15s ease, transform 0.06s ease, background 0.15s ease;
}
.matchday-action:hover:not(:disabled) {
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border-soft));
  background: color-mix(in oklab, var(--accent) 6%, var(--surface));
}
.matchday-action:active:not(:disabled) { transform: scale(0.98); }
.matchday-action:disabled { opacity: 0.4; cursor: not-allowed; }
.matchday-action.primary {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}
.matchday-action.primary:hover:not(:disabled) {
  background: var(--accent-2);
}
.matchday-action-icon {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 8px;
  background: color-mix(in oklab, var(--accent) 18%, var(--surface-2));
  color: var(--accent);
  flex-shrink: 0;
}
.matchday-action.primary .matchday-action-icon {
  background: color-mix(in oklab, var(--accent-ink) 20%, transparent);
  color: var(--accent-ink);
}
.matchday-action-label { line-height: 1.2; }

/* =====================================================================
   Sheets (Day-of Mode + Scorecard sub-flows)
   ===================================================================== */
.md-sheet {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
}
.md-sheet-bg {
  position: absolute;
  inset: 0;
  background: rgba(5, 8, 16, 0.6);
  backdrop-filter: blur(4px);
}
.md-sheet-card {
  position: relative;
  flex: 1;
  background: var(--bg);
  display: flex;
  flex-direction: column;
  max-height: 100vh;
  animation: sheetIn 0.25s ease;
}
@media (min-width: 880px) {
  .md-sheet { align-items: center; justify-content: center; }
  .md-sheet-card {
    flex: 0 0 auto;
    width: 440px;
    max-height: 85vh;
    border-radius: 28px;
    overflow: hidden;
    border: 1px solid var(--border);
    box-shadow: 0 30px 80px rgba(0,0,0,0.5);
  }
}
@keyframes sheetIn {
  from { transform: translateY(20px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}
.md-sheet-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 18px var(--pad) 14px;
  border-bottom: 1px solid var(--border-soft);
}
.md-sheet-close {
  width: 36px; height: 36px;
  border-radius: 12px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--text);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.md-sheet-body {
  flex: 1;
  overflow-y: auto;
  padding-bottom: 32px;
}

/* Check-in row (used in CheckInSheet + EmergencySubSheet) */
.checkin-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  background: transparent;
  border: 0;
  text-align: left;
  padding: 12px;
  color: var(--text);
  cursor: pointer;
}
.checkin-row .checkin-row-body { flex: 1; min-width: 0; }
.checkin-row-name { font-weight: 700; font-size: 14px; }
.checkin-row-meta { font-size: 11px; color: var(--text-mute); margin-top: 2px; }

/* =====================================================================
   Scorecard
   ===================================================================== */
.scorecard-tally {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 12px;
  align-items: center;
  padding: 18px 12px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
}
.scorecard-side {
  text-align: center;
  padding: 6px 4px;
  border-radius: var(--radius);
  border: 1.5px solid transparent;
}
.scorecard-side.win {
  background: color-mix(in oklab, var(--accent) 10%, transparent);
  border-color: color-mix(in oklab, var(--accent) 50%, transparent);
}
.scorecard-side-team {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-mute);
  margin-bottom: 4px;
}
.scorecard-side.win .scorecard-side-team { color: var(--accent); }
.scorecard-side-score {
  font-size: 48px;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.scorecard-vs {
  font-size: 24px;
  font-weight: 800;
  color: var(--text-mute);
}
.scorecard-line {
  padding: 14px 14px;
}
.scorecard-played-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 4px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  color: var(--text);
  font-size: 12px;
  font-weight: 600;
}
.scorecard-played-chip:hover { border-color: var(--border); background: var(--surface); }
.scorecard-played-chip:disabled { cursor: default; opacity: 0.9; }
.scorecard-view-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-soft);
}
.scorecard-view-line:last-child { border-bottom: 0; }
.scorecard-view-meta { flex: 1; min-width: 0; }
.scorecard-view-slot {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.scorecard-view-played { font-size: 13px; color: var(--text); margin-top: 2px; }
.scorecard-view-result {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* =====================================================================
   Onboarding
   ===================================================================== */
.onboard-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--text);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.onboard-card:hover {
  border-color: color-mix(in oklab, var(--accent) 50%, var(--border));
  background: var(--bg-elev);
}
.onboard-card-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.onboard-color {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  border: 0;
  cursor: pointer;
  transition: transform 0.1s ease, box-shadow 0.15s ease;
}
.onboard-color:hover { transform: scale(1.08); }

/* =====================================================================
   USTA Import Flow
   ===================================================================== */
.usta-step-dots {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px var(--pad) 4px;
}
.usta-step-dot {
  width: 22px;
  height: 4px;
  border-radius: 999px;
  background: var(--surface-2);
  transition: background 0.2s ease, width 0.2s ease;
}
.usta-step-dot.active {
  background: var(--accent);
  width: 32px;
}
.usta-step-dot.done {
  background: color-mix(in oklab, var(--accent) 50%, var(--border));
}

.usta-hero {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px;
  border-radius: var(--radius-lg);
  background: linear-gradient(135deg,
    color-mix(in oklab, var(--accent) 10%, var(--surface)),
    var(--surface));
  border: 1px solid color-mix(in oklab, var(--accent) 20%, var(--border-soft));
}
.usta-hero-badge {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  display: grid;
  place-items: center;
  background: var(--accent);
  color: var(--accent-ink);
  flex-shrink: 0;
}

.usta-demo-banner {
  margin: 0 var(--pad);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: color-mix(in oklab, var(--info) 12%, var(--surface));
  border: 1px solid color-mix(in oklab, var(--info) 28%, transparent);
  color: var(--info);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.45;
}

.usta-demo-note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px dashed var(--border);
  font-size: 11px;
  color: var(--text-dim);
  line-height: 1.5;
}
.usta-demo-note b { color: var(--text); }
.usta-demo-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--info);
  margin-top: 6px;
  flex-shrink: 0;
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--info) 20%, transparent);
}

.usta-error {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: color-mix(in oklab, var(--danger) 12%, var(--surface));
  border: 1px solid color-mix(in oklab, var(--danger) 30%, transparent);
  color: var(--danger);
  font-size: 12px;
  font-weight: 600;
}

.usta-loader {
  display: inline-grid;
  place-items: center;
  width: 64px;
  height: 64px;
  margin: 0 auto;
  border-radius: 50%;
  background: color-mix(in oklab, var(--accent) 12%, var(--surface));
  border: 1px solid color-mix(in oklab, var(--accent) 25%, var(--border));
}

.usta-section-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 14px 2px 8px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-mute);
}
.usta-section-icon {
  display: inline-flex;
  width: 14px;
  height: 14px;
  align-items: center;
  justify-content: center;
  color: var(--text-dim);
}
.usta-section-icon svg { width: 12px; height: 12px; }

.usta-avatar {
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-dim);
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
  flex-shrink: 0;
  border: 1px solid var(--border-soft);
}
.usta-avatar.lg {
  width: 40px;
  height: 40px;
  font-size: 13px;
}

.usta-preview-player {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 10px;
  border-radius: var(--radius-sm);
}
.usta-preview-player + .usta-preview-player {
  border-top: 1px solid var(--border-soft);
}

.usta-preview-match {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border-radius: var(--radius-sm);
}
.usta-preview-match + .usta-preview-match {
  border-top: 1px solid var(--border-soft);
}
.usta-week {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.02em;
  flex-shrink: 0;
}

/* Editable roster row used in the confirm step */
.roster-edit-row {
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  padding: 12px;
}
.roster-edit-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
@media (max-width: 380px) {
  .roster-edit-grid { grid-template-columns: 1fr; }
}
.field.tight { gap: 4px; }
.field.tight > label {
  font-size: 10px;
  letter-spacing: 0.06em;
}
.input.sm {
  padding: 8px 10px;
  /* keep ≥16px on iOS to avoid focus auto-zoom (small padding keeps it compact). */
  font-size: 16px;
}

/* Invite step rows */
.invite-toggle-all {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 10px 6px 6px;
  border-bottom: 1px solid var(--border-soft);
  margin-bottom: 4px;
}
.invite-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  border-radius: var(--radius-sm);
  transition: background 0.12s ease;
}
.invite-row + .invite-row {
  border-top: 1px solid var(--border-soft);
}
.invite-row:hover:not(:disabled) { background: var(--surface-2); }
.invite-row:disabled { cursor: not-allowed; opacity: 0.6; }
.invite-row.on { background: color-mix(in oklab, var(--accent) 8%, transparent); }

.invite-check {
  width: 20px;
  height: 20px;
  border-radius: 6px;
  border: 1.5px solid var(--border);
  background: var(--surface);
  display: grid;
  place-items: center;
  color: var(--accent-ink);
  flex-shrink: 0;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.invite-check.on {
  background: var(--accent);
  border-color: var(--accent);
}

.invite-channel-toggle {
  display: inline-flex;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  padding: 2px;
  gap: 2px;
}
.invite-channel-btn {
  border: 0;
  background: transparent;
  color: var(--text-mute);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
}
.invite-channel-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.invite-channel-btn.on {
  background: var(--accent);
  color: var(--accent-ink);
}

/* Invite manager — code pill + share buttons */
.invite-code-pill {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border-radius: var(--radius);
  background: linear-gradient(135deg,
    color-mix(in oklab, var(--accent) 12%, var(--surface-2)),
    var(--surface-2));
  border: 1.5px dashed color-mix(in oklab, var(--accent) 35%, var(--border));
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.invite-code-pill:hover {
  border-color: var(--accent);
  border-style: solid;
}
.invite-code {
  font-family: var(--font-mono);
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 0.04em;
  color: var(--accent);
}
.invite-code-action {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-mute);
}

/* Captain crown badge (co-captains + primary captain) */
.captain-crown {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--accent) 22%, var(--surface));
  color: var(--accent);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* =====================================================================
   Billing — pricing cards & upgrade banner
   ===================================================================== */
.pricing-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 22px 20px 20px;
  box-shadow: var(--shadow-card);
  transition: border-color 0.15s, transform 0.15s;
}
.pricing-card[data-selected="true"] {
  border-color: color-mix(in oklab, var(--accent) 45%, transparent);
  background: linear-gradient(
    180deg,
    color-mix(in oklab, var(--accent) 6%, var(--surface)) 0%,
    var(--surface) 100%
  );
  box-shadow:
    0 0 0 1px color-mix(in oklab, var(--accent) 22%, transparent),
    0 12px 28px color-mix(in oklab, var(--accent) 12%, transparent);
}
.pricing-card__ribbon {
  position: absolute;
  top: -10px; left: 16px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow: 0 4px 12px color-mix(in oklab, var(--accent) 35%, transparent);
}
.pricing-card__head { margin-bottom: 14px; }
.pricing-card__title {
  font-size: 18px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.pricing-card__tagline {
  font-size: 13px;
  color: var(--text-dim);
  margin-top: 4px;
}
.pricing-card__price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 14px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border-soft);
}
.pricing-card__amount {
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.pricing-card__cadence {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-mute);
  letter-spacing: 0.02em;
}
.pricing-card__bullets {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: grid;
  gap: 8px;
}
.pricing-card__bullets li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13px;
  color: var(--text-dim);
}
.pricing-card__bullets li svg {
  flex-shrink: 0;
}
.pricing-card__hint {
  margin-top: 10px;
  font-size: 11px;
  color: var(--text-mute);
  text-align: center;
}

/* Upgrade banner — slot atop the captain dashboard */
.upgrade-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border-radius: var(--radius);
  background: linear-gradient(
    180deg,
    color-mix(in oklab, var(--accent) 10%, var(--surface)) 0%,
    color-mix(in oklab, var(--accent) 4%, var(--surface)) 100%
  );
  border: 1px solid color-mix(in oklab, var(--accent) 35%, transparent);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  transition: transform 0.08s, border-color 0.15s;
  box-shadow:
    0 0 0 1px color-mix(in oklab, var(--accent) 12%, transparent),
    0 4px 14px color-mix(in oklab, var(--accent) 8%, transparent);
}
.upgrade-banner:hover {
  border-color: color-mix(in oklab, var(--accent) 55%, transparent);
}
.upgrade-banner:active {
  transform: translateY(1px);
}
.upgrade-banner__icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--accent);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.upgrade-banner__icon svg { width: 16px; height: 16px; }
.upgrade-banner__body {
  flex: 1;
  min-width: 0;
}
.upgrade-banner__title {
  font-weight: 700;
  font-size: 14px;
}
.upgrade-banner__sub {
  font-size: 11px;
  color: var(--text-mute);
  margin-top: 2px;
  text-wrap: pretty;
}
.upgrade-banner__chev {
  color: var(--accent);
  flex-shrink: 0;
}

/* =====================================================================
   Match Format Picker — used in Create Team (manual + USTA confirm)
   and in Captain → More → Lineup.
   ===================================================================== */
.mf-picker {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.mf-summary {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border-radius: 12px;
  background: color-mix(in oklab, var(--accent) 8%, var(--surface));
  border: 1px solid color-mix(in oklab, var(--accent) 25%, var(--border-soft));
}
.mf-summary-main {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 16px;
  color: var(--text);
  letter-spacing: -0.01em;
}
.mf-summary-main b {
  font-size: 22px;
  font-weight: 800;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.mf-summary-main .mf-plus {
  color: var(--text-mute);
  font-weight: 600;
}
.mf-summary-meta {
  font-size: 11px;
  color: var(--text-mute);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-top: 2px;
}

.mf-presets {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 6px;
}
.mf-preset {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 10px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
  color: var(--text);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.12s ease, background 0.12s ease;
  font: inherit;
}
.mf-preset:hover {
  border-color: var(--border);
}
.mf-preset.on {
  background: color-mix(in oklab, var(--accent) 14%, var(--surface));
  border-color: var(--accent);
}
.mf-preset-label {
  font-weight: 700;
  font-size: 13px;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
.mf-preset.on .mf-preset-label {
  color: var(--accent);
}
.mf-preset-sub {
  font-size: 10px;
  color: var(--text-mute);
  font-weight: 500;
}

.mf-steppers {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.mf-stepper {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--surface);
  border: 1px solid var(--border-soft);
}
.mf-stepper-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-dim);
}
.mf-stepper-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.mf-step-btn {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid var(--border-soft);
  background: var(--bg);
  color: var(--text);
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.mf-step-btn:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}
.mf-step-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.mf-step-value {
  font-size: 18px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  min-width: 18px;
  text-align: center;
}

/* Compact variant for in-row editing (e.g. inside settings cards) */
.mf-picker[data-compact="1"] {
  gap: 10px;
}
.mf-picker[data-compact="1"] .mf-summary {
  padding: 10px 12px;
}
.mf-picker[data-compact="1"] .mf-summary-main {
  font-size: 14px;
}
.mf-picker[data-compact="1"] .mf-summary-main b {
  font-size: 18px;
}

/* ===== Create-team league picker (STEP 1) ===== */
.league-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}
@media (min-width: 560px) {
  .league-grid { grid-template-columns: 1fr 1fr; }
}
.league-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 22px 20px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 16px;
  cursor: pointer;
  text-align: left;
  color: var(--text);
  transition: border-color 0.12s, transform 0.06s, background 0.12s;
}
.league-card:hover { border-color: var(--accent); background: var(--surface-2); }
.league-card:active { transform: scale(0.99); }
.league-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.league-card-name { font-weight: 800; font-size: 18px; letter-spacing: -0.01em; }
.league-card-sub { font-size: 12px; color: var(--text-dim); line-height: 1.5; }

/* ===== USTA photo import ===== */
.usta-example-btn {
  display: block;
  width: 100%;
  max-width: 280px;
  margin: 0 auto;
  padding: 0;
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface-2);
  cursor: zoom-in;
}
.usta-example-img { display: block; width: 100%; height: auto; }
.usta-example-fallback { display: none; }
.usta-example-btn.missing {
  cursor: default;
  display: grid;
  place-items: center;
  min-height: 150px;
  padding: 20px;
  border-style: dashed;
}
.usta-example-btn.missing .usta-example-img { display: none; }
.usta-example-btn.missing .usta-example-fallback {
  display: block;
  font-size: 12px;
  color: var(--text-mute);
  text-align: center;
}
.usta-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px 20px;
  border: 1.5px dashed var(--border-soft);
  border-radius: 16px;
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.12s;
}
.usta-drop:hover { border-color: var(--accent); }
.usta-thumb-wrap {
  border: 1px solid var(--border-soft);
  border-radius: 14px;
  overflow: hidden;
  background: var(--surface-2);
}
.usta-thumb {
  display: block;
  width: 100%;
  height: auto;
  max-height: 340px;
  object-fit: contain;
}
.usta-repick {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 8px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
  background: transparent;
  border: 0;
  cursor: pointer;
}
.usta-fail-badge {
  display: inline-grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--danger) 18%, var(--surface));
  color: var(--danger);
}
.usta-edit-card { padding: 12px; }
.usta-edit-grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.usta-roster-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px;
}
.usta-roster-row .input { flex: 1; min-width: 0; }
.usta-share-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
}
.usta-share-url {
  font-size: 10px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.usta-lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, 0.82);
  display: grid;
  place-items: center;
  padding: 24px;
  cursor: zoom-out;
}
.usta-lightbox-img {
  max-width: 100%;
  max-height: 90vh;
  border-radius: 10px;
  cursor: default;
}
.usta-lightbox-close {
  position: fixed;
  /* [safe-area] Keep the lightbox close button clear of the notch on iOS. */
  top: calc(16px + env(safe-area-inset-top));
  right: 18px;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: 0;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  font-size: 16px;
  cursor: pointer;
}

/* ===================================================================
   BRAND POLISH — carry the matchloop blue→green identity across every
   screen: depth on cards, gradient accents on section headers + the
   sticky top bar, a tinted dashboard hero, and a gradient-text helper.
   All token-driven, so the (untouched) rain/makeup flow inherits it too.
   =================================================================== */

/* Subtle brand-tinted canvas so the app never reads as flat dead white. */
[data-theme="light"] .app-frame {
  background:
    radial-gradient(720px 420px at 100% 0%, rgba(22,104,240,0.06), transparent 60%),
    radial-gradient(680px 460px at 0% 100%, rgba(12,203,136,0.06), transparent 62%),
    linear-gradient(180deg, #F7FAFF 0%, var(--bg) 42%, #F2FBF6 100%);
}

/* Cards lift with depth + a brand-tinted hover. */
.card { transition: box-shadow 0.18s ease, transform 0.08s ease, border-color 0.18s ease; }
button.card:hover, a.card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-soft);
  border-color: color-mix(in oklab, var(--accent) 22%, var(--border-soft));
}

/* Section headers get a small brand gradient bar so every screen's
   structure reads as designed, not as anonymous grey labels. */
.section .label { position: relative; padding-left: 13px; }
.section .label::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.16em;
  width: 4px;
  height: 0.82em;
  border-radius: 2px;
  background: var(--brand-grad);
}

/* Gradient hairline under the sticky top bar — brand presence on every
   screen without shouting. */
[data-theme="light"] .topbar { border-bottom-color: transparent; }
[data-theme="light"] .topbar::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: var(--brand-loop);
  opacity: 0.85;
}

/* Dashboard greeting band — a soft brand wash so the top of Home is
   colorful and welcoming instead of empty white. */
[data-theme="light"] .hero {
  background: linear-gradient(135deg, rgba(22,104,240,0.12), rgba(12,203,136,0.10) 62%, rgba(198,238,29,0.12));
  border-radius: 0 0 24px 24px;
  box-shadow: 0 8px 24px rgba(22,40,80,0.05);
}

/* Gradient-text helper for brand moments (e.g. the greeting name). */
.brand-text {
  background: var(--brand-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* Reusable gradient top-strip for showcase cards (next-match hero). */
.brand-strip {
  height: 4px;
  border-radius: 999px;
  background: var(--brand-loop);
}

