/* ===== VARIABLES & RESET ===== */

:root {
    --bg-dark: #070709;
    --bg-panel: #121215;
    --bg-card: rgba(30, 30, 35, 0.4);
    --border-light: rgba(255, 255, 255, 0.08);
    --text-main: #f0f0f0;
    --text-muted: #888890;
    --accent: #1771c9;
    --accent-hover: #298bed;
    --green: #22c55e;
    --red: #ff4a4a;

    --font-heading: 'Oswald', sans-serif;
    --font-body: 'Manrope', sans-serif;
}

html {
    scrollbar-width: thin;
    scrollbar-color: rgba(23, 113, 201, 0.72) rgba(255, 255, 255, 0.08);
}

::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.06);
}

::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(23, 113, 201, 0.82), rgba(56, 189, 248, 0.62));
    border: 2px solid rgba(6, 10, 18, 0.92);
    border-radius: 999px;
}

::-webkit-scrollbar-thumb:hover {
    background: linear-gradient(180deg, rgba(41, 139, 237, 0.95), rgba(56, 189, 248, 0.78));
}

[data-theme="light"] {
    --bg-dark: #f5f5f7;
    --bg-panel: #ffffff;
    --bg-card: rgba(0, 0, 0, 0.04);
    --border-light: rgba(0, 0, 0, 0.10);
    --text-main: #1a1a1a;
    --text-muted: #6b6b75;
    --accent: #1565c0;
    --accent-hover: #1976d2;
    --green: #16a34a;
    --red: #dc2626;
}

[data-theme="light"] {
    scrollbar-color: rgba(23, 113, 201, 0.72) rgba(0, 0, 0, 0.08);
}

[data-theme="light"] ::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] ::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(23, 113, 201, 0.78), rgba(15, 118, 178, 0.62));
    border-color: rgba(255, 255, 255, 0.9);
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    background-color: var(--bg-dark);
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 16px;
    line-height: 1.5;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

/* ===== TYPOGRAPHY ===== */

h1, h2, h3, .logo, .badge-inner, .stat, .h-time {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

a {
    color: inherit;
    text-decoration: none;
}

button {
    font-family: inherit;
    background: none;
    border: none;
    cursor: pointer;
    color: inherit;
}

/* Keyboard focus ring — uses :focus-visible so mouse clicks don't show
   the ring, but Tab navigation and screen readers always do. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

.noise-overlay {
    position: fixed;
    top: 0; left: 0; width: 100vw; height: 100vh;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.03'/%3E%3C/svg%3E");
    z-index: 999;
}

/* ===== NAV ===== */

.main-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 1.5rem 3rem;
    border-bottom: 1px solid var(--border-light);
    background: rgba(7, 7, 9, 0.8);
    backdrop-filter: blur(12px);
    position: sticky;
    top: 0;
    z-index: 100;
}

.logo {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: 0.05em;
}

.logo span {
    color: var(--accent);
}

.nav-links {
    display: flex;
    gap: 2rem;
}

.nav-links a {
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    transition: color 0.3s ease;
    position: relative;
}

.nav-links a.active, .nav-links a:hover {
    color: var(--text-main);
}

.nav-links a.active::after {
    content: '';
    position: absolute;
    bottom: -6px;
    left: 0;
    width: 100%;
    height: 2px;
    background: var(--accent);
}

/* ===== LAYOUT ===== */

/* Global page shell. One width policy for the entire site — the
 * Coach Review cockpit's policy (PR #57+) is now applied universally
 * so every view (public season / match, admin, coach all 4 tabs,
 * my feedback) shares one outer rhythm and tab-switching never
 * jumps the page edges. `min(100% - 1.5rem, 2200px)` scales the
 * shell with the viewport up to ~2200 px (after which content looks
 * weird sprawling across a 28" monitor) and keeps a consistent ~12 px
 * gutter on every side at narrower widths. Padding is reduced from
 * the historical 3rem to 1.25rem so content actually reaches the
 * new edges. **Do not add per-view max-width caps.** Every view
 * fills the shell end-to-end; rare components that genuinely need
 * a narrower readable measure (a long prose article, a focused
 * playback modal) cap themselves at the component level. See
 * AGENTS.md "One width for the whole site" for the rationale. */
#app-container {
    padding: 1.25rem;
    max-width: min(100% - 1.5rem, 2200px);
    margin: 0 auto;
}

.view {
    display: none;
    animation: fadeIn 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.view.active {
    display: block;
}

@keyframes fadeIn {
    from { opacity: 0; transform: translateY(15px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ===== SEASON VIEW ===== */

.season-header {
    display: flex;
    align-items: center;
    gap: 2.5rem;
    margin-bottom: 3.5rem;
}

.team-badge {
    width: 110px;
    height: 110px;
    border-radius: 50%;
    background: linear-gradient(135deg, #222, #111);
    border: 1px solid rgba(255,255,255,0.1);
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 10px 40px rgba(0,0,0,0.8);
    position: relative;
}

.team-badge::after {
    content: '';
    position: absolute;
    top: -2px; left: -2px; right: -2px; bottom: -2px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), transparent 70%);
    z-index: -1;
    opacity: 0.6;
}

.badge-logo {
    width: 65%;
    height: auto;
    object-fit: contain;
    z-index: 10;
}

.season-info h1 {
    font-size: 3.5rem;
    line-height: 1.1;
    margin-bottom: 0.5rem;
}

.season-info p {
    color: var(--text-muted);
    font-size: 1.15rem;
    max-width: 650px;
}

.controls-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.25rem;
    padding-bottom: 1.25rem;
    border-bottom: 1px solid var(--border-light);
}

.filter-group {
    display: flex;
    gap: 0.5rem;
}

.search-box {
    position: relative;
    display: flex;
    align-items: center;
}

.search-icon {
    position: absolute;
    left: 0.75rem;
    color: var(--text-muted);
    pointer-events: none;
}

.search-input {
    padding: 0.6rem 0.75rem 0.6rem 2.25rem;
    min-height: 40px;
    border-radius: 4px;
    border: 1px solid var(--border-light);
    background: var(--bg-dark);
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.85rem;
    width: 180px;
    transition: border-color 0.2s, width 0.2s;
}

.search-input:focus {
    outline: none;
    border-color: var(--accent);
    width: 240px;
}

.search-input::placeholder {
    color: var(--text-muted);
}

.filter-btn {
    padding: 0.7rem 1.4rem;
    min-height: 44px;
    border-radius: 4px;
    background: transparent;
    border: 1px solid transparent;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    transition: all 0.2s ease;
}

.filter-btn:hover {
    color: var(--text-main);
    background: rgba(255,255,255,0.03);
}

.filter-btn.active {
    background: var(--text-main);
    color: var(--bg-dark);
}

.stats-overview {
    display: flex;
    gap: 2.5rem;
}

.stat {
    font-size: 1.75rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.stat span {
    font-family: var(--font-body);
    font-size: 0.75rem;
    text-transform: uppercase;
    font-weight: 600;
    letter-spacing: 0.05em;
    color: var(--text-muted);
}

.team-stats-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.65rem;
    padding: 0.72rem 1rem;
    border-radius: 999px;
    border: 1px solid rgba(255,255,255,0.1);
    background: rgba(255,255,255,0.04);
    color: var(--text-main);
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

.team-stats-toggle:hover {
    border-color: rgba(23, 113, 201, 0.6);
    background: rgba(23, 113, 201, 0.1);
    transform: translateY(-1px);
}

.team-stats-toggle[aria-expanded="true"] {
    border-color: rgba(23, 113, 201, 0.75);
    background: rgba(23, 113, 201, 0.16);
}

.team-stats-toggle-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    line-height: 1;
    transform: rotate(0deg);
    transition: transform 0.24s ease;
}

.team-stats-toggle[aria-expanded="true"] .team-stats-toggle-icon {
    transform: rotate(180deg);
}

/* ===== TEAM STATS ===== */

.season-team-stats {
    margin-bottom: 2.5rem;
    padding: 1.5rem 1.6rem 1.7rem;
    border: 1px solid var(--border-light);
    border-radius: 18px;
    background:
        radial-gradient(circle at top right, rgba(23, 113, 201, 0.12), transparent 32%),
        linear-gradient(180deg, rgba(255,255,255,0.03), rgba(255,255,255,0.01));
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
    overflow: hidden;
    transform-origin: top;
    opacity: 1;
    max-height: 900px;
    transition: opacity 0.24s ease, transform 0.24s ease, max-height 0.3s ease, margin-bottom 0.24s ease, padding 0.24s ease, border-color 0.24s ease;
}

.season-team-stats.is-collapsed {
    opacity: 0;
    transform: translateY(-8px);
    max-height: 0;
    margin-bottom: 0;
    padding-top: 0;
    padding-bottom: 0;
    border-color: transparent;
    pointer-events: none;
}

.season-team-stats-head {
    display: flex;
    justify-content: space-between;
    align-items: end;
    gap: 1rem;
    margin-bottom: 1.35rem;
}

.season-team-stats-kicker {
    display: inline-block;
    margin-bottom: 0.35rem;
    color: var(--accent);
    font-size: 0.74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
}

.season-team-stats-head h2 {
    font-size: 2rem;
    line-height: 1;
}

.season-team-stats-head p {
    max-width: 540px;
    color: var(--text-muted);
    font-size: 0.95rem;
    text-align: right;
}

.team-stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 1rem;
}

.team-stat-card {
    position: relative;
    overflow: hidden;
    min-height: 138px;
    padding: 1.15rem 1.15rem 1.05rem;
    border-radius: 14px;
    border: 1px solid rgba(255,255,255,0.08);
    background: rgba(8, 8, 10, 0.62);
    display: flex;
    flex-direction: column;
    justify-content: space-between;
}

.team-stat-card::after {
    content: '';
    position: absolute;
    inset: auto -12% -40% auto;
    width: 120px;
    height: 120px;
    border-radius: 50%;
    opacity: 0.25;
    filter: blur(10px);
}

.team-stat-card.record::after {
    background: rgba(23, 113, 201, 0.65);
}

.team-stat-card.points::after {
    background: rgba(34, 197, 94, 0.55);
}

.team-stat-card.goals::after {
    background: rgba(244, 114, 182, 0.45);
}

.team-stat-card.difference::after {
    background: rgba(250, 204, 21, 0.4);
}

.team-stat-label {
    position: relative;
    z-index: 1;
    color: var(--text-muted);
    font-size: 0.76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
}

.team-stat-value {
    position: relative;
    z-index: 1;
    font-family: var(--font-heading);
    font-size: 2.75rem;
    line-height: 0.95;
    letter-spacing: 0.01em;
}

.team-stat-note {
    position: relative;
    z-index: 1;
    color: var(--text-muted);
    font-size: 0.88rem;
}

.team-stats-empty {
    color: var(--text-muted);
    font-size: 0.95rem;
    padding: 0.4rem 0.15rem 0;
}

.matches-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(380px, 1fr));
    gap: 1.5rem;
}

.match-card {
    position: relative;
    background: var(--bg-panel);
    border: 1px solid var(--border-light);
    border-radius: 12px;
    cursor: pointer;
    overflow: hidden;
    transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.4s ease;
    display: flex;
    flex-direction: column;
}

.match-card:not(.has-thumb) {
    padding: 2rem;
    min-height: 260px;
}

.card-thumb {
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: cover;
    display: block;
}

.card-body {
    position: relative;
    padding: 1.25rem 1.5rem 1.5rem;
    flex: 1;
    display: flex;
    flex-direction: column;
}

.card-body > * {
    position: relative;
    z-index: 1;
}

.match-card:hover {
    transform: translateY(-8px);
    border-color: var(--accent);
}

.card-bg {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    background: radial-gradient(circle at top right, rgba(23, 113, 201, 0.06), transparent 60%);
    z-index: 0;
    opacity: 0;
    transition: opacity 0.4s ease;
}

.match-card:hover .card-bg {
    opacity: 1;
}

.match-card > * {
    position: relative;
    z-index: 1;
}

.card-topline {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.35rem;
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.card-topline-label {
    color: var(--accent);
    font-weight: 700;
}

.card-topline-date {
    white-space: nowrap;
}

.card-matchup {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: 2rem;
    margin-bottom: 1rem;
}

.card-team-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    flex: 1;
    min-width: 0;
}

.team-side-label {
    font-size: 0.68rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 700;
}

.team-name-score-row {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.75rem;
    align-items: start;
}

.card-team-logo {
    width: 56px;
    height: 56px;
    object-fit: contain;
    border: none;
    background: transparent;
}

.card-team-initial {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-heading);
    font-size: 1.2rem;
    font-weight: 700;
    background: linear-gradient(135deg, #222, #111);
    border: 1px solid rgba(255,255,255,0.1);
    color: var(--text-muted);
}

.card-team-name {
    font-family: var(--font-heading);
    font-size: 0.95rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-align: left;
    line-height: 1.2;
    word-break: break-word;
}

.card-team-score {
    font-family: var(--font-heading);
    font-size: 2.2rem;
    font-weight: 700;
    line-height: 1;
    color: var(--text-main);
    min-width: 1.5ch;
    text-align: right;
}

.card-team-score.empty,
.game-team-score.empty {
    color: rgba(255,255,255,0.28);
}

.card-vs-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding-top: 1.2rem;
}

.card-vs {
    font-family: var(--font-heading);
    color: var(--text-muted);
    font-size: 0.8rem;
    letter-spacing: 0.1em;
}

.match-date {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: 0.15em;
    margin-bottom: 0.75rem;
    text-align: center;
}

.match-location {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-bottom: 0.75rem;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.match-detail-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.55rem;
    margin-bottom: 0.9rem;
    transition: opacity 0.3s ease;
}

.match-detail-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.38rem 0.72rem;
    border-radius: 999px;
    background: rgba(255,255,255,0.05);
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    transition: opacity 0.3s ease;
}

.match-detail-pill.location {
    max-width: 100%;
    white-space: normal;
    text-align: center;
    color: var(--text-main);
    gap: 0.35rem;
}

.pill-label {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
    opacity: 0.8;
}

.match-meta {
    margin-top: auto;
    display: flex;
    gap: 0.75rem;
    transition: opacity 0.3s ease;
}

.badge {
    padding: 0.35rem 0.7rem;
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    background: rgba(255,255,255,0.06);
}

.badge.score {
    background: var(--text-main);
    color: var(--bg-dark);
}

.badge.processing {
    background: rgba(255, 170, 0, 0.15);
    color: #ffaa00;
    animation: pulse-badge 2s ease-in-out infinite;
}

@keyframes pulse-badge {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.hover-reveal {
    position: absolute;
    bottom: -40px;
    left: 2rem;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--accent);
    letter-spacing: 0.1em;
    transition: bottom 0.4s cubic-bezier(0.16, 1, 0.3, 1);
    display: flex;
    align-items: center;
    gap: 0.5rem;
    pointer-events: none;
}

.match-card:hover .hover-reveal {
    bottom: 1.5rem;
}

.match-card:hover .match-meta,
.match-card:hover .match-detail-pill {
    opacity: 0;
}

.match-card-edit-btn {
    position: absolute;
    top: 1rem;
    right: 1rem;
    background: rgba(0, 0, 0, 0.5);
    border: 1px solid rgba(255,255,255,0.2);
    color: var(--text-muted);
    border-radius: 4px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s;
    z-index: 10;
    opacity: 0;
}

.match-card:hover .match-card-edit-btn {
    opacity: 1;
}

.match-card-edit-btn:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: white;
}

.match-card-delete-btn {
    position: absolute;
    top: 1rem;
    right: 3.5rem;
    background: rgba(0, 0, 0, 0.5);
    border: 1px solid rgba(255,74,74,0.3);
    color: var(--red);
    border-radius: 4px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s;
    z-index: 10;
    opacity: 0;
}

.match-card:hover .match-card-delete-btn {
    opacity: 1;
}

.match-card-delete-btn:hover {
    background: var(--red);
    border-color: var(--red);
    color: white;
}

/* ===== GAME VIEW ===== */

.back-btn {
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
    margin-bottom: 2rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    transition: color 0.2s ease;
}

.back-btn:hover {
    color: var(--accent);
}

.game-layout {
    display: grid;
    grid-template-columns: 1fr 420px;
    gap: 4rem;
}

.video-container {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.player-wrapper {
    aspect-ratio: 16/9;
    background: #000;
    border-radius: 12px;
    border: 1px solid rgba(255,255,255,0.1);
    position: relative;
    overflow: hidden;
    box-shadow: 0 30px 60px rgba(0,0,0,0.6);
}

.video-placeholder {
    width: 100%;
    height: 100%;
    background: linear-gradient(to bottom right, #09090b, #121215);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    background-image: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.3) 2px, rgba(0,0,0,0.3) 4px);
    background-size: 100% 4px;
}

.play-indicator {
    width: 90px;
    height: 90px;
    border-radius: 50%;
    background: rgba(23, 113, 201, 0.05);
    border: 2px solid var(--accent);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), background 0.3s ease;
    margin-bottom: 2rem;
}

.play-indicator::after {
    content: '';
    width: 0;
    height: 0;
    border-style: solid;
    border-width: 14px 0 14px 22px;
    border-color: transparent transparent transparent var(--accent);
    margin-left: 8px;
}

.play-indicator:hover {
    transform: scale(1.1);
    background: rgba(23, 113, 201, 0.15);
}

.player-label {
    font-family: var(--font-heading);
    color: var(--text-muted);
    letter-spacing: 0.25em;
    font-size: 0.9rem;
}

.player-controls {
    display: flex;
    gap: 1rem;
    padding: 1rem;
    background: var(--bg-panel);
    border-radius: 8px;
    border: 1px solid var(--border-light);
    align-items: center;
}

.player-controls button {
    padding: 0.75rem 1.5rem;
    border-radius: 4px;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    transition: all 0.2s ease;
}

.player-controls button.active {
    background: rgba(255,255,255,0.1);
    color: var(--text-main);
}

.player-controls button:hover:not(.active) {
    background: rgba(255,255,255,0.05);
}

.remote-playback-note {
    font-size: 0.84rem;
    color: var(--text-muted);
    padding: 0 0.15rem;
}

.download-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.download-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.8rem 1rem;
    border-radius: 10px;
    border: 1px solid rgba(255,255,255,0.1);
    background: rgba(255,255,255,0.04);
    color: var(--text-main);
    font-size: 0.88rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    transition: border-color 0.2s ease, background 0.2s ease, transform 0.2s ease;
}

.download-btn:hover {
    border-color: var(--accent);
    background: rgba(23, 113, 201, 0.14);
    transform: translateY(-1px);
}

.segment-pill-group {
    display: flex;
    gap: 0.5rem;
}

.segment-btn {
    padding: 0.5rem 1.25rem;
    border-radius: 4px;
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-muted);
    transition: all 0.2s ease;
    border: 1px solid transparent;
}

.segment-btn.active {
    background: rgba(255,255,255,0.1);
    color: var(--text-main);
    border-color: var(--border-light);
}

.segment-btn:hover:not(.active) {
    background: rgba(255,255,255,0.05);
}

.remote-action-group {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    margin-left: auto;
}

.remote-playback-btn,
.cast-btn {
    padding: 0.7rem 0.95rem !important;
    border-radius: 999px !important;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    border: 1px solid rgba(255,255,255,0.1) !important;
    background: rgba(255,255,255,0.04) !important;
    color: var(--text-muted) !important;
}

.remote-playback-btn span {
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.remote-playback-btn-disabled {
    opacity: 0.6;
}

.remote-playback-btn-disabled:hover {
    border-color: rgba(255,255,255,0.1) !important;
    color: var(--text-muted) !important;
}

.remote-playback-btn:hover,
.cast-btn:hover {
    border-color: var(--accent) !important;
    color: var(--text-main) !important;
}

.cast-btn.casting,
.remote-playback-btn.casting {
    color: var(--accent) !important;
    background: rgba(23, 113, 201, 0.15) !important;
}

.cast-overlay {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    background: rgba(0,0,0,0.85);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    z-index: 5;
}

.game-view-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    margin-bottom: 2rem;
}

.game-nav-group {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.match-nav-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 1px solid var(--border-light);
    background: var(--bg-panel);
    color: var(--text-muted);
    cursor: pointer;
    transition: all 0.2s ease;
}

.match-nav-btn:hover {
    color: var(--accent);
    border-color: var(--accent);
    background: rgba(23, 113, 201, 0.1);
}

.sidebar {
    display: flex;
    flex-direction: column;
    gap: 3rem;
}

.slot-status-card {
    padding: 1.35rem 1.45rem;
    border-radius: 14px;
    border: 1px solid rgba(255,255,255,0.08);
    background: linear-gradient(180deg, rgba(255,255,255,0.025), rgba(255,255,255,0.01));
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
}

.game-edit-btn {
    border: 1px solid rgba(11, 17, 32, 0.12);
    background: rgba(255, 255, 255, 0.88);
    color: #10203b;
    border-radius: 999px;
    padding: 8px 14px;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    cursor: pointer;
    transition: transform 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
}

.game-edit-btn:hover {
    transform: translateY(-1px);
    border-color: rgba(16, 32, 59, 0.24);
    box-shadow: 0 10px 20px rgba(16, 32, 59, 0.12);
}

.game-edit-btn:focus-visible {
    outline: 2px solid rgba(16, 32, 59, 0.35);
    outline-offset: 2px;
}

.status-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.35rem 0.7rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: rgba(255,255,255,0.06);
    color: var(--text-main);
}

.status-pill.ready,
.status-pill.resume {
    background: rgba(34, 197, 94, 0.12);
    color: #7be3a0;
}

.status-pill.processing {
    background: rgba(255, 170, 0, 0.14);
    color: #ffaa00;
}

.status-pill.danger {
    background: rgba(255, 74, 74, 0.14);
    color: #ff8f8f;
}

.status-pill.neutral {
    background: rgba(255,255,255,0.06);
    color: var(--text-main);
}

.game-meta-row {
    display: flex;
    gap: 2.5rem;
    padding-bottom: 2rem;
    border-bottom: 1px solid var(--border-light);
}

.g-meta {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    font-size: 0.95rem;
    font-weight: 500;
}

.g-meta .label {
    font-size: 0.7rem;
    color: var(--text-muted);
    font-weight: 700;
    letter-spacing: 0.1em;
}

.game-details {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.game-slot-status-list {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.slot-status-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding-top: 0.85rem;
    border-top: 1px solid rgba(255,255,255,0.08);
}

.slot-status-row:first-child {
    border-top: none;
    padding-top: 0;
}

.slot-status-label {
    font-size: 0.92rem;
    font-weight: 600;
    color: var(--text-main);
}

.sidebar h3 {
    font-size: 1.25rem;
    margin-bottom: 1.5rem;
    position: relative;
    padding-left: 1.25rem;
}

.sidebar h3::before {
    content: '';
    position: absolute;
    left: 0;
    top: 4px;
    bottom: 4px;
    width: 4px;
    background: var(--accent);
}

.game-matchup {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    gap: 2rem;
    margin-bottom: 1.5rem;
}

.game-team-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.55rem;
    flex: 1;
    min-width: 0;
}

.game-side-label {
    font-size: 0.72rem;
}

.game-team-name-score-row {
    width: 100%;
    max-width: 240px;
}

.game-logo-large {
    width: 72px;
    height: 72px;
    object-fit: contain;
    border: none;
    background: transparent;
}

.game-logo-initial-large {
    width: 72px;
    height: 72px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-heading);
    font-size: 1.75rem;
    font-weight: 700;
    background: linear-gradient(135deg, #222, #111);
    border: 2px solid rgba(255,255,255,0.1);
    color: var(--text-muted);
}

.game-team-name {
    font-family: var(--font-heading);
    font-size: 1.1rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    text-align: left;
    line-height: 1.2;
    word-break: break-word;
}

.game-team-score {
    font-family: var(--font-heading);
    font-size: 2.8rem;
    font-weight: 700;
    line-height: 1;
    color: var(--text-main);
    min-width: 1.8ch;
    text-align: right;
}

.game-vs-col {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding-top: 1.5rem;
    font-family: var(--font-heading);
    color: var(--text-muted);
    font-size: 0.9rem;
    letter-spacing: 0.1em;
}

@media (max-width: 1300px) {
    .game-view-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 1rem;
    }
    .game-layout {
        grid-template-columns: 1fr;
    }
    .sidebar {
        display: grid;
        grid-template-columns: 1fr;
        gap: 2rem;
    }
}
@media (min-width: 768px) and (max-width: 1300px) {
    .sidebar {
        grid-template-columns: 1fr 1fr;
        gap: 3rem;
    }
    .game-details {
        grid-column: 1 / -1;
    }
}

/* ===== FORMS ===== */

.options-container {
    max-width: 800px;
    margin: 4rem auto;
    padding: 2.5rem;
    background:
        radial-gradient(circle at top right, rgba(23, 113, 201, 0.08), transparent 28%),
        linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01)),
        var(--bg-panel);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 18px;
    box-shadow: 0 28px 70px rgba(0, 0, 0, 0.35);
}

.options-container h2 {
    font-family: var(--font-heading);
    font-size: 2.1rem;
    line-height: 1;
    margin-bottom: 0.65rem;
    color: var(--text-main);
    letter-spacing: 0.03em;
}

.options-container p {
    color: var(--text-muted);
    margin-bottom: 2.25rem;
    font-size: 1rem;
    max-width: 44rem;
    line-height: 1.65;
}

.options-card {
    background: var(--bg-card);
    padding: 1.6rem;
    border-radius: 14px;
    border: 1px solid rgba(255,255,255,0.09);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
}

.options-card h3 {
    font-family: var(--font-heading);
    font-size: 1.35rem;
    margin-bottom: 1.25rem;
    color: var(--text-main);
    letter-spacing: 0.04em;
}

.form-group {
    margin-bottom: 1.1rem;
}

.form-row {
    display: flex;
    gap: 1.15rem;
}

.form-row .form-group {
    flex: 1;
}

.form-group label {
    display: block;
    margin-bottom: 0.6rem;
    font-size: 0.8rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
}

.label-optional {
    font-size: 0.72rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    opacity: 0.65;
}

.form-group input[type="text"],
.form-group input[type="date"],
.form-group input[type="time"],
.form-group input[type="number"],
.form-group input[type="password"],
.form-group textarea {
    width: 100%;
    padding: 0.95rem 1rem;
    background: rgba(0, 0, 0, 0.38);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 10px;
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 1rem;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}

input[type="number"] {
    appearance: textfield;
    -moz-appearance: textfield;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
    opacity: 0.75;
    cursor: pointer;
    filter: invert(1) saturate(0.3);
}

.form-group textarea {
    resize: vertical;
    min-height: 120px;
}

.form-group input:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--accent);
    background: rgba(0, 0, 0, 0.5);
    box-shadow: 0 0 0 3px rgba(23, 113, 201, 0.14);
}

.settings-checkbox-group {
    display: flex;
    align-items: flex-end;
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 54px;
    padding: 0.95rem 1rem;
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.38);
    cursor: pointer;
    user-select: none;
    transition: border-color 0.15s, background 0.15s;
}

.checkbox-label:has(input:checked) {
    border-color: rgba(23, 113, 201, 0.5);
    background: rgba(23, 113, 201, 0.08);
}

.checkbox-label:focus-within {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 10px;
}

.checkbox-label input[type="checkbox"] {
    -webkit-appearance: none;
    appearance: none;
    width: 18px;
    height: 18px;
    flex: 0 0 auto;
    border: 2px solid rgba(255, 255, 255, 0.25);
    border-radius: 4px;
    background: transparent;
    position: relative;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.checkbox-label input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.checkbox-label input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    left: 3px;
    top: 0px;
    width: 5px;
    height: 9px;
    border: 2px solid #fff;
    border-top: none;
    border-left: none;
    transform: rotate(45deg);
}

.radio-group {
    display: flex;
    gap: 0.9rem;
    flex-wrap: wrap;
}

.radio-label {
    display: flex;
    align-items: center;
    padding: 0.85rem 1.2rem;
    border: 1px solid var(--border-light);
    border-radius: 999px;
    background: transparent;
    cursor: pointer;
    user-select: none;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}

.radio-label input[type="radio"] {
    display: none;
}

.radio-label:has(input:checked) {
    background: var(--text-main);
    color: var(--bg-dark);
    border-color: var(--text-main);
}

.radio-label:not(:has(input:checked)):hover {
    border-color: rgba(255, 255, 255, 0.2);
    color: var(--text-main);
}

.radio-label:focus-within {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.file-upload-row {
    display: flex;
    align-items: center;
    gap: 0;
    min-width: 0;
    padding: 0;
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.38);
    overflow: hidden;
    min-height: 3.4rem;
    transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}

.file-upload-row:focus-within {
    border-color: rgba(23, 113, 201, 0.85);
    background: rgba(0, 0, 0, 0.5);
    box-shadow: 0 0 0 3px rgba(23, 113, 201, 0.14);
}

.file-input {
    font-size: 0.9rem;
    color: var(--text-muted);
}

.file-input-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Use .file-upload-row .file-picker-button so this rule beats
   .form-group label on specificity — that base rule injects margin-bottom,
   display:block, font-size:0.8rem, and text-transform that otherwise leak
   through and break layout.
   align-self:stretch makes the button fill row height so the hairline
   divider runs edge-to-edge; padding shrinks because the row's min-height
   already enforces the input-matching height. */
.file-upload-row .file-picker-button,
.file-picker-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: stretch;
    margin: 0;
    padding: 0 1.25rem;
    background: transparent;
    border: none;
    border-right: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 0;
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    line-height: 1;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s ease, color 0.2s ease;
    flex: 0 0 auto;
}

.file-picker-button:hover {
    background: rgba(23, 113, 201, 0.10);
    color: var(--accent);
}

.file-input::file-selector-button {
    padding: 0.5rem 1rem;
    background: var(--bg-dark);
    border: 1px solid var(--border-light);
    border-radius: 4px;
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.85rem;
    cursor: pointer;
    transition: all 0.2s;
}

.file-input::file-selector-button:hover {
    border-color: var(--accent);
}

.file-label {
    font-size: 0.85rem;
    color: var(--text-muted);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    padding: 0 1rem;
    line-height: 1.35;
}

.uploaded-state {
    margin-top: 0.55rem;
    font-size: 0.82rem;
    color: var(--text-muted);
    line-height: 1.45;
}

.uploaded-state.ready {
    color: #7be3a0;
}

.uploaded-state.pending {
    color: #9ccfff;
}

/* ===== UPLOAD PROGRESS ===== */

.upload-progress {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
}

.progress-bar {
    flex: 1;
    height: 8px;
    background: var(--bg-dark);
    border-radius: 999px;
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    background: var(--accent);
    border-radius: 999px;
    width: 0%;
    transition: width 0.3s ease;
}

.progress-fill.indeterminate {
    width: 35%;
    animation: upload-indeterminate 1.2s ease-in-out infinite;
}

@keyframes upload-indeterminate {
    0% { transform: translateX(-30%); }
    50% { transform: translateX(80%); }
    100% { transform: translateX(-30%); }
}

.progress-text {
    font-size: 0.8rem;
    color: var(--text-muted);
    min-width: 88px;
    text-align: right;
}

