/* ===== RallyFlow theme ===== */
:root {
    /* Site only ships a light theme; without this, browsers/OSes with an
       auto-dark-mode heuristic can invert an element's inherited background
       without also re-coloring an explicitly-set text color on top of it,
       breaking contrast (e.g. the club tile name bug). */
    color-scheme: light;
    --rf-green: #5FA31E;
    --rf-green-dark: #0F3A1E;
    --rf-green-light: #8ED84F;
    --rf-ink: #0A1F10;
    --rf-shadow: 0 6px 20px rgba(15, 58, 30, 0.08);
    --rf-shadow-lg: 0 14px 38px rgba(15, 58, 30, 0.16);
    --rf-orange: #F5871F;
    --rf-cream: #F6E9C7;
}

html, body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    color: var(--rf-ink);
    scroll-behavior: smooth;
}

body {
    background:
        radial-gradient(1100px 480px at 100% -8%, rgba(142, 216, 79, 0.10), transparent 60%),
        radial-gradient(900px 460px at -8% 0%, rgba(95, 163, 30, 0.10), transparent 55%),
        #f5f8f6;
    min-height: 100vh;
}

/* Sticky footer layout */
.page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

a, .btn-link { color: var(--rf-green); text-decoration: none; }
a:hover { color: var(--rf-green-dark); }

h1:focus { outline: none; }

/* ===== Buttons ===== */
.btn {
    border-radius: 0;
    font-weight: 600;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--rf-shadow); }
.btn:active { transform: translateY(0); box-shadow: none; }

.btn-primary, .btn-success {
    color: #fff;
    background: linear-gradient(135deg, var(--rf-green-light), var(--rf-green));
    border: none;
}
.btn-primary:hover, .btn-success:hover {
    background: linear-gradient(135deg, var(--rf-green), var(--rf-green-dark));
}

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

.btn:focus, .btn:active:focus, .form-control:focus, .form-check-input:focus, .form-select:focus {
    box-shadow: 0 0 0 0.2rem rgba(142, 216, 79, 0.35);
    border-color: var(--rf-green-light);
}

/* ===== Cards ===== */
.card {
    border: none;
    border-radius: 0;
    box-shadow: var(--rf-shadow);
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.card.shadow-sm { box-shadow: var(--rf-shadow) !important; }

/* Lift only for interactive/clickable contexts */
a > .card:hover,
.court-card-playing:hover,
.court-card-available:hover,
.stat-card:hover { transform: translateY(-4px); box-shadow: var(--rf-shadow-lg); }

/* Big action buttons on the home page */
.btn-lg.w-100 { border-radius: 0; }

/* ===== Global square override — Bootstrap components default to rounded
   corners; RallyFlow's design language is squared-off everywhere. Circular
   elements (badges-as-circles, live-status dots, spinners) are untouched
   since those are a shape, not a corner style. ===== */
.form-control, .form-select, .alert, .list-group-item,
.modal-content, .dropdown-menu, .accordion-button, .accordion-item,
.progress, .toast, .pagination .page-link {
    border-radius: 0 !important;
}

/* ===== Navbar ===== */
header.navbar, .navbar.bg-success {
    background: linear-gradient(135deg, var(--rf-green), var(--rf-green-dark)) !important;
    box-shadow: 0 4px 18px rgba(15, 58, 30, 0.18);
}
.navbar-brand { letter-spacing: 0.02em; }

/* ===== Light/dark mode toggle ===== */
#rf-theme-toggle {
    line-height: 1;
    padding-inline: 0.55rem;
}
#rf-theme-toggle .rf-theme-icon { font-size: 0.95rem; }

/* ===== Content fade-in ===== */
.rf-main { flex: 1 0 auto; animation: rf-fade-in 0.45s ease both; }
@keyframes rf-fade-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ===== Footer ===== */
.rf-footer {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    border-top: 1px solid rgba(95, 163, 30, 0.12);
    background: linear-gradient(180deg, transparent, rgba(95, 163, 30, 0.05));
}
.rf-footer-brand { font-weight: 800; color: var(--rf-green); letter-spacing: 0.02em; }
.rf-powered { font-weight: 700; color: var(--rf-green-dark); }
.rf-footer-link { color: #6c757d; text-decoration: none; }
.rf-footer-link:hover { color: var(--rf-green); text-decoration: underline; }

/* ===== LIVE badge pulse ===== */
.rf-live {
    position: relative;
    animation: rf-pulse 1.8s ease-in-out infinite;
}
@keyframes rf-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(142, 216, 79, 0.6); }
    50%      { box-shadow: 0 0 0 0.5rem rgba(142, 216, 79, 0); }
}

/* ===== Queue board ===== */
.queue-card { border-left: 4px solid var(--rf-green); }

.court-card-playing {
    border-left: 5px solid #ffc107;
    background: linear-gradient(135deg, #fffdf4, #fff);
}
.court-card-available { border-left: 5px solid #adb5bd; }

.queue-position-badge {
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--rf-green-light), var(--rf-green));
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.85rem;
    flex-shrink: 0;
    box-shadow: 0 3px 8px rgba(95, 163, 30, 0.3);
}

