/* ───────────────────────────────────────────────────────────────────────
   13-casual.css — Casual / launcher / host UI + mobile drawer polish.

   Tokenized: all colors come from the shared --gsx-* / --area-* tokens (see
   tokens.css), including the three --plat-school/host/casual launcher colors
   defined in tokens.css (the launcher shows all three at once, so it can't use
   the single active --area-accent). Loaded last, so it can refine the shared
   drawer chrome. Replaces the inline styles that solo-play.js used to carry.
   ─────────────────────────────────────────────────────────────────────── */

/* Casual/host shell background — a subtle brand-tinted wash (was an inline
   gradient on #soloDashboardScreen). Theme-aware via --bg-primary. */
#soloDashboardScreen {
    min-height: 100vh; min-height: 100dvh;
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--gsx-brand) 9%, var(--bg-primary)) 0,
            var(--bg-primary) 280px);
}

/* ── Home header (greeting + bell) ── */
.solo-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.solo-bell { position: relative; padding: var(--space-1-5) var(--space-2-5); }
.solo-bell-badge {
    position: absolute; top: -2px; right: -2px; min-width: 16px; height: 16px;
    padding: 0 var(--space-1); border-radius: var(--radius-md); background: var(--danger, #d33); color: var(--on-danger);
    font-size: 0.62rem; line-height: 16px; text-align: center; font-weight: 700;
}

/* ── Launcher (home base): three platform cards ── */
.solo-launch { display: grid; gap: var(--space-3); }
.solo-launch-sub { margin: 0 0 var(--space-4); font-size: 0.9rem; color: var(--gsx-text-muted); }
.solo-launch-card {
    --accent: var(--gsx-brand);
    text-align: left; cursor: pointer; width: 100%;
    border: 1px solid var(--gsx-border); border-left: 5px solid var(--accent);
    border-radius: var(--radius-3xl); background: var(--gsx-surface);
    padding: var(--space-5) var(--space-4); display: flex; align-items: center; gap: var(--space-3-5);
    box-shadow: var(--shadow-xs);
    transition: transform var(--motion-instant) var(--ease-standard), box-shadow var(--motion-instant) var(--ease-standard);
}
.solo-launch-card:active { transform: scale(0.99); }
@media (hover: hover) and (pointer: fine) {
    .solo-launch-card:hover { box-shadow: var(--shadow-md); }
}
.solo-launch-card.is-school { --accent: var(--plat-school); }
.solo-launch-card.is-host { --accent: var(--plat-host); }
.solo-launch-card.is-casual { --accent: var(--plat-casual); }
.solo-launch-icon {
    flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--radius-xl);
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent);
}
.solo-launch-body { flex: 1; }
.solo-launch-title { display: block; font-weight: 800; font-size: 1.05rem; color: var(--gsx-text); }
.solo-launch-desc { display: block; font-size: 0.85rem; color: var(--gsx-text-muted); }
.solo-launch-chev { color: var(--gsx-text-muted); }

/* ── Big primary action (Quick Game / Create Tournament) ── */
.solo-cta {
    width: 100%; cursor: pointer; border: none; border-radius: var(--radius-3xl);
    background: var(--gsx-brand); color: var(--gsx-on-brand);
    padding: var(--space-4) var(--space-4); display: flex; align-items: center; gap: var(--space-3);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--gsx-brand) 35%, transparent);
    margin-bottom: var(--space-3-5); text-align: left;
}
.solo-cta:active { transform: scale(0.99); }
.solo-cta-title { display: block; font-weight: 650; font-size: 1.1rem; letter-spacing: 0.01em; }
.solo-cta-sub { display: block; font-size: 0.82rem; opacity: 0.95; font-weight: 400; }

/* ── Quick-action grid (clean 4×2 — 8 destinations, no ragged wrap) ── */
/* TASK-X X2: the column count follows the tile count (renderers stamp
   data-qcount). Full-width 1fr tracks mean no trailing empty column and the
   row is symmetric in its container at ANY count; 8 tiles keep their clean
   4x2 at phone widths via the 4-column default. */