.btn-primary, .btn-secondary, .btn-danger {
    /* Stepped twice from the original 0.95rem/1.6rem (#36 first, then #37).
       0.45rem/0.85rem keeps Save/Cancel ≥30 px tall so mobile tap targets
       are fine, but the global primary tier no longer dominates cards. */
    padding: 0.45rem 0.85rem;
    border: none;
    border-radius: 6px;
    font-family: var(--font-heading);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s ease;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

/* Section-head action button — quieter than the primary tier so it sits
   alongside data without competing with it. Used by every button inside
   an .admin-panel-head action row across the admin: Refresh, 60-s capture,
   Copy snapshot, Download (Performance · Encoder & Host); Refresh,
   Backfill HLS, Cleanup uploads, Export DB (Performance · Disk &
   Diagnostics); the three Tuning preset buttons; etc. Visually identical
   to .mini-action-btn but applied at section-head level. */
.btn-head {
    padding: 0.32rem 0.7rem;
    border-radius: 6px;
    border: 1px solid var(--border-light);
    background: transparent;
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.btn-head:hover {
    border-color: var(--accent);
    background: rgba(23, 113, 201, 0.08);
}

.btn-head:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.btn-primary {
    background: var(--accent);
    color: var(--text-main);
    box-shadow: 0 10px 24px rgba(23, 113, 201, 0.22);
}

.btn-primary:hover {
    background: var(--accent-hover);
}

.btn-primary:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-secondary {
    background: transparent;
    color: var(--text-main);
    border: 1px solid var(--border-light);
}

.btn-secondary:hover {
    background: rgba(255,255,255,0.05);
}

.btn-danger {
    background: transparent;
    color: var(--red);
    border: 1px solid var(--red);
}

.btn-danger:hover {
    background: rgba(255, 74, 74, 0.1);
}

.btn-sm {
    padding: 0.4rem 0.8rem;
    border: 1px solid var(--border-light);
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    font-size: 0.75rem;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-sm:hover {
    color: var(--text-main);
    border-color: var(--accent);
}

.btn-sm.btn-danger {
    padding: 0.4rem 0.8rem;
    font-size: 0.75rem;
    border-radius: 6px;
}

.user-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.user-row:last-child {
    border-bottom: none;
}

.user-info {
    flex: 1;
    min-width: 0;
}

.user-name {
    font-weight: 600;
    display: block;
}

.user-username {
    font-size: 0.8rem;
    color: var(--text-muted);
}

.user-actions {
    display: flex;
    gap: 0.4rem;
}

.user-add-form {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.user-add-form h4 {
    margin-bottom: 1rem;
    font-size: 1rem;
}

.form-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

/* ===== ADMIN PANEL ===== */

.admin-ops-card {
    margin-top: 2rem;
}

.admin-panel-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.admin-panel-copy {
    color: var(--text-muted);
    margin-top: 0.35rem;
    font-size: 0.92rem;
    line-height: 1.5;
}

.admin-panel-actions {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.diagnostics-grid {
    display: grid;
    /* Tighter tile minimum so 8 perf tiles fit on a single row at desktop
       width (8 × 140 = 1120 px). The full-width Encoder & Host card now
       gives them the room. */
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.7rem;
    margin-bottom: 1.25rem;
}

.diagnostic-card {
    padding: 0.85rem 0.95rem;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.18);
    border: 1px solid rgba(255,255,255,0.08);
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.diagnostic-card.danger {
    border-color: rgba(255, 74, 74, 0.35);
}

.diagnostic-label {
    font-size: 0.68rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 700;
}

.diagnostic-value {
    font-family: var(--font-heading);
    font-size: 1.7rem;
    letter-spacing: 0.04em;
    /* Bumped from 1.5 → 1.7 rem so the metric reads as the primary
       focus when an admin is watching the tile during a tuning change. */
}

.diagnostic-note {
    color: var(--text-muted);
    font-size: 0.78rem;
}

.diagnostics-columns {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

.diagnostics-section {
    padding: 1rem;
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.22);
    border: 1px solid rgba(255,255,255,0.08);
}

.diagnostics-section-title {
    font-family: var(--font-heading);
    font-size: 1rem;
    letter-spacing: 0.05em;
    margin-bottom: 0.9rem;
}

.session-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.session-item {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem 0.95rem;
    border-radius: 10px;
    background: rgba(255,255,255,0.025);
    border: 1px solid rgba(255,255,255,0.06);
}

.session-main {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.session-title-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}

.session-meta {
    font-size: 0.84rem;
    color: var(--text-muted);
    word-break: break-word;
}

.session-actions {
    display: flex;
    align-items: center;
}

.mini-action-btn {
    padding: 0.32rem 0.65rem;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,0.1);
    background: rgba(255,255,255,0.04);
    color: var(--text-main);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
}

.mini-action-btn:hover {
    border-color: var(--accent);
}

/* Variant for the row's primary action (e.g. Watch / Play in My Feedback).
   Same footprint as .mini-action-btn so it stays in the row-level tier; the
   accent fill just signals which button is the dominant one in the row. */
.mini-action-btn-primary {
    background: rgba(23, 113, 201, 0.18);
    border-color: rgba(23, 113, 201, 0.42);
    color: var(--text-main);
}

.mini-action-btn-primary:hover {
    background: rgba(23, 113, 201, 0.28);
    border-color: var(--accent);
}

[data-theme="light"] .mini-action-btn-primary {
    background: rgba(23, 113, 201, 0.14);
    border-color: rgba(23, 113, 201, 0.4);
}

[data-theme="light"] .mini-action-btn-primary:hover {
    background: rgba(23, 113, 201, 0.22);
}

.session-empty {
    color: var(--text-muted);
    font-size: 0.88rem;
}

/* ===== UTILITIES & RESPONSIVE ===== */

.mt-2 { margin-top: 1rem; }
.mt-4 { margin-top: 2rem; }
.games-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.config-game-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
    background: var(--bg-dark);
    border: 1px solid var(--border-light);
    border-radius: 6px;
}

.config-game-info strong {
    display: block;
    color: var(--text-main);
    margin-bottom: 0.25rem;
}

.config-game-info span {
    font-size: 0.85rem;
    color: var(--text-muted);
}

.config-game-actions {
    display: flex;
    gap: 0.5rem;
}

.main-video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
    display: none;
}

.main-video.active {
    display: block;
}

@media (max-width: 768px) {
    .options-container {
        margin: 2rem auto;
        padding: 1.4rem;
        border-radius: 14px;
    }
    .options-container h2 {
        font-size: 1.75rem;
    }
    .options-card {
        padding: 1.15rem;
        border-radius: 12px;
    }
    .main-nav {
        padding: 1rem 1.5rem;
        flex-wrap: wrap;
        justify-content: center;
    }
    .logo {
        width: 100%;
        text-align: center;
    }
    .nav-links,
    .nav-actions {
        width: 100%;
        justify-content: center;
    }
    .nav-links {
        gap: 0.75rem;
        flex-wrap: wrap;
    }
    .nav-links a {
        padding: 0.7rem 1rem;
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        border: 1px solid rgba(255,255,255,0.08);
        border-radius: 999px;
        background: rgba(255,255,255,0.03);
    }
    .nav-links a.active::after {
        display: none;
    }
    .nav-actions {
        display: flex;
    }
    .nav-auth-btn {
        width: 100%;
    }
    #app-container {
        padding: 1.5rem;
    }
    .season-header {
        flex-direction: column;
        text-align: center;
        gap: 1.5rem;
    }
    .season-info h1 {
        font-size: 2.5rem;
    }
    .controls-bar {
        flex-direction: column;
        align-items: stretch;
        gap: 1rem;
    }
    .search-box,
    .search-input {
        width: 100%;
    }
    .search-input:focus {
        width: 100%;
    }
    .season-team-stats-head {
        flex-direction: column;
        align-items: flex-start;
    }
    .season-team-stats-head p {
        text-align: left;
        max-width: none;
    }
    .team-stats-toggle {
        width: 100%;
    }
    .game-view-head,
    .admin-panel-head,
    .diagnostics-columns,
    .slot-status-row {
        width: 100%;
        justify-content: flex-start;
    }
    .session-item {
        grid-template-columns: 1fr;
        flex-direction: column;
        align-items: stretch;
    }
    .matches-grid {
        grid-template-columns: 1fr;
    }
    .game-view-head {
        gap: 1rem;
        margin-bottom: 1.25rem;
    }
    .game-matchup {
        gap: 0.9rem;
    }
    .score-reveal-chip-large {
        padding: 0.3rem 0.7rem;
        min-height: 32px;
        font-size: 0.68rem;
        letter-spacing: 0.14em;
    }
    .game-meta-row {
        flex-direction: column;
        gap: 1rem;
    }
    .player-controls {
        flex-wrap: wrap;
    }
    .remote-action-group {
        width: 100%;
        margin-left: 0;
        justify-content: flex-start;
    }
    .download-actions {
        width: 100%;
    }
    .download-btn {
        width: 100%;
    }
    .team-name-score-row,
    .game-team-name-score-row {
        gap: 0.5rem;
    }
    .match-detail-row {
        flex-direction: column;
        align-items: stretch;
    }
    .form-row {
        flex-direction: column;
        gap: 0;
    }
    .radio-group {
        flex-direction: column;
        gap: 0.65rem;
    }
    .file-upload-row {
        align-items: stretch;
        flex-direction: column;
    }
    .file-picker-button {
        width: 100%;
    }
    .file-label {
        padding: 0.1rem 0.2rem 0;
    }
    .form-actions {
        flex-direction: column;
    }
    .btn-primary,
    .btn-secondary {
        width: 100%;
    }
    .admin-panel-actions {
        width: 100%;
    }
}

@media (max-width: 520px) {
    .team-stats-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 480px) {
    .logo {
        font-size: 1.4rem;
    }
    .season-info h1 {
        font-size: 1.9rem;
    }
    .main-nav {
        padding: 0.85rem 1.1rem;
    }
    #app-container {
        padding: 1.1rem;
    }
}

/* ===== LOGIN MODAL ===== */

.login-modal {
    position: fixed;
    top: 0; left: 0; width: 100vw; height: 100vh;
    z-index: 500;
    display: flex;
    align-items: center;
    justify-content: center;
}

.login-modal-backdrop {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
}

.login-modal-content {
    position: relative;
    background: var(--bg-panel);
    border: 1px solid var(--border-light);
    border-radius: 12px;
    padding: 2.5rem;
    width: 100%;
    max-width: 400px;
    z-index: 1;
}

.login-modal-content h2 {
    font-family: var(--font-heading);
    margin-bottom: 1.5rem;
    text-align: center;
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.nav-auth-btn {
    padding: 0.65rem 1.2rem;
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    border-radius: 4px;
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    border: 1px solid var(--border-light);
    color: var(--text-muted);
    transition: all 0.2s;
}

.nav-auth-btn:hover {
    border-color: var(--accent);
    color: var(--text-main);
}

/* ===== TOAST NOTIFICATIONS ===== */

.toast-container {
    position: fixed;
    bottom: 1.5rem;
    right: 1.5rem;
    z-index: 9999;
    display: flex;
    flex-direction: column-reverse;
    gap: 0.5rem;
    pointer-events: none;
    max-width: min(420px, calc(100vw - 2rem));
}

.toast {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.75rem 1rem;
    border-radius: 8px;
    background: var(--bg-panel);
    border: 1px solid var(--border-light);
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.875rem;
    line-height: 1.4;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
    pointer-events: auto;
    opacity: 0;
    transform: translateY(0.75rem);
    transition: opacity 0.25s ease, transform 0.25s ease;
}

.toast-visible {
    opacity: 1;
    transform: translateY(0);
}

.toast-exit {
    opacity: 0;
    transform: translateY(0.75rem);
}

.toast svg {
    flex-shrink: 0;
}

.toast-text {
    flex: 1;
    min-width: 0;
    word-break: break-word;
}

.toast-dismiss {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 2px;
    display: flex;
    align-items: center;
    transition: color 0.15s;
}

.toast-dismiss:hover {
    color: var(--text-main);
}

.toast-success {
    border-color: rgba(34, 197, 94, 0.3);
}

.toast-success svg:first-child {
    color: var(--green);
}

.toast-error {
    border-color: rgba(255, 74, 74, 0.3);
}

.toast-error svg:first-child {
    color: var(--red);
}

.toast-info {
    border-color: rgba(23, 113, 201, 0.3);
}

.toast-info svg:first-child {
    color: var(--accent);
}

.btn-loading {
    opacity: 0.7;
    cursor: wait;
}

@media (max-width: 600px) {
    .toast-container {
        bottom: 1rem;
        right: 1rem;
        left: 1rem;
        max-width: none;
    }
}

/* ===== PROGRESS BARS (admin panel) ===== */

.progress-bar-container {
    width: 100%;
    height: 6px;
    background: var(--bg-dark);
    border-radius: 3px;
    margin-top: 0.4rem;
    overflow: hidden;
}

.progress-bar {
    height: 100%;
    background: var(--accent);
    border-radius: 3px;
    transition: width 0.3s ease;
}

.error-details {
    color: var(--text-muted);
    font-size: 0.75rem;
    word-break: break-all;
}

/* ===== THEME TOGGLE BUTTON ===== */

.nav-icon-btn {
    background: none;
    border: 1px solid var(--border-light);
    border-radius: 50%;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: var(--text-muted);
    transition: color 0.2s, border-color 0.2s;
}

.nav-icon-btn:hover {
    color: var(--text-main);
    border-color: var(--accent);
}

/* ===== LIGHT THEME OVERRIDES ===== */

[data-theme="light"] .noise-overlay {
    display: none;
}

[data-theme="light"] .team-badge {
    background: linear-gradient(135deg, #e8e8ec, #d8d8dc);
    border-color: rgba(0,0,0,0.1);
    box-shadow: 0 10px 40px rgba(0,0,0,0.12);
}

/* The dark-mode badge has an accent halo behind the circle (.team-badge::after).
   In light mode that halo reads as an obvious blue tint against the page
   background, so suppress it. The light-mode box-shadow above is the visual
   ring. */
[data-theme="light"] .team-badge::after {
    display: none;
}

[data-theme="light"] .match-card {
    background: linear-gradient(135deg, #fff, #f8f8fa);
    border-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .match-card:hover {
    border-color: var(--accent);
    box-shadow: 0 4px 20px rgba(0,0,0,0.08);
}

[data-theme="light"] .game-view-card {
    background: linear-gradient(135deg, #fff, #f8f8fa);
    border-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .player-wrapper {
    border-color: transparent;
    box-shadow: none;
    background: transparent;
}

[data-theme="light"] .main-video {
    background: transparent;
}

[data-theme="light"] .slot-status-card {
    border-color: rgba(0,0,0,0.08);
    background: rgba(0,0,0,0.02);
    box-shadow: none;
}

[data-theme="light"] .modal-content {
    background: var(--bg-panel);
    border-color: rgba(0,0,0,0.12);
    box-shadow: 0 30px 60px rgba(0,0,0,0.15);
}

[data-theme="light"] .modal-overlay {
    background: rgba(0,0,0,0.4);
}

/* Light theme — pure white inputs sit on the off-white panel like
   paper slips on a desk. Higher specificity beats .form-group input rules.
   Use background-color (not the `background` shorthand) so we don't reset
   background-image / background-repeat / background-size on <select>. */
[data-theme="light"] input,
[data-theme="light"] textarea,
[data-theme="light"] .form-group input[type="text"],
[data-theme="light"] .form-group input[type="date"],
[data-theme="light"] .form-group input[type="time"],
[data-theme="light"] .form-group input[type="number"],
[data-theme="light"] .form-group input[type="password"],
[data-theme="light"] .form-group select,
[data-theme="light"] .form-group textarea {
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
    color: var(--text-main);
}

[data-theme="light"] .form-group input::placeholder,
[data-theme="light"] .form-group textarea::placeholder {
    color: rgba(0, 0, 0, 0.34);
}

[data-theme="light"] input[type="date"]::-webkit-calendar-picker-indicator,
[data-theme="light"] input[type="time"]::-webkit-calendar-picker-indicator {
    filter: none;
    opacity: 0.62;
}

[data-theme="light"] input:focus,
[data-theme="light"] textarea:focus,
[data-theme="light"] .form-group input:focus,
[data-theme="light"] .form-group textarea:focus,
[data-theme="light"] .form-group select:focus {
    background-color: #ffffff;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(21, 101, 192, 0.14);
}

/* File upload row in light theme keeps the unified-pill shape from the
   base rule but recolors to white with a darker hairline divider. */
[data-theme="light"] .file-upload-row {
    background: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
}

[data-theme="light"] .file-upload-row:focus-within {
    border-color: var(--accent);
    background: #ffffff;
    box-shadow: 0 0 0 3px rgba(21, 101, 192, 0.14);
}

[data-theme="light"] .file-upload-row .file-picker-button {
    border-right-color: rgba(0, 0, 0, 0.10);
    color: var(--text-main);
}

[data-theme="light"] .file-upload-row .file-picker-button:hover {
    background: rgba(21, 101, 192, 0.06);
    color: var(--accent);
}

/* Upload status text — saturated colors for legibility on white. */
[data-theme="light"] .uploaded-state.ready {
    color: #15803d;
}

[data-theme="light"] .uploaded-state.pending {
    color: var(--accent);
}

[data-theme="light"] .options-card {
    background:
        linear-gradient(180deg, rgba(0,0,0,0.01), rgba(0,0,0,0.02)),
        var(--bg-panel);
    border-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .diagnostic-card {
    border-color: rgba(0,0,0,0.08);
    background: rgba(0,0,0,0.02);
}

[data-theme="light"] .session-item {
    background: rgba(0,0,0,0.02);
    border-color: rgba(0,0,0,0.06);
}

/* Performance section: diagnostics accordions and the HLS-ladder <details>
   wrapper need their dark-mode rgba(255,255,255,…) backgrounds flipped to
   black-alpha for light mode — otherwise both panels read as flat / nearly
   invisible against the off-white page. Same convention as .session-item /
   .diagnostic-card above. */
[data-theme="light"] .diag-accordion {
    background: rgba(0,0,0,0.02);
    border-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .tuning-knobs-grid .form-group-details {
    background: rgba(0,0,0,0.015);
    border-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .status-pill {
    background: rgba(0,0,0,0.06);
    color: var(--text-main);
}

[data-theme="light"] .status-pill.ready,
[data-theme="light"] .status-pill.resume {
    background: rgba(22, 163, 74, 0.12);
    color: #15803d;
}

[data-theme="light"] .status-pill.processing {
    background: rgba(217, 119, 6, 0.12);
    color: #b45309;
}

[data-theme="light"] .status-pill.danger {
    background: rgba(220, 38, 38, 0.12);
    color: #dc2626;
}

[data-theme="light"] .status-pill.neutral {
    background: rgba(0,0,0,0.06);
    color: var(--text-muted);
}

[data-theme="light"] .tab-selector button {
    border-color: rgba(0,0,0,0.1);
    background: rgba(0,0,0,0.03);
}

[data-theme="light"] .tab-selector button.active {
    border-color: var(--accent);
    background: var(--bg-panel);
}

[data-theme="light"] .filter-btn {
    border-color: rgba(0,0,0,0.1);
    background: rgba(0,0,0,0.03);
}

[data-theme="light"] .filter-btn.active {
    background: var(--text-main);
    color: var(--bg-panel);
}

[data-theme="light"] .checkbox-label input[type="checkbox"] {
    border-color: rgba(0, 0, 0, 0.3);
}

[data-theme="light"] .radio-label:not(:has(input:checked)):hover {
    border-color: rgba(0, 0, 0, 0.2);
}

[data-theme="light"] .radio-label:has(input:checked) {
    color: var(--bg-panel);
}

[data-theme="light"] .btn-primary {
    color: #fff;
}

[data-theme="light"] .btn-secondary {
    background: rgba(0,0,0,0.05);
    border-color: rgba(0,0,0,0.12);
}

[data-theme="light"] .btn-secondary:hover {
    border-color: var(--accent);
}

[data-theme="light"] .mini-action-btn {
    background: rgba(0,0,0,0.05);
}

[data-theme="light"] .toast {
    background: var(--bg-panel);
    border-color: rgba(0,0,0,0.1);
    box-shadow: 0 4px 20px rgba(0,0,0,0.1);
}

[data-theme="light"] .search-input {
    background: var(--bg-panel);
    border-color: rgba(0,0,0,0.1);
}

[data-theme="light"] .user-row {
    border-color: rgba(0,0,0,0.06);
}

[data-theme="light"] .main-nav {
    background: rgba(255, 255, 255, 0.85);
    border-bottom-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .season-team-stats {
    background:
        radial-gradient(circle at top right, rgba(23, 113, 201, 0.08), transparent 32%),
        var(--bg-panel);
    box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}

[data-theme="light"] .team-stat-card {
    background: var(--bg-panel);
    border-color: rgba(0,0,0,0.10);
    box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}

[data-theme="light"] .team-stat-card .stat {
    color: var(--text-main);
}

[data-theme="light"] .team-stat-label {
    color: var(--text-muted);
}

[data-theme="light"] .team-stat-sub {
    color: var(--text-muted);
}

[data-theme="light"] .nav-icon-btn {
    border-color: rgba(0,0,0,0.15);
    color: var(--text-muted);
}

[data-theme="light"] .nav-icon-btn:hover {
    border-color: var(--accent);
    color: var(--accent);
}

[data-theme="light"] .nav-auth-btn {
    border-color: rgba(0,0,0,0.15);
    color: var(--text-muted);
}

[data-theme="light"] .nav-auth-btn:hover {
    border-color: var(--accent);
    color: var(--text-main);
}

/* ===== Live View ===== */
.live-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 2rem;
    margin-bottom: 2rem;
}

.live-header-text {
    max-width: 720px;
}

.live-kicker {
    display: inline-block;
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.3em;
    color: var(--accent);
    font-size: 0.75rem;
    margin-bottom: 0.5rem;
}

.live-header h1 {
    font-size: 3rem;
    line-height: 1.1;
    margin-bottom: 0.5rem;
}

.live-header p {
    color: var(--text-muted);
    font-size: 1.05rem;
}

.live-status-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 1rem;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(0, 0, 0, 0.3);
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.2em;
    font-size: 0.75rem;
    color: var(--text-muted);
    flex-shrink: 0;
}

.live-status-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #555;
    box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
}

.live-status-badge[data-state="live"] {
    border-color: rgba(220, 38, 38, 0.55);
    color: #ff6b6b;
}

.live-status-badge[data-state="live"] .live-status-dot {
    background: #ef4444;
    animation: live-pulse 1.6s ease-in-out infinite;
}

.live-status-badge[data-state="offline"] .live-status-dot {
    background: #555;
}

.live-status-badge[data-state="disabled"] .live-status-dot {
    background: #4a4a52;
}

@keyframes live-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.5); }
    50% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
}

.live-stage {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.live-player-wrapper {
    aspect-ratio: 16/9;
}

.live-placeholder {
    gap: 0.6rem;
}

.player-sublabel {
    color: var(--text-muted);
    font-size: 0.9rem;
    max-width: 420px;
    text-align: center;
    margin-top: 0.25rem;
}

.live-meta-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--text-muted);
    font-size: 0.9rem;
}

.live-meta-text {
    color: var(--text-muted);
}

@media (max-width: 720px) {
    .live-header {
        flex-direction: column;
        gap: 1rem;
    }
    .live-header h1 {
        font-size: 2.25rem;
    }
}

/* ===== Settings — Live Streaming card ===== */
/*
   Stacked layout: label on top, monospace value next, actions on a third
   row. Works equally well in the narrow Live Console left-rail (~320 px
   wide) and a full-width settings card. Earlier 3-column grid (160 / 1fr
   / auto) crushed the value column inside the rail, forcing vertical
   word-break and pushing the action buttons outside the card.
*/
.live-settings-card .live-config-row {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.45rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.live-settings-card .live-config-row:last-child {
    border-bottom: none;
}

.live-config-label {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.15em;
    font-size: 0.7rem;
    color: var(--text-muted);
}

.live-config-value {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
    min-width: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
    color: var(--text-main);
    background: rgba(0, 0, 0, 0.25);
    padding: 0.45rem 0.6rem;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    white-space: normal;
}

.live-config-value.is-secret {
    letter-spacing: 0.15em;
    white-space: normal;
}

.live-config-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

[data-theme="light"] .live-status-badge {
    background: rgba(255, 255, 255, 0.7);
    border-color: rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .live-config-value {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .live-settings-card .live-config-row {
    border-bottom-color: rgba(0, 0, 0, 0.08);
}

/* ===== Season-view live CTA ===== */
.season-header {
    flex-wrap: wrap;
}

.season-info {
    flex: 1 1 320px;
}

.season-live-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1.1rem 0.85rem 1.25rem;
    border-radius: 14px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: linear-gradient(135deg, rgba(23, 113, 201, 0.18), rgba(23, 113, 201, 0.04));
    color: var(--text-main);
    text-decoration: none;
    transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.25s ease, background 0.25s ease, box-shadow 0.25s ease;
    flex-shrink: 0;
}

.season-live-cta:hover {
    transform: translateY(-2px);
    border-color: var(--accent);
    box-shadow: 0 12px 28px rgba(23, 113, 201, 0.25);
}

.season-live-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: #555;
    flex-shrink: 0;
}

.season-live-label {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    line-height: 1.1;
}

.season-live-kicker {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.2em;
    font-size: 0.7rem;
    color: var(--text-muted);
}

.season-live-text {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 1rem;
    letter-spacing: 0.05em;
}

.season-live-arrow {
    color: var(--text-muted);
    transition: transform 0.25s ease, color 0.25s ease;
}

.season-live-cta:hover .season-live-arrow {
    color: var(--accent);
    transform: translateX(3px);
}

.season-live-cta[data-state="live"] {
    border-color: rgba(239, 68, 68, 0.55);
    background: linear-gradient(135deg, rgba(239, 68, 68, 0.22), rgba(239, 68, 68, 0.05));
    box-shadow: 0 12px 32px rgba(239, 68, 68, 0.18);
}

.season-live-cta[data-state="live"] .season-live-dot {
    background: #ef4444;
    animation: live-pulse 1.6s ease-in-out infinite;
}

.season-live-cta[data-state="live"] .season-live-kicker {
    color: #ff8a8a;
}

.season-live-cta[data-state="live"] .season-live-arrow,
.season-live-cta[data-state="live"]:hover .season-live-arrow {
    color: #ff6b6b;
}

@media (max-width: 720px) {
    .season-info {
        flex: 0 1 auto;
    }
    .season-live-cta {
        width: 100%;
        justify-content: flex-start;
    }
}

[data-theme="light"] .season-live-cta {
    background: linear-gradient(135deg, rgba(23, 113, 201, 0.12), rgba(23, 113, 201, 0.02));
    border-color: rgba(0, 0, 0, 0.1);
}

[data-theme="light"] .season-live-cta[data-state="live"] {
    background: linear-gradient(135deg, rgba(239, 68, 68, 0.18), rgba(239, 68, 68, 0.04));
    border-color: rgba(220, 38, 38, 0.45);
}

/* ===== Live diagnostics report ===== */
.live-diagnose-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    padding-top: 0.75rem;
}

.live-diagnose-hint {
    color: var(--text-muted);
    font-size: 0.78rem;
    flex: 1 1 200px;
    line-height: 1.35;
}

.live-diagnose-report {
    margin-top: 0.75rem;
    padding: 0.85rem 1rem;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.25);
    border: 1px solid rgba(255, 255, 255, 0.06);
    font-size: 0.88rem;
    line-height: 1.5;
}

.live-diagnose-section {
    margin-bottom: 0.85rem;
}

.live-diagnose-section h4 {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.15em;
    font-size: 0.72rem;
    color: var(--text-muted);
    margin: 0 0 0.4rem 0;
}

.live-diagnose-pill {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    font-size: 0.78rem;
    border: 1px solid transparent;
    margin-right: 0.4rem;
}
.live-diagnose-pill.ok   { background: rgba(34, 197, 94, 0.18); border-color: rgba(34, 197, 94, 0.4); color: #6ee7a8; }
.live-diagnose-pill.warn { background: rgba(245, 158, 11, 0.18); border-color: rgba(245, 158, 11, 0.4); color: #fbcb6e; }
.live-diagnose-pill.bad  { background: rgba(239, 68, 68, 0.2);  border-color: rgba(239, 68, 68, 0.45);  color: #ff8a8a; }

.live-diagnose-row-item {
    padding: 0.25rem 0;
    color: var(--text-main);
}

.live-diagnose-row-item code {
    background: rgba(255, 255, 255, 0.04);
    padding: 1px 5px;
    border-radius: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.82rem;
}

.live-diagnose-empty {
    color: var(--text-muted);
    font-style: italic;
}

.live-diagnose-details {
    margin: 0.5rem 0;
}

.live-diagnose-details summary {
    cursor: pointer;
    color: var(--text-muted);
}

.live-diagnose-error {
    color: #ff8a8a;
}

[data-theme="light"] .live-diagnose-report {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .live-diagnose-row-item code {
    background: rgba(0, 0, 0, 0.05);
}

/* ============================================================
   ADMIN DASHBOARD — Control Room
   Consolidates Add Match + Settings into one /admin/* shell.
   ============================================================ */

/* Admin shell — no inner cap, fills the universal page shell so it
 * matches Coach Review and the rest of the site at wide widths.
 * A small horizontal pad (`0.75rem`) preserves a visible gutter
 * between the sticky sidebar / status strip and the outer
 * `#app-container` edge — without it the sidebar abuts the page
 * gutter at desktop widths. Mobile (`@media (max-width: 900px)`
 * ~L3735) overrides this to `1rem` for touch ergonomics. */
#admin-view {
    padding: 1.5rem 0.75rem 4rem;
}

/* ----- Status strip ----- */

.admin-status-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.4rem 2.2rem;
    padding: 0.85rem 1.4rem;
    margin-bottom: 1.5rem;
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: 12px;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.04);
    backdrop-filter: blur(8px);
    font-family: var(--font-heading);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.admin-status-strip .status-cell {
    display: inline-flex;
    align-items: baseline;
    gap: 0.55rem;
    line-height: 1;
}

.admin-status-strip .status-cell.is-bad .status-value { color: var(--red); }
.admin-status-strip .status-cell.is-warn .status-value { color: #f59e0b; }
.admin-status-strip .status-cell.is-busy .status-value { color: var(--accent-hover); }

.admin-status-strip .status-label {
    color: var(--text-muted);
}

.admin-status-strip .status-value {
    color: var(--text-main);
    font-weight: 600;
    letter-spacing: 0.08em;
    font-size: 0.95rem;
}

.admin-status-strip .status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
    box-shadow: 0 0 0 3px rgba(255,255,255,0.04);
    transform: translateY(-1px);
}
.admin-status-strip .status-dot.state-good   { background: var(--green); box-shadow: 0 0 12px rgba(34,197,94,0.45); }
.admin-status-strip .status-dot.state-warn   { background: #f59e0b; box-shadow: 0 0 12px rgba(245,158,11,0.45); }
.admin-status-strip .status-dot.state-bad    { background: var(--red); box-shadow: 0 0 12px rgba(255,74,74,0.45); }
.admin-status-strip .status-dot.state-busy   { background: var(--accent); box-shadow: 0 0 12px rgba(23,113,201,0.55); animation: adminPulse 1.6s ease-in-out infinite; }
.admin-status-strip .status-dot.state-accent { background: var(--accent); box-shadow: 0 0 12px rgba(23,113,201,0.45); }
.admin-status-strip .status-dot.state-idle   { background: rgba(255,255,255,0.18); }

@keyframes adminPulse {
    0%, 100% { opacity: 1; transform: translateY(-1px) scale(1); }
    50% { opacity: 0.55; transform: translateY(-1px) scale(0.85); }
}

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

.admin-shell {
    display: grid;
    grid-template-columns: 260px minmax(0, 1fr);
    gap: 1.75rem;
    align-items: start;
}

.admin-sidebar {
    position: sticky;
    top: 6rem;
    background:
        radial-gradient(circle at 30% 0%, rgba(23,113,201,0.1), transparent 60%),
        var(--bg-panel);
    border: 1px solid var(--border-light);
    border-radius: 18px;
    padding: 1.4rem 1rem 1.1rem;
    box-shadow: 0 28px 60px rgba(0,0,0,0.32);
    overflow: hidden;
}

.admin-brand {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0 0.5rem 1.1rem;
    margin-bottom: 0.65rem;
    border-bottom: 1px solid var(--border-light);
}

.admin-brand-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    background: linear-gradient(135deg, var(--accent), var(--accent-hover));
    color: #fff;
    font-size: 1.15rem;
    box-shadow: 0 12px 24px rgba(23,113,201,0.35);
}

.admin-brand-text {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    line-height: 1.05;
}

.admin-brand-kicker {
    font-family: var(--font-heading);
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.18em;
    color: var(--text-muted);
}

.admin-brand-name {
    font-family: var(--font-heading);
    font-size: 1.15rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-main);
}

.admin-nav {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.admin-nav-item {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.7rem 0.85rem;
    min-height: 52px;
    border-radius: 12px;
    color: var(--text-muted);
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    position: relative;
    overflow: hidden;
    transition: background 0.18s ease, color 0.18s ease, transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

.admin-nav-item:hover {
    color: var(--text-main);
    background: rgba(255,255,255,0.04);
    transform: translateX(2px);
}

.admin-nav-item.is-active {
    color: var(--text-main);
    background:
        radial-gradient(circle at 0% 50%, rgba(23,113,201,0.22), transparent 70%),
        rgba(23,113,201,0.08);
    box-shadow: inset 2px 0 0 var(--accent);
}

.admin-nav-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    font-family: var(--font-heading);
    font-size: 0.75rem;
    color: var(--text-muted);
    letter-spacing: 0.08em;
    border-right: 1px solid rgba(255,255,255,0.06);
    padding-right: 0.6rem;
}

.admin-nav-item.is-active .admin-nav-glyph {
    color: var(--accent-hover);
}

.admin-nav-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    line-height: 1.05;
}

.admin-nav-kicker {
    font-size: 0.62rem;
    letter-spacing: 0.16em;
    color: var(--text-muted);
}

.admin-nav-label {
    font-size: 0.95rem;
    letter-spacing: 0.06em;
}

.admin-sidebar-footer {
    margin-top: 1.4rem;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0 0.5rem;
}

.admin-sidebar-rule {
    flex: 1;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.08), transparent);
}

.admin-sidebar-tag {
    font-family: var(--font-heading);
    font-size: 0.62rem;
    letter-spacing: 0.22em;
    color: var(--text-muted);
}

/* ----- Content area ----- */

.admin-content {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    min-width: 0;
}

.admin-content-head {
    padding: 0.5rem 0.25rem 0;
}

.admin-section-kicker {
    display: inline-block;
    font-family: var(--font-heading);
    font-size: 0.7rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 0.4rem;
}

#admin-section-heading {
    font-family: var(--font-heading);
    font-size: 2.4rem;
    line-height: 1;
    letter-spacing: 0.02em;
    color: var(--text-main);
    margin-bottom: 0.5rem;
}

