/* CourtIQ CI4 — global styles layered on top of Bootstrap 5. */

:root {
    /* Session 15 round 2/3 (2026-04-29) — owner correction: org.hitcourt.com
       uses NO green at all. The brand palette is PURPLE primary
       (#5837eb = `--primary-color` on org.hitcourt.com) + lighter PURPLE
       accent (#9b87f4 = `--accent-color`) + BLUE for secondary elements.
       Round 3 also overrides Bootstrap's own CSS variables so every
       Bootstrap-internal "success" reference (alerts, focus rings,
       borders, list-group, text-emphasis) resolves to purple — not just
       the .btn-success / .text-success / .bg-success classes I named. */

    /* CourtIQ tokens (variable names retained for blast-radius; values
       are now Hitcourt purple). Sprint 4 should rename to
       --courtiq-primary etc. */
    --courtiq-green: #5837eb;
    --courtiq-green-dark: #3a23b8;
    --courtiq-green-soft: rgba(88, 55, 235, 0.12);
    --courtiq-accent: #9b87f4;
    --courtiq-bg: #f8fafc;
    --courtiq-ink: #0f172a;

    /* Bootstrap 5.3 CSS-variable overrides — replace Bootstrap's default
       green with the CourtIQ purple across ALL components that reference
       --bs-success* (alert-success, list-group-item-success, focus rings,
       text-success-emphasis, border-success-subtle, etc.). Also override
       primary so links / .btn-primary / .bg-primary stay on-brand. */
    --bs-success: #5837eb;
    --bs-success-rgb: 88, 55, 235;
    --bs-success-text-emphasis: #3a23b8;
    --bs-success-bg-subtle: #ece8fd;
    --bs-success-border-subtle: #c4b5fd;

    --bs-primary: #5837eb;
    --bs-primary-rgb: 88, 55, 235;
    --bs-primary-text-emphasis: #3a23b8;
    --bs-primary-bg-subtle: #ece8fd;
    --bs-primary-border-subtle: #c4b5fd;

    --bs-link-color: #5837eb;
    --bs-link-hover-color: #3a23b8;
    --bs-link-color-rgb: 88, 55, 235;
    --bs-link-hover-color-rgb: 58, 35, 184;
}

body {
    background-color: var(--courtiq-bg);
    color: var(--courtiq-ink);
    /* Poppins matches Hitcourt brand (owner-flagged 2026-04-28). */
    font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-weight: 400;
}
h1, h2, h3, h4, h5, h6, .fw-bold, .fw-semibold {
    font-family: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    letter-spacing: -0.005em;
}

.btn-success,
.btn-success:hover,
.btn-success:focus {
    background-color: var(--courtiq-green);
    border-color: var(--courtiq-green);
}

.btn-outline-success {
    color: var(--courtiq-green);
    border-color: var(--courtiq-green);
}

.btn-outline-success:hover {
    background-color: var(--courtiq-green);
    color: #fff;
}

a { color: var(--courtiq-green); }
a:hover { color: var(--courtiq-green-dark); }

.text-success { color: var(--courtiq-green) !important; }
.bg-success { background-color: var(--courtiq-green) !important; }
.border-success { border-color: var(--courtiq-green) !important; }

/* ===== Match setup — preset tiles ===== */
.preset-tile {
    cursor: pointer;
    border: 2px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 1rem 0.75rem;
    background: #fff;
    transition: all 0.15s;
    height: 100%;
}
.preset-tile:hover {
    border-color: var(--courtiq-green);
    box-shadow: 0 4px 14px rgba(88, 55, 235, 0.18);
}
.preset-tile.is-selected {
    border-color: var(--courtiq-green);
    background: #ece8fd;
}
.preset-tile .title {
    font-weight: 700;
    font-size: 1.1rem;
    color: var(--courtiq-ink);
}
.preset-tile .desc {
    font-size: 0.85rem;
    color: #64748b;
    margin-top: 0.25rem;
    line-height: 1.35;
}