.solo-quick-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); justify-content: center; gap: var(--space-2); }
.solo-quick-grid[data-qcount="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.solo-quick-grid[data-qcount="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.solo-quick {
    cursor: pointer; border: 1px solid var(--gsx-border); background: var(--gsx-surface);
    border-radius: var(--radius-2xl); padding: var(--space-3-5) var(--space-2); display: flex; flex-direction: column;
    align-items: center; gap: var(--space-1-5); color: var(--gsx-text);
}
.solo-quick-ico { color: var(--brand-ink); }
.solo-quick-label { font-size: 0.78rem; font-weight: 600; }

/* ── "What's happening" feed ── */
.solo-feed-list { display: flex; flex-direction: column; }
.solo-feed-row {
    width: 100%; text-align: left; cursor: pointer; border: none;
    border-bottom: 1px solid var(--gsx-border);
    padding: var(--space-2-5) var(--space-2);
    display: flex; align-items: center; justify-content: space-between; gap: var(--space-2);
    border-radius: var(--radius-md);
    transition: background var(--motion-fast) var(--ease-standard);
}
/* gentle zebra + press state so the rows read as a clean, tappable list */
.solo-feed-row { background: transparent; }
.solo-feed-row:nth-child(even) { background: color-mix(in srgb, var(--gsx-text) 3%, transparent); }
@media (hover: hover) and (pointer: fine) {
    .solo-feed-row:hover { background: color-mix(in srgb, var(--gsx-brand) 8%, transparent); }
}
.solo-feed-row:active { transform: scale(0.995); }
.solo-feed-row:last-child { border-bottom: none; }
.solo-feed-main { min-width: 0; display: flex; flex-direction: column; }
.solo-feed-name { font-weight: 700; color: var(--gsx-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.solo-feed-meta { font-size: 0.78rem; display: block; color: var(--gsx-text-muted); }
.solo-feed-go { font-weight: 700; font-size: 0.8rem; color: var(--gsx-text-muted); flex: 0 0 auto; }
.solo-feed-go.is-live { color: var(--success-ink, #277528); }
.solo-feed-more {
    width: 100%; margin-top: var(--space-2); padding: var(--space-2);
    border: 1px dashed var(--gsx-border); background: transparent;
    border-radius: var(--radius-xl); cursor: pointer;
    font-size: 0.82rem; font-weight: 700; color: var(--gsx-brand);
}
.solo-feed-more:active { transform: scale(0.99); }

/* ── Casual bottom-sheet modal chrome ── */
.solo-modal-overlay {
    position: fixed; inset: 0; background: var(--scrim); z-index: var(--z-modal);
    display: flex; align-items: flex-end; justify-content: center;
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
    animation: soloModalFade 240ms var(--ease-standard) both;
}
.solo-modal-card {
    width: 100%; max-width: 560px; margin: 0; border-radius: var(--radius-3xl) var(--radius-3xl) 0 0;
    max-height: 92vh; overflow: auto;
    /* the techy spring-in — shared by every soloModal (friends, chat, groups…) */
    animation: statModalIn 500ms cubic-bezier(0.16, 1.1, 0.3, 1) both;
}
/* Prominent variant: a substantial sheet for list/hub modals (friends, fans). */
.solo-modal-lg { min-height: 72vh; }
/* Cascade the modal body's top-level blocks in behind the panel. */
.solo-modal-card > .gsx-card-body > * { animation: smRise 440ms var(--ease-decelerate) both; }
.solo-modal-card > .gsx-card-body > *:nth-child(1) { animation-delay: 90ms; }
.solo-modal-card > .gsx-card-body > *:nth-child(2) { animation-delay: 140ms; }
.solo-modal-card > .gsx-card-body > *:nth-child(3) { animation-delay: 190ms; }
.solo-modal-card > .gsx-card-body > *:nth-child(4) { animation-delay: 240ms; }
.solo-modal-card > .gsx-card-body > *:nth-child(n+5) { animation-delay: 290ms; }
@keyframes soloModalFade { from { opacity: 0; } to { opacity: 1; } }
@media (min-width: 560px) {
    .solo-modal-overlay { align-items: center; }
    .solo-modal-card { border-radius: var(--radius-3xl); }
    .solo-modal-lg { min-height: 66vh; }
}
@media (prefers-reduced-motion: reduce) {
    .solo-modal-overlay, .solo-modal-card,
    .solo-modal-card > .gsx-card-body > * { animation: none; }
}

/* Bell + hamburger group; margin-left:auto keeps it right-aligned on desktop too
   (mobile .nav-main uses space-between, desktop has no base justify). */
.solo-nav-actions { display: flex; align-items: center; gap: var(--space-1); margin-left: auto; }

/* ── Logo platform indicator (non-interactive; the drawer 3-way switch is the
   real switcher). Only the chip survives — the old pulldown menu was removed. ── */
.solo-plat-chip {
    display: inline-flex; align-items: center; align-self: center; margin-left: var(--space-2);
    padding: var(--space-0-5) var(--space-2); border-radius: var(--radius-pill);
    font-size: 0.62rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em;
    background: color-mix(in srgb, var(--gsx-brand) 14%, transparent);
    border: 1px solid color-mix(in srgb, var(--gsx-brand) 22%, transparent);
    color: var(--brand-ink); cursor: default; white-space: nowrap;
}
/* Host/Casual drop the team crest — the platform identity is the chip + the area
   color. School still shows WOODSON on its own navbar. */
body[data-shell-nav="solo"] .nav-school-badge { display: none; }

/* ───────────────────────────────────────────────────────────────────────
   Casual utility + component classes — replace the high-frequency inline
   styles that solo-play.js used to carry. Colors are tokens only; spacing
   and layout are literals. The `solo-` prefix avoids collisions.
   ─────────────────────────────────────────────────────────────────────── */

/* Misc one-offs */
.solo-launch-wrap { padding: var(--space-2) 0 var(--space-1); }
.solo-launch-greeting { margin: 0 0 var(--space-1); }
.solo-svg { flex: 0 0 auto; vertical-align: middle; }

/* Layout / flex utilities */
.solo-row { display: flex; align-items: center; gap: var(--space-2); }
.solo-row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.solo-row-wrap { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.solo-col-2 { display: flex; gap: var(--space-3); }
.solo-col-2 > * { flex: 1; }
.solo-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-3); }
.solo-btn-row { display: flex; gap: var(--space-1-5); }
.solo-grow { flex: 1; }
.solo-w-full { width: 100%; }
.solo-center { text-align: center; }
.solo-items-center { align-items: center; }
.solo-danger { color: var(--danger-ink, #c62828); }
.solo-muted-sm-text { font-size: 0.85rem; }

/* Spacing helpers */
.solo-mb { margin-bottom: var(--space-4); }
.solo-mb-sm { margin-bottom: var(--space-2-5); }
.solo-mt { margin-top: var(--space-4); }
.solo-mt-sm { margin-top: var(--space-2-5); }

/* Headings / titles inside cards & modals (kill the inline margin resets) */
.solo-h2 { margin: 0 0 var(--space-3); }
.solo-h2-tight { margin: 0 0 var(--space-2); }
.solo-h2-lg { margin: 0 0 var(--space-4); }
.solo-title-flush { margin: 0; }
.solo-title-mb { margin: 0 0 var(--space-2); }
.solo-title-mb-sm { margin: 0 0 var(--space-1-5); }
.solo-title-mb-xs { margin: 0 0 var(--space-1); }

/* Card meta line (the repeated 0.82rem muted descriptor under a card title) */
.solo-meta { font-size: 0.82rem; }
.solo-empty-msg { font-size: 0.9rem; }

/* Misc font-size + spacing helpers */
.solo-fs-sm { font-size: 0.8rem; }
.solo-fs-xs { font-size: 0.78rem; }
.solo-fs-2xs { font-size: 0.72rem; }
.solo-fs-115 { font-size: 1.15rem; }
.solo-fs-9 { font-size: 0.9rem; }
.solo-picks-label { font-size: 0.78rem; margin: var(--space-2-5) 0 var(--space-1); }
.solo-py-sm { padding: var(--space-2) 0; }
.solo-mt-xs { margin-top: var(--space-2); }
.solo-mt-2xs { margin-top: var(--space-1-5); }
.solo-mt-3xs { margin-top: var(--space-3); }
.solo-mb-tight { margin-bottom: var(--space-2); }
.solo-mb-md { margin-bottom: var(--space-3-5); }
.solo-gap-md { gap: var(--space-2-5); }
.solo-gap-sm { gap: var(--space-1-5); }
.solo-btn-xs { font-size: 0.75rem; }
.solo-settle-btn { padding: var(--space-1) var(--space-2-5); font-size: 0.78rem; }
.solo-fs-88 { font-size: 0.88rem; }
.solo-hint { color: var(--gsx-text-muted); font-size: 0.74rem; margin-top: var(--space-2); }
.solo-reg { font-weight: 400; }
.solo-mb-2xs { margin-bottom: var(--space-1); }
.solo-py-2xs { padding: var(--space-1) 0; }
.solo-py-2xs-xs { padding: var(--space-1) 0; }
.solo-py-sm-2 { padding: var(--space-2) 0; }
.solo-mt-0 { margin-top: 0; }
.solo-pt-0 { padding-top: 0; }
.solo-fw-800 { font-weight: 800; }
.solo-stat-row { display: flex; flex-wrap: wrap; gap: var(--space-1-5) var(--space-5); margin-bottom: var(--space-2); }
.solo-spacer { width: 0.5rem; }
.solo-team-block { margin: var(--space-1-5) 0; }
.solo-team-line { margin-bottom: var(--space-1-5); }
.solo-size-select { width: 4.5rem; }
.solo-ball-input { width: 5rem; }
.solo-settle-body { margin-top: var(--space-3-5); }
.solo-flight-block { margin: var(--space-2) 0; }
.solo-empty-inline { color: var(--gsx-text-muted); font-size: 0.88rem; }

/* Notifications list rows */
.solo-notif-row { padding: var(--space-2-5) 0; border-bottom: 1px solid var(--gsx-border); cursor: pointer; }
.solo-notif-body { font-size: 0.83rem; }

/* Group activity feed items */
.solo-feed-item { padding: var(--space-2) 0; border-bottom: 1px solid var(--gsx-border); }
.solo-feed-author { font-size: 0.75rem; margin-top: var(--space-0-5); }

/* Profile */
.solo-profile-stats { margin-bottom: var(--space-3-5); }
.solo-share-btn { font-size: 0.8rem; padding: 0 var(--space-1); }
.solo-check-label-pad { padding-bottom: var(--space-2-5); }
.solo-lookup-bio { font-size: 0.85rem; margin: var(--space-1) 0; }

/* Muted text at the common small sizes */
.solo-muted { color: var(--gsx-text-muted); }
.solo-muted-sm { color: var(--gsx-text-muted); font-size: 0.85rem; }
.solo-muted-xs { color: var(--gsx-text-muted); font-size: 0.8rem; }
.solo-muted-2xs { color: var(--gsx-text-muted); font-size: 0.72rem; }
.solo-note { color: var(--gsx-text-muted); font-size: 0.85rem; }
.solo-note p, p.solo-note { margin: 0 0 var(--space-4); }
.solo-fine { color: var(--gsx-text-muted); font-size: 0.72rem; margin-top: var(--space-2); }
.solo-strong { font-weight: 600; }
.solo-strong-700 { font-weight: 700; }

/* Generic list rows with a bottom divider */
.solo-list-row {
    display: flex; justify-content: space-between; align-items: center; gap: var(--space-2);
    padding: var(--space-2) 0; border-bottom: 1px solid var(--gsx-border);
}
.solo-list-row-tight {
    display: flex; justify-content: space-between; align-items: center; gap: var(--space-2);
    padding: var(--space-1) 0; border-bottom: 1px solid var(--gsx-border);
}
.solo-divider { border: none; border-top: 1px solid var(--gsx-border); margin: var(--space-4) 0; }

/* Tappable card (recent games, events, groups) */
.solo-card-tap { margin-bottom: var(--space-2-5); cursor: pointer; }
.solo-card-mb { margin-bottom: var(--space-2-5); }
.solo-card-row { display: flex; justify-content: space-between; align-items: center; }
.solo-round-score { font-size: 1.4rem; font-weight: 700; }
.solo-group-desc { margin: 0 0 var(--space-4); }
.solo-grid-gap { display: grid; gap: var(--space-2-5); }

/* Empty-state padding presets (used on .gsx-empty-state) */
.solo-empty-pad { padding: var(--space-4); }
.solo-empty-pad-lg { padding: var(--space-5); }
.solo-empty-pad-xl { padding: var(--space-6); }

/* Table-in-card: flush body + full-width table */
.solo-card-body-flush { padding: 0; }
.solo-table { width: 100%; }
.solo-ta-c { text-align: center; }
.solo-ta-r { text-align: right; }
.solo-th-num { width: 2.5rem; }
.solo-td-pad { padding: var(--space-2-5); }
.solo-fw-500 { font-weight: 500; }
.solo-fs-82 { font-size: 0.82rem; }

/* Status colors for amounts (settle-up, payouts, results) */
.solo-amt-pos { font-weight: 700; color: var(--success-ink, #277528); }
.solo-amt-neg { font-weight: 700; color: var(--danger-ink, #c62828); }
.solo-pay { font-weight: 700; color: var(--success-ink, #277528); }
.solo-ladder-title { margin: var(--space-2) 0 var(--space-1); }
.solo-skins-title { margin: var(--space-3-5) 0 var(--space-1); }
.solo-place { display: inline-block; min-width: 2.5rem; }
.solo-result-vals { display: flex; gap: var(--space-3); align-items: baseline; }

/* Big share code + QR block */
.solo-share-code { font-size: 2rem; font-weight: 800; letter-spacing: 4px; margin: var(--space-1) 0; }
.solo-qr { border-radius: var(--radius-lg); background: var(--surface-always-white); padding: var(--space-1-5); }
.solo-code-input { text-transform: uppercase; letter-spacing: 2px; text-align: center; font-size: 1.2rem; font-weight: 700; }
.solo-code-input-lg { text-transform: uppercase; letter-spacing: 3px; text-align: center; font-size: 1.3rem; font-weight: 700; }
.solo-invite-code { letter-spacing: 2px; }

/* Inline check-in / status badge */
.solo-inline-badge { display: inline-flex; align-items: center; gap: var(--space-1); font-size: 0.78rem; font-weight: 700; }
.solo-inline-ok { color: var(--success-ink); }

/* Small inline select used in team/flight move dropdowns */
.solo-mini-select { width: auto; padding: var(--space-0-5) var(--space-1-5); font-size: 0.8rem; }

/* Stat tiles (rounds / averages) */
/* TASK-AA AA1: no tile grid may orphan its last row — at ANY width. The old
   flex-basis (28%) could never fit four across, so Host's desktop KPIs sat
   3+1 and Casual's six sat 3+1+2; the AA4 sweep caught both. The column
   count now follows the ITEM count:
     phones (<=768): pairs, odd remainder becomes a deliberate full-width cell
     >=769: 2/3/4 items one row · 5 -> 1+4 · 6 -> 3+3 · 7 -> 1+3+3 · 8 -> 4+4
   (:has() count ladder; non-:has engines fall back to 4 columns, which is
   never worse than the old wrap.) */
.solo-stat-grid { display: grid; gap: var(--space-1); grid-template-columns: repeat(4, minmax(0, 1fr)); }
.solo-stat-grid:has(> :last-child:nth-child(2)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.solo-stat-grid:has(> :last-child:nth-child(3)),
.solo-stat-grid:has(> :last-child:nth-child(6)),
.solo-stat-grid:has(> :last-child:nth-child(7)) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.solo-stat-grid:has(> :last-child:nth-child(5)) > :first-child,
.solo-stat-grid:has(> :last-child:nth-child(7)) > :first-child { grid-column: 1 / -1; }
@media (max-width: 768px) {
    .solo-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
    .solo-stat-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
.solo-stat { min-width: 0; text-align: center; padding: var(--space-2) var(--space-1); }
.solo-stat-val { font-size: 1.5rem; font-weight: 800; color: var(--gsx-text); }
.solo-stat-label { color: var(--gsx-text-muted); font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em; }

/* Checkbox label rows in forms */
.solo-check-label { display: flex; align-items: center; gap: var(--space-2); font-size: 0.9rem; line-height: 1.35; }
.solo-field-end { display: flex; align-items: flex-end; }
.solo-py-2xs-sm { padding: var(--space-1) 0; }
.solo-check-row { margin: var(--space-1) 0 var(--space-2); }
.solo-check-row-last { margin: var(--space-1) 0 var(--space-4); }
.solo-relative { position: relative; }
.solo-picked-note { font-size: 0.75rem; margin-top: var(--space-1); }
.solo-p-mb { margin: 0 0 var(--space-3); }
.solo-modal-lead { margin: 0 0 var(--space-4); font-size: 0.88rem; }
.solo-sk-note { margin: 0 0 var(--space-2); font-size: 0.8rem; }
.solo-scroll-list { max-height: 50vh; overflow: auto; margin-bottom: var(--space-3); }

/* Modal artwork (upgrade) */
.solo-upgrade-art { width: 100%; max-height: 140px; object-fit: contain; border-radius: var(--radius-xl); margin-bottom: var(--space-3-5); }
.solo-upgrade-fallback {
    display: none; width: 100%; height: 120px; border-radius: var(--radius-xl); margin-bottom: var(--space-3-5);
    background: var(--gsx-surface-2); border: 1px dashed var(--gsx-border);
    align-items: center; justify-content: center; color: var(--gsx-text-muted); font-size: 0.85rem;
}
.solo-upgrade-blurb { margin: 0 0 var(--space-4); font-size: 0.9rem; }

/* Course search dropdown */
.solo-course-box { border: 1px solid var(--gsx-border); border-radius: var(--radius-md); overflow: hidden; margin-top: var(--space-1); }
.solo-course-opt { padding: var(--space-2) var(--space-2-5); cursor: pointer; border-bottom: 1px solid var(--gsx-border); font-size: 0.85rem; }

/* Scorecard stepper + stat inputs */
.solo-score-area { margin-top: var(--space-3-5); }
.solo-stepper-row { display: flex; align-items: center; justify-content: center; gap: var(--space-5); margin-top: var(--space-1-5); }
.solo-stroke-val { font-size: 2.6rem; font-weight: 800; min-width: 2ch; }
.solo-stat-inputs {
    display: flex; flex-wrap: wrap; gap: var(--space-2-5) var(--space-4);
    justify-content: center; align-items: center; margin-top: var(--space-3-5); font-size: 0.85rem;
}
.solo-stat-label-input { display: flex; align-items: center; gap: var(--space-1); }
.solo-num-input { width: 3rem; text-align: center; }
.solo-hole-select { width: auto; min-width: 6.5rem; flex: 0 0 auto; }
.solo-save-hole { margin-top: var(--space-3); min-width: 60%; }
.solo-save-hint { font-size: 0.74rem; margin-top: var(--space-1); }

/* Card tile (home secondary actions) */
.solo-tile-btn {
    text-align: left; cursor: pointer; width: 100%;
    border: 1px solid var(--gsx-border); background: var(--gsx-surface);
}
.solo-tile-body { display: flex; align-items: flex-start; gap: var(--space-3); }
.solo-tile-title { font-weight: 700; color: var(--gsx-text); }
.solo-tile-sub { font-size: 0.82rem; }

/* ───────────────────────────────────────────────────────────────────────
   Mobile drawer polish — lighter header, cleaner footer buttons.
   (Refines the shared .nav-drawer-* chrome; loaded last so it wins.)
   ─────────────────────────────────────────────────────────────────────── */
.nav-drawer-header {
    background: color-mix(in srgb, var(--gsx-brand) 12%, transparent);  /* platform-tinted full-bleed band */
    border-bottom: 1px solid var(--gsx-border);
    padding: var(--space-4) var(--space-4) var(--space-3-5);
    box-sizing: border-box; width: 100%;
    /* Visibility (display:none on desktop / flex ≤768px) stays owned by the base
       rules; refine only the look here so it never leaks onto desktop. */
}
/* Left cluster: a mode-neutral avatar + the user's name. Identity chrome does
   NOT recolor per area — both the initials and the chip tint use --gsx-text
   (the only brand-adjacent token [data-area] leaves alone), matching
   .drawer-user-name below. --gsx-brand/--brand-ink would re-track the accent. */
.drawer-id { display: flex; align-items: center; gap: var(--space-2-5); min-width: 0; }
.drawer-avatar {
    flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.78rem; font-weight: 800; letter-spacing: 0.02em;
    background: color-mix(in srgb, var(--gsx-text) 12%, transparent);
    color: var(--gsx-text);
    overflow: hidden;
}
/* Photo branch: identical disc geometry to the initials span above (the tint
   doubles as the placeholder while the photo loads), so swapping either way —
   including the onerror fallback — never shifts the header. */
img.drawer-avatar { object-fit: cover; object-position: center; }
.drawer-id-text { display: flex; flex-direction: column; min-width: 0; }
.drawer-user-name {
    font-size: 0.95rem; font-weight: 700; color: var(--gsx-text); letter-spacing: -0.01em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.drawer-user-sub {
    font-size: 0.72rem; color: var(--gsx-text-muted); margin-top: 1px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Right cluster: the light/dark toggle (moved up from the footer) + close. The
   base .theme-toggle uses white-alpha icons for dark bars; here we make it
   theme-aware so it reads on the light-theme header too. */
.drawer-head-actions { display: flex; align-items: center; gap: var(--space-1); flex: 0 0 auto; }
/* Light/Dark lives at the BOTTOM-RIGHT of the footer on mobile. On desktop the
   header is display:none and this rule doesn't apply, so the toggle stays inline
   in the top bar (nav-right-group / footer via display:contents). */
@media (max-width: 768px) {
    /* Coach/admin footer stacks Help/Profile/Log out rows, so its theme toggle
       pins to the bottom-right corner. The casual footer is a single line (below). */
    .nav-user.drawer-active .nav-right-group .theme-toggle {
        position: absolute; right: var(--space-3);
        bottom: calc(var(--space-2) + env(safe-area-inset-bottom, 0px));
        display: inline-flex; margin: 0; width: 32px; height: 32px;
        color: var(--gsx-text-muted);
    }
    .nav-user.drawer-active .nav-right-group .theme-toggle:active {
        color: var(--gsx-text); background: var(--row-hover, rgba(127, 127, 127, 0.12));
    }
}
.nav-drawer-close {
    background: transparent; border: none; color: var(--gsx-text-muted);
    cursor: pointer; padding: var(--space-1); border-radius: var(--radius-md); line-height: 0;
}
@media (hover: hover) and (pointer: fine) {
    .nav-drawer-close:hover { background: var(--row-hover, rgba(0, 0, 0, 0.05)); }
}

/* Footer container — player drawer uses .nav-drawer-footer; the coach/admin
   drawer uses .nav-right-group. Scope the latter to the OPEN drawer only so the
   desktop top-nav .nav-right-group is untouched.
   These are the MOBILE DRAWER styles (stacked, full-width rows): scope them to
   ≤768px so they never override 01-foundation's desktop `.nav-drawer-footer {
   display: contents }` (this file loads after 01-foundation, and media queries
   add no specificity — without this gate the footer rendered as a vertical
   column on desktop, stacking the theme toggle above Log Out). */
@media (max-width: 768px) {
    /* The casual/host bar's DESKTOP right cluster (Help/Profile/Log Out) must
       never surface inside the mobile drawer: the coach-footer reskin below
       targets .nav-user.drawer-active .nav-right-group generally, which dressed
       this cluster up as a second, detached footer floating ABOVE the drawer
       header (it precedes .solo-drawer in DOM order). The solo drawer carries
       its own .nav-drawer-footer. The .drawer-active selector out-specifies the
       reskin's display:flex regardless of source order. */
    .nav-user.solo-nav-user .nav-right-group,
    .nav-user.solo-nav-user.drawer-active .nav-right-group { display: none; }

    .nav-drawer-footer,
    .nav-user.drawer-active .nav-right-group {
        margin-top: auto;
        padding: 0.4rem 0 calc(0.9rem + env(safe-area-inset-bottom, 0px));
        border-top: 1px solid var(--gsx-border);
        background: color-mix(in srgb, var(--gsx-brand) 12%, transparent);  /* matches header band */
        box-sizing: border-box; width: 100%;
        position: relative;   /* anchor for the bottom-right theme toggle */
        display: flex;
        flex-direction: column;
        gap: 0;
    }
    /* Brand signature fills the footer band so Log Out isn't a lone button in a
       void. Full-width, centered, muted. (order:99 keeps it last in the column.) */
    .nav-drawer-footer::after,
    .nav-user.drawer-active .nav-right-group::after {
        content: 'GolfStax';
        order: 99; text-align: center;
        font-size: 0.66rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase;
        color: var(--gsx-text-muted); opacity: 0.4;
        padding: var(--space-2) 0 var(--space-0-5);
    }
    /* Every footer control reads as a flat, left-aligned nav row (icon + label)
       that matches the section rows above — one consistent visual language for
       the whole drawer, no bordered "card" pills. */
    .nav-drawer-footer .nav-link,
    .nav-drawer-footer .nav-theme-row,
    .nav-user.drawer-active .nav-right-group .nav-link,
    .nav-user.drawer-active .nav-right-group .nav-theme-row {
        flex: 0 0 auto;
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: flex-start;
        gap: var(--space-2-5);
        padding: var(--space-2) var(--space-5);
        border: none;
        background: none;
        border-radius: 0;
        font-size: 0.9rem;
        font-weight: 500;
        text-align: left;
        color: var(--gsx-text);
        cursor: pointer;
    }
    .nav-drawer-footer .nav-link:active,
    .nav-drawer-footer .nav-theme-row:active,
    .nav-user.drawer-active .nav-right-group .nav-link:active,
    .nav-user.drawer-active .nav-right-group .nav-theme-row:active {
        background: var(--row-hover, rgba(127, 127, 127, 0.12));
    }
    /* Theme row label (icon + "Light / Dark mode") aligns like the other rows. */
    .nav-drawer-footer .nav-theme-row .nav-theme-label,
    .nav-user.drawer-active .nav-right-group .nav-theme-row .nav-theme-label {
        display: flex;
        align-items: center;
        gap: var(--space-2-5);
        font-size: 0.9rem;
        font-weight: 500;
    }
    /* Logout: red text only — subtle, not a boxed alert. */
    .nav-drawer-footer .nav-logout,
    .nav-user.drawer-active .nav-right-group .nav-logout {
        color: var(--danger-ink, #c62828);
    }
    .nav-drawer-footer .nav-logout:active,
    .nav-user.drawer-active .nav-right-group .nav-logout:active {
        background: color-mix(in srgb, var(--danger, #d33) 8%, transparent);
    }

    /* Casual/solo footer = ONE clean line: Light/Dark (left) · GolfStax (center) ·
       Log Out (right). Logout stays LABELED — icon-only logout is understood by
       only ~34% of users (NN/g / CXL) — and there's NO confirm dialog (logout is
       reversible; NN/g reserves confirms for irreversible actions). The coach
       footer keeps the stacked column above. */
    .nav-drawer-footer {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;   /* theme far-left · Log Out far-right */
        gap: var(--space-2);
        padding: var(--space-2) var(--space-4) calc(var(--space-2) + env(safe-area-inset-bottom, 0px));
    }
    .nav-drawer-footer .theme-toggle {
        position: static; order: 1; flex: 0 0 auto;
        margin: 0; width: 32px; height: 32px; color: var(--gsx-text-muted);
    }
    .nav-drawer-footer .theme-toggle:active {
        color: var(--gsx-text); background: var(--row-hover, rgba(127, 127, 127, 0.12));
    }
    /* GolfStax centered on the FULL menu width (overlay), independent of the
       theme/logout controls flanking it — so it's dead-center of the menu, not
       of the gap between them. */
    .nav-drawer-footer::after {
        position: absolute; inset: 0; padding: 0; pointer-events: none;
        display: flex; align-items: center; justify-content: center;
    }
    .nav-drawer-footer .nav-logout {
        order: 3; width: auto; flex: 0 0 auto; gap: var(--space-1-5);
        padding: var(--space-1-5) var(--space-2);
    }
}

/* ── Desktop tab strip for casual/host (C3) ──
   The bottom-nav is mobile-only; this gives desktop casual/host users their tab
   navigation. Rendered into the casual navbar's .nav-user by solo-play.js.
   Hidden ≤768px where the bottom-nav takes over. */
.solo-desktop-tabs {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}
@media (max-width: 768px) {
    .solo-desktop-tabs { display: none; }
}
/* ≥1024px the left rail (07-mobile.css) is the single nav surface — the navbar
   tab strip would double-navigate. */
@media (min-width: 1024px) {
    .solo-desktop-tabs { display: none; }
}

/* ── Desktop command-center: stop stretching the mobile column ──────────────
   The solo-* components are mobile-first full-width; on desktop a 1200px-wide
   button reads as a stretched phone. Cap the home CTAs at a comfortable reach. */
@media (min-width: 768px) {
    /* Center the capped CTAs AND the quick grid so the home column reads as
       one aligned stack, not a left-hugging button over a centered grid. */
    #soloContent .solo-cta,
    #soloContent .gsx-btn.solo-w-full {
        max-width: 560px;
        margin-inline: auto;
    }
    #soloContent .solo-quick-grid {
        max-width: 560px;
        margin-inline: auto;
    }
}

/* Desktop: the CTA stays capped (a 1200px button reads as a stretched phone),
   but the TILE GRID is the one element that SHOULD take the width — capping it
   at 560px was collateral from the CTA fix and left the dashboard as a phone
   column in a 1920px viewport. Eight tiles on one row; the icon and label
   scale with them so a wider tile does not look empty. */
@media (min-width: 1024px) {
    #soloContent .solo-quick-grid {
        max-width: none;
        gap: var(--space-3);
    }
    /* Explicit 8, not auto-fit: eight destinations; auto-fit lands on 7+1 at
       this width. Scoped to the 8-tile grid so Host's 3-tile row keeps its
       own 3 columns instead of rattling in an 8-track grid. */
    #soloContent .solo-quick-grid[data-qcount="8"] {
        grid-template-columns: repeat(8, minmax(0, 1fr));
        gap: var(--space-3);
    }

    #soloContent .solo-quick {
        padding: var(--space-5) var(--space-3);
        gap: var(--space-2-5);
    }

    #soloContent .solo-quick-ico svg {
        width: 30px;
        height: 30px;
    }

    #soloContent .solo-quick-label {
        font-size: 0.92rem;
    }

    /* The shared empty state reserves 12rem, so an empty Casual home leaves a
       tall box floating with nothing under it. Let it hug its content here —
       the audit's own alternative to filling the space with filler. This is a
       PARTIAL answer: the real fix is a shared desktop composition (Host has
       the same dead space), which spans files this task does not own. */
    #soloContent .gsx-empty-state {
        min-height: auto;
    }
}

@media (min-width: 768px) {
    /* The slim help tip is a single line of copy — cap it well under the CTAs so
       the dashed frame hugs the sentence instead of spanning the column. */
    /* TASK-AB AB2: ONE narrow measure per screen. 360px was a second narrow
       value and made Host a three-step staircase at ~1023px. The tip uses the
       same 560px measure as .solo-cta (TASK-L's established narrow). */
    #soloContent .solo-help-tip {
        width: 100%;
        max-width: 560px;
        margin-inline: auto;
    }
}
@media (min-width: 1024px) {
    /* The rail shifts the layout right; re-center the pinned save bar on the
       content column (left:50% + translateX(-50%) + half the rail). */
    .solo-save-pinned {
        margin-left: calc(var(--rail-w, 92px) / 2);
    }
}

/* Casual/host DESKTOP top-right cluster (Profile / Help / Log Out), mirroring
   School's .nav-right-group. Base .nav-right-group is display:flex (desktop);
   hide it ≤768px where the (mobile-only) .solo-drawer already carries these. */
@media (max-width: 768px) {
    .solo-nav-user .nav-right-group { display: none; }
}

/* ── Mobile drawer wrapper for casual/host ──
   The casual/host .nav-user holds BOTH the desktop tab strip (above) and the
   mobile slide-out drawer. .solo-drawer carries the drawer chrome
   (.nav-drawer-header / -links / -footer). Hide it outright on desktop so it
   never collides with the tab strip; dissolve it (display:contents) ≤768px so
   its rows become direct flex children of the full-screen .nav-user drawer and
   the shared .nav-drawer-* mobile styles apply unchanged. */
.solo-drawer { display: none; }
@media (max-width: 768px) {
    .solo-drawer { display: contents; }
}

/* "Have a team code?" launcher entry — re-wires the soloJoinTeam modal so a
   casual player can join their coach's team by activation code (complements the
   request-to-join flow). Shown only when not already on a school. */
.solo-launch-code {
    display: block;
    width: 100%;
    margin-top: var(--space-3-5);
    padding: var(--space-2-5);
    background: transparent;
    border: none;
    color: var(--gsx-text-muted);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    text-align: center;
}
.solo-launch-code span {
    color: var(--area-accent, var(--plat-casual));
    text-decoration: underline;
    text-underline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
    .solo-launch-code:hover span { opacity: 0.85; }
}

/* ── New game: one-tap chip selectors (replace dropdowns) ── */
.cg-section { margin-bottom: var(--space-3); }
.cg-section > .gsx-label { display: block; margin-bottom: var(--space-1-5); }

.cg-chips {
    /* Uniform tap-target geometry on EVERY step: a fixed grid with equal-height
       chips, so options always land in the same thumb zones (no chasing). */
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-2);
}
/* 3-option groups stay one row of thirds — same height, same baseline. */
.cg-chips[data-cg="skins"],
.cg-chips[data-cg="payout"],
.cg-chips[data-cg="team_size"],
.cg-chips[data-cg="best_n"] {
    grid-template-columns: repeat(3, 1fr);
}
.cg-chip {
    min-height: 50px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--space-2) var(--space-2-5);
    border-radius: var(--radius-lg);
    border: 1.5px solid var(--border-subtle, rgba(255, 255, 255, 0.16));
    background: var(--gsx-input-bg, rgba(255, 255, 255, 0.05));
    color: var(--text-primary, #e8e8e8);
    font: inherit;
    font-weight: 600;
    font-size: 0.92rem;
    line-height: 1.15;
    text-align: center;
    cursor: pointer;
    transition: border-color var(--motion-fast), background var(--motion-fast), transform var(--motion-instant);
}
.cg-chip:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) {
    .cg-chip:hover { border-color: var(--primary-color, #15803d); }
}
.cg-chip.active {
    border-color: var(--primary-color, #15803d);
    background: rgba(var(--gsx-brand-rgb, 21, 128, 61), 0.16);
    color: var(--text-primary, #fff);
    box-shadow: inset 0 0 0 1px var(--primary-color, #15803d);
}
.cg-chip-sub {
    display: block;
    font-weight: 400;
    font-size: 0.7rem;
    color: var(--text-muted, #9a9a9a);
    margin-top: var(--space-0-5);
}
.cg-chip.active .cg-chip-sub { color: var(--text-secondary, #c8c8c8); }
.cg-hint {
    margin: var(--space-1) 0 0;
    font-size: 0.72rem;
    line-height: 1.3;
    color: var(--text-muted, #9a9a9a);
}

/* ── Join: in-modal QR scanner ── */
.solo-qr-scan { margin-top: var(--space-3); text-align: center; }
.solo-qr-scan video {
    width: 100%;
    max-height: 260px;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: var(--radius-xl);
    background: #000;  /* tokens-allow: pure-black surface (photo letterbox) */
    border: 1.5px solid var(--primary-color, #15803d);
}
.solo-row-center {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
}

/* ── Casual modal: opaque card + close X ──
   (--card-bg is 0.92 alpha, so without this the dimmed page shows through.) */
.solo-modal-card { position: relative; background: var(--surface-solid); }
.solo-modal-x {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    background: rgba(127, 127, 127, 0.14);  /* tokens-allow: neutral control gray (no neutral-fill token) */
    color: var(--text-muted, #999);
    z-index: 2;
    transition: background var(--motion-fast), color var(--motion-fast);
}
@media (hover: hover) and (pointer: fine) {
    .solo-modal-x:hover {
        background: rgba(127, 127, 127, 0.26);  /* tokens-allow: neutral control gray (no neutral-fill token) */
        color: var(--text-primary, #fff);
    }
}

/* ── New game wizard (Next/Back steps) ── */
.cg-progress {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--primary-color, #15803d);
    letter-spacing: 0.02em;
    margin: var(--space-1) 0 var(--space-4);
}
.cg-nav {
    display: flex;
    align-items: center;
    gap: var(--space-2-5);
    margin-top: var(--space-5);
}

/* ── New-game WIZARD — native full-height sheet, scrollable body, pinned big CTA.
   (Locked decision: stepped, one decision per step, minimal vertical scroll,
   large thumb-reachable bottom button.) Scoped via :has() to the create flow so
   the shared .solo-modal-card chrome is untouched elsewhere. ── */
.solo-modal-card:has(.cg-wizard) {
    height: 90vh;
    max-height: 90dvh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.solo-modal-card:has(.cg-wizard) > .gsx-card-body {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    padding: 0;
    overflow: hidden;
}
.cg-wizard,
.cg-wizard > form {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.cg-head {
    flex: 0 0 auto;
    text-align: center;
    padding: var(--space-5) var(--space-5) var(--space-3);
}
.cg-head .solo-h2-lg { margin: 0 0 var(--space-3); }
.cg-dots {
    display: flex;
    justify-content: center;
    gap: var(--space-1-5);
    margin-bottom: var(--space-2);
}
.cg-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-pill);
    background: var(--raise-3);
    transition: width var(--motion-base) var(--ease-spring), background var(--motion-base);
}
.cg-dot.is-active { width: 22px; background: var(--primary-color); }
.cg-dot.is-done { background: var(--primary-light); }
.cg-step-name {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--brand-ink);
}
.cg-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: var(--space-2) var(--space-5) var(--space-5);
}
.cg-wizard .cg-nav {
    flex: 0 0 auto;
    margin-top: 0;
    padding: var(--space-4) var(--space-5) calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--border-subtle);
    background: var(--surface-solid);
}
.cg-wizard .cg-nav .gsx-btn-lg { flex: 1; }
@media (min-width: 560px) {
    .solo-modal-card:has(.cg-wizard) { height: auto; max-height: 88vh; }
}

/* "+ More formats" reveal + review summary */
.cg-more { margin-top: var(--space-2); }
.cg-more-toggle {
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--space-1) 0;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--primary-color, #15803d);
}
.cg-review-row {
    display: flex;
    justify-content: space-between;
    gap: var(--space-4);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.1));
    font-size: 0.92rem;
}
.cg-review-row:last-child { border-bottom: none; }
.cg-review-val { font-weight: 600; text-align: right; }

/* ── Assign-Practice wizard (reuses the .cg-* chips/steps above) ── */
.paw-roster {
    max-height: 230px;
    overflow-y: auto;
    border: 1px solid var(--gsx-border);
    border-radius: var(--radius-lg);
    padding: var(--space-1-5) var(--space-2-5);
    display: flex;
    flex-direction: column;
}
.paw-chk-row { padding: var(--space-1) 0; }
.paw-mini {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--brand-ink);
    font-size: 0.8rem;
    font-weight: 600;
    padding: 0 var(--space-0-5);
}
@media (hover: hover) and (pointer: fine) {
    .paw-mini:hover { text-decoration: underline; }
}
.pa-tag { color: var(--brand-ink); font-weight: 600; }

/* ── Teams: dismissible oversize warning ── */
.solo-team-warn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--warning-ink);
    background: rgba(var(--gsx-warning-rgb), 0.14);
    border: 1px solid rgba(var(--gsx-warning-rgb), 0.4);
}
[data-theme="dark"] .solo-team-warn { color: #ffc77a; }  /* tokens-allow: warm-amber warning text, dark-theme tuned */
.solo-team-warn-x {
    flex: 0 0 auto;
    background: none;
    border: none;
    cursor: pointer;
    color: inherit;
    font-size: 0.95rem;
    line-height: 1;
    padding: var(--space-0-5) var(--space-1);
    opacity: 0.8;
}
@media (hover: hover) and (pointer: fine) {
    .solo-team-warn-x:hover { opacity: 1; }
}

/* ── Menu: platform switcher + row icons ──
   ONE switcher to hop between School / Host / Casual; its active segment
   auto-themes to the area accent (gold school / blue host / green casual).
   DESKTOP (default, below): a compact segmented control in the top bar — School's
   single switcher element lives directly in .nav-user so these styles apply
   as-is; casual/host render a dedicated .nav-plat-desktop copy because their
   drawer copy sits inside the mobile-only .solo-drawer.
   MOBILE (≤768px block): the full-width pill row at the top of the slide-out
   drawer (overrides below).
   Row icons are shown only in the slide-out drawer, not the desktop top bar. */
.nav-plat-switch {
    display: inline-flex;
    align-items: center;
    gap: var(--space-0-5);
    padding: var(--space-0-5);
    margin-right: var(--space-1);
    flex: 0 0 auto;
    background: var(--gsx-surface-2, rgba(127, 127, 127, 0.08));
    border: 1px solid var(--gsx-border);
    border-radius: var(--radius-xl);
}
.nav-plat-opt {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border: none;
    background: none;
    cursor: pointer;
    border-radius: var(--radius-lg);
    font-size: 0.74rem;
    font-weight: 700;
    white-space: nowrap;
    color: var(--gsx-text-muted);
    transition: background var(--motion-fast), color var(--motion-fast);
}
.nav-plat-opt .nav-row-ico { width: 14px; height: 14px; margin: 0; }
/* The label is a <span>: `.nav-user span {font-size: 0.82rem; font-weight: 500}`
   (01-foundation) would out-specify the inherited values, so pin both to the
   segment's own (desktop 700 here, mobile 600 in the drawer block below). */
.nav-plat-opt span { font-size: inherit; font-weight: inherit; }
.nav-plat-opt.active {
    background: var(--primary-color);
    color: var(--gsx-on-brand);
    box-shadow: 0 1px 5px rgba(var(--gsx-brand-rgb), 0.35);
    cursor: default;
}
@media (hover: hover) and (pointer: fine) {
    .nav-plat-opt:not(.active):hover {
        color: var(--gsx-text);
        background: var(--row-hover, rgba(127, 127, 127, 0.12));
    }
}
.nav-row-ico { width: 16px; height: 16px; flex-shrink: 0; }
.nav-drawer-links .nav-row-ico { display: none; }
.nav-trig-main { display: inline-flex; align-items: center; gap: var(--space-1-5); min-width: 0; }
/* Desktop: the interactive bar switcher replaces the passive mode chip next to
   the casual/host logo (JS sets the chip's display inline, hence !important). */
@media (min-width: 769px) {
    #soloPlatformChip { display: none !important; }
}

@media (max-width: 768px) {
    /* The desktop bar copy never surfaces in the drawer (the drawer has its own). */
    .nav-plat-switch.nav-plat-desktop { display: none; }
    .nav-plat-switch {
        display: flex;
        gap: var(--space-1);
        margin: var(--space-3) var(--space-4) var(--space-1-5);
        padding: var(--space-1);
        background: var(--gsx-surface-2, rgba(127, 127, 127, 0.08));
        border: 1px solid var(--gsx-border);
        border-radius: var(--radius-xl);
    }
    .nav-plat-opt {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-1-5);
        padding: var(--space-2-5) var(--space-2);
        border: none;
        background: none;
        cursor: pointer;
        border-radius: var(--radius-md);
        font-size: 0.88rem;
        font-weight: 600;
        color: var(--gsx-text-muted);
        transition: background var(--motion-fast), color var(--motion-fast);
    }
    .nav-plat-opt .nav-row-ico { width: 17px; height: 17px; margin: 0; }
    .nav-plat-opt.active {
        background: var(--primary-color);
        color: var(--gsx-on-brand);
        box-shadow: 0 1px 5px rgba(var(--gsx-brand-rgb), 0.35);
    }
    .nav-plat-opt:not(.active):active { color: var(--gsx-text); }
    .nav-drawer-links .nav-row-ico { display: inline-block; margin-right: var(--space-3); opacity: 0.8; }
    .nav-trig-main { display: flex; align-items: center; min-width: 0; }
}

/* ── Quick scorecard (P2): list all players/teams, enter a score for each ── */
.solo-qs-list { display: flex; flex-direction: column; gap: var(--space-1-5); }
.solo-qs-row {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-2-5); padding: var(--space-2) var(--space-2-5); border: 1px solid var(--border-color);
    border-radius: var(--radius-lg); background: var(--card-bg, rgba(255,255,255,0.02));
}
.solo-qs-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.solo-qs-step { display: flex; align-items: center; gap: var(--space-2-5); flex: 0 0 auto; }
.solo-step-sm { width: 34px; height: 34px; font-size: 1.1rem; line-height: 1; }
.solo-qs-val { min-width: 1.6rem; text-align: center; font-weight: 700; font-size: 1.15rem; }
/* Per-row one-tap stat strip (putts / drive / GIR / penalties) */
.solo-qs-statbtn {
    position: relative; width: 30px; height: 30px; flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--gsx-border); border-radius: var(--radius-md);
    background: none; color: var(--gsx-text-muted); cursor: pointer;
}
.solo-qs-statbtn.open { color: var(--brand-ink); border-color: var(--brand-ink); }

@media (hover: hover) and (pointer: fine) {
    .solo-qs-statbtn:hover { color: var(--brand-ink); border-color: var(--brand-ink); }
}
.solo-qs-statbtn.has::after {
    content: ''; position: absolute; top: 2px; right: 2px; width: 6px; height: 6px;
    border-radius: 50%; background: var(--brand-ink);
}
/* ── Directional stat sheet (Mileseey-style arrows + steppers) ── */
.solo-statsheet {
    display: flex; flex-direction: column; gap: var(--space-3);
    margin: calc(-1 * var(--space-1)) var(--space-1) var(--space-2);
    padding: var(--space-3) var(--space-3) var(--space-3-5);
    background:
        radial-gradient(120% 80% at 50% -10%, color-mix(in srgb, var(--gsx-brand) 14%, transparent), transparent 60%),
        color-mix(in srgb, var(--gsx-brand) 6%, var(--gsx-surface-2));
    border-radius: var(--radius-2xl);
    border: 1px solid color-mix(in srgb, var(--gsx-brand) 18%, transparent);
}
.solo-statsheet[hidden] { display: none !important; }
.solo-stat-block { display: flex; flex-direction: column; gap: var(--space-1-5); align-items: center; }
.solo-stat-glabel {
    font-size: 0.64rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: 0.12em; color: var(--gsx-text-muted);
}
.solo-stat-pads { display: flex; gap: var(--space-3); justify-content: center; }
.solo-stat-pad {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
    padding: var(--space-2-5) var(--space-1) var(--space-2);
    background: var(--gsx-surface); border: 1px solid var(--gsx-border);
    border-radius: var(--radius-xl); min-width: 0;
}

/* Putts −/+ stepper with broadcast numeral */
.solo-putt-step { display: flex; align-items: center; gap: var(--space-3); }
.solo-pstep {
    width: 42px; height: 42px; border-radius: 50%;
    border: 1px solid var(--gsx-border); background: var(--gsx-surface);
    color: var(--gsx-text); font-size: 1.4rem; font-weight: 700; line-height: 1; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: transform var(--motion-instant) var(--ease-standard), background var(--motion-fast);
}
.solo-pstep:active { transform: scale(0.88); background: color-mix(in srgb, var(--gsx-brand) 12%, var(--gsx-surface)); }
.solo-putt-num {
    font-family: var(--font-display); font-size: 2.4rem; font-weight: 700;
    font-variant-numeric: tabular-nums; min-width: 2ch; text-align: center; color: var(--gsx-text);
}
.solo-putt-num.is-empty { color: var(--gsx-text-muted); opacity: 0.5; font-size: 1.6rem; }
.solo-putt-num.bump { animation: soloBump var(--motion-base) var(--ease-decelerate); }
@keyframes soloBump { 0% { transform: scale(1); } 40% { transform: scale(1.28); color: var(--gsx-brand); } 100% { transform: scale(1); } }

/* Directional arrow buttons (drive pad + approach compass) */
.solo-dpad-drive { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-1-5); place-items: center; }
.solo-compass { display: flex; flex-direction: column; align-items: center; gap: var(--space-1-5); }
.solo-compass-mid { display: flex; align-items: center; gap: var(--space-1-5); }
.solo-dir {
    width: 46px; height: 46px; border-radius: 50%; cursor: pointer;
    border: 1px solid var(--gsx-border); background: var(--gsx-surface);
    display: inline-flex; align-items: center; justify-content: center;
    position: relative;
    transition: transform var(--motion-fast) var(--ease-standard),
                background var(--motion-fast), border-color var(--motion-fast);
}
.solo-dir-svg { width: 22px; height: 22px; fill: var(--gsx-text-muted); transition: fill var(--motion-fast); }
.solo-dir:active { transform: scale(0.9); }
.solo-dir.on {
    background: var(--gradient-accent); border-color: transparent;
    box-shadow: var(--shadow-float);
}
.solo-dir.on .solo-dir-svg { fill: var(--gsx-on-brand); }
.solo-dir.auto { outline: 2px dashed color-mix(in srgb, var(--gsx-brand) 55%, transparent); outline-offset: 2px; }
.solo-dir-dotc {
    width: 15px; height: 15px; border-radius: 50%;
    border: 2px solid var(--gsx-text-muted);
    transition: border-color var(--motion-fast), background var(--motion-fast);
}
.solo-dir-dot.on .solo-dir-dotc { border-color: var(--gsx-on-brand); background: var(--gsx-on-brand); }

/* Pounce + ripple when a direction is picked */
.solo-dir.pick-fx { animation: soloPounce 360ms var(--ease-decelerate); }
@keyframes soloPounce { 0% { transform: scale(1); } 35% { transform: scale(1.22); } 70% { transform: scale(0.94); } 100% { transform: scale(1); } }
.solo-dir.pick-fx::after {
    content: ''; position: absolute; inset: 0; border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--gsx-brand) 70%, transparent);
    animation: soloRipple 480ms var(--ease-decelerate) forwards;
}
@keyframes soloRipple { from { transform: scale(0.6); opacity: 0.9; } to { transform: scale(2.1); opacity: 0; } }

/* GIR center hit — a celebratory pulse ring off the whole compass */
.solo-compass.gir-hit::after {
    content: ''; position: absolute; left: 50%; top: 42%; width: 46px; height: 46px;
    margin: -23px 0 0 -23px; border-radius: 50%;
    border: 2px solid color-mix(in srgb, var(--gsx-brand) 65%, transparent);
    animation: soloRipple 620ms var(--ease-decelerate) forwards; pointer-events: none;
}
.solo-compass { position: relative; }

/* Trouble (rough/hazard/OB) + penalties: compact pills under the pads */
.solo-trouble, .solo-pen-row { display: flex; gap: var(--space-1-5); flex-wrap: wrap; justify-content: center; }
.solo-troub, .solo-pen {
    min-height: 44px; min-width: 44px; padding: 3px 14px; border-radius: var(--radius-pill);
    display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--gsx-border); background: var(--gsx-surface);
    font-size: 0.78rem; font-weight: 700; color: var(--gsx-text-muted); cursor: pointer;
    transition: transform var(--motion-instant) var(--ease-standard), background var(--motion-fast);
}
.solo-troub:active, .solo-pen:active { transform: scale(0.92); }
.solo-troub.on, .solo-pen.on {
    background: var(--primary-color); border-color: var(--primary-color); color: var(--gsx-on-brand);
}
.solo-pen.on { background: var(--score-under); border-color: var(--score-under); }
/* DQ / WD badge + row */
.solo-dq-badge {
    display: inline-block; margin-left: var(--space-1-5); padding: 0 var(--space-1-5); border-radius: var(--radius-pill);
    font-size: 0.62rem; font-weight: 800; letter-spacing: 0.04em;
    color: var(--double-ink, #e74c3c); border: 1px solid var(--double-ink, #e74c3c);
}
.solo-row-out { opacity: 0.6; }

/* Side-games disclaimer: quiet fine print (matches .solo-fine), not a banner. */
.solo-money-disclaimer {
    display: flex;
    align-items: flex-start;
    gap: var(--space-1-5);
    margin: var(--space-0-5) 0 var(--space-3-5);
    font-size: 0.72rem;
    line-height: 1.4;
    color: var(--gsx-text-muted);
}
.solo-money-disclaimer svg { flex: 0 0 auto; opacity: 0.6; margin-top: var(--space-0-5); }

/* 6-6-6 segment editor + skins config (create modal) */
.solo-seg-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2-5); margin: var(--space-1) 0; }
.solo-seg-select { width: auto; min-width: 130px; flex: 0 0 auto; }

/* Casual/Host now use the SAME right-slide-in drawer as School (the shared
   .nav-user side drawer in 07-mobile.css) — the old bottom-sheet override was
   removed so all three platforms share one uniform slide-out. .solo-drawer is
   display:contents ≤768px, so its rows flow into the .nav-user flex column. */

/* End-of-round results screen */
/* Results hero — THE dark hero of the results screen (same charcoal surface
   in light and dark mode, like the in-game hole hero): deep brand wash,
   broadcast display type, winner called out in brand ink. */
.solo-results-hero {
    text-align: center; padding: var(--space-5) var(--space-3-5); margin: var(--space-1) 0 var(--space-3);
    border: none; border-radius: var(--radius-2xl);
    background:
        linear-gradient(160deg, color-mix(in srgb, var(--gsx-brand) 20%, transparent), transparent 52%),
        linear-gradient(180deg, var(--surface-hero) 0%, var(--surface-hero-2) 100%);
    color: var(--on-scrim);
    box-shadow: var(--shadow-hero);
}
.solo-results-hero.is-cancelled {
    background: linear-gradient(180deg, var(--surface-hero) 0%, var(--surface-hero-2) 100%);
    opacity: 0.85;
}
.solo-results-flag {
    font-size: 2.4rem; line-height: 1;
    filter: drop-shadow(0 2px 6px var(--scrim-soft));
}
.solo-results-title {
    font-family: var(--font-display);
    font-size: 2rem; font-weight: 700; line-height: 1.05;
    margin-top: var(--space-2);
    letter-spacing: 0.01em;
}
.solo-results-sub {
    color: color-mix(in srgb, var(--on-scrim) 72%, transparent);
    font-size: 0.92rem; margin-top: var(--space-1-5);
}
.solo-results-sub strong {
    color: var(--on-scrim);
    font-family: var(--font-display); font-weight: 700; font-size: 1.15em;
    letter-spacing: 0.01em;
}
.solo-round-tag {
    display: inline-block; margin-left: var(--space-1-5); padding: 0 var(--space-1-5); border-radius: var(--radius-pill);
    font-size: 0.6rem; font-weight: 800; letter-spacing: 0.04em; vertical-align: middle;
    color: var(--success-ink, #22c55e); border: 1px solid var(--success-ink, #22c55e);
}

/* ── Cross-scoring (Phase 2): marker badge + conflict resolver ── */
.solo-mark-badge { display: inline-block; padding: 0 var(--space-1); border-radius: var(--radius-sm); font-size: 0.6rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.03em; background: var(--info-wash); color: var(--info-ink); vertical-align: middle; }
.solo-xscore-hint { color: var(--info-ink); margin-top: var(--space-1); }
.solo-conflict { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-2); padding: var(--space-1-5) var(--space-2-5); border-radius: var(--radius-md); background: var(--danger-wash); border: 1px solid var(--danger-wash-border); }
.solo-conflict-label { font-size: 0.78rem; color: var(--danger-ink); font-weight: 600; }
.solo-conflict-actions { display: flex; gap: var(--space-1-5); margin-left: auto; }

/* ── Find Game (nearby list) ── */
.solo-nearby-list { display: flex; flex-direction: column; gap: var(--space-1-5); }
.solo-nearby-row { display: flex; align-items: center; gap: var(--space-3); width: 100%; text-align: left; cursor: pointer; border: 1px solid var(--gsx-border); background: var(--gsx-surface); border-radius: var(--radius-2xl); padding: var(--space-3) var(--space-4); }
.solo-nearby-row:active { transform: scale(0.99); }
.solo-nearby-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.solo-nearby-name { font-weight: 700; color: var(--gsx-text); }
.solo-nearby-sub { font-size: 0.78rem; }
.solo-nearby-dist { font-weight: 800; font-size: 0.82rem; color: var(--brand-ink); white-space: nowrap; }

/* ── "New to hosting?" slim help tip (host home) ── */
.solo-help-tip {
    display: flex; align-items: center; gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    /* TASK-AC AC1: dashed is the placeholder/drop-target language; this is
       permanent UI, so it wears the card treatment like its neighbours. */
    background: var(--gsx-surface);
    border: 1px solid var(--gsx-border); border-radius: var(--radius-xl);
}
.solo-help-tip-main {
    flex: 1; display: flex; align-items: center; gap: var(--space-2);
    background: none; border: none; cursor: pointer; text-align: left;
    padding: var(--space-1-5) var(--space-1); font-size: 0.84rem; color: var(--gsx-text-muted);
}
.solo-help-tip-link { color: var(--brand-ink); font-weight: 700; }
.solo-cklist-x {
    background: none; border: none; cursor: pointer; padding: 0 var(--space-1);
    font-size: 1.1rem; line-height: 1; color: var(--gsx-text-muted);
}

/* ── Rounds tab: actions, hidden section, practice-round detail ── */
.solo-round-tag.is-live {
    background: color-mix(in srgb, var(--info, #2563eb) 16%, transparent);
    color: var(--info-ink, #2563eb);
}
.solo-round-more {
    flex: 0 0 auto; background: none; border: none; cursor: pointer;
    padding: var(--space-1) var(--space-2); margin-left: var(--space-1);
    font-size: 1.05rem; line-height: 1; color: var(--gsx-text-muted);
    border-radius: var(--radius-md);
}
@media (hover: hover) and (pointer: fine) {
    .solo-round-more:hover { background: var(--row-hover, rgba(127, 127, 127, 0.12)); color: var(--gsx-text); }
}
.solo-hidden-toggle {
    display: block; width: 100%; background: none; border: none; cursor: pointer;
    text-align: left; padding: var(--space-2-5) var(--space-1);
    font-size: 0.82rem; font-weight: 700; color: var(--gsx-text-muted);
}
.solo-sheet-actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.solo-hole-row {
    display: flex; align-items: center; gap: var(--space-3);
    padding: var(--space-1-5) 0; border-bottom: 1px solid var(--hairline-faint, var(--gsx-border));
}
.solo-hole-row:last-child { border-bottom: none; }
.solo-hole-num {
    flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
    background: var(--raise-2); display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.75rem; font-weight: 800; color: var(--gsx-text);
}
.solo-hole-row .text-muted { flex: 1; font-size: 0.82rem; }
.solo-hole-strokes { font-weight: 800; font-size: 1rem; color: var(--gsx-text); }
.solo-round-score-lg { font-size: 2rem; }

/* ── Grow-open hole stat sheet (expressive motion; stays above the fold) ── */
.solo-statsheet.growing {
    animation: qsGrowIn var(--motion-slow) var(--ease-decelerate) both;
    transform-origin: top center;
}
.solo-statsheet.closing {
    animation: qsGrowOut var(--motion-base) var(--ease-standard) both;
    transform-origin: top center;
}
@keyframes qsGrowIn {
    from { opacity: 0; transform: translateY(-10px) scaleY(0.9); }
    to { opacity: 1; transform: translateY(0) scaleY(1); }
}
@keyframes qsGrowOut {
    from { opacity: 1; transform: translateY(0) scaleY(1); }
    to { opacity: 0; transform: translateY(-10px) scaleY(0.9); }
}
/* Stagger the pads/steppers in as the sheet grows — the "over the top" reveal */
.solo-statsheet.growing .solo-stat-block,
.solo-statsheet.growing .solo-stat-pad {
    animation: qsPadRise var(--motion-slow) var(--ease-decelerate) both;
}
.solo-statsheet.growing .solo-stat-block:nth-child(1) { animation-delay: 40ms; }
.solo-statsheet.growing .solo-stat-pads .solo-stat-pad:nth-child(1) { animation-delay: 90ms; }
.solo-statsheet.growing .solo-stat-pads .solo-stat-pad:nth-child(2) { animation-delay: 140ms; }
.solo-statsheet.growing .solo-stat-block:last-child { animation-delay: 180ms; }
@keyframes qsPadRise {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: translateY(0); }
}
.solo-qs-row.stat-open {
    border-color: color-mix(in srgb, var(--gsx-brand) 40%, transparent);
    box-shadow: var(--shadow-md);
}

@media (prefers-reduced-motion: reduce) {
    .solo-statsheet.growing, .solo-statsheet.closing,
    .solo-statsheet.growing .solo-stat-block, .solo-statsheet.growing .solo-stat-pad,
    .solo-putt-num.bump, .solo-dir.pick-fx, .solo-dir.pick-fx::after, .solo-compass.gir-hit::after {
        animation: none !important;
    }
}

/* ── Board tab: Standings | Scorecard toggle ── */
.solo-board-toggle {
    display: flex; gap: var(--space-1); margin-bottom: var(--space-3);
    padding: var(--space-1); background: var(--gsx-surface-2);
    border: 1px solid var(--gsx-border); border-radius: var(--radius-xl);
}
.solo-board-opt {
    flex: 1; border: none; background: transparent; cursor: pointer;
    padding: var(--space-2) var(--space-2-5); border-radius: var(--radius-lg);
    font-size: 0.85rem; font-weight: 700; color: var(--gsx-text-muted);
}
.solo-board-opt.active { background: var(--gsx-surface); color: var(--brand-ink); box-shadow: var(--shadow-xs); }

/* ── Scorecard grid (holes × players, colored score boxes, OUT/IN/TOT) ── */
.solo-scgrid-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--gsx-border); border-radius: var(--radius-xl); }
.solo-scgrid { border-collapse: collapse; width: 100%; font-size: 0.78rem; }
.solo-scgrid th, .solo-scgrid td { padding: var(--space-1) var(--space-0-5); text-align: center; min-width: 26px; }
.solo-scgrid thead th { background: var(--raise-2); color: var(--gsx-text-muted); font-weight: 700; font-size: 0.7rem; }
.solo-scgrid .sc-name {
    position: sticky; left: 0; background: var(--gsx-surface); text-align: left;
    padding-left: var(--space-2-5); max-width: 92px; overflow: hidden;
    text-overflow: ellipsis; white-space: nowrap; font-weight: 700; z-index: 1;
}
.solo-scgrid thead .sc-name { background: var(--raise-2); }
.solo-scgrid .sc-parrow td { color: var(--gsx-text-muted); font-size: 0.72rem; }
.solo-scgrid .sc-sum { font-weight: 800; background: var(--raise-1); }
.solo-scgrid .sc-tot { background: color-mix(in srgb, var(--gsx-brand) 10%, transparent); }
.sc-box {
    display: inline-flex; align-items: center; justify-content: center;
    width: 22px; height: 22px; border-radius: var(--radius-sm); font-weight: 700;
}
.sc-box.sc-eagle { background: color-mix(in srgb, var(--gsx-brand) 85%, transparent); color: var(--gsx-on-brand); border-radius: 50%; }
.sc-box.sc-birdie { background: color-mix(in srgb, var(--gsx-brand) 30%, transparent); color: var(--gsx-text); border-radius: 50%; }
.sc-box.sc-par { color: var(--gsx-text); }
.sc-box.sc-bogey { box-shadow: inset 0 0 0 1.5px var(--gsx-border); }
.sc-box.sc-dbl { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--danger, #d33) 55%, transparent); color: var(--danger-ink, #c62828); }
.solo-scgrid-legend {
    display: flex; flex-wrap: wrap; gap: var(--space-3); font-size: 0.72rem;
    padding: var(--space-2) var(--space-1) 0;
}
.solo-scgrid-legend span { display: inline-flex; align-items: center; gap: var(--space-1); }
.solo-scgrid-legend .sc-box { width: 16px; height: 16px; }

/* ── "More stats" reveal + score distribution line ── */
.solo-morestats-toggle {
    display: block; width: 100%; background: none; border: none; cursor: pointer;
    padding: var(--space-2) 0 0; font-size: 0.8rem; font-weight: 700; color: var(--brand-ink);
    text-align: center;
}
.solo-dist { display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: center; font-size: 0.8rem; padding-top: var(--space-2); }

/* ═══════════════ WOW layer — tranche 1 (docs/VISUAL_WOW_ROADMAP.md) ═══════════════ */

/* The ONE dark hero per game screen: near-black card, area-colored energy bar,
   display-face title. Everything below it stays light (WHOOP pattern). */
.solo-game-hero {
    position: relative; overflow: hidden;
    background: var(--hero-wash);
    border: 1px solid var(--hero-border);
    border-radius: var(--radius-3xl);
    padding: var(--space-4) var(--space-5) var(--space-5);
    margin-bottom: var(--space-3);
    box-shadow: var(--shadow-hero);
}
.solo-game-hero::before {
    content: ''; position: absolute; inset: 0 0 auto 0; height: 4px;
    background: var(--gradient-accent);
}
.solo-game-hero-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-2); }
.solo-game-hero .solo-hero-exit { color: var(--on-hero-muted); }
@media (hover: hover) and (pointer: fine) {
    .solo-game-hero .solo-hero-exit:hover { color: var(--on-hero); }
}
.solo-hero-status {
    font-size: 0.64rem; font-weight: 800; letter-spacing: 0.14em;
    color: var(--on-hero-muted); padding: var(--space-0-5) var(--space-2);
    border: 1px solid var(--hero-border); border-radius: var(--radius-pill);
}
.solo-hero-status.is-live {
    color: var(--on-hero);
    background: color-mix(in srgb, var(--gsx-brand) 42%, transparent);
    border-color: transparent;
}
.solo-game-hero-title {
    margin: 0; font-family: var(--font-display);
    font-size: 2.1rem; font-weight: 700; line-height: 0.98;
    letter-spacing: 0.01em; text-transform: uppercase;
    color: var(--on-hero);
}
.solo-game-hero-meta { margin-top: var(--space-1-5); font-size: 0.82rem; color: var(--on-hero-muted); }

/* Hole hero on the score screen: the giant numeral moment (4-6x over body). */
.solo-hole-hero {
    display: flex; align-items: baseline; justify-content: center; gap: var(--space-2-5);
    margin-top: var(--space-2);
}
.solo-hole-hero-label {
    font-size: 0.72rem; font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase;
    color: var(--gsx-text-muted);
}
.solo-hole-hero-num {
    font-family: var(--font-display); font-weight: 700;
    font-size: 3.4rem; line-height: 0.9; letter-spacing: -0.02em;
    color: var(--gsx-text); font-variant-numeric: tabular-nums;
}
.solo-hole-hero-par {
    font-size: 0.78rem; font-weight: 800; padding: var(--space-0-5) var(--space-2);
    border-radius: var(--radius-pill);
    background: color-mix(in srgb, var(--gsx-brand) 14%, transparent);
    color: var(--brand-ink);
}

/* Score values: bigger, display face, tabular, broadcast color grammar. */
.solo-qs-val {
    font-family: var(--font-display); font-size: 1.55rem !important;
    font-variant-numeric: tabular-nums; min-width: 34px; text-align: center;
}
.solo-qs-val.is-under { color: var(--score-under); }
.solo-qs-val.is-par { color: var(--gsx-text); }
.solo-qs-val.is-over { color: var(--gsx-text-muted); }

/* Leaderboard podium rails: 1-2-3 get metal rails + the leader floats. */
.solo-podium td { font-weight: 700; }
.solo-podium { position: relative; }
.solo-podium td:first-child { border-left: 4px solid transparent; }
.solo-podium-1 td:first-child { border-left-color: var(--podium-gold); }
.solo-podium-2 td:first-child { border-left-color: var(--podium-silver); }
.solo-podium-3 td:first-child { border-left-color: var(--podium-bronze); }
.solo-podium-1 { background: color-mix(in srgb, var(--podium-gold) 10%, transparent); }
.solo-podium-1 td { font-size: 1.02rem; font-weight: 800; }

/* Home CTA: area-gradient energy + real press state. */
.solo-cta {
    background: var(--gradient-accent);
    box-shadow: var(--shadow-float);
    transition: transform var(--motion-instant) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard);
}
.solo-cta:active { transform: scale(0.97) translateY(1px); box-shadow: var(--shadow-xs); }

/* Press tactility on the quick-action pills + interactive cards. */
.solo-quick { transition: transform var(--motion-instant) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard); }
.solo-quick:active { transform: scale(0.96) translateY(1px); }
.solo-card-tap { transition: transform var(--motion-instant) var(--ease-standard), box-shadow var(--motion-fast) var(--ease-standard); }
@media (hover: hover) and (pointer: fine) {
    .solo-card-tap:hover { box-shadow: var(--shadow-float); }
}
.solo-card-tap:active { transform: scale(0.99); }

/* Tabular numerals wherever numbers change or align (single biggest fix). */
.solo-scgrid, .solo-qs-val, .solo-round-score, .solo-stat-val, .gsx-kpi-value,
.gsx-table td { font-variant-numeric: tabular-nums; }

/* Stat tiles: the numbers get the display face + a real size jump. */
.solo-stat-val { font-family: var(--font-display); font-size: 1.9rem; font-weight: 700; line-height: 1; }

/* ── GPS-style course picker (create wizard) ── */
.solo-nearme-btn {
    display: inline-flex; align-items: center; gap: var(--space-1-5);
    margin-top: var(--space-2); padding: var(--space-1-5) var(--space-3);
    border: 1px solid color-mix(in srgb, var(--gsx-brand) 30%, transparent);
    border-radius: var(--radius-pill); background: color-mix(in srgb, var(--gsx-brand) 10%, transparent);
    color: var(--brand-ink); font-size: 0.82rem; font-weight: 700; cursor: pointer;
    transition: transform var(--motion-instant) var(--ease-standard);
}
.solo-nearme-btn:active { transform: scale(0.96); }
.solo-nearme-btn.is-locating { opacity: 0.6; }
.solo-nearme-btn.is-locating svg { animation: nearmePulse 0.9s var(--ease-standard) infinite alternate; }
@keyframes nearmePulse { from { transform: scale(0.85); } to { transform: scale(1.15); } }
.solo-course-box {
    border: 1px solid var(--gsx-border); border-radius: var(--radius-xl);
    overflow: hidden; margin-top: var(--space-2); box-shadow: var(--shadow-float);
    background: var(--gsx-surface);
}
.solo-course-row {
    display: flex; align-items: center; gap: var(--space-2-5); width: 100%;
    padding: var(--space-2-5) var(--space-3); cursor: pointer; text-align: left;
    background: none; border: none; border-bottom: 1px solid var(--hairline-faint, var(--gsx-border));
}
.solo-course-row:last-child { border-bottom: none; }
.solo-course-row:active { background: var(--row-hover, rgba(127, 127, 127, 0.10)); }
.solo-course-pin {
    flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--gsx-brand) 14%, transparent);
    color: var(--brand-ink);
}
.solo-course-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.solo-course-name { font-weight: 700; font-size: 0.9rem; color: var(--gsx-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.solo-course-loc { font-size: 0.76rem; color: var(--gsx-text-muted); }
.solo-course-dist {
    flex: 0 0 auto; font-family: var(--font-display); font-weight: 700; font-size: 0.88rem;
    color: var(--brand-ink); font-variant-numeric: tabular-nums;
}

/* ── WOW iteration 2 (user testing feedback) ── */

/* Hole hero: number anchors LEFT, par + yardage RIGHT (yardage slot shows a
   placeholder when the course is mapped but distances haven't backfilled —
   the header is pre-structured for the GPS/maps upgrade). */
.solo-hole-hero {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--space-3); margin-top: var(--space-2);
    padding: var(--space-2) var(--space-1);
}
.solo-hole-hero-left { display: flex; align-items: baseline; gap: var(--space-2); }
.solo-hole-hero-right { display: flex; align-items: center; gap: var(--space-2); }
.solo-hole-hero-yds {
    font-family: var(--font-display); font-weight: 700; font-size: 1.35rem;
    color: var(--gsx-text); font-variant-numeric: tabular-nums;
}
.solo-hole-hero-yds small {
    font-size: 0.66rem; font-weight: 800; letter-spacing: 0.08em;
    color: var(--gsx-text-muted); margin-left: 2px; text-transform: uppercase;
}
.solo-hole-hero-yds.is-empty { color: var(--gsx-text-muted); opacity: 0.55; }

/* Player-row identity: initials chip makes rows feel like people, not text. */
.solo-qs-ava {
    flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 0.68rem; font-weight: 800; letter-spacing: 0.02em;
    background: color-mix(in srgb, var(--gsx-brand) 16%, transparent);
    color: var(--brand-ink); margin-right: var(--space-2);
}

/* Save hole floats FIXED above the bottom nav — sticky couldn't work because
   the button is the last element in its card (nothing to stick against). The
   .solo-save-spacer keeps its slot in the card so content never hides. */
.solo-save-pinned {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    width: min(100% - (var(--space-4) * 2), 488px);
    bottom: calc(var(--footer-h) + env(safe-area-inset-bottom, 0px) + var(--space-2-5));  /* TASK-BA: shell height from the token, not a magic 64 */
    z-index: 900;   /* below the bottom nav (950), above content */
    box-shadow: var(--shadow-float);
}
.solo-save-pinned:active { transform: translateX(-50%) scale(0.98); }
.solo-save-spacer { height: 56px; }
@media (min-width: 769px) {
    .solo-save-pinned { bottom: var(--space-4); }   /* no bottom nav on desktop */
}

/* Stat tiles are buttons now: zoomable affordance + press state. */
.solo-stat { border: none; background: none; font: inherit; text-align: center; cursor: default; }
.solo-stat.is-zoomable { cursor: pointer; border-radius: var(--radius-xl); transition: transform var(--motion-instant) var(--ease-standard), background var(--motion-fast) var(--ease-standard); }
.solo-stat.is-zoomable:active { transform: scale(0.94); background: color-mix(in srgb, var(--gsx-brand) 8%, transparent); }

/* The zoom modal: content scales up from center with a springy pop. */
.solo-zoom-wrap {
    text-align: center; padding: var(--space-3) var(--space-2) var(--space-2);
    animation: statZoomIn var(--motion-slow) var(--ease-spring) both;
    transform-origin: center 40%;
}
@keyframes statZoomIn {
    from { opacity: 0; transform: scale(0.62); }
    to { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .solo-zoom-wrap { animation: none; } }
.solo-zoom-label {
    font-size: 0.74rem; font-weight: 800; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--gsx-text-muted);
}
.solo-zoom-num {
    font-family: var(--font-display); font-weight: 700;
    font-size: 4.6rem; line-height: 1; letter-spacing: -0.02em;
    color: var(--brand-ink); font-variant-numeric: tabular-nums;
    margin: var(--space-2) 0;
}
.solo-zoom-blurb { font-size: 0.88rem; max-width: 300px; margin: 0 auto var(--space-3); }
.solo-zoom-rel { display: flex; justify-content: center; gap: var(--space-4); flex-wrap: wrap; }
.solo-zoom-rel-item { font-size: 0.82rem; color: var(--gsx-text-muted); }
.solo-zoom-rel-item b {
    font-family: var(--font-display); font-size: 1.15rem; color: var(--gsx-text);
    margin-right: var(--space-1); font-variant-numeric: tabular-nums;
}

/* ── Identity strip (casual home): avatar + name + tappable mini stats ── */
.solo-id-strip {
    display: flex; align-items: center; gap: var(--space-2-5);
    margin-bottom: var(--space-3);
}
.solo-id-ava {
    flex: 0 0 auto; width: 46px; height: 46px; border-radius: 50%;
    object-fit: cover; box-shadow: var(--shadow-float);
    border: 2px solid color-mix(in srgb, var(--gsx-brand) 40%, transparent);
}
.solo-id-ava.is-initials {
    display: inline-flex; align-items: center; justify-content: center;
    font-family: var(--font-display); font-size: 1.05rem; font-weight: 700;
    background: var(--gradient-accent); color: var(--gsx-on-brand);
    border: none;
}
/* role="button" and it literally says "tap for stats", so it owes the same
   44px minimum as every other tappable control (see 15-touch-targets.css). It
   is a stacked two-line block, so real height is right here — an overlay would
   reach across the avatar and the stats chips beside it. */
.solo-id-main { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; min-height: 44px; }
.solo-id-name {
    font-family: var(--font-display); font-size: 1.35rem; font-weight: 700;
    line-height: 1.05; color: var(--gsx-text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.solo-id-sub { font-size: 0.68rem; font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; }
.solo-id-stats { display: flex; gap: var(--space-1-5); flex: 0 0 auto; }
.solo-id-chip {
    display: inline-flex; flex-direction: column; align-items: center;
    border: 1px solid var(--gsx-border); background: var(--gsx-surface);
    border-radius: var(--radius-xl); padding: var(--space-1) var(--space-2);
    cursor: pointer; font-size: 0.6rem; font-weight: 700; text-transform: uppercase;
    letter-spacing: 0.05em; color: var(--gsx-text-muted);
    transition: transform var(--motion-instant) var(--ease-standard);
}
.solo-id-chip:active { transform: scale(0.92); }
.solo-id-chip b {
    font-family: var(--font-display); font-size: 1rem; font-weight: 700;
    color: var(--gsx-text); font-variant-numeric: tabular-nums;
}

/* ── Page-enter transition (native-app content swap) ── */
.solo-page-enter { animation: soloPageIn var(--motion-slow) var(--ease-decelerate) both; }
@keyframes soloPageIn {
    from { opacity: 0; transform: translateY(10px) scale(0.985); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .solo-page-enter { animation: none; } }

/* ── Friends hub + chat ── */
.fr-row { display: flex; align-items: center; gap: var(--space-2); }
.fr-ava {
    flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
    object-fit: cover;
}
.fr-ava-initials {
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--gradient-accent); color: var(--gsx-on-brand);
    font-weight: 700; font-size: 0.9rem;
}
.fr-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fr-actions { display: flex; gap: var(--space-1-5); flex: 0 0 auto; }
.fr-msg-btn { position: relative; }
.fr-badge {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 17px; height: 17px; padding: 0 4px; margin-left: var(--space-1);
    border-radius: var(--radius-full); background: var(--gsx-danger, #e5484d);
    color: var(--on-scrim); font-size: 0.62rem; font-weight: 800;
    font-variant-numeric: tabular-nums;
}
.fr-chat-thread {
    display: flex; flex-direction: column; gap: var(--space-1-5);
    max-height: 46vh; min-height: 120px; overflow-y: auto;
    padding: var(--space-2) var(--space-1);
}
.fr-bubble {
    max-width: 82%; padding: var(--space-2) var(--space-2-5);
    border-radius: var(--radius-xl); font-size: 0.9rem; line-height: 1.35;
    overflow-wrap: break-word;
}
.fr-mine {
    align-self: flex-end; background: var(--gsx-brand); color: var(--gsx-on-brand);
    border-bottom-right-radius: var(--radius-xs);
}
.fr-theirs {
    align-self: flex-start; background: var(--gsx-surface-sunken, var(--gsx-surface));
    border: 1px solid var(--gsx-border);
    border-bottom-left-radius: var(--radius-xs);
}

/* Quick-action badge (Friends: pending requests + unread DMs) */
.solo-quick { position: relative; }
.solo-quick-badge {
    position: absolute; top: 4px; right: 10px;
    min-width: 17px; height: 17px; padding: 0 4px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--radius-full); background: var(--gsx-danger, #e5484d);
    color: var(--on-scrim); font-size: 0.62rem; font-weight: 800;
    font-variant-numeric: tabular-nums;
    box-shadow: var(--shadow-float);
}

/* ── Round recap overlay ("your round in 20 seconds") ── */
.rc-overlay {
    position: fixed; inset: 0; z-index: 11000;
    background: linear-gradient(180deg, var(--surface-hero) 0%, var(--surface-hero-2) 100%);
    color: var(--on-scrim);
    display: flex; flex-direction: column; align-items: center;
    opacity: 0; transition: opacity var(--motion-slow) var(--ease-standard);
}
.rc-overlay.open { opacity: 1; }
.rc-close {
    position: absolute; top: calc(env(safe-area-inset-top, 0px) + 10px); right: 14px;
    width: 40px; height: 40px; border-radius: 50%;
    border: 1px solid color-mix(in srgb, var(--on-scrim) 25%, transparent);
    background: transparent; color: var(--on-scrim);
    font-size: 1.4rem; line-height: 1; cursor: pointer; z-index: 2;
}
.rc-progress {
    display: flex; gap: var(--space-1); width: min(92%, 480px);
    margin-top: calc(env(safe-area-inset-top, 0px) + var(--space-4));
}
.rc-tick {
    flex: 1; height: 3px; border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--on-scrim) 20%, transparent);
    transition: background var(--motion-fast);
}
.rc-tick.done { background: var(--on-scrim); }
.rc-tick.live { background: var(--gsx-brand); }
.rc-stage {
    flex: 1; width: min(92%, 480px);
    display: flex; align-items: center; justify-content: center;
    text-align: center; cursor: pointer;
}
.rc-slide {
    opacity: 0; transform: translateY(16px) scale(0.98);
    transition: opacity var(--motion-slow) var(--ease-decelerate),
                transform var(--motion-slow) var(--ease-decelerate);
    width: 100%;
}
.rc-slide.in { opacity: 1; transform: translateY(0) scale(1); }
.rc-kicker {
    font-size: 0.72rem; font-weight: 800; letter-spacing: 0.18em;
    text-transform: uppercase; color: color-mix(in srgb, var(--on-scrim) 55%, transparent);
    margin-bottom: var(--space-3);
}
.rc-num {
    font-family: var(--font-display); font-size: 7.5rem; font-weight: 700;
    line-height: 0.95; font-variant-numeric: tabular-nums;
}
.rc-big {
    font-family: var(--font-display); font-size: 2.6rem; font-weight: 700;
    line-height: 1.05;
}
.rc-hole-num {
    font-family: var(--font-display); font-size: 5rem; font-weight: 700;
    line-height: 1; color: color-mix(in srgb, var(--on-scrim) 85%, transparent);
}
.rc-under { color: var(--score-under); }
.rc-sub { margin-top: var(--space-2-5); font-size: 0.95rem; color: color-mix(in srgb, var(--on-scrim) 70%, transparent); }
.rc-dim { opacity: 0.55; font-style: italic; }
.rc-dist { display: flex; justify-content: center; gap: var(--space-4); }
.rc-dist-item { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); }
.rc-dist-ico { font-size: 1.3rem; }
.rc-dist-n { font-family: var(--font-display); font-size: 2.2rem; font-weight: 700; }
.rc-dist-l { font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.08em; color: color-mix(in srgb, var(--on-scrim) 55%, transparent); }
.rc-badge-medal {
    width: 84px; height: 84px; margin: 0 auto var(--space-3); border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 2.4rem; background: var(--gradient-accent); color: var(--gsx-on-brand);
    box-shadow: var(--shadow-float);
}
.rc-hint {
    padding-bottom: calc(env(safe-area-inset-bottom, 0px) + var(--space-4));
    font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
    color: color-mix(in srgb, var(--on-scrim) 40%, transparent);
}
.rc-share-canvas {
    width: min(78vw, 300px); height: auto; border-radius: var(--radius-2xl);
    box-shadow: var(--shadow-float); margin: 0 auto;
}
.rc-share-actions { display: flex; gap: var(--space-2); justify-content: center; margin-top: var(--space-3); }
.rc-hr { border: none; border-top: 1px solid color-mix(in srgb, var(--on-scrim) 15%, transparent); margin: var(--space-4) 0; }

/* ── Badges rail (Stats tab) ── */
/* TASK-AA AA3: badges are a browsable set that will grow past five — a column
   count can never be right. ONE row, horizontal scroll with snap, clipped at
   the container edge so a partial next badge says "there is more". overflow-x
   lives on the RAIL only; the page never scrolls sideways. */
.bdg-rail {
    display: flex;
    flex-wrap: nowrap;
    justify-content: flex-start;
    gap: var(--space-2) var(--space-3);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    padding-bottom: var(--space-1);
}
.bdg { scroll-snap-align: start; }
.bdg {
    flex: 0 0 auto; width: 84px; display: flex; flex-direction: column;
    align-items: center; gap: var(--space-1); text-align: center;
}
.bdg-medal {
    width: 52px; height: 52px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; font-size: 1.4rem;
}
.bdg.earned .bdg-medal {
    background: var(--gradient-accent); color: var(--gsx-on-brand);
    box-shadow: var(--shadow-float);
}
.bdg.locked .bdg-medal {
    background: var(--gsx-surface-sunken, var(--gsx-surface));
    border: 1px dashed var(--gsx-border); color: var(--gsx-text-muted);
    opacity: 0.55;
}
.bdg-label { font-size: 0.62rem; font-weight: 700; line-height: 1.15; color: var(--gsx-text-muted); }
.bdg.earned .bdg-label { color: var(--gsx-text); }

/* ── Course insights (board view) ── */
.ci-grid { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.ci-item {
    flex: 1 1 28%; min-width: 90px; text-align: center;
    border: 1px solid var(--gsx-border); border-radius: var(--radius-xl);
    padding: var(--space-2) var(--space-1);
    display: flex; flex-direction: column; gap: 2px;
}
.ci-item b {
    font-family: var(--font-display); font-size: 1.35rem; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.ci-item span { font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--gsx-text-muted); }
.ci-item.ci-good b { color: var(--score-under); }

/* Rivalry chip on friend rows */
.fr-rival {
    font-size: 0.66rem; font-weight: 800; letter-spacing: 0.03em;
    padding: 2px 7px; border-radius: var(--radius-full);
    border: 1px solid var(--gsx-border); color: var(--gsx-text-muted);
    font-variant-numeric: tabular-nums; white-space: nowrap;
}
.fr-rival.leading { border-color: var(--gsx-brand); color: var(--gsx-brand); }

/* Reduced-motion recap digest: everything at once must be scrollable. */
.rc-stage.digest {
    overflow-y: auto;
    align-items: flex-start;
    padding: var(--space-4) 0;
    overscroll-behavior: contain;
    cursor: default;
}

/* Recap CTA subtitle — plain-language "what this is" for new players */
.solo-recap-hint { font-weight: 500; font-size: 0.8em; opacity: 0.85; }

/* ── Badges page ── */
.bdg-card { cursor: pointer; }
.bdg-card:active { transform: scale(0.995); }
.bdg-progress {
    display: flex; align-items: center; gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-2xl);
    background: linear-gradient(180deg, var(--surface-hero) 0%, var(--surface-hero-2) 100%);
    color: var(--on-scrim);
    box-shadow: var(--shadow-hero);
}
.bdg-progress-num {
    font-family: var(--font-display); font-size: 2.4rem; font-weight: 700;
    font-variant-numeric: tabular-nums; line-height: 1;
}
.bdg-progress-of { font-size: 0.8rem; color: color-mix(in srgb, var(--on-scrim) 65%, transparent); }
.bdg-progress-bar {
    flex: 1; height: 6px; border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--on-scrim) 18%, transparent);
    overflow: hidden;
}
.bdg-progress-fill { display: block; height: 100%; background: var(--gradient-accent); border-radius: var(--radius-full); }
.bdg-grid {
    display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
    gap: var(--space-3) var(--space-2);
}
.bdg-lg { width: auto; }
.bdg-blurb { font-size: 0.6rem; color: var(--gsx-text-muted); line-height: 1.25; }
.bdg-date { font-size: 0.58rem; color: var(--gsx-brand); font-weight: 700; font-variant-numeric: tabular-nums; }