.admin-section-sub {
    color: var(--text-muted);
    font-size: 0.95rem;
    max-width: 60ch;
    line-height: 1.55;
}

.admin-section {
    display: none;
    flex-direction: column;
    gap: 1.5rem;
}

.admin-section.is-active {
    display: flex;
}

.admin-section .options-card {
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    border-radius: 14px;
    padding: 1.6rem;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
}

.admin-card-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    margin-bottom: 1.1rem;
    border-bottom: 1px solid var(--border-light);
    padding-bottom: 0.85rem;
}

.admin-card-head h3 {
    font-family: var(--font-heading);
    font-size: 1.3rem;
    letter-spacing: 0.04em;
    color: var(--text-main);
    margin: 0;
}

.admin-card-kicker {
    font-family: var(--font-heading);
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* ----- Overview KPIs ----- */

.overview-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 0.95rem;
}

.overview-tile {
    position: relative;
    padding: 1.15rem 1.2rem;
    border-radius: 14px;
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    overflow: hidden;
    isolation: isolate;
}

.overview-tile::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(circle at 100% 0%, rgba(23,113,201,0.08), transparent 55%);
    z-index: -1;
}

.overview-tile.tone-good::before { background: radial-gradient(circle at 100% 0%, rgba(34,197,94,0.10), transparent 55%); }
.overview-tile.tone-bad::before  { background: radial-gradient(circle at 100% 0%, rgba(255,74,74,0.10), transparent 55%); }
.overview-tile.tone-warn::before { background: radial-gradient(circle at 100% 0%, rgba(245,158,11,0.12), transparent 55%); }
.overview-tile.tone-accent::before { background: radial-gradient(circle at 100% 0%, rgba(23,113,201,0.16), transparent 55%); }
.overview-tile.tone-idle::before { background: radial-gradient(circle at 100% 0%, rgba(255,255,255,0.04), transparent 55%); }

.overview-tile-kicker {
    display: block;
    font-family: var(--font-heading);
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.55rem;
}

.overview-tile-value {
    display: block;
    font-family: var(--font-heading);
    font-size: 2rem;
    letter-spacing: 0.02em;
    color: var(--text-main);
    line-height: 1;
    margin-bottom: 0.55rem;
    font-variant-numeric: tabular-nums;
}

.overview-tile-note {
    display: block;
    font-size: 0.82rem;
    color: var(--text-muted);
    line-height: 1.45;
}

/* Quick actions */

.overview-quick-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 0.95rem;
}

.overview-quick-action {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.2rem 1.3rem;
    border-radius: 14px;
    background: var(--bg-card);
    border: 1px solid var(--border-light);
    color: var(--text-main);
    transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.2s ease, box-shadow 0.2s ease;
    cursor: pointer;
}

.overview-quick-action:hover {
    transform: translateY(-3px);
    border-color: rgba(23,113,201,0.45);
    box-shadow: 0 16px 32px rgba(0,0,0,0.28);
}

.overview-quick-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 12px;
    background: rgba(23,113,201,0.14);
    color: var(--accent-hover);
    font-size: 1.4rem;
    flex-shrink: 0;
}

.overview-quick-label {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    line-height: 1.35;
}

.overview-quick-label strong {
    font-family: var(--font-heading);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.95rem;
    color: var(--text-main);
}

.overview-quick-label span {
    font-size: 0.85rem;
    color: var(--text-muted);
}

/* ----- Mobile ----- */

@media (max-width: 900px) {
    #admin-view {
        padding: 1rem 1rem 3rem;
    }

    .admin-status-strip {
        gap: 0.75rem 1.4rem;
        padding: 0.7rem 0.95rem;
        font-size: 0.7rem;
        letter-spacing: 0.1em;
    }

    .admin-shell {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    .admin-sidebar {
        position: relative;
        top: auto;
        padding: 0.85rem 0.85rem 0.65rem;
        border-radius: 14px;
    }

    .admin-brand {
        padding-bottom: 0.7rem;
        margin-bottom: 0.5rem;
    }

    /* Sidebar nav becomes a wrapping pill row instead of a horizontal
       scroller. The previous design (overflow-x + flex-shrink: 0) hid
       sections behind a non-obvious horizontal scroll on phones — this
       lets every section be visible without scrolling, at the cost of
       letting the sidebar wrap to two rows on the smallest screens.
       The 520 px block below tightens it further. */
    .admin-nav {
        flex-direction: row;
        flex-wrap: wrap;
        gap: 0.4rem;
    }

    .admin-nav-item {
        flex: 1 1 auto;          /* grow to fill the wrap row, shrink as needed */
        min-width: 0;            /* allow text truncation                       */
        min-height: 44px;        /* touch target — was 52, still ≥WCAG          */
        padding: 0.55rem 0.7rem;
        gap: 0.55rem;
    }

    .admin-nav-item.is-active {
        box-shadow: inset 0 -2px 0 var(--accent);
    }

    .admin-nav-glyph {
        width: 22px;
        padding-right: 0.45rem;
        font-size: 0.7rem;
    }

    .admin-nav-kicker { display: none; }
    .admin-nav-label  { font-size: 0.82rem; letter-spacing: 0.04em; }

    .admin-sidebar-footer {
        display: none;
    }

    #admin-section-heading {
        font-size: 1.85rem;
    }
}

/* KPI grid 2-col happens at 768 px (was 900 px) so tablets 769–900 px
   keep the full grid while phones break into a denser layout. */
@media (max-width: 768px) {
    .overview-kpi-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* Quick actions go single-column at 640 px (was 520 px) so phones
   376–520 px don't get oversized 260 px cards. */
@media (max-width: 640px) {
    .overview-quick-actions {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 520px) {
    #admin-view {
        padding: 0.85rem 0.85rem 2.5rem;
    }

    /* Drop the decorative 01–07 glyphs on phones so labels can grow. */
    .admin-nav { gap: 0.3rem; }
    .admin-nav-item { padding: 0.5rem 0.55rem; min-height: 40px; }
    .admin-nav-glyph { display: none; }
    .admin-nav-label { font-size: 0.78rem; }

    .admin-card-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.3rem;
    }
}

/* KPI grid drops to 1-column at 480 px (was 520 px). Phones 376–480 px
   are the only ones that hit this. */
@media (max-width: 480px) {
    .overview-kpi-grid {
        grid-template-columns: 1fr;
    }
}

/* ----- Light theme overrides ----- */

[data-theme="light"] .admin-status-strip {
    background: rgba(255,255,255,0.85);
    border-color: rgba(0,0,0,0.08);
}

[data-theme="light"] .admin-sidebar {
    box-shadow: 0 18px 40px rgba(0,0,0,0.10);
    background:
        radial-gradient(circle at 30% 0%, rgba(21,101,192,0.08), transparent 60%),
        var(--bg-panel);
}

[data-theme="light"] .admin-nav-item.is-active {
    background:
        radial-gradient(circle at 0% 50%, rgba(21,101,192,0.18), transparent 70%),
        rgba(21,101,192,0.08);
}

[data-theme="light"] .admin-section .options-card,
[data-theme="light"] .overview-tile,
[data-theme="light"] .overview-quick-action {
    background: var(--bg-card);
    border-color: rgba(0,0,0,0.10);
}

[data-theme="light"] .overview-quick-glyph {
    background: rgba(21,101,192,0.10);
    color: var(--accent-hover);
}

/* ============================================================
   Custom <select> — match the broadcast aesthetic
   ============================================================ */

.form-group select {
    width: 100%;
    padding: 0.95rem 2.6rem 0.95rem 1rem;
    background: rgba(0, 0, 0, 0.38);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 10px;
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.92rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23888890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 12px 8px;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}

.form-group select:hover {
    border-color: rgba(255,255,255,0.18);
}

.form-group select:focus {
    outline: none;
    border-color: var(--accent);
    background-color: rgba(0, 0, 0, 0.5);
    box-shadow: 0 0 0 3px rgba(23, 113, 201, 0.14);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23298bed' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}

.form-group select option {
    background: var(--bg-panel);
    color: var(--text-main);
    font-family: var(--font-body);
    text-transform: none;
    letter-spacing: 0;
    padding: 0.5rem;
}

[data-theme="light"] .form-group select {
    /* Pure white on the off-white page so the select reads as a fillable
       field, not a disabled grey box. The earlier rule at line ~2531 sets
       this; we only override the dropdown chevron colour here, deliberately
       NOT the background. */
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%236b6b75' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}

[data-theme="light"] .form-group select:focus {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%231565c0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}

/* ============================================================
   Custom modal dialog (replaces native confirm/alert/prompt)
   ============================================================ */

.app-modal {
    position: fixed;
    inset: 0;
    z-index: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
    opacity: 0;
    transition: opacity 0.18s ease;
}

.app-modal.is-open { opacity: 1; }
.app-modal.is-closing { opacity: 0; }

.app-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(6px);
}

.app-modal-card {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 460px;
    background:
        radial-gradient(circle at top right, rgba(23, 113, 201, 0.10), transparent 50%),
        var(--bg-panel);
    border: 1px solid var(--border-light);
    border-radius: 16px;
    box-shadow: 0 36px 80px rgba(0, 0, 0, 0.55);
    padding: 1.7rem 1.7rem 1.4rem;
    transform: translateY(8px) scale(0.985);
    transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

.app-modal.is-open .app-modal-card { transform: translateY(0) scale(1); }

.app-modal-card.is-danger {
    background:
        radial-gradient(circle at top right, rgba(255, 74, 74, 0.10), transparent 55%),
        var(--bg-panel);
    border-color: rgba(255, 74, 74, 0.22);
}

.app-modal-kicker {
    display: inline-block;
    font-family: var(--font-heading);
    font-size: 0.68rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 0.65rem;
}

.app-modal-card.is-danger .app-modal-kicker { color: var(--red); }

.app-modal-title {
    font-family: var(--font-heading);
    font-size: 1.55rem;
    line-height: 1.05;
    letter-spacing: 0.02em;
    color: var(--text-main);
    margin-bottom: 0.7rem;
}

.app-modal-message {
    color: var(--text-muted);
    font-size: 0.95rem;
    line-height: 1.55;
    white-space: pre-wrap;
    margin-bottom: 1.3rem;
}

.app-modal-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.3rem;
}

.app-modal-picker-btn {
    padding: 0.6rem 1rem;
    min-height: 40px;
    border-radius: 10px;
    border: 1px solid rgba(255,255,255,0.12);
    background: rgba(0, 0, 0, 0.32);
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    cursor: pointer;
    transition: border-color 0.18s ease, background 0.18s ease, color 0.18s ease;
}

.app-modal-picker-btn:hover {
    border-color: rgba(255,255,255,0.24);
    background: rgba(255,255,255,0.04);
}

.app-modal-picker-btn.is-active {
    border-color: var(--accent);
    color: var(--text-main);
    background: rgba(23, 113, 201, 0.18);
    box-shadow: inset 0 0 0 1px rgba(23, 113, 201, 0.35);
}

.app-modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.6rem;
}

.app-modal-actions .btn-primary,
.app-modal-actions .btn-secondary,
.app-modal-actions .btn-danger {
    min-width: 7rem;
}

@media (max-width: 520px) {
    .app-modal-card {
        padding: 1.4rem;
        border-radius: 14px;
    }
    .app-modal-title { font-size: 1.35rem; }
    .app-modal-actions { flex-direction: column-reverse; }
    .app-modal-actions .btn-primary,
    .app-modal-actions .btn-secondary,
    .app-modal-actions .btn-danger {
        width: 100%;
        min-width: 0;
    }
}

[data-theme="light"] .app-modal-backdrop {
    background: rgba(20, 20, 30, 0.45);
}

[data-theme="light"] .app-modal-picker-btn {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
}

[data-theme="light"] .app-modal-picker-btn.is-active {
    background: rgba(21, 101, 192, 0.10);
}

/* ============================================================
   Score reveal — replay-first, results-quiet
   ============================================================ */

.card-team-score.is-hidden,
.game-team-score.is-hidden {
    color: var(--text-muted);
    opacity: 0.45;
    font-weight: 500;
    letter-spacing: 0.18em;
    user-select: none;
}

.score-reveal-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-left: auto;
    padding: 0.3rem 0.7rem;
    min-height: 32px;
    border-radius: 999px;
    border: 1px solid rgba(255,255,255,0.14);
    background: rgba(0, 0, 0, 0.28);
    color: var(--text-muted);
    font-family: var(--font-heading);
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    cursor: pointer;
    transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease, transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);
    z-index: 3;
}

.score-reveal-chip:hover {
    color: var(--text-main);
    border-color: var(--accent);
    background: rgba(23, 113, 201, 0.12);
    transform: translateY(-1px);
}

.score-reveal-chip svg { flex-shrink: 0; }

/* Larger variant on the game-page reveal row */
.game-score-reveal-row {
    display: flex;
    justify-content: center;
    margin-bottom: 1.25rem;
}

/* The base chip uses margin-left:auto to sit at the right edge of card rows.
   Override here so the chip stays centered inside the game-page reveal row. */
.game-score-reveal-row .score-reveal-chip {
    margin-left: 0;
}

.score-reveal-chip-large {
    padding: 0.55rem 1.1rem;
    min-height: 40px;
    font-size: 0.78rem;
    letter-spacing: 0.16em;
}

[data-theme="light"] .score-reveal-chip {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.10);
}

[data-theme="light"] .score-reveal-chip:hover {
    background: rgba(21, 101, 192, 0.10);
    border-color: var(--accent);
}

/* Tighten card-team-score weight when revealed too — keep it readable
   but never the loudest thing on the card. */
.card-team-score:not(.is-hidden) {
    color: var(--text-main);
    opacity: 0.95;
}

/* Mobile: chip sizes to content and visually matches .match-detail-pill */
@media (max-width: 520px) {
    .score-reveal-chip,
    .score-reveal-chip-large {
        margin-left: 0;
        flex-basis: auto;
        align-self: center;
        padding: 0.38rem 0.72rem;
        min-height: 0;
        font-size: 0.68rem;
        letter-spacing: 0.12em;
        white-space: nowrap;
    }
}

/* ============================================================
   Team performance — effort tiles + collapsed record strip
   ============================================================ */

.team-stat-grid-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 1rem;
    /* span all columns of the parent .team-stats-grid so the effort-tile
       sub-grid occupies a full row rather than a single auto-fit cell */
    grid-column: 1 / -1;
}

/* Neutral variant — drop the colored radial accent on the new effort tiles */
.team-stat-card.neutral {
    background: rgba(8, 8, 10, 0.62);
}

.team-stat-card.neutral::after {
    display: none;
}

.team-stat-card.neutral .team-stat-value {
    font-variant-numeric: tabular-nums;
    color: var(--text-main);
}

[data-theme="light"] .team-stat-card.neutral {
    background: rgba(0, 0, 0, 0.04);
}

.team-record-toggle {
    grid-column: 1 / -1;
    align-self: center;
    margin: 0.4rem auto -0.2rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.95rem;
    min-height: 36px;
    border-radius: 999px;
    border: 1px solid rgba(255,255,255,0.10);
    background: transparent;
    color: var(--text-muted);
    font-family: var(--font-heading);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    cursor: pointer;
    transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}

.team-record-toggle:hover {
    color: var(--text-main);
    border-color: var(--accent);
}

.team-record-toggle-caret {
    transition: transform 0.2s ease;
}

.team-record-toggle.is-open .team-record-toggle-caret {
    transform: rotate(180deg);
}

[data-theme="light"] .team-record-toggle {
    border-color: rgba(0, 0, 0, 0.12);
}

.team-record-strip {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.85rem;
    padding: 1rem 1.1rem;
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.32);
    border: 1px solid rgba(255,255,255,0.06);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.03);
}

.team-record-cell {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    position: relative;
    padding-left: 0.85rem;
}

.team-record-cell::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.2rem;
    bottom: 0.2rem;
    width: 2px;
    border-radius: 2px;
    background: var(--text-muted);
    opacity: 0.5;
}

.team-record-cell.record::before    { background: var(--accent); opacity: 0.85; }
.team-record-cell.points::before    { background: var(--green); opacity: 0.85; }
.team-record-cell.difference::before { background: rgba(250, 204, 21, 0.85); }

.team-record-label {
    font-family: var(--font-heading);
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--text-muted);
}

.team-record-value {
    font-family: var(--font-heading);
    font-size: 1.55rem;
    line-height: 1;
    color: var(--text-main);
    letter-spacing: 0.01em;
    font-variant-numeric: tabular-nums;
}

.team-record-note {
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.35;
}

[data-theme="light"] .team-record-strip {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}

@media (max-width: 600px) {
    .team-record-strip {
        grid-template-columns: 1fr;
        gap: 0.6rem;
    }

    /* Library filter bar: search forces a wrap break onto its own row;
       the three selects share the row beneath at equal widths. The
       desktop min-width: 200px on the search input is overridden
       (0 here) so it can fully shrink to the viewport. */
    .library-filter-bar input[type="search"] {
        flex: 1 0 100%;
        min-width: 0;
    }
    .library-filter-bar select {
        flex: 1 1 0;
        min-width: 0;
    }

    /* Tuning knobs + the generic form-grid drop to a single column on
       phones — desktop's auto-fit minmax(220px, 1fr) and minmax(260px,
       1fr) leave too little room for the controls otherwise. */
    .form-grid,
    .tuning-knobs-grid {
        grid-template-columns: 1fr;
        gap: 0.75rem;
    }
    .ladder-editor { font-size: 0.78rem; }
    .diag-row-id { max-width: 22ch; }   /* tighter ellipsis on phones */
}

/* ----- Performance Tuning admin card ----------------------------------- */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 1rem 1.2rem;
    margin-top: 1rem;
}

.form-help {
    margin-top: 0.4rem;
    font-size: 0.78rem;
    color: var(--text-muted);
    line-height: 1.35;
}

.ladder-editor {
    overflow-x: auto;
    padding: 0.4rem;
    background: rgba(0, 0, 0, 0.25);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
}

.ladder-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}

.ladder-table th,
.ladder-table td {
    padding: 0.35rem 0.5rem;
    text-align: left;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}

.ladder-table th {
    text-transform: uppercase;
    font-size: 0.68rem;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.ladder-table input[type="text"],
.ladder-table input[type="number"] {
    padding: 0.3rem 0.45rem;
    background: rgba(0, 0, 0, 0.4);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.85rem;
}

.ladder-table input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    display: inline-grid;
    place-items: center;
    border: 1px solid rgba(255, 255, 255, 0.24);
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.35);
    cursor: pointer;
}

.ladder-table input[type="checkbox"]:checked {
    background: var(--accent);
    border-color: var(--accent);
}

.ladder-table input[type="checkbox"]:checked::after {
    content: "";
    width: 5px;
    height: 9px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg) translateY(-1px);
}

.ladder-table input[type="checkbox"]:focus-visible {
    outline: 2px solid rgba(56, 189, 248, 0.75);
    outline-offset: 2px;
}

.status-pill.warn {
    background: rgba(255, 165, 0, 0.18);
    color: #ffb454;
    border: 1px solid rgba(255, 165, 0, 0.3);
    margin-left: 0.5rem;
    font-size: 0.65rem;
    padding: 0.1rem 0.45rem;
}

/* ===== Match Library (Admin → Matches) ===== */

.library-header-card .library-header-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.library-header-summary h3 {
    margin-bottom: 0.25rem;
}

.library-header-actions {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}

.library-filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1rem;
}

.library-filter-bar input[type="search"] {
    flex: 1 1 240px;
    min-width: 200px;
    padding: 0.5rem 0.75rem;
    border-radius: 8px;
    border: 1px solid var(--border-light);
    background: rgba(0, 0, 0, 0.35);
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.9rem;
}

.library-filter-bar select {
    padding: 0.5rem 2.2rem 0.5rem 0.75rem;
    border-radius: 8px;
    border: 1px solid var(--border-light);
    background: rgba(0, 0, 0, 0.35);
    color: var(--text-main);
    font-family: var(--font-body);
    font-size: 0.85rem;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23888890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    background-size: 12px 8px;
}

/* Light theme — match the rest of the form elements: pure white fields with a
   visible hairline border. The default rule above used var(--bg-dark) which
   evaluates to the page background in light mode and made the controls look
   disabled. */
[data-theme="light"] .library-filter-bar input[type="search"],
[data-theme="light"] .library-filter-bar select {
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
}

.library-filter-bar input:focus,
.library-filter-bar select:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.library-table-card {
    padding: 0;
    overflow: hidden;
}

.library-table-wrap {
    width: 100%;
    overflow-x: auto;
}

.match-library-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9rem;
}

.match-library-table thead th {
    text-align: left;
    padding: 0.85rem 0.9rem;
    font-family: var(--font-heading);
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border-light);
    background: rgba(255, 255, 255, 0.02);
}

.match-library-table tbody td {
    padding: 0.85rem 0.9rem;
    border-bottom: 1px solid var(--border-light);
    vertical-align: middle;
    color: var(--text-main);
}

.match-library-table .library-row:hover td {
    background: rgba(255, 255, 255, 0.025);
}

/* Only error rows get a colored stripe — ready/encoding stay neutral so the
   table doesn't drown in green/amber when most matches are healthy. The pill
   in the Slots column is the per-row signal. */
.match-library-table .library-row.is-error td {
    box-shadow: inset 3px 0 0 var(--red);
}

.match-library-table .lib-col-expand,
.match-library-table .lib-col-menu {
    width: 36px;
    white-space: nowrap;
    text-align: center;
}

.match-library-table .lib-col-date {
    width: 110px;
    white-space: nowrap;
}

.match-library-table .lib-col-matchup {
    width: auto;
    min-width: 220px;
}

.match-library-table .lib-col-slots {
    min-width: 160px;
}

.match-library-table .lib-col-format,
.match-library-table .lib-col-score,
.match-library-table .lib-col-watching {
    white-space: nowrap;
}

/* Watching column — narrow, right-leaning, tabular-nums so the count
   doesn't shift the column width as it ticks up/down. */
.match-library-table .lib-col-watching {
    text-align: right;
    font-variant-numeric: tabular-nums;
    width: 1%;
    padding-right: 0.5rem;
}

.slot-pill-stack {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    align-items: center;
}

.library-matchup {
    display: flex;
    align-items: center;
    gap: 0.7rem;
}

.library-matchup-text {
    min-width: 0;
}

.library-thumb {
    width: 56px;
    height: 32px;
    object-fit: cover;
    border-radius: 4px;
    border: 1px solid var(--border-light);
    flex-shrink: 0;
    background: var(--bg-card);
    display: block;
}

.library-thumb-placeholder {
    background: rgba(255, 255, 255, 0.03);
}

.match-library-table .row-sub {
    color: var(--text-muted);
    font-size: 0.78rem;
    margin-top: 0.15rem;
}

.match-library-table .muted {
    color: var(--text-muted);
}

.match-library-table strong {
    color: var(--text-main);
}

.row-expand-btn {
    background: transparent;
    border: 1px solid var(--border-light);
    color: var(--text-main);
    border-radius: 6px;
    width: 28px;
    height: 28px;
    cursor: pointer;
    font-size: 0.95rem;
    line-height: 1;
}

.row-expand-btn:hover { border-color: var(--accent); }

.format-pill {
    display: inline-block;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border-light);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.slot-pill {
    display: inline-block;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    border: 1px solid var(--border-light);
    background: rgba(255, 255, 255, 0.04);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

/* Slot-pill palette mirrors .status-pill (styles.css:1173) so the new admin
   table reads as part of the same design system rather than introducing a
   second green/amber/red. */
.slot-pill.ready {
    background: rgba(34, 197, 94, 0.12);
    color: #7be3a0;
    border-color: rgba(34, 197, 94, 0.28);
}

.slot-pill.transcoding {
    background: rgba(255, 170, 0, 0.14);
    color: #ffaa00;
    border-color: rgba(255, 170, 0, 0.30);
}

.slot-pill.error {
    background: rgba(255, 74, 74, 0.14);
    color: #ff8f8f;
    border-color: rgba(255, 74, 74, 0.30);
}

/* Row action menu */

.row-menu { position: relative; display: inline-block; }

.row-menu-btn {
    background: transparent;
    border: 1px solid var(--border-light);
    color: var(--text-main);
    border-radius: 6px;
    width: 28px;
    height: 28px;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
}

.row-menu-btn:hover { border-color: var(--accent); }

.row-menu-list {
    position: absolute;
    right: 0;
    top: calc(100% + 4px);
    z-index: 5;
    min-width: 180px;
    background: var(--bg-panel);
    border: 1px solid var(--border-light);
    border-radius: 10px;
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.45);
    padding: 0.35rem;
    display: flex;
    flex-direction: column;
}

.row-menu-list[hidden] { display: none; }

.row-menu-list button {
    text-align: left;
    background: transparent;
    border: 0;
    color: var(--text-main);
    padding: 0.5rem 0.65rem;
    border-radius: 6px;
    font-size: 0.85rem;
    cursor: pointer;
}

.row-menu-list button:hover {
    background: rgba(255, 255, 255, 0.04);
}

.row-menu-list button.is-danger {
    color: var(--red);
}

.row-menu-list button.is-danger:hover {
    background: rgba(255, 74, 74, 0.10);
}

/* Expanded diagnostics row */

.library-detail-row td {
    background: rgba(255, 255, 255, 0.015);
    padding: 0.5rem 1rem 1.1rem;
}

.slot-diagnostics-panel {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.slot-diagnostics-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.78rem;
}

.slot-diagnostics-head code {
    font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
    font-size: 0.75rem;
    color: var(--text-muted);
}

.slot-cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 0.7rem;
}

.slot-card {
    border: 1px solid var(--border-light);
    border-radius: 10px;
    padding: 0.8rem 0.9rem;
    background: rgba(255, 255, 255, 0.02);
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.slot-card-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8rem;
}

.slot-card-meta {
    color: var(--text-muted);
    font-size: 0.78rem;
    word-break: break-all;
}

.slot-card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* Form-style modal */

.app-modal-card.is-form,
.app-modal-card.is-wide {
    max-width: 720px;
    padding: 1.5rem 1.6rem 1.2rem;
}

.app-modal-body {
    margin-top: 0.6rem;
    margin-bottom: 1rem;
    max-height: min(72vh, 760px);
    overflow-y: auto;
    padding-right: 0.4rem;
    /* Custom scrollbar — never expose unstyled native browser chrome inside
       a styled modal. Firefox uses scrollbar-width/-color; WebKit uses the
       ::-webkit-scrollbar pseudo-elements below. */
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}

.app-modal-body::-webkit-scrollbar {
    width: 8px;
}

.app-modal-body::-webkit-scrollbar-track {
    background: transparent;
}

.app-modal-body::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.14);
    border-radius: 4px;
}

.app-modal-body::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.22);
}

.app-modal-body .modal-form-section {
    border: 1px solid var(--border-light);
    border-radius: 10px;
    padding: 0.9rem 1rem;
    margin-bottom: 0.9rem;
    background: rgba(255, 255, 255, 0.015);
}

.modal-form-section-head {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-bottom: 0.7rem;
}

.modal-form-section-head h4 {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 0.95rem;
    letter-spacing: 0.04em;
    color: var(--text-main);
}

.modal-form-step {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 600;
}

.hidden-form-submit {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    border: 0;
}

/* Match library at ≤640 px: switch from a flat <table> to a labeled
   card-per-row layout. Top row holds chevron · matchup · ⋯ menu. Slot
   pills get their own row. Date / format / score / watching collapse
   to muted "LABEL · value" lines beneath, with the label coming from
   the data-label attribute set in _renderMatchRow (admin-views.js).
   Tablets 641–900 px keep the regular table — they have room for it. */
@media (max-width: 640px) {
    .match-library-table,
    .match-library-table tbody,
    .match-library-table tr,
    .match-library-table td { display: block; }

    .match-library-table thead { display: none; }

    .match-library-table .library-row {
        display: grid;
        grid-template-columns: 28px 1fr auto;
        column-gap: 0.6rem;
        row-gap: 0.4rem;
        padding: 0.7rem 0.85rem;
        border-bottom: 1px solid var(--border-light);
    }

    /* Top row: chevron · matchup · ⋯ menu */
    .match-library-table .lib-col-expand  { grid-column: 1; padding: 0; }
    .match-library-table .lib-col-matchup { grid-column: 2; padding: 0; min-width: 0; }
    .match-library-table .lib-col-menu    { grid-column: 3; padding: 0; }

    /* Slots get their own row, full width below the matchup */
    .match-library-table .lib-col-slots {
        grid-column: 2 / -1;
        padding: 0;
    }

    /* Date / format / score / watching: each on its own labeled meta line.
       Auto-placement stacks them in DOM order under the slot pills. */
    .match-library-table .lib-col-date,
    .match-library-table .lib-col-format,
    .match-library-table .lib-col-score,
    .match-library-table .lib-col-watching {
        grid-column: 2 / -1;
        padding: 0;
        font-size: 0.78rem;
        color: var(--text-muted);
    }
    .match-library-table .lib-col-date::before,
    .match-library-table .lib-col-format::before,
    .match-library-table .lib-col-score::before,
    .match-library-table .lib-col-watching::before {
        content: attr(data-label) " · ";
        text-transform: uppercase;
        font-family: var(--font-heading);
        font-size: 0.66rem;
        letter-spacing: 0.1em;
        opacity: 0.55;
        margin-right: 0.25rem;
    }

    /* Smaller thumbnail inside the cramped matchup cell */
    .match-library-table .library-thumb { width: 40px; height: 24px; border-radius: 3px; }

    /* Tighter expand chevron — fits the 28 px column */
    .match-library-table .row-expand-btn { width: 24px; height: 24px; font-size: 0.85rem; }

    /* Detail row spans full width — already block from the rule above */
    .match-library-table .library-detail-row td { padding: 0.5rem 0.85rem 1rem; }
}