.player-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem;
    border-bottom: 1px solid #f0f2f0;
    transition: background-color 0.15s ease;
}
.player-row:last-child { border-bottom: none; }
/* Zebra striping: alternate rows get a subtle tint so each player reads as its own band */
.player-row:nth-child(even) { background: rgba(95, 163, 30, 0.045); }
.player-row:hover { background: rgba(95, 163, 30, 0.10); }

/* Highlight "me" in the live queue list so a player can pick themselves out at a glance. */
.player-row.rf-me {
    background: rgba(95, 163, 30, 0.18) !important;
    border-left: 4px solid #5FA31E;
    padding-left: calc(0.75rem - 4px);
}

/* Gentle pulse on the "you're up" / "you're playing" banner so it draws the eye. */
.rf-you-banner {
    animation: rf-banner-pulse 1.8s ease-in-out infinite;
}
@keyframes rf-banner-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(95, 163, 30, 0.35); }
    50%      { box-shadow: 0 0 0 10px rgba(95, 163, 30, 0); }
}

/* Celebratory toast shown briefly on LiveQueue when the current player's win
   count ticks up, alongside the confetti burst fired via rallyflow.confetti(). */
.rf-win-toast {
    position: fixed;
    top: 1.25rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 1090;
    background: linear-gradient(135deg, #20a779, #5FA31E);
    color: #fff;
    border-radius: 1rem;
    padding: 0.75rem 1.5rem;
    text-align: center;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
    pointer-events: none;
    animation: rf-win-toast-in 0.35s ease-out both;
}
@keyframes rf-win-toast-in {
    from { opacity: 0; transform: translateX(-50%) translateY(-12px) scale(0.95); }
    to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

/* TV variant — same toast, scaled up so it reads clearly from across a gym. */
.rf-tv-win-toast {
    top: 2rem;
    padding: 1.5rem 3rem;
    border-radius: 1.5rem;
}

/* Confetti pieces are created/removed by rallyflow.confetti() in notify.js. */
@keyframes rf-confetti-fall {
    0%   { transform: translateY(0) rotate(0deg); opacity: 0.95; }
    100% { transform: translateY(105vh) rotate(540deg); opacity: 0; }
}

/* Honeypot field — kept in the DOM for bots but invisible/unreachable for humans */
.rf-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

/* ===== FAQ disclosures (native <details>, no JS needed) ===== */
.rf-faq-item { overflow: hidden; }
.rf-faq-item > summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
}
.rf-faq-item > summary::-webkit-details-marker { display: none; }
.rf-faq-item > summary::after {
    content: "▼";
    font-size: 0.7rem;
    color: var(--rf-green);
    margin-left: 0.75rem;
    transition: transform 0.2s ease;
}
.rf-faq-item[open] > summary::after { transform: rotate(180deg); }

/* Podium chips in the dashboard session list (themable for dark mode below) */
.rf-podium-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    background: #f1f5f3;
    color: var(--rf-ink);
    border: 1px solid #dde5e1;
    border-radius: 0;
    padding: 0.3rem 0.5rem;
    font-weight: 600;
    font-size: 0.8rem;
}

.badge { border-radius: 0; font-weight: 600; }

/* Longest-waiting stat badge in the dashboard Queue panel header (themable for dark mode below) */
.rf-wait-badge {
    background: #f1f5f3;
    color: var(--rf-ink);
    border: 1px solid #dde5e1;
}