/* ── Full-screen stat modal (Mileseey-style: one player, one hole) ── */
.solo-statmodal {
    position: fixed; inset: 0; z-index: 10500;
    display: flex; align-items: flex-end; justify-content: center;
    background: color-mix(in srgb, var(--surface-hero) 55%, transparent);
    opacity: 0; transition: opacity var(--motion-base) var(--ease-standard);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.solo-statmodal.open { opacity: 1; }
.solo-statmodal-panel {
    width: 100%; max-width: 560px;
    max-height: 94vh; overflow-y: auto;
    background: var(--gsx-surface);
    border-radius: var(--radius-3xl) var(--radius-3xl) 0 0;
    padding: var(--space-3) var(--space-4) calc(env(safe-area-inset-bottom, 0px) + var(--space-4));
    box-shadow: var(--shadow-float);
    /* the "expand" — rise + scale up from slightly small */
    transform: translateY(24px) scale(0.96); transform-origin: bottom center;
    opacity: 0;
    transition: transform var(--motion-slow) var(--ease-decelerate), opacity var(--motion-base);
}
/* Premium entrance: the panel springs up with a slight overshoot, then the
   controls cascade in behind it — reads as "expand", not just "appear". */
.solo-statmodal.open .solo-statmodal-panel {
    animation: statModalIn 540ms cubic-bezier(0.16, 1.1, 0.3, 1) both;
}
@keyframes statModalIn {
    0%   { transform: translateY(52px) scale(0.90); opacity: 0; }
    55%  { transform: translateY(-9px) scale(1.015); opacity: 1; }
    78%  { transform: translateY(3px) scale(0.997); }
    100% { transform: translateY(0) scale(1); opacity: 1; }
}
.solo-statmodal.open .solo-statmodal-holenav { animation: smRise 460ms var(--ease-decelerate) both 90ms; }
.solo-statmodal.open .solo-statmodal-name    { animation: smRise 460ms var(--ease-decelerate) both 140ms; }
.solo-statmodal.open .solo-score-block       { animation: smRise 460ms var(--ease-decelerate) both 200ms; }
.solo-statmodal.open .solo-statsheet > .solo-stat-block:first-child { animation: smRise 460ms var(--ease-decelerate) both 250ms; }
.solo-statmodal.open .solo-stat-pads         { animation: smRise 460ms var(--ease-decelerate) both 300ms; }
.solo-statmodal.open .solo-statsheet > .solo-stat-block:last-child  { animation: smRise 460ms var(--ease-decelerate) both 350ms; }
.solo-statmodal.open .solo-statmodal-save    { animation: smRise 460ms var(--ease-decelerate) both 400ms; }
/* the hole numeral gives a confident little pop on open */
.solo-statmodal.open .solo-statmodal-holenum { animation: smHolePop 620ms var(--ease-decelerate) both 120ms; }
@keyframes smRise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
@keyframes smHolePop { 0% { transform: scale(0.7); opacity: 0; } 55% { transform: scale(1.12); opacity: 1; } 100% { transform: scale(1); } }
@media (min-width: 600px) {
    .solo-statmodal { align-items: center; }
    .solo-statmodal-panel { border-radius: var(--radius-3xl); max-height: 90vh; }
}
.solo-statmodal-x {
    position: absolute; top: var(--space-3); right: var(--space-3);
    width: 36px; height: 36px; border-radius: 50%;
    border: 1px solid var(--gsx-border); background: var(--gsx-surface);
    color: var(--gsx-text-muted); font-size: 1.4rem; line-height: 1; cursor: pointer; z-index: 2;
}
.solo-statmodal-holenav {
    display: flex; align-items: center; justify-content: center; gap: var(--space-3);
    margin-top: var(--space-1);
}
.solo-hnav {
    width: 52px; height: 52px; border-radius: 50%;
    border: 1px solid var(--gsx-border); background: var(--gsx-surface); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    color: var(--gsx-brand);
    animation: soloHnavFade 2.6s ease-in-out infinite;
}
.solo-hnav svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.solo-hnav:active { transform: scale(0.9); }
/* the "fading" left/right arrows — a subtle breathing hint they're tappable
   (rests fully visible, dips gently — not a janky flash) */
@keyframes soloHnavFade { 0%, 100% { opacity: 1; } 50% { opacity: 0.62; } }
.solo-statmodal-hole { text-align: center; min-width: 120px; }
.solo-statmodal-holenum {
    display: block; font-family: var(--font-display); font-size: 1.9rem; font-weight: 700;
    line-height: 1; color: var(--gsx-text);
}
.solo-statmodal-holesub { display: block; font-size: 0.78rem; color: var(--gsx-text-muted); margin-top: 2px; }
.solo-statmodal-name {
    text-align: center; font-weight: 700; font-size: 1.05rem; color: var(--gsx-text);
    margin: var(--space-1) 0 var(--space-3);
}
.solo-statmodal-body { display: flex; flex-direction: column; gap: var(--space-3); }
.solo-statmodal-body .solo-statsheet {
    margin: 0; background: transparent; border: none; padding: 0; gap: var(--space-3);
}
.solo-score-num {
    font-family: var(--font-display); font-size: 2.8rem; font-weight: 700;
    font-variant-numeric: tabular-nums; min-width: 2ch; text-align: center;
}
/* Save pinned to the bottom of the sheet — always reachable while the stat
   controls scroll UNDER it (the surface-coloured top shadow fades them out
   cleanly before they reach the button). */
.solo-statmodal-save {
    position: sticky; bottom: 0; z-index: 3;
    width: 100%; margin-top: var(--space-4);
    box-shadow:
        0 -10px 14px -2px var(--gsx-surface),
        0 -22px 14px -12px var(--gsx-surface);
}

/* hole cross-fade / slide on prev-next nav */
.solo-statmodal-body.slide-l { animation: soloSlideL var(--motion-slow) var(--ease-decelerate); }
.solo-statmodal-body.slide-r { animation: soloSlideR var(--motion-slow) var(--ease-decelerate); }
@keyframes soloSlideL { from { opacity: 0; transform: translateX(22px); } to { opacity: 1; transform: translateX(0); } }
@keyframes soloSlideR { from { opacity: 0; transform: translateX(-22px); } to { opacity: 1; transform: translateX(0); } }

@media (prefers-reduced-motion: reduce) {
    .solo-statmodal, .solo-statmodal-panel { transition: none; }
    .solo-statmodal.open .solo-statmodal-panel { animation: none; transform: none; opacity: 1; }
    .solo-hnav, .solo-statmodal-body.slide-l, .solo-statmodal-body.slide-r,
    .solo-statmodal.open .solo-statmodal-holenav, .solo-statmodal.open .solo-statmodal-name,
    .solo-statmodal.open .solo-score-block, .solo-statmodal.open .solo-stat-pads,
    .solo-statmodal.open .solo-statsheet > .solo-stat-block,
    .solo-statmodal.open .solo-statmodal-save, .solo-statmodal.open .solo-statmodal-holenum {
        animation: none;
    }
}

/* ══ Stats dashboard (charts) ══ */
.solo-dash { display: flex; flex-direction: column; gap: var(--space-3); margin: var(--space-3) 0 var(--space-1); }
.solo-dash-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); }
@media (max-width: 560px) {
    /* Phones: stack Score-mix over Accuracy so the 3 accuracy rings get full
       width instead of overflowing a cramped half-column. */
    .solo-dash-row { grid-template-columns: 1fr; }
}
.solo-dash-card {
    background: var(--gsx-surface); border: 1px solid var(--gsx-border);
    border-radius: var(--radius-2xl); padding: var(--space-3);
}
.solo-dash-h {
    font-size: 0.68rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.08em;
    color: var(--gsx-text-muted); margin-bottom: var(--space-2);
}
.solo-dash-h .text-muted { font-weight: 600; letter-spacing: 0.02em; text-transform: none; }