/* ===== Live Console (admin → /live) ===== */

.live-console-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.live-console-header-state {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.live-onair-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.85rem;
    border-radius: 999px;
    font-family: var(--font-heading);
    font-size: 0.8rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid var(--border-light);
    color: var(--text-muted);
}

.live-onair-pill[data-state="on"] {
    background: rgba(255, 74, 74, 0.14);
    border-color: rgba(255, 74, 74, 0.35);
    color: #ff8f8f;
}

.live-onair-pill[data-state="standby"] {
    background: rgba(255, 170, 0, 0.14);
    border-color: rgba(255, 170, 0, 0.30);
    color: #ffaa00;
}

.live-onair-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: currentColor;
}

.live-onair-pill[data-state="on"] .live-onair-dot {
    animation: liveOnAirPulse 1.4s ease-in-out infinite;
}

@keyframes liveOnAirPulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.4; transform: scale(0.9); }
}

.live-console-viewers {
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* Two-column grid: write-rail (form) on the left, read-rail (telemetry) on
   the right. Collapses to single column at ≤900 px so the existing admin
   breakpoint isn't introduced into the new layout. */
.live-console-grid {
    display: grid;
    grid-template-columns: minmax(320px, 420px) 1fr;
    gap: 1rem;
    align-items: start;
}

.live-console-rail .options-card,
.live-console-read .options-card {
    margin-top: 0;
}

.live-console-rail .options-card + .options-card,
.live-console-read .options-card + .options-card {
    margin-top: 1rem;
}

@media (max-width: 768px) {
    /* Was 900 px. Tablets 769–900 px keep the two-rail layout — they
       have ≥420 px for the form rail and 348 px+ for telemetry, which
       is workable. Below 768 px the right rail gets squeezed enough
       that stacking is the better experience. */
    .live-console-grid { grid-template-columns: 1fr; }
}

.live-throughput-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.live-throughput-now {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.live-throughput-value {
    font-family: var(--font-heading);
    font-size: 1.6rem;
    color: var(--text-main);
    letter-spacing: 0.04em;
}

.live-throughput-note {
    color: var(--text-muted);
    font-size: 0.78rem;
}

.live-throughput-spark {
    color: var(--accent);
    flex-shrink: 0;
}

.live-encoder-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
    gap: 0.6rem;
}

.live-encoder-cell {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid var(--border-light);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.02);
}

.live-encoder-kicker {
    font-family: var(--font-heading);
    font-size: 0.65rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.live-encoder-value {
    font-family: var(--font-heading);
    font-size: 1.05rem;
    color: var(--text-main);
}

/* ===== Performance section (admin → /performance) =====
   Stacked full-width cards instead of the previous 2-column grid that
   crushed the tuning sidebar. The Encoder & Host tile grid and the
   Tuning Knobs editor each get the full width of the section. */

/* Tuning knobs grid — flex-friendly multi-column. Most knobs are scalar
   (label + small input + helper text) and fit at 220 px. Knobs marked
   .form-group-fullwidth (HLS variant ladder, etc.) span the whole row. */
.tuning-knobs-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem 1.25rem;
}

.tuning-knobs-grid .form-group {
    margin-bottom: 0;
}

.tuning-knobs-grid .form-group-fullwidth {
    grid-column: 1 / -1;
}

/* HLS variant ladder hides behind a <details> toggle. Closed state is
   compact summary; open state lets the ladder table extend horizontally. */
.tuning-knobs-grid .form-group-details {
    border: 1px solid var(--border-light);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.015);
}

.tuning-knobs-grid .form-group-details summary {
    list-style: none;
    cursor: pointer;
    padding: 0.55rem 0.85rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    user-select: none;
    font-family: var(--font-heading);
    font-size: 0.8rem;
    letter-spacing: 0.06em;
    color: var(--text-main);
}

/* Suppress the native disclosure triangle in both webkit (Safari < 15) and
   the standards-track ::marker pseudo-element so Firefox doesn't render
   its native triangle alongside our custom ▸ chevron. */
.tuning-knobs-grid .form-group-details summary::-webkit-details-marker { display: none; }
.tuning-knobs-grid .form-group-details summary::marker { display: none; }

.tuning-knobs-grid .form-group-details summary::before {
    content: '▸';
    color: var(--text-muted);
    font-size: 0.78rem;
    transition: transform 0.2s ease;
}

.tuning-knobs-grid .form-group-details[open] summary::before {
    transform: rotate(90deg);
    display: inline-block;
}

.tuning-knobs-grid .form-group-summary-label {
    flex: 1;
}

.tuning-knobs-grid .form-group-details-body {
    padding: 0 0.85rem 0.85rem;
}

.tuning-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

/* Diagnostics accordion — one-line summary closed, expands on click. Replaces
   the always-on session-list panels that took 30+ vertical lines. */
.diag-accordions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 1rem;
}

.diag-accordion {
    border: 1px solid var(--border-light);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.02);
    overflow: hidden;
}

.diag-accordion summary {
    list-style: none;
    cursor: pointer;
    padding: 0.7rem 0.95rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    user-select: none;
}

/* See note on .form-group-details summary above — both webkit and standards
   marker pseudo-elements need to be suppressed so Firefox doesn't double
   up the native triangle and our custom chevron. */
.diag-accordion summary::-webkit-details-marker { display: none; }
.diag-accordion summary::marker { display: none; }

.diag-accordion summary::before {
    content: '▸';
    color: var(--text-muted);
    font-size: 0.8rem;
    margin-right: 0.4rem;
    transition: transform 0.2s ease;
}

.diag-accordion[open] summary::before { transform: rotate(90deg); display: inline-block; }

.diag-accordion-title {
    flex: 1;
    font-family: var(--font-heading);
    font-size: 0.78rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-main);
}

.diag-accordion-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    height: 22px;
    padding: 0 0.55rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid var(--border-light);
    color: var(--text-muted);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

.diag-accordion[open] > *:not(summary) {
    padding: 0 0.75rem 0.75rem;
}

/* Flat 1-row-per-entry layout used inside the Performance diagnostics
   accordions (Recent errors, Upload sessions, Recent transcodes, Active
   streaming sessions, Tuning audit). Replaces the old .session-item
   stacked-card layout that was 3 layers of dark grey deep. */
.diag-accordion .session-list {
    display: flex;
    flex-direction: column;
    /* Tight rows, separated by hairline borders rather than gaps. */
    gap: 0;
}

.diag-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.55rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--border-light);
    font-size: 0.8rem;
    color: var(--text-main);
}

.diag-row:last-child {
    border-bottom: none;
}

.diag-row-time {
    color: var(--text-muted);
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

.diag-row-id {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.74rem;
    color: var(--text-main);
    flex-shrink: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 36ch;
    white-space: nowrap;
}

.diag-row-tag {
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-muted);
    flex-shrink: 0;
}

.diag-row-code {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--red);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    flex-shrink: 0;
}

.diag-row-reason {
    color: var(--text-main);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.diag-row-meta {
    color: var(--text-muted);
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
}

.diag-row-action {
    margin-left: auto;
}

.diag-row-empty {
    padding: 0.6rem 0;
    color: var(--text-muted);
    font-size: 0.85rem;
}

.diag-row-error .diag-row-code {
    background: rgba(255, 74, 74, 0.12);
    border: 1px solid rgba(255, 74, 74, 0.3);
    border-radius: 4px;
    padding: 0.04rem 0.35rem;
    color: #ff8f8f;
}

/* Collapsible error row — when an error has a `details` blob the row is
   a <details> element so mobile / keyboard users can tap-to-expand
   instead of relying on a hover tooltip. The summary holds the inline
   row content (matching .diag-row's flex layout) and the body shows
   the full details blob in a monospace pre. */
details.diag-row-details {
    /* Override the .diag-row flex on the <details> element itself —
       <details> needs `display: block` so the summary + body stack
       vertically on expand. The summary uses flex to lay out the row
       content; see .diag-row-details summary below. */
    display: block;
    padding: 0;
    cursor: pointer;
}

details.diag-row-details > summary {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.55rem;
    padding: 0.4rem 0;
    user-select: none;
}

details.diag-row-details > summary::-webkit-details-marker { display: none; }
details.diag-row-details > summary::marker { display: none; }

details.diag-row-details > summary::after {
    content: '▸';
    margin-left: 0.4rem;
    color: var(--text-muted);
    font-size: 0.7rem;
    transition: transform 0.15s ease;
}

details.diag-row-details[open] > summary::after {
    transform: rotate(90deg);
    display: inline-block;
}

.diag-row-details-body {
    margin: 0.2rem 0 0.6rem;
    padding: 0.6rem 0.7rem;
    background: rgba(0, 0, 0, 0.18);
    border: 1px solid var(--border-light);
    border-radius: 6px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.74rem;
    color: var(--text-main);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 12rem;
    overflow: auto;
}

[data-theme="light"] .diag-row-details-body {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}

/* "browser" tag pill on resumable upload rows — accent-tinted so it's
   easy to scan past from the server-side rows above. */
.diag-row-resume .diag-row-tag {
    background: rgba(23, 113, 201, 0.14);
    border: 1px solid rgba(23, 113, 201, 0.35);
    color: var(--accent);
    border-radius: 4px;
    padding: 0.04rem 0.4rem;
}

/* Single-line summary for resumable uploads kept by THIS browser.
   Replaces the old 2-column "Server | This browser" grid that wasted
   horizontal space when (almost always) empty. */
.local-resume-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.55rem;
    padding-top: 0.55rem;
    border-top: 1px dashed var(--border-light);
    color: var(--text-muted);
    font-size: 0.78rem;
}

.local-resume-line:empty {
    margin: 0;
    padding: 0;
    border: 0;
}

.local-resume-summary {
    /* Container element written into by renderLocalResumeSessions.
       Empty by default; the inline .local-resume-line provides its
       own border so this wrapper just needs to participate in flow. */
    display: block;
}

/* Drop the dark sub-card background — the accordion provides containment
   on its own, and three nested grey panels was the visual problem. */
.diagnostics-section {
    padding: 0;
    border: 0;
    background: transparent;
}

/* ===== Overview activity strip ===== */

.overview-activity-card { padding-bottom: 0.75rem; }

.activity-strip {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin-top: 0.5rem;
}

.activity-empty {
    padding: 0.5rem 0;
    color: var(--text-muted);
    font-size: 0.85rem;
}

.activity-event {
    display: grid;
    grid-template-columns: 24px auto 1fr auto auto;
    align-items: center;
    gap: 0.55rem;
    padding: 0.45rem 0.6rem;
    border-radius: 8px;
    border: 1px solid var(--border-light);
    background: rgba(255, 255, 255, 0.015);
    font-size: 0.85rem;
}

.activity-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-muted);
    font-size: 0.85rem;
}

.activity-event.tone-bad .activity-glyph { background: rgba(255, 74, 74, 0.14); color: #ff8f8f; }
.activity-event.tone-good .activity-glyph { background: rgba(34, 197, 94, 0.14); color: #7be3a0; }
.activity-event.tone-accent .activity-glyph { background: rgba(23, 113, 201, 0.16); color: var(--accent); }
.activity-event.tone-warn .activity-glyph { background: rgba(245, 158, 11, 0.15); color: #fbbf24; }

.activity-verb {
    font-family: var(--font-heading);
    font-size: 0.7rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.activity-subject {
    color: var(--text-main);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.activity-detail {
    color: var(--text-muted);
    font-size: 0.78rem;
}

.activity-time {
    color: var(--text-muted);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

/* ===== Slot diagnostics — VOD viewers pill on expanded library row ===== */

.slot-diagnostics-viewers {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: rgba(23, 113, 201, 0.14);
    color: var(--accent);
    border: 1px solid rgba(23, 113, 201, 0.35);
    font-size: 0.72rem;
    letter-spacing: 0.04em;
    margin-left: auto;
    /* When rendered as a <button> (admin + viewers > 0) it stays a pill, but
       gains a hover affordance and pointer cursor so the click is obvious. */
    font-family: inherit;
}

.slot-diagnostics-viewers.is-clickable {
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.slot-diagnostics-viewers.is-clickable:hover,
.slot-diagnostics-viewers.is-clickable:focus-visible {
    background: rgba(23, 113, 201, 0.22);
    border-color: rgba(23, 113, 201, 0.55);
    outline: none;
}

.match-viewers-modal-body {
    max-height: 60vh;
    overflow-y: auto;
}

/* Compact "● N" pill for the Watching column — accent palette, pulses
   gently so live VOD activity catches the eye without being noisy. */
.library-watching-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    background: rgba(23, 113, 201, 0.14);
    color: var(--accent);
    border: 1px solid rgba(23, 113, 201, 0.35);
    font-size: 0.72rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    vertical-align: middle;
    animation: libraryWatchingPulse 2.4s ease-in-out infinite;
}

/* ===== Coaching workspace =====
 * No inner max-width cap — the Coach surfaces fill the universal
 * page shell (`#app-container`) end-to-end so they read like the
 * Coach Review cockpit on a wide monitor instead of leaving large
 * empty bands on either side. */
.coach-page-head {
    margin: 0 0 1.25rem;
}

.coach-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

.coach-wide-card {
    grid-column: 1 / -1;
}

.coach-list {
    display: grid;
    gap: 0.65rem;
}

.coach-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.8rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.coach-row:last-child {
    border-bottom: 0;
}

.coach-row strong {
    display: block;
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 1rem;
    letter-spacing: 0;
}

.coach-row span,
.coach-row p {
    display: block;
    margin: 0.15rem 0 0;
    color: var(--text-muted);
    font-size: 0.82rem;
    line-height: 1.45;
}

.coach-row-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.coach-link-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin: 0.4rem 0.35rem 0 0;
    border: 1px solid rgba(23, 113, 201, 0.35);
    background: rgba(23, 113, 201, 0.10);
    color: var(--text-main);
    border-radius: 999px;
    padding: 0.24rem 0.55rem;
    font-size: 0.75rem;
}

.coach-check-list {
    min-height: 132px;
    max-height: 210px;
    overflow: auto;
    display: grid;
    align-content: start;
    gap: 0.38rem;
    padding: 0.5rem;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(0, 0, 0, 0.24);
    border-radius: 6px;
    scrollbar-width: thin;
    scrollbar-color: rgba(23, 113, 201, 0.7) rgba(255, 255, 255, 0.08);
}

.coach-check-list.compact {
    min-height: 116px;
    max-height: 150px;
}

.coach-check-list::-webkit-scrollbar {
    width: 10px;
}

.coach-check-list::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.06);
    border-radius: 999px;
}

.coach-check-list::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(23, 113, 201, 0.85), rgba(56, 189, 248, 0.65));
    border: 2px solid rgba(6, 10, 18, 0.92);
    border-radius: 999px;
}

.coach-check-option {
    width: 100%;
    min-height: 38px;
    display: grid;
    grid-template-columns: 1.05rem 1fr;
    align-items: center;
    gap: 0.55rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    background: rgba(255, 255, 255, 0.035);
    color: var(--text-main);
    border-radius: 6px;
    padding: 0.48rem 0.6rem;
    text-align: left;
    cursor: pointer;
    font: inherit;
    font-size: 0.84rem;
}

.coach-check-option:hover {
    border-color: rgba(23, 113, 201, 0.45);
    background: rgba(23, 113, 201, 0.10);
}

.coach-check-option:focus-visible {
    outline: 2px solid rgba(56, 189, 248, 0.75);
    outline-offset: 2px;
}

.coach-check-option.is-selected {
    border-color: rgba(23, 113, 201, 0.65);
    background: rgba(23, 113, 201, 0.18);
}

.coach-check-box {
    width: 1.05rem;
    height: 1.05rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.28);
    background: rgba(0, 0, 0, 0.28);
    border-radius: 4px;
}

.coach-check-option.is-selected .coach-check-box {
    border-color: var(--accent);
    background: var(--accent);
}

.coach-check-option.is-selected .coach-check-box::after {
    content: "";
    width: 0.34rem;
    height: 0.58rem;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg) translateY(-1px);
}

.coach-check-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.coach-check-empty {
    min-height: 38px;
    display: flex;
    align-items: center;
    color: var(--text-muted);
    padding: 0.45rem 0.55rem;
    font-size: 0.84rem;
}

/* The in-match coach side panel and toggle (.coach-match-panel,
   .coach-mode-bar, .coach-mode-toggle, .sidebar.coach-mode-on …) was
   removed — Coach > Review is now the single authoring surface. */

.coach-mini-form {
    display: grid;
    gap: 0.55rem;
}

.coach-mini-form input,
.coach-mini-form textarea,
.coach-mini-form select {
    width: 100%;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(0, 0, 0, 0.24);
    color: var(--text-main);
    border-radius: 6px;
    padding: 0.55rem 0.65rem;
    font: inherit;
    font-size: 0.85rem;
    /* Issue #78 — make the focus transition snappy enough to feel
     * responsive without being distracting. Only paint properties
     * are animated (`border-color`, `box-shadow`, `background-color`)
     * — none of them affect layout, so there is no layout shift on
     * focus. `background-color` (not the `background` shorthand) so
     * a focused `<select>` keeps its `background-image` chevron. */
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
/* Issue #78 — dedicated themed focus ring for Coach Review + Notes
 * Edit modal textareas / inputs / selects. The global :focus-visible
 * rule already paints a 2 px accent outline at 2 px offset; here we
 * additionally swap the border to the accent and add an inset glow
 * so the focused control reads as the same component family as the
 * picker selects above the video (which use the same pattern). The
 * outline still wins as the primary AT cue; the border-color +
 * box-shadow + background-color are visual polish that ties the
 * form together without changing box dimensions (no padding /
 * border-width changes → no layout shift). Both dark + light
 * themes covered.
 *
 * Note — `background-color` (not the `background` shorthand) so
 * we don't reset `background-image` on focused `<select>`s, which
 * would erase the SVG chevron. Same pattern the file's other
 * select-focus rules use (`.coach-link-modal select`,
 * `.coach-review-picker select:focus-visible`, etc.). */
.coach-mini-form input:focus-visible,
.coach-mini-form textarea:focus-visible,
.coach-mini-form select:focus-visible {
    border-color: var(--accent, #298bed);
    background-color: rgba(0, 0, 0, 0.32);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.18);
}

.coach-mini-form select {
    padding-right: 2.35rem;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23888890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    background-size: 12px 8px;
}

/* Issue #80 / #78 — light-mode overrides for `.coach-mini-form`
 * controls used by both the Coach Review composer and the Notes-tab
 * Edit modal. The dark defaults above use a pale border on a near-
 * black background; in light mode that translates to invisible-on-
 * invisible. Use white inputs with a darker border, the same dark
 * chevron arrow for selects, and a higher-contrast focus state.
 * Issue #80 specifically called out unreadable select controls in the
 * Coach note modal — this rule fixes both selects and the textarea /
 * input siblings in one go.
 *
 * Note — `background-color` (not `background` shorthand) so the
 * select keeps its `background-image` chevron when the rule wins
 * the cascade. `border-color: 0.14` matches the rest of the light-
 * theme form selects (`.coach-review-picker select`,
 * `.form-group select`, `.library-filter-bar select`). This block
 * also subsumes the older `[data-theme="light"] .coach-mini-form
 * input/textarea/select` rule that was sitting later in the file
 * — we removed that duplicate so the cascade is single-sourced. */
[data-theme="light"] .coach-mini-form input,
[data-theme="light"] .coach-mini-form textarea,
[data-theme="light"] .coach-mini-form select {
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
    color: var(--text-main);
}
[data-theme="light"] .coach-mini-form input:hover,
[data-theme="light"] .coach-mini-form textarea:hover,
[data-theme="light"] .coach-mini-form select:hover {
    border-color: rgba(0, 0, 0, 0.32);
}
[data-theme="light"] .coach-mini-form input:focus-visible,
[data-theme="light"] .coach-mini-form textarea:focus-visible,
[data-theme="light"] .coach-mini-form select:focus-visible {
    background-color: #ffffff;
    border-color: var(--accent, #1565c0);
    box-shadow: 0 0 0 2px rgba(21, 101, 192, 0.22);
}
[data-theme="light"] .coach-mini-form select {
    /* Re-encode the chevron with a darker stroke so it reads on the
     * white background. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23475569' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}

.coach-panel-grid,
.coach-draw-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
}

.coach-draw-actions {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.coach-telestrator {
    display: grid;
    gap: 0.55rem;
}

.coach-telestrator input[type="text"] {
    width: 100%;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: rgba(0, 0, 0, 0.24);
    color: var(--text-main);
    border-radius: 6px;
    padding: 0.55rem 0.65rem;
    font: inherit;
    font-size: 0.85rem;
}

.coach-telestrator input[type="text"]:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(23, 113, 201, 0.18);
}

[data-theme="light"] .coach-telestrator input[type="text"] {
    background: #fff;
    color: var(--text-main);
    border-color: rgba(0, 0, 0, 0.14);
}

/* Formation tool — controls panel under the toolbar (Quick/Linked toggle,
   roster picker, anchor counter, Cancel/Done). */
.coach-formation-controls {
    display: grid;
    gap: 0.5rem;
    padding: 0.6rem 0.7rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.02);
}

.coach-formation-controls[hidden] { display: none; }

.coach-formation-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}

.coach-formation-head strong {
    font-family: var(--font-heading);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.coach-formation-modes {
    display: inline-flex;
    gap: 0.3rem;
}

.coach-formation-roster {
    max-height: 168px;
    overflow: auto;
    display: grid;
    gap: 0.3rem;
    padding: 0.3rem;
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
    background: rgba(0, 0, 0, 0.18);
    /* Match .coach-check-list scrollbar theming so realistic team rosters
       (15-25 players) overflow into a styled scrollbar, not the wider
       global default. */
    scrollbar-width: thin;
    scrollbar-color: rgba(23, 113, 201, 0.75) rgba(255, 255, 255, 0.06);
}

.coach-formation-roster::-webkit-scrollbar {
    width: 8px;
}

.coach-formation-roster::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.06);
    border-radius: 999px;
}

.coach-formation-roster::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(23, 113, 201, 0.85), rgba(56, 189, 248, 0.65));
    border: 2px solid rgba(6, 10, 18, 0.92);
    border-radius: 999px;
}

[data-theme="light"] .coach-formation-roster {
    scrollbar-color: rgba(23, 113, 201, 0.7) rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .coach-formation-roster::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .coach-formation-roster::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(23, 113, 201, 0.78), rgba(15, 118, 178, 0.62));
    border-color: rgba(255, 255, 255, 0.85);
}

/* Reuse the `.coach-check-option` pill but show queue order in the box.
   The number in the box is the placement order, not a checkmark. */
.coach-formation-roster .coach-check-option .coach-check-box {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--accent);
}

.coach-formation-hint {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.78rem;
    line-height: 1.4;
}

.coach-formation-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.coach-formation-count {
    margin-right: auto;
    color: var(--text-muted);
    font-size: 0.76rem;
}

[data-theme="light"] .coach-formation-controls {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .coach-formation-roster {
    background: rgba(255, 255, 255, 0.6);
    border-color: rgba(0, 0, 0, 0.08);
}

.coach-tool-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 0.35rem;
}

.coach-tool-grid .mini-action-btn.active,
.coach-tool-grid .coach-tool-btn.active,
.coach-color-swatch.active {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.22);
}

/* ============================================================
 * Sprint 3: icon-first telestrator tool buttons
 *
 * Default (touch / narrow / pointer:coarse) state shows the icon AND
 * the text label so a casual or coarse-pointer user has a 44 px target
 * with a clear name. Desktop (pointer:fine + ≥900px) collapses the
 * label so a coach with a mouse gets a dense 34 px icon grid that
 * doesn't crowd the video canvas.
 *
 * Visual + a11y rules:
 * - Always-visible focus ring via :focus-visible (not just :focus —
 *   we don't want it on every click).
 * - aria-pressed="true" → border accent + soft inset ring (active tool
 *   styling already provided by `.coach-tool-grid .coach-tool-btn.active`).
 * - currentColor used inside the SVG so the icon picks up the button's
 *   foreground color in both themes.
 * ============================================================ */
.coach-tool-btn {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.18rem;
    padding: 0.35rem 0.4rem;
    border-radius: 8px;
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
    /* Touch-first default — a 44px target above any pointer override. */
    min-height: 44px;
}
.coach-tool-btn:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.22);
}
.coach-tool-btn:focus-visible {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.32);
}
.coach-tool-icon {
    width: 20px;
    height: 20px;
    color: currentColor;
    flex: 0 0 auto;
}
.coach-tool-label {
    line-height: 1;
}

/* Desktop with a fine pointer: collapse to a 34px icon grid. The text
 * label is hidden from sight but remains in the DOM (and on the button
 * via aria-label/title) so screen readers and tooltips still work. */
@media (pointer: fine) and (min-width: 900px) {
    .coach-tool-btn {
        min-height: 0;
        width: 34px;
        height: 34px;
        padding: 0;
        gap: 0;
        margin: 0 auto;
    }
    .coach-tool-label {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }
}

[data-theme="light"] .coach-tool-btn {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.10);
}
[data-theme="light"] .coach-tool-btn:hover {
    background: rgba(0, 0, 0, 0.07);
    border-color: rgba(0, 0, 0, 0.22);
}

/* Width slider gets a small "W" icon-label so it reads as compact */
.coach-width-label {
    font-family: var(--font-heading);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

/* Soft destructive variant for Clear — still legible as text but
 * visually different from neutral Undo / Delete. The plan asks to keep
 * text labels for destructive actions, so this stays a text button.
 *
 * NOT a new button tier — `.btn-danger-soft` is a modifier applied to
 * the existing `.mini-action-btn` tier (the CLAUDE.md three-tier rule
 * tracks top-level button structure, not emphasis variants). The
 * destructive accent is a translucent rose; both dark and light mode
 * get explicit overrides so the user's "no native chrome / themed in
 * both modes" rule holds at every breakpoint.
 */
.mini-action-btn.btn-danger-soft {
    color: rgba(244, 63, 94, 0.95);
    border-color: rgba(244, 63, 94, 0.28);
}
.mini-action-btn.btn-danger-soft:hover {
    background: rgba(244, 63, 94, 0.12);
    border-color: rgba(244, 63, 94, 0.55);
}
[data-theme="light"] .mini-action-btn.btn-danger-soft {
    color: rgba(190, 18, 60, 0.95);
    border-color: rgba(190, 18, 60, 0.32);
}
[data-theme="light"] .mini-action-btn.btn-danger-soft:hover {
    background: rgba(190, 18, 60, 0.08);
    border-color: rgba(190, 18, 60, 0.55);
}

/* ============================================================
 * Phase 2 — coaching templates
 *
 * Compact selector row at the top of the composer: a coach picks a
 * starter template (grouped by soccer area) and presses Apply to
 * fill the structured fields. The row sits in a single line on
 * desktop and wraps on narrow viewports. Themed selects + buttons
 * follow the same dark/light pattern as the rest of the composer.
 * ============================================================ */
.coach-review-template {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.1rem;
}
.coach-review-template-label {
    font-family: var(--font-heading);
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    flex: 0 0 auto;
}
.coach-review-template select {
    /* Issue #85 — visual alignment with neighbouring `.coach-mini-form`
     * controls (Title, Players, Category, Tone chips, More-details
     * textareas) which the template selector sits next to inside
     * `#coach-review-form`. We adopt the same dark-mode background
     * (`rgba(0, 0, 0, 0.24)`) and border alpha (`rgba(255, 255, 255,
     * 0.12)`) those siblings use, plus the same mixed-case body font.
     * Template option text like "Scanning before receiving" is
     * deliberately NOT uppercased — sentence-case keeps the labels
     * legible (the Coach Review picker selects above the video can use
     * `text-transform: uppercase` because they label single words like
     * "Full" or "1st Half"). Never expose native chrome — see
     * `.agent-skills/css-responsive-accessibility.md`. */
    flex: 1 1 12rem;
    min-width: 10rem;
    padding: 0.45rem 2.2rem 0.45rem 0.7rem;
    background: rgba(0, 0, 0, 0.24);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    color: var(--text-main);
    font-size: 0.85rem;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23888890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    background-size: 10px 6px;
    cursor: pointer;
    /* Animate `background-color` (not the `background` shorthand) so
     * the SVG chevron's `background-image` is not implicitly reset
     * to `none` on transition. */
    transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
}
.coach-review-template select:hover {
    /* Slightly more opaque border on hover — keeps the rest state
     * subtle while making the affordance discoverable. The
     * `.coach-mini-form` siblings have no dedicated dark-mode hover
     * rule (their hover state is the global :focus-visible outline
     * triggered when keyboard-focused); this rule adds a mouse-only
     * hover signal for the template selector. */
    border-color: rgba(255, 255, 255, 0.22);
}
.coach-review-template select:focus-visible {
    /* Match the focus pattern of `.coach-mini-form input/textarea/
     * select:focus-visible` so the whole composer reads as one
     * component family. `background-color` (not `background`
     * shorthand) so the SVG chevron survives focus. */
    outline: none;
    border-color: var(--accent, #298bed);
    background-color: rgba(0, 0, 0, 0.32);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.18);
}
.coach-review-template .mini-action-btn {
    flex: 0 0 auto;
}
.coach-review-template .mini-action-btn[aria-disabled="true"] {
    /* Match the visual weight of the surrounding controls when no
     * template is selected — the button is reachable by keyboard but
     * communicates "not actionable yet" without becoming invisible. */
    opacity: 0.45;
    cursor: not-allowed;
}

/* Issue #86 — light-mode override aligned to the surrounding
 * `[data-theme="light"] .coach-mini-form select` pattern (the
 * template selector lives inside `.coach-mini-form` so it should
 * read as one component family with its siblings). White background,
 * `border-color: rgba(0, 0, 0, 0.14)` to match the mini-form
 * siblings + the picker selects + every other light-theme form
 * select in the file (`.form-group select`, `.library-filter-bar
 * select`). Dark chevron stroke for legibility on white.
 * `background-color` (not the `background` shorthand) so the
 * `background-image` chevron survives the cascade. */
[data-theme="light"] .coach-review-template select {
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
    color: var(--text-main);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23475569' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}
[data-theme="light"] .coach-review-template select:hover {
    border-color: rgba(0, 0, 0, 0.32);
}
[data-theme="light"] .coach-review-template select:focus-visible {
    background-color: #ffffff;
    border-color: var(--accent, #1565c0);
    box-shadow: 0 0 0 2px rgba(21, 101, 192, 0.22);
}

@media (pointer: coarse), (max-width: 899px) {
    /* On touch / narrow widths bump the buttons to a 44 px tap target
     * and let the selector own a full row above them. */
    .coach-review-template select {
        flex: 1 1 100%;
        min-height: 44px;
    }
    .coach-review-template .mini-action-btn {
        min-height: 44px;
        flex: 1 1 auto;
    }
}

/* ============================================================
 * Sprint 4: fast note composer with collapsed advanced details
 *
 * The default composer shows title → players → category → Save-at-MM:SS.
 * Visibility, body, and tags collapse into a <details> disclosure so
 * they're available without dominating the inspector vertically. The
 * disclosure summary uses a small chevron drawn via CSS so we don't
 * expose the native browser triangle (which differs across platforms
 * and would clash with the rest of the themed UI).
 * ============================================================ */
.coach-review-advanced {
    margin-top: 0.1rem;
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.02);
    overflow: hidden;
}
.coach-review-advanced > summary {
    list-style: none;        /* remove the native triangle (Firefox) */
    cursor: pointer;
    padding: 0.45rem 0.7rem;
    font-family: var(--font-heading);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 0.4rem;
    transition: background 0.15s ease, color 0.15s ease;
}
.coach-review-advanced > summary::-webkit-details-marker {
    display: none;           /* remove the native triangle (Safari/Chrome) */
}
.coach-review-advanced > summary::marker {
    display: none;           /* remove the native triangle (Firefox / standards) */
}
.coach-review-advanced > summary::before {
    content: "";
    width: 6px;
    height: 6px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    transition: transform 0.15s ease;
    flex: 0 0 auto;
}
.coach-review-advanced[open] > summary::before {
    transform: rotate(45deg);
}
.coach-review-advanced > summary:hover {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-main);
}
.coach-review-advanced > summary:focus-visible {
    outline: none;
    background: rgba(255, 255, 255, 0.05);
    box-shadow: inset 0 0 0 2px rgba(23, 113, 201, 0.32);
}
/* Default-hide the body when <details> is closed. Without this gate the
 * `display: grid` rule below overrides the browser default
 * `details:not([open]) > *:not(summary) { display: none }` and the
 * advanced fields render regardless of the toggle state. */
.coach-review-advanced:not([open]) > .coach-review-advanced-body {
    display: none;
}
.coach-review-advanced[open] > .coach-review-advanced-body {
    display: grid;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem 0.7rem;
    border-top: 1px solid rgba(255, 255, 255, 0.04);
}
.coach-review-field-label {
    display: grid;
    gap: 0.25rem;
}
.coach-review-field-label > span {
    font-family: var(--font-heading);
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

[data-theme="light"] .coach-review-advanced {
    border-color: rgba(0, 0, 0, 0.08);
    background: rgba(0, 0, 0, 0.02);
}
[data-theme="light"] .coach-review-advanced > summary:hover,
[data-theme="light"] .coach-review-advanced > summary:focus-visible {
    background: rgba(0, 0, 0, 0.04);
}
[data-theme="light"] .coach-review-advanced-body {
    border-top-color: rgba(0, 0, 0, 0.05);
}

/* PR 1b: tone chip group above the Save button. Compact `radiogroup`
 * — one chip per `_VALID_NOTE_TYPES` value, default `correction`
 * highlighted. `pointer:fine` desktop runs them in a single row;
 * `pointer:coarse` / narrow viewports wrap. The `coach-review-tone-
 * modal` variant inherits everything but lives inside the Notes-tab
 * modal where the labels can be slightly wider. */
.coach-review-tone {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    padding: 0.25rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    margin-top: 0.1rem;
}
[data-theme="light"] .coach-review-tone {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.08);
}
.coach-review-tone-btn {
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    min-height: 30px;
    padding: 0.32rem 0.55rem;
    border-radius: 6px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.72rem;
    font-family: var(--font-heading);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.coach-review-tone-btn:hover {
    color: var(--text-main);
    background: rgba(255, 255, 255, 0.05);
}
.coach-review-tone-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}
.coach-review-tone-btn.is-active {
    background: rgba(23, 113, 201, 0.18);
    border-color: rgba(23, 113, 201, 0.45);
    color: var(--text-main);
}
[data-theme="light"] .coach-review-tone-btn:hover {
    background: rgba(0, 0, 0, 0.04);
}
[data-theme="light"] .coach-review-tone-btn.is-active {
    background: rgba(23, 113, 201, 0.14);
    border-color: rgba(23, 113, 201, 0.4);
}
.coach-review-tone-glyph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: rgba(23, 113, 201, 0.22);
    color: var(--accent, #298bed);
    font-size: 0.78rem;
    line-height: 1;
    flex: 0 0 auto;
}
.coach-review-tone-btn.is-active .coach-review-tone-glyph {
    background: rgba(23, 113, 201, 0.42);
    color: #fff;
}
@media (pointer: coarse), (max-width: 899px) {
    .coach-review-tone-btn {
        min-height: 44px;
    }
}

/* Inline `(visible to player/family)` hint inside a structured-field
 * label (Phase 1 — distinguishes the player-facing summary from the
 * coach-private fields). The Review composer renders the hint as
 * `<small>` inside the label `<span>` (this rule); the Notes-tab
 * Edit modal uses `<span class="form-label-hint">` instead. Two
 * different markups, same visual treatment — both render as a
 * muted, lower-weight, non-uppercase tail. */
.coach-review-field-label > span small {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    color: var(--text-muted);
    opacity: 0.75;
    margin-left: 0.25rem;
}

.coach-tool-row {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-wrap: wrap;
}

.coach-color-swatch {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.22);
    background: var(--swatch);
    cursor: pointer;
}