/* ===== Scoring screen ===== */
.scoring-header {
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
    color: #f1f5f9;
    border-radius: 1rem;
    padding: 1.25rem;
}
.scoring-header .player-row {
    display: grid;
    grid-template-columns: 1fr auto auto auto auto;
    gap: 0.5rem;
    align-items: center;
    padding: 0.4rem 0.5rem;
    border-bottom: 1px solid rgba(255,255,255,0.1);
}
.scoring-header .player-row:last-child { border-bottom: none; }
.scoring-header .player-row.serving { background: rgba(88, 55, 235, 0.22); border-radius: 0.5rem; }
.scoring-header .player-row .name { font-weight: 600; }
.scoring-header .player-row .game-score { font-size: 1.4rem; font-weight: 700; color: #fbbf24; min-width: 50px; text-align: center; }
.scoring-header .player-row .set-score { font-size: 1.1rem; min-width: 30px; text-align: center; }
.scoring-header .player-row .serve-dot { color: #fbbf24; font-size: 1.2rem; }

.winner-btn {
    background: #fff;
    border: 2px solid #e2e8f0;
    border-radius: 0.75rem;
    padding: 0.85rem 1rem;       /* Session 16 r6 stakeholder ask: reduce
                                    height — buttons were too tall (140px)
                                    making the scoreboard area cramped */
    min-height: 78px;
    font-size: 1.2rem;
    font-weight: 700;
    transition: all 0.1s;
    width: 100%;
    color: var(--courtiq-ink);
}
.winner-btn:hover {
    border-color: var(--courtiq-green);
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(88, 55, 235, 0.22);
}
.winner-btn:active {
    transform: translateY(0);
}
.winner-btn .player-name { font-size: 1rem; color: #64748b; font-weight: 500; }
.winner-btn .hint { font-size: 0.7rem; color: #94a3b8; font-weight: 400; margin-top: 0.2rem; }

.direct-award-btn {
    font-weight: 600;
    padding: 0.75rem 1rem;
}

.point-via-btn {
    min-height: 90px;
    font-size: 1rem;
    font-weight: 600;
    text-align: left;
    padding: 1rem;
}
.point-via-btn .subtitle { font-size: 0.8rem; font-weight: 400; opacity: 0.75; display: block; margin-top: 0.2rem; }

/* ===== PF-001 Level 3 taxonomy modals ===== */
.cat-btn {
    text-align: left;
    padding: 1rem;
    border: 2px solid #e2e8f0;
    background: #fff;
    border-radius: 0.75rem;
    width: 100%;
    transition: all 0.1s;
    color: var(--courtiq-ink);
}
.cat-btn:hover {
    border-color: var(--courtiq-green);
    box-shadow: 0 4px 14px rgba(88, 55, 235, 0.14);
}
.cat-btn .cat-title { font-weight: 700; font-size: 1.05rem; }
.cat-btn .cat-hint { font-size: 0.8rem; color: #64748b; margin-top: 0.25rem; }

.subcat-pill {
    border: 2px solid #cbd5e1;
    background: #fff;
    color: var(--courtiq-ink);
    padding: 0.5rem 0.9rem;
    border-radius: 999px;
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.08s;
    user-select: none;
}
.subcat-pill:hover {
    border-color: var(--courtiq-green);
}
.subcat-pill.is-selected {
    background: var(--courtiq-green);
    color: #fff;
    border-color: var(--courtiq-green);
}
.subcat-pill.is-selected::before {
    content: "✓ ";
    font-weight: 700;
}

/* ===== PF-035 Per-match Stats page ===== */
.stats-header { background: linear-gradient(135deg, #ffffff 0%, #f1f5f9 100%); }

.chart-wrap { position: relative; height: 220px; }
.chart-wrap-md { height: 280px; }
.chart-wrap-tall { height: 240px; }

.hero-player {
    transition: transform 0.15s, box-shadow 0.15s;
}
.hero-player:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(15, 23, 42, 0.08) !important;
}
.hero-stat-box {
    background: #f8fafc;
    border-radius: 0.5rem;
    padding: 0.65rem 0.5rem;
}
.hero-stat-value {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1;
}
.hero-stat-label {
    font-size: 0.7rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-top: 0.25rem;
}

.stats-pressure-table th { font-weight: 600; }

.cooc-count {
    display: inline-block;
    min-width: 2rem;
    padding: 0.15rem 0.5rem;
    background: var(--courtiq-green);
    color: #fff;
    border-radius: 0.4rem;
    font-weight: 700;
    font-size: 0.85rem;
    text-align: center;
    margin-right: 0.4rem;
}

/* ===== PF-034 Coach Dashboard ===== */
.dash-hero-tile {
    background: #fff;
    border-radius: 0.75rem;
    padding: 1rem 1.25rem;
    border: 1px solid #e2e8f0;
    text-align: center;
    transition: transform 0.15s, box-shadow 0.15s;
}
.dash-hero-tile:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(15, 23, 42, 0.08);
}
.dash-hero-value {
    font-size: 2rem;
    font-weight: 800;
    line-height: 1;
}
.dash-hero-label {
    font-size: 0.75rem;
    color: #64748b;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-weight: 600;
    margin-top: 0.4rem;
}

.insight-panel {
    background: linear-gradient(135deg, #ece8fd 0%, #ffffff 100%);
    border: 1px solid #c4b5fd !important;
}
.insight-icon {
    width: 48px; height: 48px;
    border-radius: 50%;
    background: var(--courtiq-green);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.4rem;
    box-shadow: 0 4px 12px rgba(88, 55, 235, 0.32);
}
.insight-body p { line-height: 1.6; margin-bottom: 0.5rem; }
.insight-body .num {
    font-weight: 700;
    color: var(--courtiq-green-dark);
    background: #ece8fd;
    padding: 0.05rem 0.35rem;
    border-radius: 0.3rem;
}
.insight-body em { color: var(--courtiq-ink); font-style: normal; font-weight: 600; }
.insight-body strong { color: var(--courtiq-ink); }

.sync-badge {
    font-size: 0.75rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: rgba(255,255,255,0.1);
    color: #cbd5e1;
}
.sync-badge.has-failed { background: rgba(239,68,68,0.25); color: #fca5a5; }
.sync-badge.has-pending { background: rgba(251,191,36,0.2); color: #fcd34d; }

/* ===== Dashboards + lists ===== */
.stat-card {
    background: #fff;
    border-radius: 1rem;
    padding: 1.25rem;
    border: 1px solid #e2e8f0;
}
.stat-card .stat-value { font-size: 2rem; font-weight: 700; color: var(--courtiq-green); }
.stat-card .stat-label { font-size: 0.85rem; color: #64748b; text-transform: uppercase; letter-spacing: 0.05em; }

/* ===== Result page ===== */
.result-banner {
    background: linear-gradient(135deg, var(--courtiq-green) 0%, var(--courtiq-green-dark) 100%);
    color: #fff;
    border-radius: 1rem;
    padding: 2rem;
    text-align: center;
}
.result-banner.abandoned { background: linear-gradient(135deg, #64748b 0%, #475569 100%); }
.result-banner .winner { font-size: 2rem; font-weight: 700; }
.result-banner .subtitle { font-size: 1rem; opacity: 0.9; }

/* ===========================================================================
   Session 16 (2026-04-30) — fixed-grid scoreboard for the scoring screen.
   Stakeholder feedback: layout should be FIXED, not text-flowing. Inspired
   by the broadcast-style scoreboards on tour websites + the legacy VB
   scorer screenshot in _project-docs/screenshots/old-match-scorer.jpg.

   Three columns: Player 1 (left), Sets-won grid (centre), Player 2 (right).
   Score boxes never move; only the numbers inside change. Ace + Fault are
   compact buttons under each player's score box. Tennis-ball server icon
   sits beside the player's name on the side currently serving.
   =========================================================================== */
.scoring-meta {
    color: #64748b;
}
.scoring-meta .text-muted-2 { color: #94a3b8; font-style: italic; }

.scoreboard {
    display: grid;
    /* Session 16 r7 owner-flagged: minmax(0, 1fr) instead of bare 1fr —
       bare 1fr resolves to minmax(auto, 1fr), which lets the track shrink
       below equal-share when content has a smaller intrinsic min-content.
       Result was P1 column wider than P2 column whenever player names
       differed in length. minmax(0, 1fr) pins both player tracks to
       exactly 50% of free space regardless of content width. */
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    grid-template-rows: 1fr;        /* explicit single row — Session 16 r5 fix:
                                       prevents auto-placement from wrapping a
                                       child to row 2 when grid-column is set
                                       dynamically by .sb-on-left/.sb-on-right */
    gap: 1rem;
    align-items: stretch;
    background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
    color: #f1f5f9;
    border-radius: 1rem;
    padding: 1.25rem 1rem;
}
/* Pin every direct child of .scoreboard to row 1 so dynamic
   grid-column reassignment (Session 16 side-rotation) can't wrap. */
.scoreboard > .sb-player,
.scoreboard > .sb-centre {
    grid-row: 1;
}

.sb-player {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.5rem;
    border-radius: 0.6rem;
    transition: background 0.15s;
}
/* Session 16 r7 — removed the .serving background tint. It made the
   serving column look visually wider/heavier than the receiving column
   (because only one side carried the tint). The yellow serve-dot next
   to the player name + the highlighted Ace/Fault buttons are enough to
   signal who's serving. Both columns now visually carry equal weight. */
.sb-player.serving {
    /* intentionally no background — see comment above */
}

.sb-player-name {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 1.4rem;
    font-weight: 700;
    line-height: 1.1;
    min-height: 2rem; /* Session 16 r6: pin row height so P1's serving-side
                         dot and P2's invisible dot don't cause vertical
                         misalignment between the two columns */
    color: #f8fafc;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sb-player-2 .sb-player-name {
    justify-content: flex-end;
}
.serve-dot {
    display: inline-block;
    width: 0.9rem;
    height: 0.9rem;
    border-radius: 50%;
    background: transparent;
    flex-shrink: 0;
    transition: all 0.15s;
}
.serve-dot.is-serving {
    background: radial-gradient(circle at 30% 30%, #fde047 20%, #facc15 70%, #ca8a04 100%);
    box-shadow: 0 0 0 2px rgba(250, 204, 21, 0.35), 0 0 8px rgba(250, 204, 21, 0.45);
}

.sb-game-box {
    background: #ffffff;
    color: #0f172a;
    border-radius: 0.75rem;
    padding: 0.75rem 0.5rem;
    text-align: center;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
    min-height: 90px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}
.sb-game-score {
    font-size: 3rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.01em;
    color: #5837eb;
}
/* .sb-court-side rule removed Session 17 r3 — court-side caption
   ("deuce" / "ad" alternating under the score) is no longer rendered.
   Mobile breakpoint overrides for this class are also removed below. */

.sb-direct-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem;
}
.sb-direct-btn {
    background: rgba(255, 255, 255, 0.06);
    color: #cbd5e1;
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 0.4rem;
    padding: 0.45rem 0.4rem;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: not-allowed;
    transition: all 0.1s;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
}
.sb-direct-btn .sb-direct-label { font-size: 0.78rem; }
.sb-direct-btn.is-active-server {
    background: rgba(88, 55, 235, 0.85);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.45);
    cursor: pointer;
}
.sb-direct-btn.is-active-server:hover {
    background: #5837eb;
    transform: translateY(-1px);
}
.sb-direct-btn.sb-fault.is-active-server {
    background: rgba(245, 158, 11, 0.85);
}
.sb-direct-btn.sb-fault.is-active-server:hover {
    background: #f59e0b;
}

/* Sets-won grid — three header cells (S1 S2 S3) + two rows of cells */
.sb-sets {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.35rem;
    padding: 0.5rem 0.35rem;
    background: #000;
    border-radius: 0.6rem;
    align-self: center;
}
.sb-sets-header,
.sb-sets-row {
    display: grid;
    /* Session 16 r9 — leading column for the player INITIAL identifier
       (e.g., "RK" / "MO"), then one column per set. Owner ask: at the
       end of a set the row reads "RK 7" / "MO 6" so it's instantly
       clear who won. */
    grid-template-columns: 2.4rem;
    grid-auto-columns: minmax(2.6rem, 1fr);
    grid-auto-flow: column;
    gap: 0.25rem;
    text-align: center;
    align-items: center;
}
.sb-sets-initial {
    font-size: 0.85rem;
    font-weight: 800;
    color: #fbbf24;
    letter-spacing: 0.04em;
    text-align: center;
    line-height: 1;
}
.sb-sets-initial-h {
    /* Empty header cell above the initials column — stays blank to
       keep visual symmetry with the S1/S2/S3 row. */
}
.sb-sets-h {
    font-size: 0.7rem;
    font-weight: 600;
    color: #94a3b8;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 0.2rem 0;
}
.sb-sets-cell {
    font-size: 1.6rem;
    font-weight: 800;
    color: #f1f5f9;
    background: #1e293b;
    border-radius: 0.4rem;
    padding: 0.35rem 0.2rem;
    line-height: 1;
    border: 1px solid #334155;
    transition: all 0.15s;
    position: relative;
}
.sb-sets-cell sup {
    font-size: 0.7rem;
    font-weight: 600;
    color: #fbbf24;
    margin-left: 0.05rem;
    top: -0.5em;
}
.sb-sets-cell.sb-sets-current {
    background: #5837eb;
    border-color: #c4b5fd;
    box-shadow: 0 0 0 2px rgba(88, 55, 235, 0.45);
}
.sb-sets-cell.sb-sets-won {
    background: #064e3b;
    border-color: #10b981;
    color: #6ee7b7;
}

/* Footer controls */
/* Session 17 r3 — Footer layout.
   Desktop: flex row with explicit `order` keeping the visual sequence
     [Start Match]  [Undo]  [Swap]  [End Match]
   Source order is Undo, Swap, Start Match, End Match (so the mobile
   grid fills naturally as: Undo|Swap on row 1, Start|End on row 2). */
.sb-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}
.sb-footer .btn { font-weight: 600; padding: 0.5rem 1rem; }
.sb-footer-start { order: 1; }
.sb-footer-undo  { order: 2; }
.sb-footer-swap  { order: 3; }
.sb-footer-end   { order: 4; }
.sb-keyhint { color: #94a3b8; }

/* Session 17 r1 — KEEP the 3-column horizontal layout at all viewports.
   Owner ruling 2026-04-30: stacking vertically on phones loses the
   left-of-chair / right-of-chair anchor, which is the core spatial
   metaphor of the scoreboard. Instead, scale every element down
   progressively. The Chair Umpire badge stays between the two players
   no matter how narrow the viewport.

   Three breakpoints under 720px:
     ≤720px : moderately compact — still very legible
     ≤480px : tight — labels shrink, padding tightens
     ≤380px : super tight (iPhone SE class) — Ace/Fault + Chair drop
              their text labels and become icon-only.

   A soft landscape advisory banner ALSO renders at ≤568px portrait
   (see .landscape-tip below) — a non-blocking hint, no forced rotation. */

/* === Compact (≤720px — phones, small tablets) === */
/* Session 17 r2 — owner ruling 2026-04-30 evening: at narrow widths,
   keep the two players side-by-side (so left-of-chair / right-of-chair
   stays meaningful) but DROP the sets-won grid below the players to
   row 2. The Chair Umpire becomes an icon-only marker between the two
   players. This gives each player ~45% of the viewport horizontally
   instead of ~30%, which fixes the previous overlap-onto-P1 problem.

   Implemented via `display: contents` on `.sb-centre` so its two
   children (`.sb-sets` and `.sb-chair`) participate in the parent
   `.scoreboard` grid directly. Then `.sb-sets` gets row 2 / full-width;
   `.sb-chair` gets row 1 / column 2 (the small centre marker). */
@media (max-width: 720px) {
    .scoreboard {
        grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
        grid-template-rows: auto auto;        /* row 1 = players + chair, row 2 = sets */
        gap: 0.5rem 0.4rem;                    /* row-gap, column-gap */
        padding: 0.7rem 0.5rem;
    }
    /* Promote .sb-centre's children to the .scoreboard grid */
    .scoreboard > .sb-centre { display: contents; }
    /* Tiny chair marker stays between players on row 1 */
    .scoreboard > .sb-centre > .sb-chair {
        grid-row: 1;
        grid-column: 2;
        align-self: center;
        justify-self: center;
        margin-top: 0;
        padding: 0.4rem 0.5rem;
        font-size: 0.6rem;
        gap: 0.3rem;
        border-radius: 999px;       /* round badge for the icon-only state */
    }
    .scoreboard > .sb-centre > .sb-chair i { font-size: 1.1rem; }
    .sb-chair-label { display: none; }
    /* Sets grid drops below — full width on row 2 */
    .scoreboard > .sb-centre > .sb-sets {
        grid-row: 2;
        grid-column: 1 / -1;
        align-self: stretch;
        padding: 0.55rem 0.5rem;
        gap: 0.4rem;
    }
    /* With full width below, the cells can breathe — wider initials col,
       fluid set cells. */
    .sb-sets-header,
    .sb-sets-row {
        grid-template-columns: 2.6rem;
        grid-auto-columns: 1fr;
        gap: 0.4rem;
    }
    .sb-sets-h { font-size: 0.7rem; padding: 0.15rem 0; }
    .sb-sets-cell { font-size: 1.4rem; padding: 0.4rem 0.2rem; }
    .sb-sets-cell sup { font-size: 0.65rem; }
    .sb-sets-initial { font-size: 0.85rem; }
    /* Player columns now have ~45% of the viewport each — more breathing room */
    .sb-player { gap: 0.4rem; padding: 0.3rem; }
    .sb-player-name {
        font-size: 1rem;
        min-height: 1.6rem;
        gap: 0.3rem;
    }
    .sb-game-box { padding: 0.55rem 0.3rem; min-height: 78px; }
    .sb-game-score { font-size: 2.2rem; }
    .sb-sets-won-label { font-size: 0.55rem; letter-spacing: 0.06em; }
    .sb-sets-won-value { font-size: 1.1rem; }
    .sb-direct-row { gap: 0.3rem; }
    .sb-direct-btn {
        padding: 0.32rem 0.25rem;
        font-size: 0.72rem;
        gap: 0.2rem;
    }
    .sb-direct-btn .sb-direct-label { font-size: 0.72rem; }
    /* Sub-line on the winner button is noise on phones; hide it */
    .winner-btn .hint { display: none; }
    .winner-btn { min-height: 60px; padding: 0.6rem 0.6rem; font-size: 1.05rem; }

    /* Footer flips to a 2×2 grid on mobile per Session 17 r3 owner ask:
       row 1 = [Undo][Swap] · row 2 = [Start Match][End Match]. The desktop
       `order` overrides are reset so HTML source order drives the grid. */
    .sb-footer {
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-auto-rows: auto;
        gap: 0.55rem;
        justify-content: stretch;
    }
    .sb-footer-undo,
    .sb-footer-swap,
    .sb-footer-start,
    .sb-footer-end {
        order: 0;       /* cancel desktop ordering — let grid auto-flow drive */
    }
    /* Make every cell content fill its grid cell uniformly so the four
       buttons read as equal-sized tap targets. */
    .sb-footer .sb-footer-btn,
    .sb-footer .sb-footer-btn > .btn {
        width: 100%;
    }
    .sb-footer .btn { padding: 0.55rem 0.6rem; }
}

/* === Tight (≤480px — large phones in portrait) === */
@media (max-width: 480px) {
    .scoreboard {
        gap: 0.4rem 0.3rem;
        padding: 0.55rem 0.4rem;
    }
    .scoreboard > .sb-centre > .sb-chair {
        padding: 0.35rem 0.4rem;
    }
    .scoreboard > .sb-centre > .sb-chair i { font-size: 1rem; }
    .scoreboard > .sb-centre > .sb-sets {
        padding: 0.4rem 0.35rem;
        gap: 0.3rem;
    }
    .sb-sets-header,
    .sb-sets-row {
        grid-template-columns: 2.2rem;
        gap: 0.3rem;
    }
    .sb-sets-cell { font-size: 1.2rem; padding: 0.3rem 0.15rem; }
    .sb-sets-h { font-size: 0.65rem; }
    .sb-sets-initial { font-size: 0.78rem; }
    .sb-player { padding: 0.2rem; gap: 0.35rem; }
    .sb-player-name { font-size: 0.92rem; min-height: 1.4rem; gap: 0.25rem; }
    .sb-game-box { padding: 0.45rem 0.25rem; min-height: 64px; }
    .sb-game-score { font-size: 1.85rem; }
    .sb-sets-won-label { font-size: 0.5rem; }
    .sb-sets-won-value { font-size: 0.95rem; }
    .sb-direct-row { gap: 0.25rem; }
    .sb-direct-btn {
        padding: 0.28rem 0.2rem;
        font-size: 0.65rem;
        gap: 0.18rem;
    }
    .winner-btn { min-height: 50px; padding: 0.45rem 0.5rem; font-size: 0.95rem; }
}

/* === Super tight (≤380px — iPhone SE, smallest case) === */
@media (max-width: 380px) {
    .scoreboard {
        gap: 0.3rem 0.2rem;
        padding: 0.45rem 0.3rem;
    }
    .scoreboard > .sb-centre > .sb-chair {
        padding: 0.3rem 0.35rem;
    }
    .scoreboard > .sb-centre > .sb-sets {
        padding: 0.35rem 0.25rem;
        gap: 0.25rem;
    }
    .sb-sets-header,
    .sb-sets-row {
        grid-template-columns: 1.9rem;
        gap: 0.22rem;
    }
    .sb-sets-cell { font-size: 1.05rem; padding: 0.25rem 0.1rem; }
    .sb-sets-cell sup { font-size: 0.55rem; }
    .sb-sets-h { font-size: 0.6rem; }
    .sb-sets-initial { font-size: 0.7rem; }
    .sb-player { padding: 0.15rem; gap: 0.3rem; }
    .sb-player-name { font-size: 0.85rem; min-height: 1.3rem; }
    .sb-game-box { padding: 0.4rem 0.2rem; min-height: 56px; }
    .sb-game-score { font-size: 1.6rem; }
    .sb-sets-won-label {
        font-size: 0.45rem;
        letter-spacing: 0.04em;
    }
    .sb-sets-won-value { font-size: 0.9rem; }
    .sb-direct-btn {
        padding: 0.25rem 0.18rem;
        font-size: 0.62rem;
    }
    /* Drop the text labels on Ace / Fault at this smallest width — icons only */
    .sb-direct-btn .sb-direct-label { display: none; }
}

/* === Soft landscape advisory ===
   Shown only on portrait phones ≤568px wide. User can dismiss; the
   dismissal sticks for the session via sessionStorage (handled in JS). */
.landscape-tip {
    display: none;
    background: linear-gradient(135deg, rgba(88, 55, 235, 0.14), rgba(88, 55, 235, 0.05));
    border: 1px solid rgba(88, 55, 235, 0.35);
    border-radius: 0.5rem;
    padding: 0.5rem 0.7rem;
    margin: 0 0 0.6rem 0;
    color: #3a23b8;
    font-size: 0.8rem;
    align-items: center;
    gap: 0.5rem;
    line-height: 1.3;
}
@media (max-width: 568px) and (orientation: portrait) {
    .landscape-tip:not(.is-dismissed) {
        display: flex;
    }
}
.landscape-tip-icon { flex-shrink: 0; font-size: 1.05rem; }
.landscape-tip-text { flex: 1 1 auto; }
.landscape-tip-close {
    background: transparent;
    border: 0;
    color: inherit;
    opacity: 0.55;
    padding: 0.1rem 0.4rem;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
}
.landscape-tip-close:hover { opacity: 1; }

/* Session 16 r2 — Sets-won badge per player. Sits between the player
   name and the big game-score box; gives the coach an at-a-glance
   match-level set count alongside the per-set games grid in the centre.
   Session 16 r6 fix: align-items center (not baseline) + explicit
   min-height + box-sizing so P1 and P2 pills sit at IDENTICAL vertical
   positions regardless of font-baseline differences between the small
   "SETS WON" caption and the big yellow number. */
.sb-sets-won {
    display: flex;
    flex-direction: row;       /* Session 16 r7 owner ruling: drop the
                                  L/R mirror on the sets-won pill — owner
                                  asked: "Can we not copy the code from
                                  left side and paste it to the right
                                  side?" Both pills now identical layout
                                  (label LEFT, value RIGHT) regardless of
                                  which side the player is on. */
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 0.45rem;
    padding: 0.35rem 0.6rem;
    min-height: 2.4rem;
    box-sizing: border-box;
}
.sb-sets-won-label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #94a3b8;
    font-weight: 600;
    white-space: nowrap;       /* never wrap "SETS WON" onto two lines */
}
.sb-sets-won-value {
    font-size: 1.5rem;
    font-weight: 800;
    line-height: 1;
    color: #fbbf24;
    min-width: 1.2em;
    text-align: center;
}

/* Session 16 r3+r7 — physical side rotation around the umpire chair.
   .sb-on-left and .sb-on-right are toggled by scoring.js render() based
   on the engine's serve.ends + initial leftOfChair config. Grid-column
   placement makes p1/p2 visually swap when sides change.

   Session 16 r7 simplification: the only mirror behaviour kept is the
   PLAYER NAME alignment (names sit on the OUTSIDE of the chair —
   visually clearer). The sets-won pill is identical on both sides
   (owner ruling: "copy the left side and paste to the right"). */
.sb-on-left  { grid-column: 1; }
.sb-on-right { grid-column: 3; }

.sb-on-left  .sb-player-name { justify-content: flex-start; }
.sb-on-right .sb-player-name { justify-content: flex-end; }

/* Neutralise the older .sb-player-2 cascade rules so they don't fight
   the dynamic .sb-on-* classes. .sb-player-2 keeps its semantic name
   for future hooks but does no layout work. */
.sb-player-2 .sb-player-name { justify-content: inherit; }

/* Subtle colour for footer Undo + Swap buttons (Session 16 owner ask) */
.sb-footer .btn-outline-secondary {
    color: var(--courtiq-green);
    border-color: rgba(88, 55, 235, 0.35);
    background: rgba(88, 55, 235, 0.04);
}
.sb-footer .btn-outline-secondary:hover {
    background: var(--courtiq-green);
    border-color: var(--courtiq-green);
    color: #fff;
}
.sb-footer .btn-outline-secondary:focus,
.sb-footer .btn-outline-secondary.show {
    box-shadow: 0 0 0 0.2rem rgba(88, 55, 235, 0.25);
}

/* Session 16 r4 — Chair Umpire reference + centre column wrapper.
   Owner-flagged: the layout needs a fixed visual reference for "left
   vs right of chair" so the side-rotation logic is grounded in a
   real-world point of reference. The chair sits centre-bottom of the
   scoreboard, between the two players' columns. */
.sb-centre {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    grid-column: 2;
    align-self: center;
}
.sb-chair {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.95rem;
    margin-top: 1.5rem;       /* Session 16 r5 owner ask: push the chair
                                 marker lower — visually anchor it BELOW
                                 the sets-won grid rather than hugging it */
    background: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);
    color: #422006;
    border: 2px solid #fcd34d;
    border-radius: 0.5rem;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    box-shadow: 0 4px 14px rgba(251, 191, 36, 0.35);
}
.sb-chair i {
    font-size: 1.1rem;
}
@media (max-width: 720px) {
    .sb-centre { grid-column: 1; grid-row: auto; order: 3; }
    .sb-chair { margin-top: 0.5rem; }
}