/* Score-mix donut — SVG circle strokes (motion spec): stroke segments with 2px
   surface gaps, swept in sequence via stroke-dasharray; hover thickens a
   segment 14→18 and shows a count+percent tooltip. The old conic-gradient +
   mask-composite reveal is gone (this animates everywhere, no feature gate). */
.solo-donut-wrap { display: flex; align-items: center; gap: var(--space-3); position: relative; }
.solo-donut {
    flex: 0 0 auto; position: relative; width: 92px; height: 92px;
    display: flex; align-items: center; justify-content: center;
}
.solo-donut-svg { position: absolute; inset: 0; transform: rotate(-90deg); overflow: visible; }
.solo-donut-seg {
    fill: none; stroke-width: 14; cursor: pointer;
    transition: stroke-width var(--m-fast) var(--e-out);
}
@media (hover: hover) and (pointer: fine) {
    .solo-donut-seg:hover { stroke-width: 18; }
}
.solo-donut-hole {
    position: relative; display: flex; flex-direction: column; align-items: center; line-height: 1;
    font-size: 0.56rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--gsx-text-muted);
    pointer-events: none;
}
.solo-donut-hole b { font-family: var(--font-display); font-size: 1.4rem; color: var(--gsx-text); font-variant-numeric: tabular-nums; }
.solo-legend { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.solo-legend-item { display: flex; align-items: center; gap: var(--space-1-5); font-size: 0.72rem; color: var(--gsx-text); font-variant-numeric: tabular-nums; }
.solo-legend-dot { width: 9px; height: 9px; border-radius: 3px; flex: 0 0 auto; }
.solo-legend-n { font-weight: 700; }

/* Shared chart tooltip (trend crosshair tip + donut segment tip). */
.gsx-tip {
    position: absolute; z-index: 5; pointer-events: none;
    transform: translate(-50%, -130%);
    background: var(--gsx-text); color: var(--gsx-bg);
    font-size: 0.72rem; font-weight: 600; padding: 3px 8px;
    border-radius: var(--radius-md); white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.gsx-tip[hidden] { display: none; }

/* Accuracy rings */
.solo-rings { display: flex; justify-content: space-around; gap: var(--space-1); }
.solo-ring { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); }
/* Ring fill angle as an @property so the conic-gradient can animate (fill-sweep).
   Falls back gracefully: unsupported engines just show the final fill. */
@property --rdeg { syntax: '<angle>'; initial-value: 0deg; inherits: false; }
.solo-ring-dial {
    width: 62px; height: 62px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    --rdeg: var(--rfill, 0deg);
    background: conic-gradient(var(--rcolor, var(--chart-birdie)) var(--rdeg), var(--chart-track) 0);
    -webkit-mask: radial-gradient(circle 21px at center, transparent 98%, var(--gsx-text) 100%);
            mask: radial-gradient(circle 21px at center, transparent 98%, var(--gsx-text) 100%);
}
.solo-ring-val {
    font-family: var(--font-display); font-weight: 700; font-size: 0.92rem; color: var(--gsx-text);
    font-variant-numeric: tabular-nums; -webkit-mask: none; mask: none;
}
.solo-ring-label { font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--gsx-text-muted); }