.coach-width-control {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--text-muted);
    font-size: 0.78rem;
}

.coach-width-control input {
    width: 84px;
    padding: 0;
    appearance: none;
    -webkit-appearance: none;
    height: 18px;
    border: 0;
    background: transparent;
    cursor: pointer;
}

.coach-width-control input::-webkit-slider-runnable-track {
    height: 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    border: 1px solid rgba(255, 255, 255, 0.08);
}

.coach-width-control input::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    margin-top: -6px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.75);
    background: var(--accent);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

.coach-width-control input::-moz-range-track {
    height: 6px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    border: 1px solid rgba(255, 255, 255, 0.08);
}

.coach-width-control input::-moz-range-thumb {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.75);
    background: var(--accent);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
}

.coach-panel-notes {
    margin-top: 0.75rem;
    display: grid;
    gap: 0.45rem;
}

.coach-note-jump {
    width: 100%;
    display: grid;
    grid-template-columns: 3.5rem 1fr;
    gap: 0.5rem;
    align-items: center;
    text-align: left;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
    border-radius: 6px;
    padding: 0.45rem 0.55rem;
    cursor: pointer;
}

.coach-note-jump:hover {
    border-color: rgba(23, 113, 201, 0.45);
}

.coach-note-jump span {
    color: var(--accent);
    font-family: var(--font-heading);
}

.coach-note-jump strong {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.82rem;
}

.coach-drawing-canvas {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 5;
    pointer-events: auto;
    touch-action: none;
}

/* No inner max-width cap — fills the universal page shell. */
.feedback-content {
    margin: 0;
}

/* ===== Coach + Feedback sub-tab navigation =====
   Uses the same visual language as `.btn-head`: pill buttons with an
   accent-tinted active state. One nav, two scopes (coach / feedback). */
.coach-subnav {
    margin: 0 0 1rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    padding: 0.35rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
}

.coach-subnav-btn {
    flex: 0 1 auto;
    padding: 0.55rem 1rem;
    border-radius: 7px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    cursor: pointer;
    transition: background 0.18s, color 0.18s, border-color 0.18s;
}

.coach-subnav-btn:hover {
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
}

.coach-subnav-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.coach-subnav-btn.is-active,
.coach-subnav-btn[aria-selected="true"] {
    background: rgba(23, 113, 201, 0.18);
    border-color: rgba(23, 113, 201, 0.42);
    color: var(--text-main);
}

[data-theme="light"] .coach-subnav {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .coach-subnav-btn:hover {
    background: rgba(0, 0, 0, 0.05);
}

[data-theme="light"] .coach-subnav-btn.is-active,
[data-theme="light"] .coach-subnav-btn[aria-selected="true"] {
    background: rgba(23, 113, 201, 0.14);
    border-color: rgba(23, 113, 201, 0.4);
}

.coach-tab-panel {
    animation: coachTabFade 0.18s ease-out;
}

.coach-tab-panel[hidden] { display: none; }

@keyframes coachTabFade {
    from { opacity: 0; transform: translateY(2px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Coach > Review shell ============================ */
.coach-review-shell { padding: 1rem 1.25rem; }

.coach-review-picker {
    margin-bottom: 1rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

/* Each segment of the compact top bar — Match, Slot, Time, Save Note. */
.coach-review-picker-group {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
}

/* Match segment grows to fill leftover space; Slot/Time stay sized to content. */
.coach-review-picker-group:first-child {
    flex: 1 1 280px;
}
.coach-review-picker-group:first-child select {
    flex: 1 1 auto;
    min-width: 0;
}

.coach-review-picker-label {
    font-family: var(--font-heading);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    white-space: nowrap;
}

/* Time readout uses tabular numbers so the digits don't shift while playing. */
.coach-review-picker-time {
    padding: 0.35rem 0.65rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
}
.coach-review-time-value {
    font-family: var(--font-heading), system-ui, sans-serif;
    font-variant-numeric: tabular-nums;
    font-size: 0.95rem;
    color: var(--text-primary, inherit);
    letter-spacing: 0.04em;
}
[data-theme="light"] .coach-review-picker-time {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}

/* Themed selects for the compact picker. The repo's standard select styling
 * is scoped to `.form-group select` (3.8k of styles.css); since the picker
 * no longer wraps each select in a .form-group, we need a scoped variant.
 * This must override the browser default — never expose native chrome inside
 * styled UI (see .agent-skills/css-responsive-accessibility.md). Compacts
 * the form-group padding from 0.95rem to 0.45rem so the bar stays slim. */
.coach-review-picker select {
    padding: 0.45rem 2.2rem 0.45rem 0.7rem;
    background: rgba(0, 0, 0, 0.38);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23888890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    background-size: 10px 6px;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}
.coach-review-picker select:hover {
    border-color: rgba(255, 255, 255, 0.18);
}
.coach-review-picker select:focus-visible {
    outline: none;
    border-color: var(--accent, #298bed);
    background-color: rgba(0, 0, 0, 0.5);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.18);
}

[data-theme="light"] .coach-review-picker select {
    /* Pure white matches the rest of the light-mode form selects (see
     * .form-group select rule). rgba() with alpha layered over the off-white
     * page background produces a low-contrast stripe artifact in some
     * browsers, so do not use transparency here. */
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
    color: var(--text-main);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%236b6b75' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}
[data-theme="light"] .coach-review-picker select:hover {
    border-color: rgba(0, 0, 0, 0.22);
}
[data-theme="light"] .coach-review-picker select:focus-visible {
    background-color: #ffffff;
    box-shadow: 0 0 0 2px rgba(21, 101, 192, 0.18);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%231565c0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}

/* Phase 6d-1 — Tactical Board mode picker-bar text + date inputs.
 * The picker bar previously only contained <select> elements, which
 * `.coach-review-picker select` styles. Adding the unified Coach
 * Review introduces <input type="text"> for Event title and
 * <input type="date"> for Event date — these need the same dark
 * tile background, accent focus, and dark-theme calendar-picker
 * indicator the rest of the picker uses, so the bar reads as one
 * surface and never exposes raw browser chrome. */
.coach-review-picker input[type="text"],
.coach-review-picker input[type="date"] {
    /* `appearance: none` is required to suppress Safari/macOS Chrome's
     * native input chrome (the inner white field that bleeds through
     * the styled tile background). Without it the date picker
     * specifically renders as raw OS chrome. */
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding: 0.45rem 0.7rem;
    background: rgba(0, 0, 0, 0.38);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.85rem;
    line-height: 1.2;
    min-height: 0;
    transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
}
.coach-review-picker input[type="text"]::placeholder,
.coach-review-picker input[type="date"]::placeholder {
    color: rgba(255, 255, 255, 0.45);
}
.coach-review-picker input[type="text"]:hover,
.coach-review-picker input[type="date"]:hover {
    border-color: rgba(255, 255, 255, 0.18);
}
.coach-review-picker input[type="text"]:focus-visible,
.coach-review-picker input[type="date"]:focus-visible {
    outline: none;
    border-color: var(--accent, #298bed);
    background-color: rgba(0, 0, 0, 0.5);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.18);
}
.coach-review-picker input[type="date"]::-webkit-calendar-picker-indicator {
    /* Match the global indicator styling (styles.css:1530). The
     * filter keeps the indicator readable on the dark tile in both
     * Chrome and Safari. */
    opacity: 0.75;
    cursor: pointer;
    filter: invert(1) saturate(0.3);
}

[data-theme="light"] .coach-review-picker input[type="text"],
[data-theme="light"] .coach-review-picker input[type="date"] {
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
    color: var(--text-main);
}
[data-theme="light"] .coach-review-picker input[type="text"]:hover,
[data-theme="light"] .coach-review-picker input[type="date"]:hover {
    border-color: rgba(0, 0, 0, 0.22);
}
[data-theme="light"] .coach-review-picker input[type="text"]:focus-visible,
[data-theme="light"] .coach-review-picker input[type="date"]:focus-visible {
    background-color: #ffffff;
    border-color: var(--accent, #1565c0);
    box-shadow: 0 0 0 2px rgba(21, 101, 192, 0.18);
}
[data-theme="light"] .coach-review-picker input[type="date"]::-webkit-calendar-picker-indicator {
    /* No invert in light theme — the calendar glyph is dark on white
     * by default, which already matches the rest of the light-theme
     * iconography. */
    filter: none;
}
[data-theme="light"] .coach-review-picker input[type="text"]::placeholder,
[data-theme="light"] .coach-review-picker input[type="date"]::placeholder {
    color: rgba(15, 23, 42, 0.40);
}

/* Top-bar Save Note: compact variant of .btn-primary. The form's full-width
 * Save Note button stays as the secondary affordance for first-time users. */
.coach-review-picker-save {
    flex: 0 0 auto;
    padding: 0.45rem 0.95rem;
    font-size: 0.85rem;
    white-space: nowrap;
}

@media (max-width: 720px) {
    .coach-review-picker {
        gap: 0.5rem;
    }
    .coach-review-picker-group:first-child {
        flex: 1 1 100%;
    }
    .coach-review-picker-save {
        flex: 1 1 100%;
    }
}

.coach-review-grid {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
    gap: 1.25rem;
}

.coach-review-video {
    min-width: 0;
}

.coach-review-wrapper {
    position: relative;
    background: #000;
    border-radius: 10px;
    overflow: hidden;
    aspect-ratio: 16 / 9;
}

.coach-review-wrapper video {
    width: 100%;
    height: 100%;
    display: block;
}

.coach-review-empty {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    background: rgba(0, 0, 0, 0.55);
    font-size: 0.92rem;
    text-align: center;
    padding: 1rem;
}

.coach-review-side {
    display: grid;
    gap: 0.85rem;
    align-content: start;
}

.coach-review-side h4 {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

[data-theme="light"] .coach-review-picker {
    border-bottom-color: rgba(0, 0, 0, 0.08);
}

/* Sprint 1: video-first Review cockpit ============================
 *
 * `is-review-mode` is set on #coach-view by setCoachTab() while the Review
 * sub-tab is active. Overrides are scoped to that class so Roster / Notes /
 * Playlists keep their existing density. Below the laptop breakpoint the
 * grid collapses back to a single column.
 */
#coach-view.is-review-mode .coach-page-head {
    /* Shrink the page intro so the video gets ~250px of vertical real estate back. */
    margin-bottom: 0.4rem;
}
#coach-view.is-review-mode .coach-page-head h2 {
    font-size: 1.1rem;
    margin: 0;
}
#coach-view.is-review-mode .coach-page-head .admin-section-kicker {
    font-size: 0.65rem;
}
#coach-view.is-review-mode .coach-page-head .admin-section-sub {
    /* Visible to AT but visually hidden in Review mode (the subnav makes the
     * surface obvious). Restored at narrow widths so mobile keeps context. */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

#coach-view.is-review-mode .coach-review-shell {
    padding: 0.65rem 0.85rem;
}

#coach-view.is-review-mode .coach-review-picker {
    margin-bottom: 0.6rem;
    padding-bottom: 0.6rem;
}

/* Review mode no longer needs special width handling: the universal
 * page shell + the no-inner-cap policy mean every Coach surface
 * (Roster / Notes / Playlists / Review) already fills `#app-container`
 * end-to-end. The previous `max-width: 100%` overrides on
 * `.coach-page-head` / `.coach-subnav` / `.coach-tab-panel` were
 * removed because the inner 1180 px caps they lifted are gone. */

@media (min-width: 1024px) {
    #coach-view.is-review-mode .coach-review-grid {
        /* Video column is the dominant flex; inspector is fixed at 340px so it
         * stays usable when the viewport narrows toward 1024px. align-items:
         * start so the side panel doesn't stretch and fight the inspector's
         * own scroll — its max-height is driven by JS instead (see
         * _syncCoachReviewSideHeight in js/coaching.js) so it always matches
         * the video wrapper's actual rendered height. */
        grid-template-columns: minmax(0, 1fr) 340px;
        gap: 0.85rem;
        align-items: start;
    }

    #coach-view.is-review-mode .coach-review-side {
        /* max-height is set inline by _syncCoachReviewSideHeight() and updated
         * via the existing ResizeObserver on .coach-review-wrapper (Sprint 1).
         * Fallback for the brief moment before JS runs: cap to a reasonable
         * 16:9-ish height so the panel never towers above the video. */
        max-height: calc((100vw - 380px) * 9 / 16);
        overflow: auto;
        /* Themed scrollbar — never expose native chrome inside styled UI. */
        scrollbar-width: thin;
        scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
    }

    /* Sprint 2 polish: collapse nested scrollers inside the inspector while
     * the outer .coach-review-side already scrolls independently. Two
     * scrollbars stacked (panel + player checklist) is distracting during
     * video review — the player chips just grow vertically and ride along
     * with the outer scroll. The chips themselves are tightened so a 15-25
     * player roster doesn't dominate the inspector. */
    #coach-view.is-review-mode #coach-review-players.coach-check-list {
        min-height: 0;
        max-height: none;
        overflow: visible;
        padding: 0.4rem;
    }
    #coach-view.is-review-mode #coach-review-players .coach-check-option {
        min-height: 32px;
        padding: 0.3rem 0.55rem;
        font-size: 0.85rem;
    }

    /* Tighten the inspector layout so the form doesn't dominate vertically.
     * Headers (`Telestrator`, `Save note at current time`, `Notes for this
     * match`) are visually redundant — the controls below them are obvious —
     * so squeeze them out in Review mode. AT users still get them via
     * .coach-review-side > h4's intrinsic semantics; they're hidden visually
     * only. */
    #coach-view.is-review-mode .coach-review-side {
        gap: 0.5rem;
    }
    #coach-view.is-review-mode .coach-review-side > h4 {
        position: absolute;
        width: 1px;
        height: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0, 0, 0, 0);
        white-space: nowrap;
        border: 0;
    }

    /* Tighter form spacing + shorter body textarea so the form fits without
     * forcing the side panel to scroll on a normal-height monitor. Sprint 4
     * will collapse body/visibility/tags into an "advanced" section, which
     * removes most of this height entirely. */
    #coach-view.is-review-mode .coach-mini-form {
        gap: 0.4rem;
    }
    #coach-view.is-review-mode .coach-mini-form textarea {
        min-height: 56px;
    }

    #coach-view.is-review-mode .coach-review-side::-webkit-scrollbar {
        width: 6px;
    }
    #coach-view.is-review-mode .coach-review-side::-webkit-scrollbar-track {
        background: transparent;
    }
    #coach-view.is-review-mode .coach-review-side::-webkit-scrollbar-thumb {
        background: rgba(255, 255, 255, 0.18);
        border-radius: 3px;
    }
}

[data-theme="light"] #coach-view.is-review-mode .coach-review-side {
    scrollbar-color: rgba(0, 0, 0, 0.18) transparent;
}
[data-theme="light"] #coach-view.is-review-mode .coach-review-side::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.18);
}

/* ============================================================
 * Sprint 5: current-match timeline rail
 *
 * Replaces the bulky stacked notes list (used to live inside the
 * right inspector) with a horizontal chip rail under the video. Each
 * chip shows MM:SS · player indicator · category dot · short title;
 * clicking still routes through the existing seekCoachReviewNote
 * handler (drawing render + canvas paint preserved). The rail spans
 * the full width of .coach-review-grid so it sits cleanly under both
 * the video column and the inspector column at desktop, and falls
 * naturally into the single-column flow on mobile.
 *
 * Horizontal-scroll-only: the rail keeps a themed thin scrollbar
 * (never expose native chrome — see standing rule). Vertical wrap is
 * disabled so the rail never pushes the page taller as notes
 * accumulate; instead, the user scrolls horizontally or the active
 * chip auto-scrolls into view via _setActiveCoachReviewNote.
 * ============================================================ */
.coach-timeline-rail {
    /* In the .coach-review-grid (display: grid) this is the third item;
     * span both columns at desktop so the rail sits below both video and
     * inspector. At narrow widths the grid collapses to one column and
     * this naturally lays out below them. */
    grid-column: 1 / -1;
    margin-top: 0.75rem;
    padding: 0.4rem 0;
    display: flex;
    gap: 0.45rem;
    overflow-x: auto;
    overflow-y: hidden;
    /* Themed scrollbar — never expose native chrome inside styled UI. */
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
    /* Stop the rail from pushing the page taller as notes accumulate;
     * chips wrap horizontally instead. */
    flex-wrap: nowrap;
}
.coach-timeline-rail::-webkit-scrollbar {
    height: 6px;
}
.coach-timeline-rail::-webkit-scrollbar-track {
    background: transparent;
}
.coach-timeline-rail::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 3px;
}

.coach-timeline-empty {
    color: var(--text-muted);
    font-size: 0.85rem;
    padding: 0.55rem 0.7rem;
    border: 1px dashed rgba(255, 255, 255, 0.10);
    border-radius: 8px;
    flex: 1 1 auto;
    text-align: center;
}

.coach-timeline-chip {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.4rem 0.7rem;
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
    border-radius: 999px;
    cursor: pointer;
    max-width: 22rem;
    transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.coach-timeline-chip:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.22);
}
.coach-timeline-chip:focus-visible {
    outline: none;
    border-color: var(--accent, #298bed);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.32);
}
.coach-timeline-chip.is-active {
    background: rgba(23, 113, 201, 0.18);
    border-color: rgba(23, 113, 201, 0.55);
    box-shadow: 0 0 0 1px rgba(23, 113, 201, 0.28);
}

.coach-timeline-chip-time {
    font-family: var(--font-heading);
    font-variant-numeric: tabular-nums;
    font-size: 0.78rem;
    color: var(--text-muted);
    flex: 0 0 auto;
}
.coach-timeline-chip.is-active .coach-timeline-chip-time {
    color: var(--text-main);
}
.coach-timeline-chip-player {
    font-family: var(--font-heading);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    flex: 0 0 auto;
}
.coach-timeline-chip-cat {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: rgba(255, 255, 255, 0.4);
}
.coach-timeline-chip-cat[data-cat="shape"]      { background: #38bdf8; }
.coach-timeline-chip-cat[data-cat="pressing"]   { background: #f97316; }
.coach-timeline-chip-cat[data-cat="transition"] { background: #a855f7; }
.coach-timeline-chip-cat[data-cat="set_piece"]  { background: #facc15; }
.coach-timeline-chip-cat[data-cat="build_up"]   { background: #22c55e; }
.coach-timeline-chip-cat[data-cat="finishing"]  { background: #f43f5e; }
.coach-timeline-chip-cat[data-cat="defending"]  { background: #6366f1; }
.coach-timeline-chip-cat[data-cat="goalkeeper"] { background: #14b8a6; }
.coach-timeline-chip-cat[data-cat="effort"]     { background: #eab308; }
.coach-timeline-chip-cat[data-cat="decision"]   { background: #ec4899; }
.coach-timeline-chip-cat[data-cat="other"]      { background: rgba(255, 255, 255, 0.4); }

.coach-timeline-chip-title {
    font-size: 0.85rem;
    color: var(--text-main);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1 1 auto;
    min-width: 0;
}

[data-theme="light"] .coach-timeline-rail {
    scrollbar-color: rgba(0, 0, 0, 0.18) transparent;
}
[data-theme="light"] .coach-timeline-rail::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.18);
}
[data-theme="light"] .coach-timeline-empty {
    border-color: rgba(0, 0, 0, 0.10);
}
[data-theme="light"] .coach-timeline-chip {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.10);
}
[data-theme="light"] .coach-timeline-chip:hover {
    background: rgba(0, 0, 0, 0.07);
    border-color: rgba(0, 0, 0, 0.22);
}
[data-theme="light"] .coach-timeline-chip.is-active {
    background: rgba(21, 101, 192, 0.10);
    border-color: rgba(21, 101, 192, 0.45);
    box-shadow: 0 0 0 1px rgba(21, 101, 192, 0.22);
}

/* ============================================================
 * Sprint 6: Wide / Focus mode
 *
 * Toggle that hides page chrome and collapses the right inspector
 * so the video + drawing canvas use nearly the entire screen. Tools
 * and the note composer stay reachable through a slide-over drawer
 * triggered from the picker bar's "Tools" button. Escape exits.
 * State is session-local — js/coaching.js manages the keydown
 * listener lifecycle so it's only bound while focus mode is on.
 *
 * Two cooperating states:
 *   #coach-view.is-focus-mode             — hide chrome, expand video
 *   #coach-view.is-focus-drawer-open      — slide the inspector in
 *
 * Focus mode is layered on top of is-review-mode (Sprint 1), so all
 * Sprint 1+ scoped overrides still apply.
 * ============================================================ */

/* The Tools / drawer toggle is hidden by default and only shown in
 * focus mode (where the inspector is otherwise unreachable).
 * Higher-specificity selector so it wins over the .coach-review-picker-focus
 * rule that sets `display: inline-flex` (the drawer button has both classes). */
.coach-review-picker-focus.coach-review-picker-drawer { display: none; }
#coach-view.is-focus-mode .coach-review-picker-focus.coach-review-picker-drawer {
    display: inline-flex;
}

/* Focus toggle button itself — same compact icon-button style as the
 * other picker controls. Active state mirrors the icon-toolbar pattern
 * so the user can tell at a glance that focus mode is on. */
.coach-review-picker-focus {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.4rem 0.6rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 8px;
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
    white-space: nowrap;
}
.coach-review-picker-focus svg {
    width: 16px;
    height: 16px;
    color: currentColor;
    flex: 0 0 auto;
}
.coach-review-picker-focus:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.22);
}
.coach-review-picker-focus:focus-visible {
    outline: none;
    border-color: var(--accent, #298bed);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.32);
}
.coach-review-picker-focus.is-active,
.coach-review-picker-focus[aria-pressed="true"] {
    background: rgba(23, 113, 201, 0.18);
    border-color: rgba(23, 113, 201, 0.55);
    color: var(--text-main);
}
[data-theme="light"] .coach-review-picker-focus {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.10);
}
[data-theme="light"] .coach-review-picker-focus:hover {
    background: rgba(0, 0, 0, 0.07);
    border-color: rgba(0, 0, 0, 0.22);
}
[data-theme="light"] .coach-review-picker-focus.is-active,
[data-theme="light"] .coach-review-picker-focus[aria-pressed="true"] {
    background: rgba(21, 101, 192, 0.10);
    border-color: rgba(21, 101, 192, 0.45);
}

/* ----- Focus mode ON ----- */
@media (min-width: 1024px) {
    /* Inspector hidden by default in focus mode. The grid collapses to a
     * single (full-width) column for the video. */
    #coach-view.is-focus-mode .coach-review-grid {
        grid-template-columns: minmax(0, 1fr);
    }
    #coach-view.is-focus-mode .coach-review-side {
        display: none;
    }

    /* Hide the page-head + subnav entirely in focus mode — Esc returns
     * the user to the normal cockpit so they aren't stranded. */
    #coach-view.is-focus-mode .coach-page-head,
    #coach-view.is-focus-mode .coach-subnav {
        display: none;
    }

    /* Tighten the picker bar a hair so it reads as compact heads-up
     * controls layered over the video, not a content header. */
    #coach-view.is-focus-mode .coach-review-shell {
        padding: 0.45rem 0.6rem;
    }

}

/* When the drawer is open, the inspector is moved to <body> by JS (see
 * openCoachFocusInspector) so it shares the root stacking context with
 * the backdrop. The selector is keyed on body.coach-focus-drawer-open
 * because the side panel is no longer a descendant of #coach-view at
 * that point. Without this re-parenting, an ancestor stacking context
 * (e.g. .coach-tab-panel's coachTabFade animation) traps the drawer's
 * z-index and the backdrop renders above the drawer, intercepting all
 * clicks and showing a zoom-out cursor over the panel.
 *
 * z-index 110 (and 105 for the backdrop) puts both above .main-nav
 * (z-index: 100, position: sticky). Without this the drawer's top
 * ~75px gets hidden behind the sticky nav. */
body.coach-focus-drawer-open > .coach-review-side {
    display: grid;
    position: fixed;
    top: 1rem;
    right: 1rem;
    bottom: 1rem;
    width: min(380px, calc(100vw - 2rem));
    max-height: none;
    z-index: 110;
    background: var(--bg-panel, #0e1320);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 12px;
    padding: 0.85rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
    overflow: auto;
    animation: coachFocusDrawerSlide 180ms ease-out;
    /* Themed scrollbar — never expose native chrome inside styled UI.
     * The Sprint 1 themed-scrollbar rules are scoped under
     * #coach-view.is-review-mode .coach-review-side, but we re-parented
     * the side panel to <body> in openCoachFocusInspector — so those
     * rules no longer match here. Re-declare them in this scope. */
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
body.coach-focus-drawer-open > .coach-review-side::-webkit-scrollbar {
    width: 6px;
}
body.coach-focus-drawer-open > .coach-review-side::-webkit-scrollbar-track {
    background: transparent;
}
body.coach-focus-drawer-open > .coach-review-side::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 3px;
}

/* Backdrop dim so the drawer reads as a modal layer. The element is
 * mounted by openCoachFocusInspector() in js/coaching.js so it can
 * receive a real click handler for click-outside-to-close.
 * Hidden by default; visible only while the drawer is open. */
.coach-focus-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 105;       /* Above .main-nav (z-index: 100), below the drawer (110). */
    animation: coachFocusBackdropFade 180ms ease-out;
    cursor: zoom-out;
}
.coach-focus-backdrop[hidden] { display: none; }
[data-theme="light"] .coach-focus-backdrop {
    background: rgba(0, 0, 0, 0.18);
}

/* Phase 6d-1 — in Tactical Board focus mode the backdrop dims the
 * page (visual) but does NOT intercept clicks. The pitch needs to
 * receive clicks so an armed tool can drop a token / start a drag in
 * the same gesture that closes the drawer. The drawer itself stays
 * `pointer-events: auto` (default) so its tool buttons remain
 * clickable; only the backdrop is pass-through. The pitch's own
 * mousedown handler closes the drawer (see openCoachFocusInspector
 * `pitchSvg.addEventListener('mousedown', onceClose)`) and then the
 * controller's handler armed by the previous tool click takes over. */
body.coach-focus-drawer-tb-mode .coach-focus-backdrop {
    pointer-events: none;
    cursor: default;
}

@keyframes coachFocusDrawerSlide {
    from { transform: translateX(8px); opacity: 0; }
    to   { transform: translateX(0);   opacity: 1; }
}
@keyframes coachFocusBackdropFade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

[data-theme="light"] body.coach-focus-drawer-open > .coach-review-side {
    scrollbar-color: rgba(0, 0, 0, 0.18) transparent;
    background: var(--bg-panel, #ffffff);
    border-color: rgba(0, 0, 0, 0.12);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
}
[data-theme="light"] body.coach-focus-drawer-open > .coach-review-side::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.18);
}