/* DUPR-style tiers, low -> high (2.5 -> 4.5+) */
.skill-badge-1 { background: #5FA31E; }            /* 2.5  Beginner       */
.skill-badge-2 { background: #20a779; }            /* 3.0  Adv. Beginner  */
.skill-badge-3 { background: #0d6efd; }            /* 3.5  Intermediate   */
.skill-badge-4 { background: #fd7e14; }            /* 4.0  Advanced       */
.skill-badge-5 { background: #dc3545; }            /* 4.5+ Pro / Open     */

/* Milestone-achievement badges (My Dashboard) — tiered by how hard they are to earn. */
.rf-badge-bronze { background: #ad8a56; color: #fff; }
.rf-badge-silver { background: linear-gradient(135deg, #9ea7b3, #cfd6dd); color: #22262b; }
.rf-badge-gold   { background: linear-gradient(135deg, #d4a017, #ffd76a); color: #4a3600; box-shadow: 0 0 0 1px rgba(212, 160, 23, 0.4); }

/* ===== TV display ===== */
/* Light page background so the white match cards + dark panels contrast
   against it, matching the reference scoreboard layout. */
.rf-tv-root-light {
    background:
        radial-gradient(1100px 480px at 100% -8%, rgba(142, 216, 79, 0.16), transparent 60%),
        radial-gradient(900px 460px at -8% 0%, rgba(95, 163, 30, 0.16), transparent 55%),
        #eef2ee;
    color: var(--rf-ink);
    min-height: 100vh;
}

.rf-tv-match-card {
    background: #fff;
    border: 2px solid transparent;
    border-radius: 1rem;
    padding: 1.1rem 1.25rem;
    color: var(--rf-ink);
    box-shadow: 0 12px 28px rgba(15, 58, 30, 0.14);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.rf-tv-match-card:hover { transform: translateY(-3px); }

.rf-tv-match-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.9rem; gap: 0.5rem; }
.rf-tv-match-title { display: flex; align-items: center; gap: 0.6rem; }
.rf-tv-court-name { font-weight: 800; font-size: 1.1rem; }
.rf-tv-match-timer { color: #6c757d; font-size: 0.85rem; font-weight: 600; white-space: nowrap; }

.rf-tv-live-badge, .rf-tv-open-badge {
    display: inline-flex; align-items: center; gap: 0.35rem;
    font-weight: 700; font-size: 0.68rem; letter-spacing: 0.05em;
    text-transform: uppercase; padding: 0.22rem 0.6rem; border-radius: 999px;
}
.rf-tv-live-badge { background: #dc3545; color: #fff; }
.rf-tv-live-badge::before { content: ""; width: 0.4rem; height: 0.4rem; border-radius: 50%; background: #fff; }
.rf-tv-open-badge { background: #e9ecef; color: #6c757d; }

.rf-tv-matchup { display: flex; align-items: stretch; gap: 0.6rem; }
.rf-tv-team-box { flex: 1 1 0; min-width: 0; border-radius: 0.65rem; overflow: hidden; }
.rf-tv-team-box.rf-team-1 { background: rgba(95, 163, 30, 0.08); }
.rf-tv-team-box.rf-team-2 { background: rgba(245, 135, 31, 0.10); }
.rf-tv-team-box-label {
    font-size: 0.68rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
    color: #fff; padding: 0.3rem 0.65rem;
}
.rf-tv-team-box.rf-team-1 .rf-tv-team-box-label { background: var(--rf-green); }
.rf-tv-team-box.rf-team-2 .rf-tv-team-box-label { background: var(--rf-orange); }
.rf-tv-team-players { padding: 0.55rem 0.7rem; display: flex; flex-direction: column; gap: 0.6rem; }
.rf-tv-team-player .tv-player-name { font-size: 1.05rem; font-weight: 700; line-height: 1.15; white-space: nowrap; }
.rf-tv-team-player .rf-tv-player-skill { font-size: 0.72rem; color: #b5860a; margin-top: 0.1rem; }
.rf-tv-vs-mini { flex: 0 0 auto; align-self: center; font-weight: 800; color: #adb5bd; font-size: 0.85rem; padding: 0 0.15rem; }

/* "Next Up" preview — a distinct blue/dashed theme so it reads at a glance as
   different from the red-badged, solid-card LIVE courts above it. Team 1/Team 2
   colors stay green/orange (same meaning everywhere else in the app); only the
   outer panel/card gets the "this is a preview, not live" treatment. */
.rf-tv-nextup-panel {
    position: relative;
    background: linear-gradient(180deg, rgba(58, 107, 237, 0.08), rgba(58, 107, 237, 0.02));
    border: 1px solid rgba(58, 107, 237, 0.28);
    border-radius: 1rem;
    padding: 1.25rem 1.5rem;
    box-shadow: 0 12px 28px rgba(15, 58, 30, 0.1);
}
.rf-tv-nextup-label {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: #3a56c4;
    font-weight: 800;
}
.rf-tv-nextup-card {
    background: #fff;
    border: 2px dashed rgba(58, 107, 237, 0.4);
    border-radius: 0.85rem;
    padding: 0.9rem 1rem;
    height: 100%;
}

.rf-tv-root.rf-dark-theme .rf-tv-nextup-panel {
    background: linear-gradient(180deg, rgba(109, 148, 255, 0.16), rgba(109, 148, 255, 0.04));
    border-color: rgba(109, 148, 255, 0.4);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4);
}
.rf-tv-root.rf-dark-theme .rf-tv-nextup-label { color: #a9bdff; }
.rf-tv-root.rf-dark-theme .rf-tv-nextup-card {
    background: var(--rf-dark-surface);
    border-color: rgba(109, 148, 255, 0.45);
}

.rf-tv-panel {
    position: relative;
    overflow: hidden;
    background: #fff;
    border: 1px solid #dde5e1;
    border-radius: 1rem;
    padding: 1.25rem 1.5rem;
    color: var(--rf-ink);
    box-shadow: 0 12px 28px rgba(15, 58, 30, 0.14);
}
.rf-tv-panel > * { position: relative; z-index: 1; }
.rf-tv-panel.rf-tv-has-logo::before {
    content: "";
    position: absolute;
    inset: 15%;
    background-image: var(--rf-tv-logo);
    background-position: center;
    background-repeat: no-repeat;
    background-size: contain;
    opacity: 0.08;
    pointer-events: none;
    z-index: 0;
    filter: grayscale(0.2);
}
.rf-tv-panel-label {
    font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.1em;
    color: #6c757d; font-weight: 700;
}

/* TV display — dark mode, synced with the site-wide toggle (theme.js applies
   .rf-dark-theme to .rf-tv-root the same way MainLayout applies it to .page). */
.rf-tv-root.rf-dark-theme {
    --rf-dark-surface: #0F2416;
    --rf-dark-surface-2: #163020;
    --rf-dark-border: #1E3A28;
    --rf-dark-text: #e6ece9;
    --rf-dark-muted: #9fb0a8;
}
.rf-tv-root.rf-dark-theme.rf-tv-root-light {
    background:
        radial-gradient(1100px 480px at 100% -8%, rgba(142, 216, 79, 0.10), transparent 60%),
        radial-gradient(900px 460px at -8% 0%, rgba(95, 163, 30, 0.12), transparent 55%),
        #081409;
    color: var(--rf-dark-text);
}
.rf-tv-root.rf-dark-theme .text-secondary,
.rf-tv-root.rf-dark-theme .text-muted { color: var(--rf-dark-muted) !important; }
.rf-tv-root.rf-dark-theme .bg-white { background: var(--rf-dark-surface-2) !important; color: var(--rf-dark-text); }
.rf-tv-root.rf-dark-theme .form-select.text-dark { color: var(--rf-dark-text) !important; }
.rf-tv-root.rf-dark-theme .rf-tv-match-card {
    background: var(--rf-dark-surface);
    color: var(--rf-dark-text);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4);
}
.rf-tv-root.rf-dark-theme .rf-tv-match-timer { color: var(--rf-dark-muted); }
.rf-tv-root.rf-dark-theme .rf-tv-open-badge { background: var(--rf-dark-surface-2); color: var(--rf-dark-muted); }
.rf-tv-root.rf-dark-theme .rf-tv-team-box.rf-team-1 { background: rgba(95, 163, 30, 0.18); }
.rf-tv-root.rf-dark-theme .rf-tv-team-box.rf-team-2 { background: rgba(245, 135, 31, 0.20); }
.rf-tv-root.rf-dark-theme .rf-tv-panel {
    background: var(--rf-dark-surface);
    border-color: var(--rf-dark-border);
    color: var(--rf-dark-text);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4);
}
.rf-tv-root.rf-dark-theme .rf-tv-panel-label { color: var(--rf-dark-muted); }
.rf-tv-root.rf-dark-theme .rf-tv-standings-row { background: rgba(255, 255, 255, 0.05); }
.rf-tv-root.rf-dark-theme .rf-tv-standings-rank { color: var(--rf-dark-muted); }
.rf-tv-root.rf-dark-theme .rf-tv-standings-name { color: var(--rf-dark-text); }
.rf-tv-root.rf-dark-theme .rf-podium.rf-podium-on-light {
    --rf-podium-name-color: #fff;
    --rf-podium-stats-color: #cbd3d0;
    --rf-podium-trophy-shadow: 0 4px 8px rgba(0, 0, 0, 0.35);
}

/* Highlight a court (or the up-next strip) when a fresh match is announced.
   Pulsing gold border + glow draws the eye across the room. */
.rf-tv-flash {
    border-color: #ffc107 !important;
    animation: rf-tv-flash-anim 0.9s ease-in-out infinite;
}
@keyframes rf-tv-flash-anim {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.55); }
    50%      { box-shadow: 0 0 24px 8px rgba(255, 193, 7, 0.55); }
}

/* Fullscreen "Tap to enable announcements" overlay shown until the first
   click — required because browsers block TTS/Web Audio without a gesture. */
.rf-tv-unlock {
    position: fixed; inset: 0; z-index: 1080;
    background: rgba(0, 0, 0, 0.85);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
}

/* Full-screen announcement banner shown for ~8s when a match is assigned.
   Sits above the court grid; pointer-events:none so the page stays usable. */
.rf-tv-overlay {
    position: fixed; inset: 0; z-index: 1070;
    background: rgba(0, 0, 0, 0.78);
    color: #fff;
    display: flex; align-items: center; justify-content: center;
    pointer-events: none;
    animation: rf-tv-overlay-fade 0.3s ease-out;
}
@keyframes rf-tv-overlay-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}
.rf-tv-overlay-title {
    font-size: 5rem; font-weight: 900; color: #ffc107; line-height: 1.05;
    margin-top: 0.5rem;
}
.rf-tv-overlay-body {
    font-size: 2.4rem; font-weight: 600; margin-top: 1rem; max-width: 90vw;
}

/* ===== Club-logo watermark: see .rf-tv-panel.rf-tv-has-logo above ===== */

/* Preview tile on the Account page. */
.rf-logo-preview {
    width: 6.5rem; height: 6.5rem;
    border-radius: 0;
    border: 2px dashed rgba(95, 163, 30, 0.35);
    background: #f5f8f6;
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
}
.rf-logo-preview img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* Club picker tiles (public Results page). */
.rf-club-tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 1rem;
}
.rf-club-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 1rem 0.5rem;
    border: none;
    background: transparent;
    transition: transform 0.15s;
}
.rf-club-tile:hover, .rf-club-tile:focus-visible {
    transform: scale(1.05);
}
.rf-club-tile-logo {
    width: 5rem; height: 5rem;
    border-radius: 0;
    object-fit: contain;
    background: transparent;
}
.rf-club-tile-placeholder {
    display: flex; align-items: center; justify-content: center;
    border: 2px dashed rgba(95, 163, 30, 0.35);
    font-size: 2rem;
}
.rf-club-tile-placeholder .rf-icon { width: 2rem; height: 2rem; }
.rf-club-tile-name {
    font-weight: 600;
    text-align: center;
    font-size: 0.9rem;
    line-height: 1.2;
    color: #212529;
    /* Explicit background paired with the text color so the two are always
       inverted/kept together as one surface, not left to inherit whatever
       background happens to be behind a transparent tile. */
    background: #fff;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    box-shadow: var(--rf-shadow);
}

/* ===== Final-score entry (dashboard, shown once when ending a match) ===== */
.rf-score-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 0.4rem 0.5rem;
}
.rf-score-input {
    width: 4rem;
    text-align: center;
    font-size: 1.1rem;
    font-weight: 700;
    -moz-appearance: textfield;
}
.rf-score-input::-webkit-inner-spin-button,
.rf-score-input::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}
.rf-score-sep {
    font-weight: 700;
    color: #adb5bd;
    font-size: 1.3rem;
}

/* ===== Podium (top-3 winners) — reusable across TV / Results / Dashboard =====
   Defaults are tuned for the dark TV background; the .rf-podium-on-light
   modifier retunes text colors + shadows for light-mode cards. */
.rf-podium {
    --rf-podium-name-color: #fff;
    --rf-podium-stats-color: #cbd3d0;
    --rf-podium-trophy-shadow: 0 4px 8px rgba(0, 0, 0, 0.35);
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
    padding-top: 0.5rem;
}
.rf-podium.rf-podium-on-light {
    --rf-podium-name-color: var(--rf-ink);
    --rf-podium-stats-color: #6c757d;
    --rf-podium-trophy-shadow: 0 3px 6px rgba(15, 58, 30, 0.18);
}
.rf-podium-slot {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 9rem;
    flex: 0 1 12rem;
    text-align: center;
    animation: rf-podium-in 0.6s ease-out both;
}
@keyframes rf-podium-in {
    from { opacity: 0; transform: translateY(24px); }
    to   { opacity: 1; transform: translateY(0); }
}
.rf-podium-trophy {
    font-size: 3.2rem;
    line-height: 1;
    margin-bottom: 0.35rem;
    filter: drop-shadow(var(--rf-podium-trophy-shadow));
}
.rf-podium-name {
    font-size: 1.55rem;
    font-weight: 800;
    color: var(--rf-podium-name-color);
    max-width: 12rem;
    overflow-wrap: break-word;
    line-height: 1.1;
}
.rf-podium-stats {
    font-size: 0.9rem;
    color: var(--rf-podium-stats-color);
    margin: 0.25rem 0 0.5rem;
    font-weight: 500;
}
.rf-podium-step {
    width: 100%;
    max-width: 12rem;
    min-height: 3.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0;
    color: #0A1F10;
    font-size: 2.4rem;
    font-weight: 900;
    letter-spacing: 0.05em;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.35);
    box-shadow: 0 -4px 0 rgba(0, 0, 0, 0.25) inset,
                0 8px 22px rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(0, 0, 0, 0.15);
}
.rf-podium-step-gold {
    background: linear-gradient(180deg, #ffe680, #f2b400 55%, #b98700);
    height: 8rem;
}
.rf-podium-step-silver {
    background: linear-gradient(180deg, #f2f4f6, #b9c0c7 55%, #808891);
    height: 6rem;
}
.rf-podium-step-bronze {
    background: linear-gradient(180deg, #f0b479, #b8752b 55%, #7d4c15);
    height: 4.5rem;
    color: #1f150a;
}
/* Gold trophy gets a subtle sheen so the champion pops. */
.rf-podium-gold .rf-podium-trophy {
    animation: rf-podium-shine 2.4s ease-in-out infinite;
}
@keyframes rf-podium-shine {
    0%, 100% { transform: translateY(0)   scale(1);    filter: drop-shadow(0 4px 8px rgba(255, 193, 7, 0.5)); }
    50%      { transform: translateY(-4px) scale(1.06); filter: drop-shadow(0 8px 16px rgba(255, 193, 7, 0.75)); }
}

/* Same trophy emoji as gold, tinted via CSS filters so 2nd/3rd read as
   silver/bronze without needing a separate glyph (Unicode has no
   silver/bronze trophy variants). */
.rf-podium-silver .rf-podium-trophy {
    filter: grayscale(1) brightness(1.08) drop-shadow(0 4px 8px rgba(0, 0, 0, 0.35));
}
.rf-podium-bronze .rf-podium-trophy {
    filter: sepia(1) saturate(1.6) hue-rotate(-18deg) brightness(0.9) drop-shadow(0 4px 8px rgba(0, 0, 0, 0.35));
}

/* Rank 4+ list on the TV, styled to match the light card. */
.rf-tv-standings { display: flex; flex-direction: column; gap: 0.35rem; }
.rf-tv-standings-row {
    display: grid;
    grid-template-columns: 2.5rem 1fr auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.4rem 0.75rem;
    background: rgba(15, 58, 30, 0.04);
    border-radius: 0.6rem;
}
.rf-tv-standings-rank {
    font-size: 1.1rem; font-weight: 800; color: #6c757d; text-align: center;
}
.rf-tv-standings-name { font-size: 1.15rem; font-weight: 700; color: var(--rf-ink); }
.rf-tv-standings-stats { display: inline-flex; gap: 0.9rem; font-weight: 700; font-size: 1rem; }
.rf-tv-standings-winpct { color: #b5860a; }

/* Respect reduced motion for the podium animations too. */
@media (prefers-reduced-motion: reduce) {
    .rf-podium-slot,
    .rf-podium-gold .rf-podium-trophy { animation: none !important; }
}

/* ===== Admin dashboard ===== */
.stat-card { border-top: 4px solid var(--rf-green); text-align: center; border-radius: 0; }
.stat-value {
    font-size: 1.9rem; font-weight: 800; line-height: 1;
    background: linear-gradient(135deg, var(--rf-green-light), var(--rf-green-dark));
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent;
}

/* ===== Blazor error ===== */
.blazor-error-boundary {
    background: #b32121; padding: 1rem; color: white; border-radius: 0;
}
.blazor-error-boundary::after { content: "An error has occurred."; }
#blazor-error-ui { display: none; }

/* =====================================================================
   DARK THEME — applied to the admin pages and the home/landing page.
   MainLayout adds .rf-dark-theme to the .page wrapper for those routes;
   other public pages (join-queue, etc.) stay light.
   ===================================================================== */
.page.rf-dark-theme {
    --rf-dark-bg: #081409;
    --rf-dark-surface: #0F2416;
    --rf-dark-surface-2: #163020;
    --rf-dark-border: #1E3A28;
    --rf-dark-text: #e6ece9;
    --rf-dark-muted: #9fb0a8;

    color: var(--rf-dark-text);
    background:
        radial-gradient(1100px 480px at 100% -8%, rgba(142, 216, 79, 0.10), transparent 60%),
        radial-gradient(900px 460px at -8% 0%, rgba(95, 163, 30, 0.12), transparent 55%),
        var(--rf-dark-bg);
}

/* Surfaces */
.rf-dark-theme .card { background: var(--rf-dark-surface); color: var(--rf-dark-text); }
.rf-dark-theme .card-header,
.rf-dark-theme .bg-white,
.rf-dark-theme .bg-light { background: var(--rf-dark-surface-2) !important; color: var(--rf-dark-text); }
.rf-dark-theme .list-group-item { background: var(--rf-dark-surface); color: var(--rf-dark-text); border-color: var(--rf-dark-border); }
.rf-dark-theme .list-group-item:hover { background: var(--rf-dark-surface-2); }

/* Text + borders */
.rf-dark-theme .text-muted { color: var(--rf-dark-muted) !important; }
.rf-dark-theme .text-secondary { color: #aeb9b3 !important; }
.rf-dark-theme .border,
.rf-dark-theme .border-top,
.rf-dark-theme .border-bottom { border-color: var(--rf-dark-border) !important; }

/* Tables */
.rf-dark-theme .table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--rf-dark-text);
    color: var(--rf-dark-text);
    border-color: var(--rf-dark-border);
}
.rf-dark-theme .table > :not(caption) > * > * {
    background-color: transparent;
    color: var(--rf-dark-text);
    border-color: var(--rf-dark-border);
}
.rf-dark-theme .table-light,
.rf-dark-theme .table-light > th,
.rf-dark-theme .table-light > td,
.rf-dark-theme thead.table-light th {
    --bs-table-bg: var(--rf-dark-surface-2);
    background-color: var(--rf-dark-surface-2) !important;
    color: var(--rf-dark-muted) !important;
}
.rf-dark-theme .table-hover > tbody > tr:hover > * { background-color: rgba(255, 255, 255, 0.04); }

/* Forms */
.rf-dark-theme .form-control,
.rf-dark-theme .form-select {
    background-color: var(--rf-dark-surface-2);
    color: var(--rf-dark-text);
    border-color: var(--rf-dark-border);
}
.rf-dark-theme .form-control::placeholder { color: var(--rf-dark-muted); }
.rf-dark-theme .form-control:focus,
.rf-dark-theme .form-select:focus { background-color: var(--rf-dark-surface-2); color: var(--rf-dark-text); }
.rf-dark-theme .form-label,
.rf-dark-theme .form-check-label,
.rf-dark-theme .form-text { color: var(--rf-dark-text); }

/* Modal */
.rf-dark-theme .modal-content { background: var(--rf-dark-surface); color: var(--rf-dark-text); }
.rf-dark-theme .modal-header,
.rf-dark-theme .modal-footer { border-color: var(--rf-dark-border); }
.rf-dark-theme .btn-close { filter: invert(1) grayscale(1) brightness(1.6); }

/* Alerts */
.rf-dark-theme .alert-info { background: rgba(13, 202, 240, 0.12); color: #9eeaf9; border-color: rgba(13, 202, 240, 0.25); }
.rf-dark-theme .alert-danger { background: rgba(220, 53, 69, 0.15); color: #f1aeb5; border-color: rgba(220, 53, 69, 0.30); }

/* Court cards keep their accent stripe but adopt dark fills */
.rf-dark-theme .court-card-playing { background: linear-gradient(135deg, #2a2410, #0F2416); }
.rf-dark-theme .court-card-available { background: var(--rf-dark-surface); }

/* Zebra striping + dividers on dark */
.rf-dark-theme .player-row { border-bottom-color: var(--rf-dark-border); }
.rf-dark-theme .player-row:nth-child(even) { background: rgba(255, 255, 255, 0.04); }
.rf-dark-theme .player-row:hover { background: rgba(142, 216, 79, 0.12); }

/* Podium chips on dark */
.rf-dark-theme .rf-podium-badge { background: var(--rf-dark-surface-2); color: var(--rf-dark-text); border-color: var(--rf-dark-border); }
.rf-dark-theme .rf-wait-badge { background: var(--rf-dark-surface-2); color: var(--rf-dark-text); border-color: var(--rf-dark-border); }

/* Footer on dark */
.rf-dark-theme .rf-footer {
    background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.25));
    border-top-color: var(--rf-dark-border);
}
.rf-dark-theme .rf-footer .text-muted { color: var(--rf-dark-muted) !important; }
.rf-dark-theme .rf-footer-link { color: var(--rf-dark-muted); }
.rf-dark-theme .rf-footer-link:hover { color: var(--rf-green-light); }

/* =====================================================================
   INTERACTIVITY POLISH — added in the interactivity pass.
   ===================================================================== */

/* Landing-page background: two slow-drifting green auras + a very faint
   pickleball court watermark. Painted with pseudo-elements on .page itself
   so they layer above .page's own dark background but below its content.
   `isolation: isolate` keeps the negative z-index contained. */
.page.rf-hero-page {
    position: relative;
    isolation: isolate;
    overflow-x: hidden;
    color: #8ED84F;
}
.page.rf-hero-page::before {
    content: "";
    position: absolute;
    inset: -8%;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(720px 500px at 22% 30%, rgba(142, 216, 79, 0.20), transparent 60%),
        radial-gradient(640px 460px at 78% 70%, rgba(95, 163, 30, 0.22), transparent 55%);
    animation: rf-hero-drift 34s ease-in-out infinite alternate;
}
.page.rf-hero-page::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: min(1200px, 92vw);
    aspect-ratio: 440 / 200;
    transform: translate(-50%, -50%) rotate(-4deg);
    z-index: -1;
    pointer-events: none;
    background: url("/img/court.svg") center/contain no-repeat;
    opacity: 0.10;
    animation: rf-hero-court-drift 46s ease-in-out infinite alternate;
}
@keyframes rf-hero-drift {
    0%   { transform: translate3d(0, 0, 0)    scale(1); }
    50%  { transform: translate3d(-3%, 2%, 0) scale(1.06); }
    100% { transform: translate3d(2%, -1%, 0) scale(1.02); }
}
@keyframes rf-hero-court-drift {
    0%   { transform: translate(-50%, -50%) rotate(-4deg) scale(1); }
    100% { transform: translate(-50%, -52%) rotate(-2deg) scale(1.04); }
}

/* Keyboard users get the same lift as mouse hover. */
.btn:focus-visible { transform: translateY(-2px); box-shadow: var(--rf-shadow); outline: none; }

/* "Updated Ns ago" ticker + stale state. */
.rf-updated {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    color: #6c757d;
    transition: color 0.2s ease;
}
.rf-updated .rf-updated-dot {
    width: 0.4rem; height: 0.4rem; border-radius: 50%;
    background: var(--rf-green-light);
    box-shadow: 0 0 0 0 rgba(142, 216, 79, 0.6);
    animation: rf-updated-blink 2s ease-in-out infinite;
}
.rf-updated.rf-stale { color: #b45309; }
.rf-updated.rf-stale .rf-updated-dot { background: #f59e0b; animation: none; }
@keyframes rf-updated-blink {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.35; }
}

/* Queue position badge flashes briefly when the number changes. */
.rf-badge-flash { animation: rf-badge-flash-anim 0.9s ease-out; }
@keyframes rf-badge-flash-anim {
    0%   { transform: scale(1); box-shadow: 0 3px 8px rgba(95, 163, 30, 0.3); }
    30%  { transform: scale(1.25); box-shadow: 0 0 0 8px rgba(142, 216, 79, 0.35); }
    100% { transform: scale(1); box-shadow: 0 3px 8px rgba(95, 163, 30, 0.3); }
}

/* Court card flashes when a new match is assigned to it. Reuses the gold
   colour used on the TV so the phone view and TV feel like one system. */
.rf-court-flash { animation: rf-court-flash-anim 1.2s ease-out; }
@keyframes rf-court-flash-anim {
    0%   { box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.55); }
    40%  { box-shadow: 0 0 22px 6px rgba(255, 193, 7, 0.55); }
    100% { box-shadow: 0 0 0 0 rgba(255, 193, 7, 0); }
}

/* Stat cards briefly pop when their number changes. */
.rf-count-flash { animation: rf-count-flash-anim 0.7s ease-out; }
@keyframes rf-count-flash-anim {
    0%   { transform: scale(1); }
    40%  { transform: scale(1.18); filter: brightness(1.15); }
    100% { transform: scale(1); }
}

/* Auto-assign toggle's row briefly tints on flip. */
.rf-toggle-flip { animation: rf-toggle-flip-anim 0.6s ease-out; }
@keyframes rf-toggle-flip-anim {
    0%   { background: rgba(142, 216, 79, 0.0); }
    40%  { background: rgba(142, 216, 79, 0.18); }
    100% { background: rgba(142, 216, 79, 0.0); }
}

/* Home hero emoji bounces in on load, then a soft idle wobble. */
.rf-home-emoji { display: inline-block; animation: rf-home-emoji-in 0.7s ease-out both; transform-origin: 50% 80%; }
@keyframes rf-home-emoji-in {
    0%   { transform: scale(0.4) rotate(-15deg); opacity: 0; }
    60%  { transform: scale(1.15) rotate(6deg); opacity: 1; }
    100% { transform: scale(1) rotate(0deg); opacity: 1; }
}

/* Pickleball paddle+ball SVG used as the brand mark on the home hero and
   navbar. The hero variant is sized generously to match the display-4 heading;
   the nav variant is sized to the .fs-4 navbar-brand cap height. */
.rf-home-icon {
    width: 3.5rem;
    height: 3.5rem;
    vertical-align: -0.35em;
    margin-right: 0.25rem;
    filter: drop-shadow(0 4px 10px rgba(142, 216, 79, 0.35));
}
.rf-nav-icon {
    width: 1.75rem;
    height: 1.75rem;
    display: inline-block;
    filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
}

/* Same pickleball SVG used inline wherever a 🏓 emoji stand-in used to appear
   (headings, labels, banners). Sized to the surrounding text via 1em unless
   overridden inline for standalone/oversized use. */
.rf-icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.125em;
    display: inline-block;
}

/* Sortable table headers. */
.rf-sortable {
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.rf-sortable::after {
    content: "▾";
    margin-left: 0.25rem;
    color: #adb5bd;
    font-size: 0.7em;
}
.rf-sortable.rf-sort-asc::after  { content: "▴"; color: var(--rf-green); }
.rf-sortable.rf-sort-desc::after { content: "▾"; color: var(--rf-green); }
.rf-sortable:hover { color: var(--rf-green); }

/* Trend arrows in the standings — set from a data attribute in code. */
.rf-trend { display: inline-block; margin-left: 0.35rem; font-size: 0.8em; opacity: 0.9; }
.rf-trend.rf-trend-up   { color: var(--rf-green); }
.rf-trend.rf-trend-down { color: #dc3545; }

/* Making a whole card clickable via a wrapping anchor should feel like a card,
   not a link. Reset the anchor styling so the child .card fully owns the look. */
a.rf-card-link { display: block; color: inherit; text-decoration: none; }
a.rf-card-link:hover, a.rf-card-link:focus { color: inherit; text-decoration: none; }

/* Club-vs-player choice cards on the /register landing page. */
a.rf-choice-card { transition: transform 0.15s ease, box-shadow 0.15s ease; }
a.rf-choice-card:hover, a.rf-choice-card:focus { transform: translateY(-3px); box-shadow: 0 0.5rem 1rem rgba(0,0,0,0.1) !important; }

/* Respect the OS/user's motion preference: turn off decorative pulses and
   entrance animations while keeping structural transitions intact. */
@media (prefers-reduced-motion: reduce) {
    .rf-live,
    .rf-you-banner,
    .rf-tv-flash,
    .rf-court-flash,
    .rf-badge-flash,
    .rf-count-flash,
    .rf-toggle-flip,
    .rf-home-emoji,
    .rf-main,
    .rf-win-toast,
    .rf-updated .rf-updated-dot,
    .page.rf-hero-page::before,
    .page.rf-hero-page::after {
        animation: none !important;
    }
    .btn:hover, .btn:focus-visible { transform: none; }
    html { scroll-behavior: auto; }
}