/* Par-average bars */
.solo-bars { display: flex; align-items: flex-end; justify-content: space-around; gap: var(--space-3); height: 120px; padding-top: var(--space-2); }
.solo-bar-col { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); flex: 1; height: 100%; justify-content: flex-end; }
.solo-bar-val { font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; color: var(--gsx-text); font-variant-numeric: tabular-nums; }
.solo-bar-track { position: relative; width: 60%; max-width: 44px; flex: 1; display: flex; align-items: flex-end; background: var(--chart-track); border-radius: var(--radius-md); overflow: hidden; }
/* Bars grow via scaleY (entrance keyframe) — never animate height (spec §2). */
.solo-bar-fill { width: 100%; border-radius: var(--radius-md) var(--radius-md) 0 0; }
/* Dashed par tick inside each bar: over-par distance reads instantly. */
.solo-bar-tick {
    position: absolute; left: 2px; right: 2px; z-index: 1; pointer-events: none;
    border-top: 2px dashed color-mix(in srgb, var(--gsx-text) 45%, transparent);
    opacity: 0.7;
}
.solo-bar-fill.is-under { background: var(--chart-birdie); }
.solo-bar-fill.is-par { background: var(--chart-par); }
.solo-bar-fill.is-over { background: var(--chart-bogey); }
.solo-bar-label { font-size: 0.62rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--gsx-text-muted); }