/* ============================================================
 * Sprint 7: Coach Review keyboard shortcuts help popover
 *
 * Compact themed dialog above the cockpit. Toggled by the picker bar
 * "?" button OR by pressing the "?" key anywhere in Coach Review. The
 * "?" key shortcut is wired in js/coaching.js _handleCoachReviewShortcut.
 * ============================================================ */
.coach-shortcuts-help {
    margin: 0 0 0.6rem;
    padding: 0.7rem 0.85rem;
    background: var(--bg-panel, rgba(255, 255, 255, 0.04));
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 10px;
    animation: coachShortcutsHelpFade 160ms ease-out;
}
.coach-shortcuts-help[hidden] { display: none; }

.coach-shortcuts-help-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 0.4rem;
}
.coach-shortcuts-help-head h4 {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
}

.coach-shortcuts-help-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 0.35rem 0.85rem;
}
.coach-shortcuts-help-list li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.82rem;
    color: var(--text-main);
}
.coach-shortcuts-help-list li > span {
    color: var(--text-muted);
    flex: 1 1 auto;
}
.coach-shortcuts-help kbd {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 4px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.72rem;
    color: var(--text-main);
    line-height: 1.4;
    min-width: 1.4em;
    text-align: center;
}

@keyframes coachShortcutsHelpFade {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

[data-theme="light"] .coach-shortcuts-help {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.10);
}
[data-theme="light"] .coach-shortcuts-help kbd {
    background: rgba(255, 255, 255, 0.85);
    border-color: rgba(0, 0, 0, 0.18);
    color: #1f2937;
}

/* ============================================================
 * Sprint 8: pointer-coarse / mobile a11y polish
 *
 * On touch devices and narrow viewports bump compact controls up to
 * the 44 px WCAG-recommended tap target. The Sprint 3 telestrator
 * toolbar already does this; extend the same rule to the Sprint 2
 * picker bar buttons (Save, Focus, Tools, Shortcuts), Sprint 5
 * timeline chips, and Sprint 6 focus toggle.
 * ============================================================ */
@media (pointer: coarse), (max-width: 899px) {
    /* Catch every interactive element inside the picker bar in one pass
     * so a future button added without the *-save / *-focus class still
     * meets the 44 px minimum. */
    .coach-review-picker button,
    .coach-review-picker select,
    .coach-review-picker [role="button"],
    .coach-review-picker-save,
    .coach-review-picker-focus,
    .coach-timeline-chip,
    .coach-shortcuts-help-head .mini-action-btn {
        min-height: 44px;
    }
}

/* ============================================================
 * Sprint 8: visible focus rings on every new interactive control
 *
 * Browser-default focus outlines are inconsistent (different colour
 * on Chrome vs Safari, sometimes invisible in dark mode); we already
 * theme tool buttons + chips, but the Sprint 7 shortcuts dialog's
 * <kbd> tags and a few less-trafficked buttons need a uniform
 * :focus-visible ring so keyboard users always see where focus is.
 * ============================================================ */
.coach-shortcuts-help button:focus-visible,
.coach-review-picker-save:focus-visible,
.coach-timeline-chip:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.40);
    border-color: var(--accent, #298bed);
}
[data-theme="light"] .coach-shortcuts-help button:focus-visible,
[data-theme="light"] .coach-review-picker-save:focus-visible,
[data-theme="light"] .coach-timeline-chip:focus-visible {
    box-shadow: 0 0 0 2px rgba(21, 101, 192, 0.32);
    border-color: var(--accent, #1565c0);
}

/* Match-page deep link to /coach?tab=review (coach/admin only) */
.coach-this-match-link {
    text-decoration: none;
    align-items: center;
    display: inline-flex;
}

.coach-this-match-link[hidden] { display: none !important; }

/* /feedback view ============================ */
.feedback-linked-strip {
    margin: 0 0 1rem;
    padding: 0.6rem 0.85rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.45rem;
    align-items: center;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
}

.feedback-linked-label {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-right: 0.25rem;
}

.feedback-linked-pill {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0.65rem;
    border-radius: 999px;
    background: rgba(23, 113, 201, 0.14);
    border: 1px solid rgba(23, 113, 201, 0.32);
    color: var(--text-main);
    font-size: 0.78rem;
    font-weight: 600;
}

.feedback-linked-empty {
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* No inner caps on the feedback rails — fill the universal shell. */

[data-theme="light"] .feedback-linked-strip {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.08);
}

/* Focused feedback player (modal body) ============================ */
.feedback-player {
    display: grid;
    gap: 0.85rem;
}

.feedback-player-meta strong {
    display: block;
    font-family: var(--font-heading);
    font-size: 1.05rem;
    color: var(--text-main);
}

.feedback-player-meta span {
    display: block;
    margin-top: 0.2rem;
    font-size: 0.82rem;
    color: var(--text-muted);
}

.feedback-player-wrapper {
    position: relative;
    background: #000;
    border-radius: 10px;
    overflow: hidden;
    aspect-ratio: 16 / 9;
}

.feedback-player-wrapper video {
    width: 100%;
    height: 100%;
    display: block;
}

.feedback-player-rail {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 0.85rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
}
/* The `hidden` HTML attribute on `[data-field="rail"]` is set by JS
 * for single-note mode (no playlist session). CSS `display: flex`
 * above wins over the UA `hidden`-stylesheet, which left the empty
 * rail rendering as a ~26 px bar between the video and the body
 * text. Re-assert `display: none` for the hidden state so the
 * single-note modal collapses it cleanly. */
.feedback-player-rail[hidden] {
    display: none;
}

.feedback-rail-info span,
.feedback-rail-info small {
    display: block;
    color: var(--text-muted);
    font-size: 0.78rem;
}

.feedback-rail-info strong {
    display: block;
    color: var(--text-main);
    font-family: var(--font-heading);
    font-size: 0.95rem;
}

.feedback-rail-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.feedback-player-body {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.88rem;
    line-height: 1.5;
}

[data-theme="light"] .feedback-player-rail {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}

/* ============================================================
 * PR 1c — My Feedback structured-note rendering
 *
 * Shows player_summary first (with body as fallback), a small
 * accent-tinted tone pill, and an optional what / why / next stack
 * for notes that have the structured fields filled in. coach_
 * private_note is never rendered here (server scrubs it; we also
 * never template it).
 * ============================================================ */

/* Tone pill — accent-tinted by default; the four other note types
 * keep the same visual weight but pick up a slightly different
 * accent so a player can scan a feedback list and know at a glance
 * whether a note is a positive call-out vs a correction. */
.feedback-tone-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Use min-height + symmetric padding instead of a hard 22 px so
     * the box grows around the rendered cap-height. With `height:
     * 22px` + `align-items: center`, the all-caps glyphs sat slightly
     * low inside the pill because most heading fonts have a larger
     * descender region than ascender region — the visual centre of
     * an all-caps run sits ABOVE the box's geometric centre. Switching
     * to padding-driven sizing lets the pill fit the glyphs and
     * removes the visible drop. */
    min-height: 22px;
    padding: 0.18rem 0.55rem 0.14rem;
    border-radius: 999px;
    border: 1px solid rgba(23, 113, 201, 0.40);
    background: rgba(23, 113, 201, 0.14);
    color: var(--accent, #298bed);
    font-family: var(--font-heading);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    line-height: 1;
    /* Keep the pill optically centred when it sits inline next to
     * plain-case body text (e.g. inside `.feedback-rail-info` and
     * `.feedback-note-head`). Without this the pill hangs off the
     * surrounding text baseline. */
    vertical-align: middle;
    flex: 0 0 auto;
}
.feedback-tone-pill[data-tone="positive"] {
    border-color: rgba(34, 197, 94, 0.45);
    background: rgba(34, 197, 94, 0.16);
    color: #4ade80;
}
.feedback-tone-pill[data-tone="question"] {
    border-color: rgba(245, 158, 11, 0.45);
    background: rgba(245, 158, 11, 0.16);
    color: #fbbf24;
}
.feedback-tone-pill[data-tone="team_concept"] {
    border-color: rgba(168, 85, 247, 0.45);
    background: rgba(168, 85, 247, 0.16);
    color: #c084fc;
}
.feedback-tone-pill[data-tone="individual_goal"] {
    border-color: rgba(236, 72, 153, 0.45);
    background: rgba(236, 72, 153, 0.16);
    color: #f472b6;
}
[data-theme="light"] .feedback-tone-pill {
    background: rgba(23, 113, 201, 0.10);
}
[data-theme="light"] .feedback-tone-pill[data-tone="positive"] {
    background: rgba(22, 163, 74, 0.14);
    color: #166534;
    border-color: rgba(22, 163, 74, 0.35);
}
[data-theme="light"] .feedback-tone-pill[data-tone="question"] {
    background: rgba(217, 119, 6, 0.14);
    color: #92400e;
    border-color: rgba(217, 119, 6, 0.35);
}
[data-theme="light"] .feedback-tone-pill[data-tone="team_concept"] {
    background: rgba(126, 34, 206, 0.12);
    color: #6b21a8;
    border-color: rgba(126, 34, 206, 0.35);
}
[data-theme="light"] .feedback-tone-pill[data-tone="individual_goal"] {
    background: rgba(190, 24, 93, 0.12);
    color: #9d174d;
    border-color: rgba(190, 24, 93, 0.35);
}

/* Notes-list row — single-column layout because the body now
 * carries up to four pieces (tone + meta + summary + structured
 * stack + collapsible Coach context) and the existing two-column
 * `.coach-row` would crowd the right action column. */
.feedback-note-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 0.7rem 0.9rem;
    align-items: start;
}
.feedback-note-row .coach-row-actions {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    align-items: flex-end;
}
.feedback-note-body {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    min-width: 0;
}
.feedback-note-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.45rem;
}
.feedback-note-meta {
    color: var(--text-muted);
    font-size: 0.78rem;
}
.feedback-note-summary {
    margin: 0;
    color: var(--text-main);
    font-size: 0.92rem;
    line-height: 1.5;
}

/* Structured "What happened / Why it matters / What to do next"
 * stack. Renders as a definition list so AT users get the field
 * label/value relationship for free. */
.feedback-structured {
    margin: 0.2rem 0 0;
    display: grid;
    gap: 0.45rem;
}
.feedback-structured-item {
    display: grid;
    gap: 0.1rem;
    padding: 0.5rem 0.7rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
}
.feedback-structured-item dt {
    font-family: var(--font-heading);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0;
}
.feedback-structured-item dd {
    margin: 0;
    color: var(--text-main);
    font-size: 0.86rem;
    line-height: 1.45;
}
[data-theme="light"] .feedback-structured-item {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.08);
}

/* Collapsed "Coach context" disclosure — same pattern as Coach
 * Review's "More details", just borrowed for the player surface so
 * a curious player can see the long-form `body` alongside the
 * polished `player_summary`. */
.feedback-note-more {
    margin-top: 0.2rem;
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.02);
}
.feedback-note-more > summary {
    list-style: none;
    cursor: pointer;
    padding: 0.4rem 0.65rem;
    font-family: var(--font-heading);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.feedback-note-more > summary::-webkit-details-marker { display: none; }
.feedback-note-more > summary::marker { display: none; }
.feedback-note-more > summary::before {
    content: "";
    width: 5px; height: 5px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    transition: transform 0.15s ease;
}
.feedback-note-more[open] > summary::before { transform: rotate(45deg); }
.feedback-note-more > p {
    margin: 0;
    padding: 0 0.7rem 0.55rem;
    color: var(--text-muted);
    font-size: 0.84rem;
    line-height: 1.5;
}
[data-theme="light"] .feedback-note-more {
    background: rgba(0, 0, 0, 0.02);
    border-color: rgba(0, 0, 0, 0.08);
}

/* Focused-modal body — hosts the same composition as a notes-list
 * row, just at the modal's wider measure. */
.feedback-player-tone {
    margin-bottom: 0.4rem;
}
.feedback-player-summary {
    color: var(--text-main);
    font-size: 0.96rem;
    line-height: 1.5;
}

/* Per-item tone + summary inside the playlist player rail */
.feedback-rail-item-detail {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-top: 0.3rem;
}
.feedback-rail-item-summary {
    color: var(--text-main);
    font-size: 0.82rem;
    line-height: 1.4;
}

/* Mobile / touch — two-row stacking so the tone pill + summary
 * stay readable and the actions are full-width. */
@media (max-width: 720px) {
    .feedback-note-row {
        grid-template-columns: minmax(0, 1fr);
    }
    .feedback-note-row .coach-row-actions {
        flex-direction: row;
        align-items: stretch;
        justify-content: flex-start;
    }
    .feedback-note-row .coach-row-actions .mini-action-btn {
        flex: 1 1 auto;
    }
}
@media (pointer: coarse), (max-width: 899px) {
    .feedback-note-row .coach-row-actions .mini-action-btn {
        min-height: 44px;
    }
    .feedback-tone-pill,
    .feedback-note-more > summary {
        min-height: 28px;
    }
}

/* ============================================================
 * My Feedback — single-pane card grid
 *
 * Each note / playlist renders as a self-contained card in a
 * responsive grid. The card holds everything a player needs to
 * decide whether to watch (tone, summary, structured what / why /
 * next stack). Click "Watch" / "Play session" to open the focused
 * modal (mounted from `feedback-player-template`). No inline
 * video and no separate selection state — the page is one
 * scannable surface.
 *
 * Breakpoints:
 *   1920 px → 4 cols   (auto-fill at 440 px min)
 *   1440 px → 3 cols
 *   1024 px → 2 cols
 *   ≤  720 px → 1 col
 * ============================================================ */

/* Cards are scannable previews — tone + title + meta + clamped
 * summary + actions. Because every card emits the same shape
 * now, CSS Grid auto-fill no longer creates ugly height gaps,
 * and we get a true grid (cards in a row stay aligned). The
 * full structured stack lives in the Watch modal. */
.feedback-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
    gap: 1rem;
    align-items: stretch;
}

@media (max-width: 720px) {
    .feedback-card-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

.feedback-card {
    background: var(--bg-card);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    padding: 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    min-width: 0;
    /* Push the actions to the bottom edge of the tallest card
     * in the row so all "Watch" buttons line up horizontally. */
    height: 100%;
}
[data-theme="light"] .feedback-card {
    border-color: rgba(0, 0, 0, 0.08);
}

.feedback-card-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
    justify-content: space-between;
}

.feedback-card-status {
    font-family: var(--font-heading);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.feedback-card-kicker {
    font-family: var(--font-heading);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent, #298bed);
}

.feedback-card-title {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 1.1rem;
    line-height: 1.3;
    color: var(--text-main);
    overflow-wrap: anywhere;
}

.feedback-card-meta {
    color: var(--text-muted);
    font-size: 0.82rem;
}

.feedback-card-description {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.88rem;
    line-height: 1.5;
    /* Keep playlist descriptions to ~3 lines so cards stay roughly
     * the same height in the grid. Falls back gracefully when the
     * `-webkit-line-clamp` extensions are unsupported. */
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
}

/* One-line preview summary on the card. Clamped to two lines so
 * a verbose `player_summary` doesn't blow the card height out. */
.feedback-card-summary {
    margin: 0;
    color: var(--text-main);
    font-size: 0.9rem;
    line-height: 1.5;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.feedback-card-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    /* `margin-top: auto` inside a flex column pushes this row to
     * the card's bottom edge — combined with `align-items: stretch`
     * on the grid, every card's Watch button lines up with its
     * row neighbours. */
    margin-top: auto;
}

.feedback-card-actions .btn-primary {
    padding: 0.55rem 1rem;
    font-size: 0.85rem;
}

@media (pointer: coarse), (max-width: 899px) {
    .feedback-card-actions .btn-primary,
    .feedback-card-actions .mini-action-btn {
        min-height: 44px;
    }
}

.admin-card-sub {
    margin: 0.25rem 0 0;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.5;
}

[data-theme="light"] .coach-row {
    border-bottom-color: rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .coach-check-list {
    background: rgba(255, 255, 255, 0.82);
    border-color: rgba(0, 0, 0, 0.14);
    scrollbar-color: rgba(23, 113, 201, 0.75) rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .coach-check-list::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.06);
}

[data-theme="light"] .coach-check-list::-webkit-scrollbar-thumb {
    background: linear-gradient(180deg, rgba(23, 113, 201, 0.8), rgba(15, 118, 178, 0.68));
    border-color: rgba(255, 255, 255, 0.85);
}

[data-theme="light"] .coach-check-option {
    background: rgba(255, 255, 255, 0.72);
    border-color: rgba(0, 0, 0, 0.08);
    color: var(--text-main);
}

[data-theme="light"] .coach-check-option:hover,
[data-theme="light"] .coach-check-option.is-selected {
    background: rgba(23, 113, 201, 0.12);
    border-color: rgba(23, 113, 201, 0.42);
}

[data-theme="light"] .coach-check-box {
    background: rgba(255, 255, 255, 0.86);
    border-color: rgba(0, 0, 0, 0.22);
}

/* `[data-theme="light"] .coach-mini-form input/textarea/select` was
 * defined here historically; PR #87 consolidated it with the new
 * #80/#78 light-mode override block defined earlier in this file
 * (alongside the dark-mode `.coach-mini-form` rules and the focused
 * state). The earlier block uses the same `background-color: #fff`
 * + `border-color: rgba(0, 0, 0, 0.14)` values and adds the missing
 * :hover and :focus-visible variants. Removed from this section so
 * the cascade is single-sourced and future readers don't trip on
 * the duplicate. */

[data-theme="light"] .coach-width-control input::-webkit-slider-runnable-track {
    background: rgba(0, 0, 0, 0.12);
    border-color: rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .coach-width-control input::-moz-range-track {
    background: rgba(0, 0, 0, 0.12);
    border-color: rgba(0, 0, 0, 0.08);
}

[data-theme="light"] .coach-width-control input::-webkit-slider-thumb {
    border-color: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

[data-theme="light"] .coach-width-control input::-moz-range-thumb {
    border-color: #fff;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

@media (max-width: 820px) {
    .coach-grid {
        grid-template-columns: 1fr;
    }

    .coach-row {
        flex-direction: column;
    }

    .coach-row-actions,
    .coach-draw-actions {
        width: 100%;
        grid-template-columns: 1fr;
    }

    .coach-tool-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .coach-review-grid {
        grid-template-columns: 1fr;
    }

    .feedback-rail-controls {
        justify-content: stretch;
    }

    .feedback-rail-controls .mini-action-btn {
        flex: 1 1 42%;
    }
}

@keyframes libraryWatchingPulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.55; }
}

/* "Updated <timestamp>" inline note in the expanded slot-diagnostics
   panel head. Sits between Match ID and the viewers pill. */
.slot-diagnostics-updated {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--text-main);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
}

/* ============================================================
 * Coach section alignment pass (post-Sprint 9)
 *
 * Goal: make Roster / Notes / Playlists feel as compact and
 * scannable as the new Coach Review cockpit (PR #57-#60).
 * Without this pass the non-Review tabs use the wider
 * "options-card" admin treatment (1.6rem padding, 1.35rem h3,
 * heavy intro paragraphs) which made the section feel jarring
 * when switching tabs.
 *
 * Strategy:
 *   - Coach-scoped layout vars at #coach-view (no global side effects)
 *   - Tighten card padding + heading on desktop pointer:fine
 *   - Tighter list rows, with the dominant row action elevated
 *     via .mini-action-btn-primary (no new tier — reuse the
 *     existing modifier already used by My Feedback)
 *   - Touch widths keep the existing comfortable spacing so
 *     mobile / tablet remain easy to tap
 *   - All overrides scoped to #coach-view :not(.is-review-mode)
 *     so the Review cockpit's own tighter shell rules win
 * ============================================================ */
#coach-view {
    --coach-shell-gap: 1rem;
    --coach-card-padding: 1.1rem;
    --coach-card-padding-y: 0.95rem;
    --coach-row-padding-y: 0.6rem;
    --coach-compact-control-height: 30px;
    --coach-row-gap: 0.55rem;
}

/* Desktop / pointer:fine — tighten the workspace cards so they
 * read like a coach worklist, not an admin form dashboard. */
@media (pointer: fine) and (min-width: 900px) {
    #coach-view:not(.is-review-mode) .coach-tab-panel .options-card {
        padding: var(--coach-card-padding-y) var(--coach-card-padding);
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .options-card h3 {
        font-size: 1.05rem;
        margin-bottom: 0.6rem;
        letter-spacing: 0.02em;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .admin-card-head,
    #coach-view:not(.is-review-mode) .coach-tab-panel .admin-panel-head {
        margin-bottom: 0.7rem;
        gap: 0.6rem;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .admin-card-head h3 {
        font-size: 1.05rem;
        margin: 0;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .admin-card-sub,
    #coach-view:not(.is-review-mode) .coach-tab-panel .admin-section-sub {
        font-size: 0.82rem;
        line-height: 1.45;
        margin: 0.2rem 0 0;
    }
    #coach-view:not(.is-review-mode) .coach-grid {
        gap: var(--coach-shell-gap);
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .form-group {
        margin-bottom: 0.7rem;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .form-row {
        gap: 0.7rem;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .form-group label {
        margin-bottom: 0.3rem;
        font-size: 0.7rem;
    }
    /* Tighten Roster / Notes / Playlists list density. The .coach-list
     * grid gap was 0.65rem; bring rows closer together so a 5-10
     * row list reads like a worklist instead of a stack of cards.
     * The visual separator is `.coach-row { border-bottom }` which
     * is defined globally on the base rule (`.coach-row` ~L5603) —
     * we re-assert it here so a future cleanup that removes the
     * global border doesn't silently collapse Coach list rows into
     * a single unreadable block. */
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-list {
        gap: 0;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row {
        padding: var(--coach-row-padding-y) 0;
        gap: 0.75rem;
        border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row:last-child {
        border-bottom: 0;
    }
    [data-theme="light"] #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row {
        border-bottom-color: rgba(0, 0, 0, 0.08);
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row strong {
        font-size: 0.95rem;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row span,
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row p {
        font-size: 0.78rem;
        margin-top: 0.1rem;
    }
    /* Make row action buttons compact on desktop — same height tier
     * as Review's picker-bar buttons (~30 px) so the eye doesn't
     * jump between tabs. We deliberately match all `<button>` and
     * `<input type=submit>` direct children of `.options-card` (the
     * Add Player / Link Account form CTAs) instead of enumerating
     * `.btn-primary` / `.btn-secondary` — that keeps the rule from
     * pinning a single button tier in place and avoids tripping the
     * "don't reach for .btn-secondary in section-head positions"
     * guidance in CLAUDE.md (sizing rules shouldn't sanction a tier
     * by name). */
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row-actions .mini-action-btn,
    #coach-view:not(.is-review-mode) .coach-tab-panel .admin-panel-head .btn-head,
    #coach-view:not(.is-review-mode) .coach-tab-panel .options-card > button {
        min-height: var(--coach-compact-control-height);
        line-height: 1;
    }
    /* Section intro paragraph — keep readable but pull it closer to
     * the subnav so the page doesn't open with a giant header band. */
    #coach-view:not(.is-review-mode) .coach-page-head {
        margin-bottom: 0.85rem;
    }
    #coach-view:not(.is-review-mode) .coach-page-head h2 {
        font-size: 1.45rem;
        margin: 0 0 0.15rem;
    }
    #coach-view:not(.is-review-mode) .coach-page-head .admin-section-sub {
        margin: 0;
    }
    #coach-view:not(.is-review-mode) .coach-subnav {
        margin-bottom: 0.9rem;
    }
    /* Player checkboxes inside the note composer + roster sections —
     * compact density for desktop. Touch widths fall back to the
     * default comfortable size below. */
    #coach-view:not(.is-review-mode) .coach-check-list {
        min-height: 100px;
        max-height: 180px;
    }
}

/* Touch / pointer:coarse — keep comfortable tap targets (≥44 px)
 * on the row-level actions and the Add Player / Link Account
 * primary CTAs. We DO tighten the card padding a little so mobile
 * doesn't feel like an admin form, but never below the 44 px tap
 * minimum on actual buttons. */
@media (pointer: coarse), (max-width: 899px) {
    #coach-view:not(.is-review-mode) .coach-tab-panel .options-card {
        padding: 1rem;
    }
    /* Same selector strategy as the desktop block — match form CTAs
     * by element, not by button tier, so we don't sanction
     * `.btn-secondary` in any section-head context. */
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row-actions .mini-action-btn,
    #coach-view:not(.is-review-mode) .coach-tab-panel .admin-panel-head .btn-head,
    #coach-view:not(.is-review-mode) .coach-tab-panel .options-card > button {
        min-height: 44px;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row {
        flex-direction: column;
        align-items: stretch;
    }
    #coach-view:not(.is-review-mode) .coach-tab-panel .coach-row-actions {
        justify-content: flex-start;
    }
}

/* Notes / Playlists — the dominant row action is signalled with
 * the existing `.mini-action-btn-primary` modifier (accent-fill;
 * themed in both light and dark; same modifier My Feedback uses for
 * its Watch / Play buttons). No Coach-specific font-weight bump:
 * the modifier was deliberately defined without a font-weight in
 * its base rule so all surfaces inherit `.mini-action-btn`'s
 * `font-weight: 600` and the visual lift comes from colour alone.
 * Re-asserting that here as a placeholder block so future tuning
 * has a single, scoped landing spot — but it intentionally adds
 * nothing today. */

/* Empty state — make it feel like part of the new compact list
 * instead of a standalone admin card. */
#coach-view:not(.is-review-mode) .coach-tab-panel .session-empty {
    padding: 0.9rem 0.5rem;
    border: 1px dashed rgba(255, 255, 255, 0.10);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.02);
    text-align: center;
}
[data-theme="light"] #coach-view:not(.is-review-mode) .coach-tab-panel .session-empty {
    border-color: rgba(0, 0, 0, 0.10);
    background: rgba(0, 0, 0, 0.02);
}

/* ============================================================
 * Coach > Roster redesign — dashboard-style roster cockpit
 *
 * Header (kicker + title + sub + Link Account / Add Player)
 * → KPI tile grid (4 tiles)
 * → Search + status-filter chip rail
 * → Two-column body: roster table | right-side Quick Add panel
 *
 * All scoped to #coach-tab-roster so the Notes / Playlists /
 * Review tabs are untouched.
 *
 * Theming reuses existing tokens — accent fill for active pills,
 * green for active status, muted gray for inactive. No new fonts,
 * no new build step, no framework.
 * ============================================================ */
#coach-tab-roster .roster-shell {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Header --------------------------------------------------- */
#coach-tab-roster .roster-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.25rem;
    flex-wrap: wrap;
}
#coach-tab-roster .roster-head-text {
    flex: 1 1 360px;
    min-width: 0;
}
#coach-tab-roster .roster-kicker {
    display: block;
    font-family: var(--font-heading);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--accent, #298bed);
    margin-bottom: 0.2rem;
}
#coach-tab-roster .roster-title {
    font-family: var(--font-heading);
    font-size: 1.45rem;
    margin: 0 0 0.25rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}
#coach-tab-roster .roster-sub {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.45;
    max-width: 60ch;
}
#coach-tab-roster .roster-head-actions {
    display: flex;
    gap: 0.55rem;
    align-items: center;
    flex-wrap: wrap;
}
#coach-tab-roster .roster-link-btn,
#coach-tab-roster .roster-add-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-height: 36px;
    padding: 0.5rem 0.95rem;
    line-height: 1;
}

/* KPI grid ------------------------------------------------- */
#coach-tab-roster .roster-kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem;
}
#coach-tab-roster .roster-kpi {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    padding: 0.95rem 1.1rem;
    background: var(--bg-card);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
}
#coach-tab-roster .roster-kpi-label {
    font-family: var(--font-heading);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}
#coach-tab-roster .roster-kpi-value {
    font-family: var(--font-heading);
    font-size: 1.85rem;
    font-weight: 700;
    color: var(--text-main);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
#coach-tab-roster .roster-kpi-delta {
    font-size: 0.72rem;
    color: var(--accent, #298bed);
    letter-spacing: 0.04em;
}
[data-theme="light"] #coach-tab-roster .roster-kpi {
    border-color: rgba(0, 0, 0, 0.08);
}

/* Search + filter chips ----------------------------------- */
#coach-tab-roster .roster-controls {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    flex-wrap: wrap;
}
#coach-tab-roster .roster-search {
    position: relative;
    flex: 1 1 320px;
    min-width: 0;
}
#coach-tab-roster .roster-search input {
    width: 100%;
    padding: 0.6rem 0.85rem 0.6rem 2.4rem;
    background: rgba(0, 0, 0, 0.24);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 8px;
    color: var(--text-main);
    font: inherit;
    font-size: 0.9rem;
}
#coach-tab-roster .roster-search input::placeholder {
    color: var(--text-muted);
    opacity: 0.7;
}
#coach-tab-roster .roster-search input:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}
#coach-tab-roster .roster-search-icon {
    position: absolute;
    left: 0.8rem;
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    color: var(--text-muted);
    pointer-events: none;
}
#coach-tab-roster .roster-search-icon svg {
    width: 16px;
    height: 16px;
    display: block;
}
#coach-tab-roster .roster-filters {
    display: inline-flex;
    gap: 0.25rem;
    padding: 0.25rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
}
#coach-tab-roster .roster-filter-btn {
    padding: 0.42rem 0.85rem;
    border-radius: 6px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
#coach-tab-roster .roster-filter-btn:hover {
    color: var(--text-main);
}
#coach-tab-roster .roster-filter-btn.is-active {
    background: rgba(255, 255, 255, 0.10);
    border-color: rgba(255, 255, 255, 0.18);
    color: var(--text-main);
}
#coach-tab-roster .roster-filter-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}
[data-theme="light"] #coach-tab-roster .roster-search input {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
}
[data-theme="light"] #coach-tab-roster .roster-filters {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.08);
}
[data-theme="light"] #coach-tab-roster .roster-filter-btn.is-active {
    background: rgba(0, 0, 0, 0.06);
    border-color: rgba(0, 0, 0, 0.12);
}

/* Two-column body — table + Quick Add panel --------------- */
#coach-tab-roster .roster-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 1rem;
    align-items: start;
}
@media (max-width: 1023px) {
    #coach-tab-roster .roster-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Roster table -------------------------------------------- */
#coach-tab-roster .roster-table-wrap {
    background: var(--bg-card);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    overflow: hidden;
    /* Allow horizontal scroll on narrow viewports without clipping the
     * card's rounded corners. */
    overflow-x: auto;
    /* Themed scrollbar — matches the rest of the Coach surfaces. */
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
[data-theme="light"] #coach-tab-roster .roster-table-wrap {
    border-color: rgba(0, 0, 0, 0.08);
}
/* WebKit (Chrome / Safari / Edge) ignore `scrollbar-width` and
 * `scrollbar-color` — paint the scrollbar explicitly so we never
 * fall back to native chrome on the dominant browsers. Same
 * pattern as `.coach-timeline-rail`, `.coach-review-side`, etc. */
#coach-tab-roster .roster-table-wrap::-webkit-scrollbar {
    height: 6px;
}
#coach-tab-roster .roster-table-wrap::-webkit-scrollbar-track {
    background: transparent;
}
#coach-tab-roster .roster-table-wrap::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 3px;
}
[data-theme="light"] #coach-tab-roster .roster-table-wrap::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.18);
}
#coach-tab-roster .roster-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
}
#coach-tab-roster .roster-table thead th {
    text-align: left;
    padding: 0.7rem 0.9rem;
    font-family: var(--font-heading);
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    background: rgba(255, 255, 255, 0.02);
    position: sticky;
    top: 0;
    z-index: 1;
}
[data-theme="light"] #coach-tab-roster .roster-table thead th {
    border-bottom-color: rgba(0, 0, 0, 0.08);
    background: rgba(0, 0, 0, 0.02);
}
#coach-tab-roster .roster-row + .roster-row .roster-cell {
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}
[data-theme="light"] #coach-tab-roster .roster-row + .roster-row .roster-cell {
    border-top-color: rgba(0, 0, 0, 0.06);
}
#coach-tab-roster .roster-cell {
    padding: 0.7rem 0.9rem;
    vertical-align: middle;
}
#coach-tab-roster .roster-col-num { width: 72px; }
#coach-tab-roster .roster-col-status { width: 110px; }
#coach-tab-roster .roster-col-actions { width: 150px; }
/* The actions cell keeps `display: table-cell` (so the row's
 * vertical-align: middle still applies and tall rows stay aligned)
 * but its inner `.roster-actions-row` wrapper is a flexbox that
 * lays out the three 32 px icon buttons in a single line, flush
 * right. The previous approach used `text-align: right` + inline-
 * flex children, which wrapped the third button onto a second row
 * in some viewports. */
#coach-tab-roster .roster-actions-row {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.3rem;
    white-space: nowrap;
}
/* The `#` header glyph itself reads tiny at the small uppercase
 * header size. Promote it to a normal-case symbol that matches the
 * jersey-badge weight so the column heading is visible at a glance. */
#coach-tab-roster .roster-table thead .roster-col-num {
    font-size: 0.95rem;
    font-weight: 700;
    text-transform: none;
    letter-spacing: 0;
    color: var(--text-main);
}

#coach-tab-roster .roster-jersey-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 38px;
    height: 34px;
    padding: 0 0.55rem;
    border-radius: 999px;
    background: rgba(23, 113, 201, 0.16);
    border: 1px solid rgba(23, 113, 201, 0.45);
    color: var(--accent, #298bed);
    font-family: var(--font-heading);
    font-size: 0.95rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
#coach-tab-roster .roster-jersey-badge.is-muted {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.10);
    color: var(--text-muted);
}
#coach-tab-roster .roster-player-name {
    display: block;
    font-family: var(--font-heading);
    font-size: 0.92rem;
    color: var(--text-main);
}
#coach-tab-roster .roster-player-sub {
    display: block;
    font-size: 0.74rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-top: 0.15rem;
}

/* Linked-account chips ------------------------------------ */
#coach-tab-roster .roster-link-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.32rem;
    margin: 0.15rem 0.3rem 0.15rem 0;
    padding: 0.22rem 0.45rem 0.22rem 0.6rem;
    border: 1px solid rgba(23, 113, 201, 0.35);
    background: rgba(23, 113, 201, 0.12);
    border-radius: 999px;
    color: var(--text-main);
    font: inherit;
    font-size: 0.72rem;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
#coach-tab-roster .roster-link-chip:hover {
    background: rgba(23, 113, 201, 0.22);
    border-color: var(--accent, #298bed);
}
#coach-tab-roster .roster-link-chip:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}
#coach-tab-roster .roster-link-rel {
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 700;
    color: var(--accent, #298bed);
    font-size: 0.65rem;
}
#coach-tab-roster .roster-link-user {
    color: var(--text-main);
}
#coach-tab-roster .roster-link-x {
    margin-left: 0.15rem;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1;
}
#coach-tab-roster .roster-no-links {
    color: var(--text-muted);
    font-size: 0.78rem;
}

/* Status pill --------------------------------------------- */
#coach-tab-roster .roster-status-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.04em;
}
#coach-tab-roster .roster-status-pill.is-active {
    background: rgba(34, 197, 94, 0.14);
    border: 1px solid rgba(34, 197, 94, 0.40);
    color: #4ade80;
}
#coach-tab-roster .roster-status-pill.is-inactive {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: var(--text-muted);
}
#coach-tab-roster .roster-status-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: currentColor;
}

/* Action icon buttons --------------------------------------
 * Per CLAUDE.md the row-level action tier is `.mini-action-btn`.
 * `.mini-action-btn-icon` is a *modifier* (not a new tier) that
 * compacts the existing button into a 30 × 30 square for icon-only
 * use, plus a `.is-danger` modifier that paints the hover red. */
.mini-action-btn.mini-action-btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    font-size: 0.95rem;
    color: var(--text-main);
}
.mini-action-btn.mini-action-btn-icon svg {
    display: block;
    width: 16px;
    height: 16px;
}
.mini-action-btn.mini-action-btn-icon:hover {
    color: var(--accent);
    border-color: var(--accent);
}
.mini-action-btn.mini-action-btn-icon[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
}
.mini-action-btn.mini-action-btn-icon[disabled]:hover {
    border-color: rgba(255, 255, 255, 0.1);
    color: var(--text-muted);
}
.mini-action-btn.mini-action-btn-icon.is-danger:hover {
    border-color: rgba(239, 68, 68, 0.50);
    color: #f87171;
}

/* Empty state row ----------------------------------------- */
#coach-tab-roster .roster-empty-row td {
    padding: 1.5rem;
    text-align: center;
    border-top: 0;
}

/* Right-side Quick Add Player panel ----------------------- */
#coach-tab-roster .roster-quick-add {
    background: var(--bg-card);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 12px;
    padding: 0.95rem 1.05rem;
    /* Stick to the top of the viewport on tall screens so the form is
     * always reachable while scrolling a long roster. The 6rem offset
     * clears the sticky main nav. */
    position: sticky;
    top: 6rem;
    align-self: start;
}
[data-theme="light"] #coach-tab-roster .roster-quick-add {
    border-color: rgba(0, 0, 0, 0.08);
}
#coach-tab-roster .roster-quick-add-title {
    margin: 0 0 0.7rem;
    font-family: var(--font-heading);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
}
#coach-tab-roster .roster-quick-add-body {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
#coach-tab-roster .roster-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
#coach-tab-roster .roster-field-label {
    font-family: var(--font-heading);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
}
#coach-tab-roster .roster-field-hint {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    color: var(--text-muted);
    opacity: 0.7;
}
#coach-tab-roster .roster-field input,
#coach-tab-roster .roster-field select {
    width: 100%;
    padding: 0.5rem 0.7rem;
    background: rgba(0, 0, 0, 0.24);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 6px;
    color: var(--text-main);
    font: inherit;
    font-size: 0.85rem;
}
/* Suppress native OS dropdown chrome and paint a custom chevron —
 * `.roster-field` lives outside `.form-group`, so it doesn't inherit
 * the existing `.form-group select` chevron treatment. Same pattern
 * as the `.form-group select` rule (~L3882). */
#coach-tab-roster .roster-field select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 2.1rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23888890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.7rem center;
    background-size: 10px 7px;
    cursor: pointer;
}
#coach-tab-roster .roster-field input:focus-visible,
#coach-tab-roster .roster-field select:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}
#coach-tab-roster .roster-field select:focus-visible {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23298bed' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}
[data-theme="light"] #coach-tab-roster .roster-field input,
[data-theme="light"] #coach-tab-roster .roster-field select {
    background-color: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
}
#coach-tab-roster .roster-quick-add-submit {
    margin-top: 0.4rem;
    width: 100%;
    min-height: 38px;
}
#coach-tab-roster .roster-quick-add-tip {
    margin: 0.6rem 0 0;
    padding: 0.55rem 0.7rem;
    background: rgba(23, 113, 201, 0.06);
    border: 1px solid rgba(23, 113, 201, 0.18);
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 0.74rem;
    line-height: 1.45;
}
#coach-tab-roster .roster-quick-add-tip strong {
    color: var(--accent, #298bed);
    font-family: var(--font-heading);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-right: 0.35rem;
}

/* Touch / mobile — disable sticky panel and ensure tap targets ≥44 px */
@media (pointer: coarse), (max-width: 899px) {
    #coach-tab-roster .roster-quick-add {
        position: static;
    }
    #coach-tab-roster .mini-action-btn-icon {
        width: 44px;
        height: 44px;
    }
    /* Sprint 8 (PR #60) established 44 px as the floor on
     * `(pointer: coarse)`. Both elements are interactive (chip
     * unlinks an account, filter tabs change the visible roster)
     * so they must reach the same threshold the icon buttons do. */
    #coach-tab-roster .roster-link-chip,
    #coach-tab-roster .roster-filter-btn {
        min-height: 44px;
    }
    #coach-tab-roster .roster-quick-add-submit {
        min-height: 44px;
    }
}

/* Visually hidden helper (for screen-reader-only labels) */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Link Account modal body --------------------------------- */
.coach-link-modal .form-row {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}
.coach-link-modal .form-group label {
    display: block;
    margin-bottom: 0.3rem;
    font-family: var(--font-heading);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--text-muted);
}
/* Preserve the inherited `.form-group select` chevron — the modal
 * lives inside `.form-group`, so we only override colour / padding,
 * NOT `background` (shorthand would wipe the SVG chevron). */
.coach-link-modal select {
    width: 100%;
    padding: 0.55rem 2.1rem 0.55rem 0.7rem;
    background-color: rgba(0, 0, 0, 0.24);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 6px;
    color: var(--text-main);
    font: inherit;
    font-size: 0.85rem;
    text-transform: none;
    letter-spacing: 0;
}
[data-theme="light"] .coach-link-modal select {
    background-color: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
}
/* Text inputs inside the Edit modal — same colour/border as the
 * select so the form reads as a single block. */
.coach-link-modal input[type="text"] {
    width: 100%;
    padding: 0.55rem 0.7rem;
    background-color: rgba(0, 0, 0, 0.24);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: 6px;
    color: var(--text-main);
    font: inherit;
    font-size: 0.85rem;
}
.coach-link-modal input[type="text"]:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
}
[data-theme="light"] .coach-link-modal input[type="text"] {
    background-color: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.12);
}
/* Inline "(optional)" hint inside a form label — keeps the small-
 * caps tone of the label but resets case + weight so the hint
 * reads as secondary. */
.form-label-hint {
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
    color: var(--text-muted);
    opacity: 0.75;
    margin-left: 0.25rem;
}
/* "Active on roster" toggle row inside the Edit modal — a plain
 * checkbox + label that visually groups under the form-row block. */
.coach-edit-active {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.85rem;
    padding: 0.5rem 0.7rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 6px;
    color: var(--text-main);
    font-size: 0.85rem;
    cursor: pointer;
}
.coach-edit-active input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: var(--accent, #298bed);
    cursor: pointer;
}
[data-theme="light"] .coach-edit-active {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.08);
}


/* ==========================================================================
 * Phase 3b — Coach-note thumbnail tiles
 *
 * Single primitive `.coach-thumb` used by every surface that shows a
 * per-note thumbnail. The `data-thumb-state="placeholder"` attribute
 * keeps a neutral fallback visible until JS swaps in the authenticated
 * object URL (see `mountCoachNoteThumbnail` in `js/api.js`); on success
 * the attribute flips to `loaded` and the placeholder background is
 * hidden. Variants set the size only — no color or shadow tokens are
 * duplicated, so dark / light theming follows the rest of the app.
 *
 * Defense-in-depth: the rendered <img> never carries a token in its
 * URL, never gets cached by a shared proxy (Cache-Control: no-cache on
 * the GET endpoint), and a 404 / 403 from the server simply leaves the
 * placeholder visible — no broken-image icon.
 * ========================================================================== */

.coach-thumb {
    position: relative;
    flex: 0 0 auto;
    overflow: hidden;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    isolation: isolate;
}
[data-theme="light"] .coach-thumb {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}

/* The placeholder pattern: a faint film-strip glyph rendered as an SVG
 * data URI so we don't need a network request to show "no thumbnail
 * yet". Hidden once the real <img> loads (state flip via JS). */
.coach-thumb[data-thumb-state="placeholder"]::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='6' width='18' height='12' rx='2'/><path d='M3 10h18M3 14h18M7 6v12M17 6v12'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 38% auto;
    opacity: 0.5;
    pointer-events: none;
}
[data-theme="light"] .coach-thumb[data-thumb-state="placeholder"]::after {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'><rect x='3' y='6' width='18' height='12' rx='2'/><path d='M3 10h18M3 14h18M7 6v12M17 6v12'/></svg>");
    opacity: 0.55;
}

/* The real <img> sits on top; while it has no `src` it is invisible
 * (no broken-image icon because we never hand it a bad URL — see
 * `mountCoachNoteThumbnail` which only assigns on success). */
.coach-thumb-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transition: opacity 120ms ease-out;
}
.coach-thumb[data-thumb-state="loaded"] .coach-thumb-img {
    opacity: 1;
}

/* Time chip overlay — bottom-right corner, mirrors the match-thumbnail
 * timestamp rendering on the public season page. */
.coach-thumb-time {
    position: absolute;
    right: 4px;
    bottom: 4px;
    padding: 1px 5px;
    border-radius: 3px;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    font-size: 0.7rem;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    pointer-events: none;
    z-index: 1;
}

/* Variant sizes. 16:9 throughout so the tile composition feels native
 * to the underlying video frame. */
.coach-thumb--list  { width: 120px;  aspect-ratio: 16 / 9; }
.coach-thumb--card  { width: 100%;   max-width: 220px; aspect-ratio: 16 / 9; }
.coach-thumb--chip  { width: 56px;   aspect-ratio: 16 / 9; }
.coach-thumb--rail  { width: 80px;   aspect-ratio: 16 / 9; }
.coach-thumb--strip { width: 48px;   aspect-ratio: 16 / 9; }

/* Stacked thumbnail strip used on Coach Playlists rows. Tiles overlap
 * slightly (negative margin) and the leftmost tile sits on top via
 * z-index — same idiom as a stacked-avatar group. */
.coach-thumb-strip {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
}
.coach-thumb-strip .coach-thumb {
    margin-right: -10px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5);
}
[data-theme="light"] .coach-thumb-strip .coach-thumb {
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
}
.coach-thumb-strip .coach-thumb:first-child { z-index: 3; }
.coach-thumb-strip .coach-thumb:nth-child(2) { z-index: 2; }
.coach-thumb-strip .coach-thumb:nth-child(3) { z-index: 1; }
.coach-thumb-strip-more {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: 0.6rem;
    padding: 2px 6px;
    border-radius: 4px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: var(--text-muted);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}
[data-theme="light"] .coach-thumb-strip-more {
    background: rgba(0, 0, 0, 0.05);
    border-color: rgba(0, 0, 0, 0.1);
}

/* Coach-row layout adjustments when a thumbnail is present. The flex
 * row picks up a leading thumb tile + body + actions; we widen the
 * gap a touch so the tile breathes. */
.coach-row.coach-row-with-thumb {
    align-items: center;
    gap: 0.85rem;
}
.coach-row-with-thumb .coach-row-body {
    flex: 1 1 auto;
    min-width: 0;
}

/* Phase 6b — observation-note thumbnail placeholder. Observation
 * notes have no video frame, so we render a static "no video" tile
 * with a clipboard glyph instead of firing a network request that
 * would 404. The base `.coach-thumb` rules give it the same border
 * + radius as the video tile; we just hide the film-strip
 * placeholder ::after pattern (set in `.coach-thumb[data-thumb-state="placeholder"]`)
 * by re-painting it with a clipboard glyph. */
.coach-thumb--observation {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(56, 189, 248, 0.08);
    border-color: rgba(56, 189, 248, 0.3);
}
[data-theme="light"] .coach-thumb--observation {
    background: rgba(2, 132, 199, 0.08);
    border-color: rgba(2, 132, 199, 0.3);
}
.coach-thumb--observation::after {
    /* Suppress the inherited film-strip glyph — observation tiles
     * use the inline clipboard span below instead. */
    display: none;
}
.coach-thumb-observation-glyph {
    font-size: 1.4rem;
    line-height: 1;
    opacity: 0.8;
    pointer-events: none;
}

/* Phase 6b — context pill on coach-notes / feedback-notes rows.
 * Surfaces the video / observation context with an accent colour so
 * the row's meta line doesn't have to spell it out. */
.coach-row-head {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.coach-row-context-pill {
    display: inline-flex;
    align-items: center;
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    border: 1px solid transparent;
    line-height: 1.4;
}
.coach-row-context-pill[data-context="observation"] {
    background: rgba(56, 189, 248, 0.12);
    color: #38bdf8;
    border-color: rgba(56, 189, 248, 0.35);
}
.coach-row-context-pill[data-context="video"] {
    background: rgba(148, 163, 184, 0.12);
    color: var(--text-muted);
    border-color: rgba(148, 163, 184, 0.3);
}
[data-theme="light"] .coach-row-context-pill[data-context="observation"] {
    background: rgba(2, 132, 199, 0.1);
    color: #0369a1;
    border-color: rgba(2, 132, 199, 0.35);
}
[data-theme="light"] .coach-row-context-pill[data-context="video"] {
    background: rgba(71, 85, 105, 0.08);
    color: #475569;
    border-color: rgba(71, 85, 105, 0.3);
}

/* Phase 6b — observation composer styling. The helper paragraph at
 * the top of the modal explains the surface; the tactical-board
 * indicator (Phase 6c will edit; 6b only previews) renders a small
 * pill so the field doesn't feel orphaned. Mobile drops the form-row
 * grid to a single column for the event metadata so the date input
 * doesn't compress to an unusable width. */
.coach-observation-helper {
    margin: 0 0 0.75rem 0;
    padding: 0.55rem 0.75rem;
    border-radius: 6px;
    background: rgba(56, 189, 248, 0.08);
    border: 1px solid rgba(56, 189, 248, 0.25);
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.45;
}
[data-theme="light"] .coach-observation-helper {
    background: rgba(2, 132, 199, 0.08);
    border-color: rgba(2, 132, 199, 0.3);
}
.coach-observation-board-indicator {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.75rem;
    border-radius: 6px;
    background: rgba(148, 163, 184, 0.08);
    border: 1px dashed rgba(148, 163, 184, 0.35);
}
.coach-observation-board-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(56, 189, 248, 0.15);
    color: #38bdf8;
    font-size: 0.78rem;
    font-weight: 600;
    border: 1px solid rgba(56, 189, 248, 0.35);
}
[data-theme="light"] .coach-observation-board-pill {
    background: rgba(2, 132, 199, 0.1);
    color: #0369a1;
    border-color: rgba(2, 132, 199, 0.35);
}
@media (max-width: 720px) {
    .coach-observation-form .form-row {
        grid-template-columns: 1fr;
    }
}

/* Coach Review timeline chip with a thumbnail. The chip is a
 * horizontal pill with a tiny tile on the left and a stacked meta
 * column on the right. We override flex-direction (existing chip is a
 * single-row hgroup) so the meta lines wrap cleanly under the time. */
.coach-timeline-chip--with-thumb {
    align-items: center;
    gap: 0.5rem;
    padding-left: 0.35rem;
}
.coach-timeline-chip--with-thumb .coach-timeline-chip-meta {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
}
.coach-timeline-chip--with-thumb .coach-timeline-chip-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 14ch;
}

/* Feedback cards — wrap the original card body in a flex row so the
 * thumbnail sits to the left and the body fills the rest. */
.feedback-card.feedback-card--with-thumb {
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr);
    gap: 1rem;
    align-items: stretch;
}
.feedback-card.feedback-card--with-thumb .coach-thumb {
    width: 100%;
    height: 100%;
    max-width: none;
    aspect-ratio: auto;
}
.feedback-card.feedback-card--with-thumb .feedback-card-body {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    min-width: 0;
}
@media (max-width: 720px) {
    .feedback-card.feedback-card--with-thumb {
        grid-template-columns: 1fr;
    }
    .feedback-card.feedback-card--with-thumb .coach-thumb {
        height: auto;
        aspect-ratio: 16 / 9;
        max-width: 100%;
    }
}

/* Playlist session rail tile — sits to the left of the session info
 * block. Existing `.feedback-rail-info` is the next sibling; rely on
 * the rail container's flex layout. */
.feedback-rail-info { min-width: 0; }

/* ==========================================================================
 * Phase 4b — first-class coaching clips
 *
 * Clip-specific UI primitives. Most layout reuses existing surfaces
 * (`coach-row`, `feedback-card`, the focused feedback player modal,
 * the `coach-thumb` tile) so the new tab/cards inherit dark + light
 * theming, mobile breakpoints, and a11y patterns without duplication.
 * ========================================================================== */

/* "Save Clip" picker-bar button. Sits next to "Save Note"; uses the
 * secondary tier so the primary visual weight stays on note save. */
.coach-review-picker-save-clip {
    flex: 0 0 auto;
}

/* Duration display inside the clip composer. Goes red when the
 * window invariant fails (end <= start) or the duration cap is
 * exceeded, so a coach who's typing the wrong number sees the
 * problem before clicking Save. */
.coach-clip-duration {
    display: inline-flex;
    align-items: center;
    height: 32px;
    padding: 0 0.6rem;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 6px;
    color: var(--text-main);
    font-size: 0.85rem;
    font-variant-numeric: tabular-nums;
}
[data-theme="light"] .coach-clip-duration {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.1);
}
.coach-clip-duration--invalid {
    color: #f43f5e;
    border-color: rgba(244, 63, 94, 0.45);
    background: rgba(244, 63, 94, 0.08);
}

/* "From note #N" pill that appears on edit when a clip has a
 * `source_note_id`. Visually similar to the visibility chips so the
 * coach instantly recognises this clip carries a snapshot drawing
 * from the linked note. */
.coach-clip-source-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(56, 189, 248, 0.12);
    border: 1px solid rgba(56, 189, 248, 0.3);
    color: var(--text-main);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.02em;
}
[data-theme="light"] .coach-clip-source-pill {
    background: rgba(56, 189, 248, 0.12);
    border-color: rgba(56, 189, 248, 0.4);
}
.coach-clip-source-row {
    margin-top: 0.5rem;
}

/* My Feedback clip card. Inherits the existing `feedback-card`
 * + `feedback-card--with-thumb` grid (220 px thumb + body), but
 * adds a light "Clip · {category}" pill so the player recognises
 * this isn't a single-moment note. */
.feedback-clip-pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(168, 85, 247, 0.14);
    border: 1px solid rgba(168, 85, 247, 0.3);
    color: var(--text-main);
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: capitalize;
    letter-spacing: 0.02em;
}
[data-theme="light"] .feedback-clip-pill {
    background: rgba(168, 85, 247, 0.12);
    border-color: rgba(168, 85, 247, 0.45);
}

/* PR #96 review fix — small "fixed on edit" hint shown next to the
 * Match + Slot selects in the clip composer modal when editing an
 * existing clip. Backend's `UpdateCoachingClipRequest` is
 * `extra="forbid"`; rebinding mid-life would silently swap the
 * captured drawing snapshot anyway, so the controls are disabled and
 * this hint surfaces the constraint. */
.coach-clip-field-hint {
    display: block;
    margin-top: 0.25rem;
    color: var(--text-muted);
    font-size: 0.72rem;
    font-style: italic;
    line-height: 1.3;
}

/* ===== Phase 5b — Player development profile =====
 *
 * Two surfaces share these styles:
 *   - Coach: rendered inside `.app-modal-card.is-wide` opened via
 *     `app.openCoachPlayerDevelopmentModal`, so all rules below
 *     also need to look right against the modal's `.app-modal-body`
 *     padding.
 *   - Viewer: rendered inline inside `#feedback-tab-development`'s
 *     panel. Same rules, no modal chrome.
 *
 * Theme: dark by default, with `[data-theme="light"]` overrides for
 * borders/backgrounds where the modal background changes. Mobile
 * collapses tile grid + flex rows below 720px to stay scannable.
 */

.player-dev-shell {
    display: block;
    width: 100%;
}

.player-dev-modal-body {
    display: block;
    min-width: 0;
}

.player-dev-header {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    margin-bottom: 1rem;
}
[data-theme="light"] .player-dev-header {
    border-bottom-color: rgba(0, 0, 0, 0.08);
}

.player-dev-headline {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.player-dev-jersey {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.25rem;
    height: 2.25rem;
    padding: 0 0.5rem;
    border-radius: 8px;
    background: rgba(41, 139, 237, 0.16);
    color: var(--accent, #298bed);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.04em;
}
[data-theme="light"] .player-dev-jersey {
    background: rgba(23, 113, 201, 0.10);
    color: #1d4ed8;
}

.player-dev-name {
    margin: 0;
    font-family: var(--font-heading);
    font-size: 1.2rem;
    line-height: 1.2;
    color: var(--text-main);
}

.player-dev-notes {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.88rem;
    line-height: 1.5;
}

.player-dev-linked {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.player-dev-linked-label {
    font-size: 0.75rem;
    color: var(--text-muted);
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.player-dev-linked-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.18rem 0.55rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.08);
    font-size: 0.78rem;
}
[data-theme="light"] .player-dev-linked-chip {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}
.player-dev-linked-rel {
    color: var(--accent, #298bed);
    font-weight: 600;
    text-transform: capitalize;
}
.player-dev-linked-user {
    color: var(--text-muted);
}

.player-dev-section {
    padding: 1rem 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.player-dev-section:last-child {
    border-bottom: 0;
}
[data-theme="light"] .player-dev-section {
    border-bottom-color: rgba(0, 0, 0, 0.06);
}

.player-dev-section-title {
    margin: 0 0 0.4rem;
    font-family: var(--font-heading);
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-main);
    letter-spacing: 0.02em;
}

.player-dev-section-sub {
    margin: 0 0 0.65rem;
    font-size: 0.8rem;
    color: var(--text-muted);
    line-height: 1.45;
}

.player-dev-empty {
    color: var(--text-muted);
    font-size: 0.85rem;
    padding: 0.5rem 0;
}

/* ----- Counts / Summary tile grid ----- */

.player-dev-tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 0.55rem;
}

.player-dev-tile {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 0.6rem 0.75rem;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.06);
}
[data-theme="light"] .player-dev-tile {
    background: rgba(0, 0, 0, 0.03);
    border-color: rgba(0, 0, 0, 0.06);
}

.player-dev-tile-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.player-dev-tile-value {
    font-family: var(--font-heading);
    font-size: 1.15rem;
    color: var(--text-main);
}

/* ----- Themes chips ----- */

.player-dev-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.player-dev-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.08);
    font-size: 0.78rem;
    color: var(--text-main);
}
[data-theme="light"] .player-dev-chip {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.08);
}
.player-dev-chip strong {
    color: var(--accent, #298bed);
    font-weight: 700;
}

/* Same accents the feedback tone pills use, for consistency. */
.player-dev-chip--type[data-tone="positive"]      { border-color: rgba(34, 197, 94, 0.55); }
.player-dev-chip--type[data-tone="correction"]    { border-color: rgba(245, 158, 11, 0.55); }
.player-dev-chip--type[data-tone="question"]      { border-color: rgba(59, 130, 246, 0.55); }
.player-dev-chip--type[data-tone="team_concept"]  { border-color: rgba(168, 85, 247, 0.55); }
.player-dev-chip--type[data-tone="individual_goal"]{ border-color: rgba(20, 184, 166, 0.55); }
/* Light-mode tone overrides — mirrors `.feedback-tone-pill[data-tone=…]`
 * (see ~line 7722) so the chip backgrounds + text remain readable on a
 * light card. Without these the 55%-opacity dark-tuned border on a near-
 * transparent background dropped contrast below readable on light. */
[data-theme="light"] .player-dev-chip--type[data-tone="positive"] {
    background: rgba(22, 163, 74, 0.14);
    color: #166534;
    border-color: rgba(22, 163, 74, 0.40);
}
[data-theme="light"] .player-dev-chip--type[data-tone="correction"] {
    background: rgba(217, 119, 6, 0.14);
    color: #92400e;
    border-color: rgba(217, 119, 6, 0.40);
}
[data-theme="light"] .player-dev-chip--type[data-tone="question"] {
    background: rgba(37, 99, 235, 0.12);
    color: #1d4ed8;
    border-color: rgba(37, 99, 235, 0.40);
}
[data-theme="light"] .player-dev-chip--type[data-tone="team_concept"] {
    background: rgba(126, 34, 206, 0.12);
    color: #6b21a8;
    border-color: rgba(126, 34, 206, 0.40);
}
[data-theme="light"] .player-dev-chip--type[data-tone="individual_goal"] {
    background: rgba(13, 148, 136, 0.12);
    color: #115e59;
    border-color: rgba(13, 148, 136, 0.40);
}
.player-dev-chip--tag {
    background: rgba(168, 85, 247, 0.10);
    border-color: rgba(168, 85, 247, 0.30);
}
[data-theme="light"] .player-dev-chip--tag {
    background: rgba(126, 34, 206, 0.10);
    color: #6b21a8;
    border-color: rgba(126, 34, 206, 0.35);
}

.player-dev-meta-row {
    margin-top: 0.5rem;
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}
.player-dev-meta-item {
    display: inline-flex;
    flex-direction: column;
    gap: 0.1rem;
}
.player-dev-meta-label {
    font-size: 0.7rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.player-dev-subsection {
    margin-top: 0.55rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}
.player-dev-subsection-title {
    font-size: 0.72rem;
    color: var(--text-muted);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* ----- Focus areas ----- */

.player-dev-focus-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.player-dev-focus-item {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 0.55rem 0.7rem;
    border-radius: 8px;
    background: rgba(245, 158, 11, 0.08);
    border-left: 3px solid rgba(245, 158, 11, 0.6);
    color: var(--text-main);
}
[data-theme="light"] .player-dev-focus-item {
    background: rgba(245, 158, 11, 0.10);
}

.player-dev-focus-cat {
    flex-shrink: 0;
    align-self: flex-start;
    padding: 0.1rem 0.4rem;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-muted);
    font-size: 0.7rem;
    text-transform: capitalize;
    letter-spacing: 0.04em;
}
[data-theme="light"] .player-dev-focus-cat {
    background: rgba(0, 0, 0, 0.06);
}

.player-dev-focus-body {
    color: var(--text-main);
    font-size: 0.9rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
}

/* ----- Recent notes ----- */

.player-dev-note-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.player-dev-note-item {
    display: flex;
    gap: 0.7rem;
    padding: 0.55rem;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    background: rgba(255, 255, 255, 0.02);
}
[data-theme="light"] .player-dev-note-item {
    border-color: rgba(0, 0, 0, 0.06);
    background: rgba(0, 0, 0, 0.02);
}

.player-dev-note-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.player-dev-note-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.player-dev-note-title {
    color: var(--text-main);
    font-size: 0.9rem;
    overflow-wrap: anywhere;
}

.player-dev-note-meta {
    font-size: 0.75rem;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}

.player-dev-note-summary {
    margin: 0;
    color: var(--text-main);
    font-size: 0.88rem;
    line-height: 1.5;
}

.player-dev-note-next {
    margin: 0;
    padding: 0.4rem 0.6rem;
    border-radius: 6px;
    background: rgba(20, 184, 166, 0.08);
    color: var(--text-main);
    font-size: 0.85rem;
    line-height: 1.45;
    overflow-wrap: anywhere;
}
.player-dev-note-next.is-emphasized {
    background: rgba(245, 158, 11, 0.10);
}
/* Light-mode overrides — the 8–10% opacity tints disappear on a light
 * background. Mirrors the `.feedback-structured-item` precedent
 * (see ~line 7813) by inverting transparency direction so the tint
 * still reads against #fff. */
[data-theme="light"] .player-dev-note-next {
    background: rgba(13, 148, 136, 0.10);
    border-left: 3px solid rgba(13, 148, 136, 0.45);
    padding-left: 0.55rem;
}
[data-theme="light"] .player-dev-note-next.is-emphasized {
    background: rgba(217, 119, 6, 0.12);
    border-left-color: rgba(217, 119, 6, 0.55);
}
.player-dev-note-next-label {
    display: inline-block;
    margin-right: 0.35rem;
    font-weight: 600;
    color: var(--accent, #298bed);
}
.player-dev-note-next.is-emphasized .player-dev-note-next-label {
    color: rgba(245, 158, 11, 1);
}
[data-theme="light"] .player-dev-note-next-label {
    color: #115e59;
}
[data-theme="light"] .player-dev-note-next.is-emphasized .player-dev-note-next-label {
    color: #92400e;
}

/* ----- Recent clips ----- */

.player-dev-clip-list,
.player-dev-playlist-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}

.player-dev-clip-item {
    display: flex;
    gap: 0.7rem;
    padding: 0.55rem;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    background: rgba(255, 255, 255, 0.02);
    align-items: center;
}
[data-theme="light"] .player-dev-clip-item {
    border-color: rgba(0, 0, 0, 0.06);
    background: rgba(0, 0, 0, 0.02);
}

.player-dev-clip-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}
.player-dev-clip-title {
    color: var(--text-main);
    font-size: 0.92rem;
    overflow-wrap: anywhere;
}
.player-dev-clip-meta {
    font-size: 0.75rem;
    color: var(--text-muted);
    overflow-wrap: anywhere;
}
.player-dev-clip-desc {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.82rem;
    line-height: 1.45;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.player-dev-clip-actions {
    display: flex;
    flex-shrink: 0;
}

/* ----- Recent playlists ----- */

.player-dev-playlist-item {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.55rem 0.7rem;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    background: rgba(255, 255, 255, 0.02);
}
[data-theme="light"] .player-dev-playlist-item {
    border-color: rgba(0, 0, 0, 0.06);
    background: rgba(0, 0, 0, 0.02);
}
.player-dev-playlist-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.player-dev-playlist-meta {
    font-size: 0.75rem;
    color: var(--text-muted);
}

/* ----- Linked-players selector chips for the My Feedback Development tab ----- */

.feedback-dev-player-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 0.9rem;
}
.feedback-dev-player-chip {
    appearance: none;
    border: 1px solid rgba(255, 255, 255, 0.10);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
    padding: 0.35rem 0.75rem;
    border-radius: 999px;
    font-size: 0.85rem;
    cursor: pointer;
    /* Smooth interaction-state transitions matching `.coach-subnav-btn`. */
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
[data-theme="light"] .feedback-dev-player-chip {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.10);
}
.feedback-dev-player-chip:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.18);
}
[data-theme="light"] .feedback-dev-player-chip:hover {
    background: rgba(0, 0, 0, 0.07);
    border-color: rgba(0, 0, 0, 0.18);
}
/* Visible keyboard focus — never rely on the browser default outline,
 * which gets suppressed by `appearance: none` on some platforms.
 * Matches the focus-ring treatment used elsewhere in the app. */