/* Scoring trend line */
.solo-trend-wrap { position: relative; }
.solo-trend { width: 100%; height: 92px; display: block; overflow: visible; }
/* Hover crosshair (JS snaps it to the nearest round) + one-shot endpoint ring
   (opacity 0 at rest — it only flashes once after the draw-in, never pulses). */
.solo-trend-cross {
    stroke: var(--gsx-text-muted); stroke-width: 1; stroke-dasharray: 3 3;
    opacity: 0; vector-effect: non-scaling-stroke; pointer-events: none;
    transition: opacity var(--m-fast);
}
.solo-trend-ring {
    fill: none; stroke: var(--gsx-brand); stroke-width: 2; opacity: 0;
    vector-effect: non-scaling-stroke; pointer-events: none; transform: scale(0.4);
}
.solo-trend-area { fill: color-mix(in srgb, var(--gsx-brand) 12%, transparent); stroke: none; }
.solo-trend-line { fill: none; stroke: var(--gsx-brand); stroke-width: 2.4; stroke-linejoin: round; stroke-linecap: round;
    vector-effect: non-scaling-stroke; }
.solo-trend-base { stroke: var(--gsx-border); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.solo-trend-dot { fill: var(--gsx-surface); stroke: var(--gsx-brand); stroke-width: 2; vector-effect: non-scaling-stroke; }
.solo-trend-dot.is-under { fill: var(--score-under); stroke: var(--score-under); }
.solo-trend-meta { display: flex; justify-content: space-between; font-size: 0.64rem; margin-top: var(--space-1); font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) { .solo-bar-fill { transition: none; } }

/* ── Graduate → Casual welcome moment (soloMaybeGradWelcome) ── */
.grad-welcome { text-align: center; padding: var(--space-2) var(--space-1); }
.grad-welcome-cap { font-size: 3.5rem; line-height: 1; margin-bottom: var(--space-2); }
.grad-welcome-eyebrow {
    font-size: 0.8rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: 0.08em; color: var(--brand-ink); margin-bottom: var(--space-2);
}
.grad-welcome-title {
    font-family: var(--font-display); font-size: 1.9rem; line-height: 1.08;
    margin: 0 0 var(--space-3); color: var(--gsx-text);
}
.grad-welcome-text {
    font-size: 0.95rem; line-height: 1.55; color: var(--gsx-text-muted);
    margin: 0 auto var(--space-4); max-width: 30rem;
}
.grad-welcome-stats { display: flex; justify-content: center; gap: var(--space-3); margin-bottom: var(--space-5); }
.grad-welcome-stat {
    background: var(--gsx-surface-2); border-radius: var(--gsx-radius-md);
    padding: var(--space-3) var(--space-4); min-width: 4.5rem;
}
.grad-welcome-stat-val {
    font-family: var(--font-display); font-size: 1.7rem; font-weight: 800;
    color: var(--brand-ink); line-height: 1; font-variant-numeric: tabular-nums;
}
.grad-welcome-stat-label {
    font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em;
    color: var(--gsx-text-muted); margin-top: var(--space-1);
}

/* ── Host event page — tournament-grade stat strip (Option A reskin) ──
   Gives the Host event hero the School dashboard's stat-card feel; data-area=
   "tournament" already themes the accent. All token-based. */
.solo-event-hero .solo-event-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-2);
}
.solo-event-stat {
    background: var(--raise-2, var(--card-bg));
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-3);
    text-align: center;
}
.solo-event-stat-v {
    font-family: var(--font-display, inherit);
    font-size: 1.5rem; font-weight: 700; line-height: 1.1;
    color: var(--text-primary);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.solo-event-stat-course { font-size: 1rem; }
.solo-event-stat-l {
    margin-top: var(--space-1); font-size: 0.7rem; font-weight: 700;
    text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted);
}