.feedback-dev-player-chip:focus-visible {
    outline: 2px solid var(--accent, #298bed);
    outline-offset: 2px;
}
.feedback-dev-player-chip.is-active {
    background: rgba(41, 139, 237, 0.16);
    border-color: var(--accent, #298bed);
    color: var(--text-main);
}
[data-theme="light"] .feedback-dev-player-chip.is-active {
    background: rgba(23, 113, 201, 0.14);
    border-color: var(--accent, #298bed);
    color: #1d4ed8;
}
/* Keep the active state visually dominant on hover so the selected
 * chip never silently regresses to the resting hover style. */
.feedback-dev-player-chip.is-active:hover {
    background: rgba(41, 139, 237, 0.22);
}
[data-theme="light"] .feedback-dev-player-chip.is-active:hover {
    background: rgba(23, 113, 201, 0.20);
}

/* ----- Mobile collapse ----- */

@media (max-width: 720px) {
    .player-dev-tile-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .player-dev-clip-item {
        flex-wrap: wrap;
    }
    .player-dev-clip-actions {
        width: 100%;
    }
    .player-dev-clip-actions .mini-action-btn {
        width: 100%;
        text-align: center;
    }
}

/* =====================================================================
   Phase 6c — tactical board
   ===================================================================== */

.tb-section {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.75rem;
    border-radius: 8px;
    background: rgba(148, 163, 184, 0.06);
    border: 1px dashed rgba(148, 163, 184, 0.32);
}
[data-theme="light"] .tb-section {
    background: rgba(15, 23, 42, 0.04);
    border-color: rgba(15, 23, 42, 0.18);
}
.tb-section--editor {
    background: rgba(56, 189, 248, 0.05);
    border-style: solid;
    border-color: rgba(56, 189, 248, 0.3);
}
[data-theme="light"] .tb-section--editor {
    background: rgba(2, 132, 199, 0.05);
    border-color: rgba(2, 132, 199, 0.3);
}

.tb-section-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.tb-section-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--text-main);
    font-size: 0.92rem;
}
.tb-section-glyph {
    color: #38bdf8;
    font-size: 1.1rem;
}
.tb-section-hint {
    color: var(--text-muted);
    font-size: 0.8rem;
}
.tb-section-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
/* Self-contained section-head button. NOT a global .btn-secondary —
 * the section header sits inside a form modal, so we don't want the
 * generic primary/secondary palette competing with the modal's own
 * Save/Cancel footer. Mirrors .tb-tool-btn's surface so the editor
 * and section header read as one component. */
.tb-section-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.35rem 0.8rem;
    border-radius: 5px;
    border: 1px solid rgba(148, 163, 184, 0.32);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
    font-size: 0.85rem;
    line-height: 1.2;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.tb-section-btn:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(56, 189, 248, 0.4);
}
.tb-section-btn:focus-visible {
    outline: 2px solid #38bdf8;
    outline-offset: 1px;
}
[data-theme="light"] .tb-section-btn {
    background: #ffffff;
    border-color: rgba(15, 23, 42, 0.18);
    color: var(--text-main);
}
[data-theme="light"] .tb-section-btn:hover {
    background: rgba(15, 23, 42, 0.04);
    border-color: rgba(2, 132, 199, 0.4);
}
.tb-section-btn--primary {
    background: rgba(23, 113, 201, 0.28);
    border-color: rgba(23, 113, 201, 0.55);
    color: #ffffff;
}
.tb-section-btn--primary:hover {
    background: rgba(23, 113, 201, 0.42);
    border-color: rgba(23, 113, 201, 0.7);
}
[data-theme="light"] .tb-section-btn--primary {
    background: #1771c9;
    border-color: #1771c9;
    color: #ffffff;
}
[data-theme="light"] .tb-section-btn--primary:hover {
    background: #1361b0;
    border-color: #1361b0;
}
.tb-section-btn--danger {
    color: #fca5a5;
    border-color: rgba(248, 113, 113, 0.35);
}
.tb-section-btn--danger:hover {
    background: rgba(248, 113, 113, 0.18);
    color: #fecaca;
}
[data-theme="light"] .tb-section-btn--danger {
    color: #b91c1c;
    border-color: rgba(185, 28, 28, 0.35);
    background: #ffffff;
}
[data-theme="light"] .tb-section-btn--danger:hover {
    background: rgba(185, 28, 28, 0.08);
    color: #991b1b;
}

/* Local in-section confirm bar (replaces global confirmAction inside
 * the tactical-board section because the section is mounted inside
 * the observation formModal — opening another app modal would close
 * the parent and lose every coach-typed field). */
.tb-confirm-bar {
    flex: 1 0 100%;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.5rem;
    padding: 0.55rem 0.7rem;
    border-radius: 6px;
    background: rgba(248, 113, 113, 0.12);
    border: 1px solid rgba(248, 113, 113, 0.35);
}
/* `display: flex` above overrides the [hidden] attribute's default
 * `display: none`. Restore the hide behavior explicitly. */
.tb-confirm-bar[hidden] {
    display: none;
}
[data-theme="light"] .tb-confirm-bar {
    background: rgba(185, 28, 28, 0.08);
    border-color: rgba(185, 28, 28, 0.32);
}
.tb-confirm-bar-msg {
    flex: 1 1 auto;
    margin: 0;
    color: var(--text-main);
    font-size: 0.85rem;
    line-height: 1.45;
}
.tb-confirm-bar-actions {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}
@media (pointer: coarse), (max-width: 720px) {
    .tb-section-btn {
        min-height: 44px;
    }
}
.tb-section-helper {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.85rem;
    line-height: 1.45;
}
.tb-section-preview {
    display: flex;
    justify-content: center;
}

/* SVG wrapper sizes — preview (in composer + viewer cards),
 * chip (thumbnail tile), full (editor stage). All maintain
 * the soccer pitch's natural aspect ratio. */
.tb-svg-wrap {
    position: relative;
    width: 100%;
    aspect-ratio: 1050 / 680;
    overflow: hidden;
    border-radius: 6px;
    background: #168a3f;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) inset;
}
.tb-svg-wrap--preview {
    max-width: 540px;
}
.tb-svg-wrap--chip {
    max-width: 100%;
    border-radius: 4px;
}
.tb-svg-wrap--full {
    max-width: 100%;
}
.tb-svg-wrap--editor .tb-svg {
    cursor: crosshair;
}
.tb-svg-wrap--editor .tb-token,
.tb-svg-wrap--editor .tb-shape {
    cursor: grab;
}
.tb-svg-wrap--editor .tb-token.is-selected,
.tb-svg-wrap--editor .tb-shape.is-selected {
    filter: drop-shadow(0 0 6px rgba(251, 191, 36, 0.55));
}
.tb-svg {
    display: block;
    width: 100%;
    height: 100%;
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}
.tb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1050 / 680;
    border-radius: 6px;
    background: rgba(148, 163, 184, 0.1);
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* Editor toolbar */
.tb-editor {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
}
.tb-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem;
    background: rgba(15, 23, 42, 0.45);
    border: 1px solid rgba(148, 163, 184, 0.18);
    border-radius: 6px;
}
[data-theme="light"] .tb-toolbar {
    background: rgba(241, 245, 249, 0.85);
    border-color: rgba(15, 23, 42, 0.18);
}
.tb-tool-group {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    flex-wrap: wrap;
}
.tb-tool-group--right {
    margin-left: auto;
}
.tb-tool-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.32rem 0.7rem;
    border-radius: 5px;
    border: 1px solid rgba(148, 163, 184, 0.32);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-main);
    font-size: 0.82rem;
    line-height: 1.2;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.tb-tool-btn:hover {
    background: rgba(255, 255, 255, 0.08);
    border-color: rgba(56, 189, 248, 0.35);
}
.tb-tool-btn:focus-visible {
    outline: 2px solid #38bdf8;
    outline-offset: 1px;
}
.tb-tool-btn.is-active {
    background: rgba(23, 113, 201, 0.28);
    border-color: rgba(23, 113, 201, 0.55);
    color: var(--text-main);
}
.tb-tool-btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}
/* Light-mode palette — without these the rgba(255,255,255,0.04) base
 * is invisible against a near-white card background. Border carries
 * the affordance until hover/focus surface. */
[data-theme="light"] .tb-tool-btn {
    background: #ffffff;
    border-color: rgba(15, 23, 42, 0.18);
    color: var(--text-main);
}
[data-theme="light"] .tb-tool-btn:hover {
    background: rgba(15, 23, 42, 0.04);
    border-color: rgba(2, 132, 199, 0.45);
}
[data-theme="light"] .tb-tool-btn.is-active {
    background: rgba(2, 132, 199, 0.12);
    border-color: rgba(2, 132, 199, 0.55);
    color: #0c4a6e;
}
.tb-tool-btn--danger {
    color: #fca5a5;
    border-color: rgba(248, 113, 113, 0.35);
}
[data-theme="light"] .tb-tool-btn--danger {
    color: #b91c1c;
    border-color: rgba(185, 28, 28, 0.35);
    background: #ffffff;
}
.tb-tool-btn--danger:hover:not([disabled]) {
    background: rgba(248, 113, 113, 0.18);
}
[data-theme="light"] .tb-tool-btn--danger:hover:not([disabled]) {
    background: rgba(185, 28, 28, 0.08);
}
/* 44 px touch target on mobile / coarse pointer — matches the
 * Sprint 8 (PR #60) a11y convention applied to .coach-tool-btn. */
@media (pointer: coarse), (max-width: 720px) {
    .tb-tool-btn {
        min-height: 44px;
    }
}
.tb-token-label-wrap {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    font-size: 0.78rem;
    color: var(--text-muted);
}
.tb-token-label-input {
    width: 110px;
    padding: 0.28rem 0.5rem;
    border-radius: 5px;
    border: 1px solid rgba(148, 163, 184, 0.32);
    background: rgba(15, 23, 42, 0.4);
    color: var(--text-main);
    font-size: 0.85rem;
}
[data-theme="light"] .tb-token-label-input {
    background: #ffffff;
    color: var(--text-main);
    border-color: rgba(15, 23, 42, 0.18);
}
.tb-token-label-input:focus-visible {
    outline: 2px solid #38bdf8;
    outline-offset: 1px;
    border-color: #38bdf8;
}
.tb-helper {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.45;
}
.tb-stage {
    display: block;
    width: 100%;
    background: transparent;
}
.tb-status {
    margin: 0;
    min-height: 1.1rem;
    color: var(--text-muted);
    font-size: 0.82rem;
}

/* Compact-thumb variant: when an observation row carries a board,
 * we render the SVG into the thumbnail slot. The slot has a fixed
 * aspect from `.coach-thumb` — tighten the SVG wrap to fill it. */
.coach-thumb--board {
    background: #168a3f;
    overflow: hidden;
    padding: 0;
}
.coach-thumb--board .tb-svg-wrap {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
}
.coach-thumb--board .tb-svg {
    width: 100%;
    height: 100%;
}

/* Inline board pill in the row head — mirrors the observation
 * context pill so they sit next to each other consistently. */
.coach-row-board-pill {
    display: inline-flex;
    align-items: center;
    padding: 1px 7px;
    border-radius: 999px;
    background: rgba(56, 189, 248, 0.12);
    color: #38bdf8;
    font-size: 0.72rem;
    font-weight: 600;
    border: 1px solid rgba(56, 189, 248, 0.32);
}
[data-theme="light"] .coach-row-board-pill {
    background: rgba(2, 132, 199, 0.1);
    color: #0369a1;
    border-color: rgba(2, 132, 199, 0.3);
}

/* Read-only board preview inside My Feedback note cards. */
.feedback-card-board {
    margin-top: 0.5rem;
    border-radius: 6px;
    overflow: hidden;
    background: #168a3f;
}
.feedback-card-board .tb-svg-wrap {
    border-radius: 0;
    box-shadow: none;
    max-width: 100%;
}

/* Tactical-board observation composer needs more horizontal room than
 * the standard wide modal (720 px) for the editor. This is a SCOPED
 * variant — the existing `.is-wide` rule (used by Player Development
 * and the focused My Feedback player) keeps its 720 px max-width.
 * Apply with `app.formModal({ size: 'wide-board' })`. */
.app-modal-card.is-wide-board {
    max-width: 1080px;
    width: calc(100vw - 32px);
}

/* Mobile collapse — stack toolbar groups, shrink label input, keep
 * the SVG full-width. */
@media (max-width: 720px) {
    .tb-toolbar {
        gap: 0.35rem;
    }
    .tb-tool-group--right {
        margin-left: 0;
        width: 100%;
        justify-content: flex-end;
    }
    .tb-token-label-wrap {
        flex: 1 1 100%;
    }
    .tb-token-label-input {
        width: 100%;
    }
    .tb-svg-wrap--preview {
        max-width: 100%;
    }
    .tb-section-head {
        flex-direction: column;
        align-items: stretch;
    }
    .tb-section-actions {
        justify-content: flex-end;
    }
}

/* ============================================================
 * Phase 6d-1 — Coach Review unified source modes
 *
 * The Review tab has a single shared workspace shell. A
 * `data-source` attribute on `.coach-review-shell` toggles which
 * picker controls, main canvas, and side-panel pane is visible.
 * Elements with `data-source-only="video"` show only when the
 * shell is in video mode; `data-source-only="tactical_board"`
 * shows only in board mode. */

.coach-review-shell .coach-review-source-toggle {
    display: inline-flex;
    gap: 0.4rem;
    padding: 0.25rem;
    border-radius: 999px;
    background: var(--surface-1, rgba(255, 255, 255, 0.04));
    border: 1px solid var(--border-subtle, rgba(255, 255, 255, 0.08));
    margin-bottom: 0.6rem;
}

.coach-review-source-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.32rem 0.85rem;
    border-radius: 999px;
    background: transparent;
    border: 1px solid transparent;
    color: var(--text-muted);
    font-size: 0.85rem;
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}

.coach-review-source-btn:hover {
    color: var(--text);
    background: rgba(255, 255, 255, 0.04);
}

.coach-review-source-btn:focus-visible {
    outline: 2px solid var(--accent, #38bdf8);
    outline-offset: 2px;
}

.coach-review-source-btn.is-active {
    /* Match the rest of the app's primary-blue button family
     * (.btn-primary, Save Note, Save Observation) — white text on
     * the resolved --accent so the contrast holds on both the
     * sky-blue (#38bdf8) and the deeper rgb(21,101,192) tone the
     * accent token resolves to in the dark theme. The previous
     * `color: #0b1220` was readable on bright cyan but became
     * low-contrast on the darker accent. */
    background: var(--accent, #38bdf8);
    color: #ffffff;
    border-color: var(--accent, #38bdf8);
    font-weight: 600;
}

.coach-review-source-glyph {
    font-size: 0.95rem;
    line-height: 1;
}

[data-theme="light"] .coach-review-shell .coach-review-source-toggle {
    background: rgba(0, 0, 0, 0.04);
    border-color: rgba(0, 0, 0, 0.1);
}
[data-theme="light"] .coach-review-source-btn {
    color: #475569;
}
[data-theme="light"] .coach-review-source-btn:hover {
    background: rgba(0, 0, 0, 0.05);
    color: #0f172a;
}
[data-theme="light"] .coach-review-source-btn.is-active {
    /* Same white-on-blue treatment as dark theme — the light-theme
     * .btn-primary equivalents also use white text on the accent. */
    color: #ffffff;
}

/* Source-mode pane visibility. The shell's `data-source` attribute
 * drives which children are visible. Hidden children are removed
 * from the layout (display:none) so the grid doesn't reserve
 * space. */
.coach-review-shell[data-source="video"] [data-source-only="tactical_board"],
.coach-review-shell[data-source="tactical_board"] [data-source-only="video"] {
    display: none !important;
}

/* The stage wrapper centers either the video pane or the board pane
 * in the same visual area. */
.coach-review-stage {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.coach-review-stage-pane {
    min-width: 0;
}

/* Tactical Board canvas — shares the video's visual real estate.
 * The pitch SVG fills the wrapper at 16:9-ish ratio so the picker
 * bar / side panel / timeline rail layout doesn't shift between
 * modes. */
.coach-review-board {
    /* Grass-green frame around the pitch SVG so the canvas reads as a
     * soccer pitch surface in BOTH dark and light themes (matches the
     * default `.tb-svg-wrap` background `#168a3f`). The SVG itself
     * paints its own gradient grass on top; this frame only shows
     * through the 0.6rem padding ring around the SVG so the surface
     * is uniformly green from edge to edge. */
    background: #168a3f;
    border-radius: 10px;
    padding: 0.6rem;
    border: 1px solid rgba(0, 0, 0, 0.25);
}

[data-theme="light"] .coach-review-board {
    /* Same grass-green tile in light theme — keeping the surface
     * green in both modes per the request. The deeper border stays
     * visible against the light page background. */
    background: #168a3f;
    border-color: rgba(0, 0, 0, 0.18);
}

.coach-review-board-canvas {
    width: 100%;
    aspect-ratio: 1050 / 680;  /* matches PITCH_VIEWBOX */
    overflow: hidden;
}

.coach-review-board-canvas .tb-svg-wrap,
.coach-review-board-canvas .tb-svg-wrap--full,
.coach-review-board-canvas .tb-svg-wrap--editor {
    width: 100%;
    height: 100%;
    max-width: none;
    /* Inherit the grass-green frame from `.coach-review-board` so a
     * sliver of green shows through behind the SVG even before the
     * `<rect fill="url(#tb-grass-grad)">` paints. */
    background: #168a3f;
    border-radius: 6px;
    overflow: hidden;
}

.coach-review-board-canvas svg.tb-svg {
    width: 100%;
    height: 100%;
    display: block;
    cursor: crosshair;
}

/* Status text overlays the bottom-left of the green pitch as a
 * high-contrast pill, so the active-tool prompt ("Click the pitch
 * to drop a player token", "Drag to draw an arrow", …) reads
 * clearly against the grass without competing with the pitch
 * markings. Empty status collapses the pill to zero height. The
 * .coach-review-board frame is `position: relative` so this
 * absolute overlay anchors to the pitch surface.
 *
 * The same treatment works in both dark and light themes — the
 * pill is opaque on its own dark base so the green pitch behind
 * doesn't reduce contrast. */
.coach-review-board {
    position: relative;
}
.coach-review-board-status {
    margin: 0;
    min-height: 0;
}
.coach-review-board-status:empty {
    display: none;
}
.coach-review-board-status:not(:empty) {
    position: absolute;
    left: 0.85rem;
    bottom: 0.85rem;
    padding: 0.35rem 0.7rem;
    background: rgba(15, 23, 42, 0.85);
    color: #ffffff;
    font-size: 0.78rem;
    font-weight: 500;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
    pointer-events: none;
    max-width: calc(100% - 1.7rem);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
[data-theme="light"] .coach-review-board-status:not(:empty) {
    background: rgba(15, 23, 42, 0.88);
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.15);
}

/* Tactical board side-panel toolbar. Visually mirrors the video
 * telestrator toolbar (.coach-tool-grid) so the side panel feels
 * consistent across source modes. */
/* Phase 6d-2 follow-up — the tactical board side panel now reuses the
 * exact same `.coach-telestrator` + `.coach-tool-grid` + `.coach-tool-
 * btn` chain as the video telestrator, so 99% of the visual rules come
 * from the existing video-side CSS. The only tactical-only blocks left
 * here are the structural wrappers above the telestrator (formation
 * controls) and below it (text inputs container). The earlier 6d-2
 * tactical-only `coach-tb-tool-*` overrides (2-col grid, left-aligned
 * row layout, glyph swap) have been deleted because they conflict with
 * parity. Tokens placed by the Player tool still get their `label`
 * from the same `data-coach-tb-input="player-label"` input — the
 * input lives in the new `.coach-tb-tool-meta` row below the swatches
 * + slider so it visually rhymes with the video telestrator's label-
 * text input. */
.coach-tb-toolbar {
    display: grid;
    gap: 0.6rem;
}

.coach-tb-tool-meta {
    display: grid;
    gap: 0.4rem;
}

/* Tactical-board toolbar text inputs share the visual language of the
 * existing `.coach-mini-form input` rule (rgba black tile, light-grey
 * border, accent focus ring). Same dimensions / typography as the rest
 * of the Coach side-panel inputs so the side panel reads as one
 * surface across source modes. Light-theme override mirrors the
 * `.coach-mini-form` rule above. */
.coach-tb-input {
    width: 100%;
    padding: 0.55rem 0.65rem;
    background: rgba(0, 0, 0, 0.24);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 6px;
    color: var(--text-main);
    font: inherit;
    font-size: 0.85rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.coach-tb-input:focus-visible {
    outline: none;
    border-color: var(--accent, #298bed);
    background-color: rgba(0, 0, 0, 0.32);
    box-shadow: 0 0 0 2px rgba(23, 113, 201, 0.18);
}

[data-theme="light"] .coach-tb-input {
    background-color: #ffffff;
    border-color: rgba(0, 0, 0, 0.14);
    color: var(--text-main);
}
[data-theme="light"] .coach-tb-input:hover {
    border-color: rgba(0, 0, 0, 0.32);
}
[data-theme="light"] .coach-tb-input:focus-visible {
    background-color: #ffffff;
    border-color: var(--accent, #1565c0);
    box-shadow: 0 0 0 2px rgba(21, 101, 192, 0.18);
}

.coach-tb-tool-actions {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.coach-tb-form .coach-tb-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.4rem;
}

.coach-tb-section-label {
    font-family: var(--font-heading);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    margin-top: 0.25rem;
}

/* Side-pane visibility helpers — only one pane is visible at a time. */
.coach-review-side .coach-review-side-pane[data-source-only] {
    display: contents;
}
.coach-review-shell[data-source="video"] .coach-review-side-pane[data-source-only="tactical_board"],
.coach-review-shell[data-source="tactical_board"] .coach-review-side-pane[data-source-only="video"] {
    display: none !important;
}

/* Picker bar buttons need to stay visible & focusable in their mode. */
.coach-review-shell[data-source="video"] [data-source-only="video"],
.coach-review-shell[data-source="tactical_board"] [data-source-only="tactical_board"] {
    /* default: each surface restores its native display via the rule above */
}

/* Make the Save Observation button visually match Save Note. */
#coach-review-save-observation {
    background: var(--accent, #38bdf8);
}

/* In Tactical Board mode, the Event Title group is the first visible
 * picker group. Mirror the Video-mode Match select's grow-to-fill
 * behavior so the trailing right-side buttons (Save Observation,
 * Focus, Shortcuts) stay flush to the right edge instead of floating
 * mid-bar. The selector targets the visible-source-only group whose
 * input is the event title.
 *
 * `flex: 1 1 0` (NOT `1 1 280px`) is deliberate — the basis is 0 so
 * the input shrinks gracefully when an extra picker control appears
 * in focus mode (the Tools button is hidden by default and shown
 * via `is-focus-mode`). With a 280-px basis the row would overflow
 * and Shortcuts would wrap to the next line. The `min-width: 200px`
 * on the input prevents shrinking past a usable width. */
.coach-review-shell[data-source="tactical_board"] .coach-review-picker-group[data-source-only="tactical_board"]:has(#coach-tb-event-title) {
    flex: 1 1 0;
    min-width: 200px;
}
.coach-review-shell[data-source="tactical_board"] .coach-review-picker-group[data-source-only="tactical_board"]:has(#coach-tb-event-title) input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
}

/* Phase 6d-1 — drawer (focus mode) source-mode pane visibility.
 *
 * The default `.coach-review-shell[data-source="X"] .coach-review-side-pane`
 * rule does NOT match when focus-mode opens the drawer, because
 * `openCoachFocusInspector()` re-parents `.coach-review-side` to
 * <body> (so it shares the root stacking context with the backdrop —
 * see js/coaching.js for the rationale). Once it's outside the shell,
 * the in-shell selector no longer applies and BOTH panes (video
 * telestrator + tactical board tools) would render in the drawer.
 *
 * Mirror the source mode onto <body> via `data-coach-review-source`
 * (set by _applyCoachReviewSource in js/coaching.js) so a body-level
 * rule still scopes the show/hide correctly when the drawer is open. */
body[data-coach-review-source="video"] > .coach-review-side .coach-review-side-pane[data-source-only="tactical_board"],
body[data-coach-review-source="tactical_board"] > .coach-review-side .coach-review-side-pane[data-source-only="video"] {
    display: none !important;
}

/* Phase 6d-2 — formation controls. Stacks game format + formation
 * selects + Apply button vertically inside the side toolbar so the
 * controls sit above the tool grid. Visually mirrors `.coach-tb-tool-
 * meta` so the side panel reads as one surface. */
.coach-tb-formation {
    display: grid;
    gap: 0.4rem;
    padding-bottom: 0.5rem;
    margin-bottom: 0.4rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

[data-theme="light"] .coach-tb-formation {
    border-bottom-color: rgba(0, 0, 0, 0.08);
}

.coach-tb-formation-apply {
    justify-self: stretch;
}

.coach-tb-formation-apply:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Phase 6d-2 follow-up — match the tactical-mode side aside to the
 * pitch height the same way `_syncCoachReviewSideHeight` matches the
 * video inspector to the video wrapper. We rely on JS to set the
 * inline `max-height` (see `_syncCoachReviewSideHeightFromBoard` in
 * `js/coaching.js`); CSS just makes the column scroll internally if
 * content overflows that cap, mirroring the video-mode pattern at
 * `#coach-view.is-review-mode .coach-review-side` (overflow: auto +
 * thin themed scrollbar). The toolbar and observation form keep
 * their natural heights and stack vertically in a single column. */
.coach-review-shell[data-source="tactical_board"] .coach-review-side {
    align-self: stretch;
    overflow: auto;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
.coach-review-shell[data-source="tactical_board"] .coach-review-side::-webkit-scrollbar {
    width: 6px;
}
.coach-review-shell[data-source="tactical_board"] .coach-review-side::-webkit-scrollbar-track {
    background: transparent;
}
.coach-review-shell[data-source="tactical_board"] .coach-review-side::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.18);
    border-radius: 3px;
}

/* Phase 6d-2 follow-up — light-theme scrollbar parity. The dark-theme
 * thumb above is white-on-dark; in light mode that renders as white-
 * on-light and is near-invisible. Mirror the video-mode pattern at
 * `[data-theme="light"] #coach-view.is-review-mode .coach-review-side`
 * with dark-on-light. Per CLAUDE.md: "Visible controls must be themed
 * in both dark and light modes... or unthemed scrollbars." */
[data-theme="light"] .coach-review-shell[data-source="tactical_board"] .coach-review-side {
    scrollbar-color: rgba(0, 0, 0, 0.18) transparent;
}
[data-theme="light"] .coach-review-shell[data-source="tactical_board"] .coach-review-side::-webkit-scrollbar-thumb {
    background: rgba(0, 0, 0, 0.18);
}

/* Phase 6d-2 follow-up — formation selectors styled like other Coach
 * <select>s (no native OS chrome). Mirrors `.coach-mini-form select`
 * (appearance:none + custom chevron) but scoped to the tactical board
 * formation row, since the row is NOT a `.coach-mini-form` ancestor
 * and the existing rule wouldn't otherwise reach it. The chevron icon
 * is the same SVG used by `.coach-mini-form select`. */
.coach-tb-formation select.coach-tb-input {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    padding-right: 2.35rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%23888890' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    background-size: 12px 8px;
}
[data-theme="light"] .coach-tb-formation select.coach-tb-input {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%231f2937' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5l5 5 5-5'/%3E%3C/svg%3E");
}

/* Phase 6d-2 — zone resize handles. The yellow squares at corners +
 * edge midpoints of a selected zone. The transparent outer rect (rendered
 * by the SVG, not styled here) gives a generous touch target. */
.tb-zone-handle {
    cursor: nwse-resize;
}
.tb-zone-handle[data-zone-resize="n"],
.tb-zone-handle[data-zone-resize="s"] {
    cursor: ns-resize;
}
.tb-zone-handle[data-zone-resize="e"],
.tb-zone-handle[data-zone-resize="w"] {
    cursor: ew-resize;
}
.tb-zone-handle[data-zone-resize="ne"],
.tb-zone-handle[data-zone-resize="sw"] {
    cursor: nesw-resize;
}

/* Mobile collapse: source toggle wraps and the picker bar stacks.
 * The tactical tool grid now reuses `.coach-tool-grid`, which already
 * has its own responsive rules from the video telestrator CSS — no
 * tactical-only override needed here. */
@media (max-width: 720px) {
    .coach-tb-form .coach-tb-row {
        grid-template-columns: 1fr;
    }
}

/* Tighter mobile (390px) — formation controls stay one column and
 * the tactical toolbar wraps cleanly. */
@media (max-width: 480px) {
    .coach-tb-formation {
        grid-template-columns: 1fr;
    }
    .coach-tb-formation-apply {
        width: 100%;
    }
}