/* ── Caddie / manual rangefinder (GPS Phase 0) ── */
.rf, .rf-empty { text-align: center; padding: var(--space-2) var(--space-1); }
.rf-title { font-family: var(--font-display); font-size: 1.7rem; margin: 0 0 var(--space-1); color: var(--gsx-text); }
.rf-sub { font-size: 0.9rem; color: var(--gsx-text-muted); margin: 0 0 var(--space-5); }
.rf-input-row { display: flex; align-items: center; justify-content: center; gap: var(--space-3); margin-bottom: var(--space-5); }
.rf-step {
    width: 3rem; height: 3rem; border-radius: 50%; flex-shrink: 0;
    border: 1px solid var(--gsx-border-strong); background: var(--gsx-surface-2);
    color: var(--gsx-text); font-size: 1.6rem; line-height: 1; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.rf-step:active { transform: scale(0.94); }
.rf-yds { display: inline-flex; align-items: baseline; gap: var(--space-1); }
.rf-yds input {
    width: 4.6rem; border: none; background: none; text-align: center;
    font-family: var(--font-display); font-size: 3.4rem; font-weight: 800;
    color: var(--brand-ink); line-height: 1; -moz-appearance: textfield;
}
.rf-yds input::-webkit-outer-spin-button,
.rf-yds input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.rf-yds-unit { font-size: 1rem; font-weight: 700; color: var(--gsx-text-muted); text-transform: uppercase; }
.rf-result { min-height: 5rem; }
.rf-club-main {
    background: var(--gsx-surface-2); border-radius: var(--gsx-radius-md);
    padding: var(--space-4); margin-bottom: var(--space-3);
}
.rf-club-name { font-family: var(--font-display); font-size: 2.2rem; font-weight: 800; color: var(--gsx-text); line-height: 1; }
.rf-club-carry { font-size: 0.9rem; color: var(--gsx-text-muted); margin-top: var(--space-2); }
.rf-club-alt { font-size: 0.9rem; color: var(--gsx-text-muted); }
.rf-club-alt strong { color: var(--brand-ink); }
.rf-empty-ico { font-size: 3rem; margin-bottom: var(--space-2); }
.solo-hole-caddie {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2.1rem; height: 2.1rem; flex-shrink: 0; margin-left: var(--space-2);
    border: 1px solid var(--gsx-border); border-radius: 50%;
    background: var(--gsx-surface-2); color: var(--gsx-text-muted); cursor: pointer;
    transition: color var(--motion-fast), border-color var(--motion-fast);
}
@media (hover: hover) and (pointer: fine) {
    .solo-hole-caddie:hover { color: var(--brand-ink); border-color: var(--brand-ink); }
}
.solo-hole-caddie:active { transform: scale(0.94); }

/* ── Stats dashboards come alive (site-wide motion spec) ──
   Entrances are GATED, not auto-run: gsxAnimateStatDashboard / gsxAnimateStatTiles
   add .gsx-anim (children held invisible) and then .gsx-go at 35% visibility
   (IntersectionObserver), ONCE per screen visit — an SPA revisit with unchanged
   data gets neither class and renders the final state instantly. No JS /
   motion.js absent → static final state too. Reduced motion: the global
   collapse in 00-gsx-system.css flattens every keyframe below; the JS tweens
   (count-ups, sweeps, draw-ins) guard themselves in motion.js. */
.solo-dash.gsx-anim:not(.gsx-go) > *,
.solo-stat-grid.gsx-anim:not(.gsx-go) .solo-stat,
.gsx-tiles.gsx-anim:not(.gsx-go) > * { opacity: 0; }

.solo-dash.gsx-go > * { animation: gsxDashRise var(--m-base) var(--e-out) both; }
.solo-dash.gsx-go > *:nth-child(2) { animation-delay: calc(1 * var(--stagger)); }
.solo-dash.gsx-go > *:nth-child(3) { animation-delay: calc(2 * var(--stagger)); }
.solo-dash.gsx-go > *:nth-child(4) { animation-delay: calc(3 * var(--stagger)); }

.solo-stat-grid.gsx-go .solo-stat { animation: gsxDashRise var(--m-base) var(--e-out) both; }
.solo-stat-grid.gsx-go .solo-stat:nth-child(2) { animation-delay: calc(1 * var(--stagger)); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(3) { animation-delay: calc(2 * var(--stagger)); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(4) { animation-delay: calc(3 * var(--stagger)); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(5) { animation-delay: calc(4 * var(--stagger)); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(6) { animation-delay: calc(5 * var(--stagger)); }

/* Generic tile strips (School coach/player overview cards, Host event hero,
   Casual home chips): gsxAnimateStatTiles adds .gsx-tiles + the gate classes. */
.gsx-tiles.gsx-go > * { animation: gsxDashRise var(--m-base) var(--e-out) both; }
.gsx-tiles.gsx-go > :nth-child(2) { animation-delay: calc(1 * var(--stagger)); }
.gsx-tiles.gsx-go > :nth-child(3) { animation-delay: calc(2 * var(--stagger)); }
.gsx-tiles.gsx-go > :nth-child(4) { animation-delay: calc(3 * var(--stagger)); }
.gsx-tiles.gsx-go > :nth-child(5) { animation-delay: calc(4 * var(--stagger)); }
.gsx-tiles.gsx-go > :nth-child(6) { animation-delay: calc(5 * var(--stagger)); }
.gsx-tiles.gsx-go > :nth-child(7) { animation-delay: calc(6 * var(--stagger)); }
.gsx-tiles.gsx-go > :nth-child(8) { animation-delay: calc(7 * var(--stagger)); }

/* 3px accent underline sweeps in per tile ~350ms after its entrance. The
   ::after exists at rest with scaleX(0) — invisible unless the sweep plays. */
.solo-stat,
.gsx-tiles > .dash-stat-card { position: relative; overflow: hidden; }
.solo-stat::after,
.gsx-tiles > .dash-stat-card::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 3px;
    background: var(--primary-color); transform: scaleX(0); transform-origin: left;
    pointer-events: none;
}
.solo-stat-grid.gsx-go .solo-stat::after,
.gsx-tiles.gsx-go > .dash-stat-card::after { animation: gsxSweepX 500ms var(--e-out) forwards 350ms; }
.solo-stat-grid.gsx-go .solo-stat:nth-child(2)::after,
.gsx-tiles.gsx-go > .dash-stat-card:nth-child(2)::after { animation-delay: calc(1 * var(--stagger) + 350ms); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(3)::after,
.gsx-tiles.gsx-go > .dash-stat-card:nth-child(3)::after { animation-delay: calc(2 * var(--stagger) + 350ms); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(4)::after,
.gsx-tiles.gsx-go > .dash-stat-card:nth-child(4)::after { animation-delay: calc(3 * var(--stagger) + 350ms); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(5)::after,
.gsx-tiles.gsx-go > .dash-stat-card:nth-child(5)::after { animation-delay: calc(4 * var(--stagger) + 350ms); }
.solo-stat-grid.gsx-go .solo-stat:nth-child(6)::after,
.gsx-tiles.gsx-go > .dash-stat-card:nth-child(6)::after { animation-delay: calc(5 * var(--stagger) + 350ms); }

.gsx-go .solo-rings .solo-ring { animation: gsxDashPop 520ms var(--e-spring) both; }
.gsx-go .solo-rings .solo-ring:nth-child(2) { animation-delay: 120ms; }
.gsx-go .solo-rings .solo-ring:nth-child(3) { animation-delay: 240ms; }

.gsx-go .solo-bar-fill { transform-origin: bottom; animation: gsxBarGrow var(--m-count) var(--e-out) both; }
.gsx-go .solo-bar-col:nth-child(2) .solo-bar-fill { animation-delay: calc(2 * var(--stagger)); }
.gsx-go .solo-bar-col:nth-child(3) .solo-bar-fill { animation-delay: calc(4 * var(--stagger)); }

.gsx-go .solo-donut { animation: gsxDonutIn 660ms var(--e-spring) both; }

/* Legend rows cascade in at +500ms (after the donut sweep is under way). */
.gsx-go .solo-legend-item {
    opacity: 0; transform: translateX(-8px);
    animation: gsxSlideIn var(--m-base) var(--e-out) forwards;
    animation-delay: calc(var(--i, 0) * var(--stagger) + 500ms);
}

@keyframes gsxDashRise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes gsxDashPop  { from { opacity: 0; transform: scale(0.82); } to { opacity: 1; transform: none; } }
@keyframes gsxBarGrow  { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes gsxDonutIn  { from { opacity: 0; transform: scale(0.86); } to { opacity: 1; transform: none; } }
@keyframes gsxSweepX   { to { transform: scaleX(1); } }
@keyframes gsxSlideIn  { to { opacity: 1; transform: none; } }

/* ── Offline sync chip + pending hole markers (offline-queue, Session A) ────
   The chip lives in the game hero beside the status pill: hidden at zero
   pending, a muted "N holes waiting to sync" pulse while offline writes are
   queued, and a brief success confirmation when the queue drains. Hole-strip
   chips carry a small dot until the server confirms their scores. */
.solo-game-hero-top { gap: var(--space-2); }
.solo-game-hero-top .solo-hero-exit { margin-right: auto; }
.solo-sync-chip {
    display: inline-flex; align-items: center; gap: var(--space-1);
    font-size: 0.68rem; font-weight: 700; letter-spacing: 0.04em;
    color: var(--on-hero-muted);
    padding: var(--space-0-5) var(--space-2);
    border: 1px solid var(--hero-border); border-radius: var(--radius-pill);
    white-space: nowrap;
}
.solo-sync-chip[hidden] { display: none; }
.solo-sync-chip svg { flex: 0 0 auto; }
.solo-sync-chip.is-pending svg { animation: soloSyncPulse 1.6s ease-in-out infinite; }
.solo-sync-chip.is-done { color: var(--success-ink); border-color: transparent; }
@keyframes soloSyncPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
    .solo-sync-chip.is-pending svg { animation: none; }
}
.solo-hole-chip { position: relative; }
.solo-hole-chip.is-pending::after {
    content: '';
    position: absolute; left: 50%; bottom: 2px;
    width: 4px; height: 4px; margin-left: -2px;
    border-radius: 50%;
    background: var(--warning-ink);
}

/* ── Mobile platform switcher (navbar-resident) ──────────────────────────────
   The drawer's switcher is parked off-canvas at x=433 on a 375px screen while
   the drawer is closed, so it is not a route to anywhere. This copy lives in
   the persistent navbar so context switching is reachable on screen in School,
   Host and Casual alike — the counterpart to removing the rail's Play item.
   TASK-X X1: no header copy exists at any width any more — mobile switching
   lives on the account surface; desktop keeps the .nav-user control. */
.nav-plat-switch.nav-plat-mobile { display: none; }

/* ── Bottom nav: fail VISIBLE, never off-screen ──────────────────────────────
   .bottom-nav:not(.hidden) animates in with `bottomNavUp ... both` and the
   keyframe starts at translateY(100%) (07-mobile.css). `both` adds a BACKWARDS
   fill, so any state where that animation is stalled, delayed or perpetually
   restarted holds the nav exactly its own height below the fold — measured
   live at translateY(53px), top=812 in an 812px viewport, with the items
   correctly rendered inside it. Mobile navigation simply vanished.

   Dropping the fill keeps the slide-up entrance but changes the failure mode:
   with no fill the element renders at its natural position (fixed, bottom:0)
   whenever the animation is not actively running, so a stall now shows the nav
   instead of hiding it. Hiding stays the job of .hidden (display:none), which
   is how the Casual launcher legitimately suppresses it.
   This file loads after 07-mobile.css, so this wins without editing that file. */
@media (max-width: 768px) {
    .bottom-nav:not(.hidden) {
        animation-fill-mode: none;
    }
}

/* ── Mobile navbar fit ───────────────────────────────────────────────────────
   At 375px the row is brand + switcher + theme + hamburger. Measured before
   this block: brand 251px (School) + actions 228px = 497px of content in a
   343px budget, so the hamburger — the ONLY way to open the drawer — sat
   entirely off-screen and the page scrolled sideways.

   The controls cannot yield: the switcher is the only on-screen route out of
   School since Play left the rail, and the hamburger opens everything else. So
   the BRAND yields instead. The crest and the platform chip stay (identity),
   the wordmark goes — the drawer header still names the school. */
@media (max-width: 768px) {
    #appShellNav .nav-main {
        min-width: 0;
        gap: var(--space-2);
    }

    #appShellNav .nav-brand {
        min-width: 0;
        flex: 0 1 auto;
        overflow: hidden;
    }

    #appShellNav .nav-brand .brand-logo-full { height: 26px; }

    /* The school WORDMARK is the single widest optional element (~90px). */
    #appShellNav .nav-school-name { display: none; }

    #appShellNav .solo-nav-actions {
        flex: 0 0 auto;
        gap: var(--space-0-5);
    }

}

/* ── Casual home dashboard ───────────────────────────────────────────────────
   The home used to end at the quick-action grid, so on a 1920 screen it was a
   560px column of buttons with nothing beneath it while /solo/stats was already
   returning twenty-one keys. These are the containers that data goes into.

   ONE content set, TWO compositions (never a desktop-only or mobile-only card):
   a single column on a phone in priority order, and two columns from 1024px so
   the width the container already has gets used. */
.solo-home-dash {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
    margin-top: var(--space-4);
    align-items: start;
}

@media (min-width: 1024px) {
    #soloContent .solo-home-dash {
        grid-template-columns: 1.4fr 1fr;
        gap: var(--space-4);
    }
}

/* Each column is a plain grid item — the cards inside carry their own chrome. */
.solo-home-dash-col { min-width: 0; }

/* Thin scoring-progress bar on the Host spotlight card. Width is inline (a
   percentage is data, not styling). */
.solo-progress {
    height: 6px;
    border-radius: var(--radius-full);
    background: var(--bg-tertiary);
    overflow: hidden;
    margin-top: var(--space-2);
}
.solo-progress-fill {
    height: 100%;
    border-radius: var(--radius-full);
    background: var(--primary-color);
    transition: width var(--motion-slow) var(--ease-out);
}

/* TASK-W W1: the surviving Create is the Host context's PRIMARY action and
   reads as one — filled accent tile with weight over Join/Help. In the
   section, in the grid; never a floating overlay again. */
.solo-quick.solo-quick-primary {
    background: var(--primary-color);
    color: var(--area-on-accent, #ffffff);
    font-weight: 700;
}
.solo-quick.solo-quick-primary .solo-quick-label { color: inherit; }
.solo-quick.solo-quick-primary .solo-quick-ico { color: inherit; }

/* TASK-Y Y2: one chrome height in every context. The solo bell was the 11px
   delta — a 44px control in a 28px-content bar made Host/Casual read 71px
   against School's 60. Desktop caps its VISUAL box to the bar's content
   height; at pointer:coarse the 15-touch-targets overlay still provides the
   44px hit area (isolated leaf control). Mobile keeps the full-size bell. */
@media (min-width: 769px) {
    body[data-shell-nav="solo"] #appShellNav .solo-bell {
        height: 32px;
        min-height: 32px;
        padding: var(--space-1);
    }
}


/* ── TASK-AB AB1: one vertical rhythm, owned by the PARENT ──────────────────
   The homes measured gaps of 0/12/14/16 from per-component margins (id-strip
   12, cta 14, solo-mb 16, empty-state 0). The flow container owns block
   separation with a single token gap; children stop carrying their own
   margins. Same scale in Host AND Casual (VISION Principle 1). Inside a
   section, cards keep --space-4 (solo-mb) and headers keep --space-2 — at
   most three distinct gaps on screen, every one a token. */
.solo-home-flow {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
}
.solo-home-flow > * { margin-top: 0; margin-bottom: 0; }
/* In a flex column, margin-inline:auto cancels stretch and shrinks a grid to
   fit-content (measured 267px/454px). Full-measure blocks state their width;
   narrow blocks (.solo-cta / .solo-help-tip) keep auto margins + max-width. */
.solo-home-flow > .solo-quick-grid { width: 100%; }

/* AB3: spotlight top-3 leaders + the last-round score line. */
.spot-leaders { margin-top: var(--space-2); display: flex; flex-direction: column; }
.spot-leader-row {
    display: flex; align-items: baseline; gap: var(--space-2);
    padding: var(--space-1) 0;
    border-top: 1px solid var(--border-subtle);
    font-size: 0.85rem;
}
.spot-leader-pos { font-weight: 800; color: var(--text-muted); min-width: 1.1em; }
.spot-leader-name { font-weight: 600; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spot-leader-score { font-weight: 700; font-variant-numeric: tabular-nums; }
.last-round-line { display: flex; align-items: baseline; gap: var(--space-2); }
.last-round-total { font-size: 1.8rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.last-round-topar { font-weight: 700; color: var(--brand-ink); }
