/* ═══════════════════════════════════════════════════════════════
   BRR SCCA Live Timing — Design System & Global Styles
   Agent #2 · Vanilla CSS · Mobile-First SPA
   
   THEME ARCHITECTURE:
   - High-Density layout optimized for on-field mobile usage.
   - Glassmorphism effects (backdrop-filter) for layered depth.
   - Dynamic Dark/Light mode tracking via [data-theme].
   ═══════════════════════════════════════════════════════════════ */

/* ── DESIGN TOKENS (Source of Truth) ─────────────────────────── 
   Change these values to update the global theme. 
   Avoid using hardcoded hex values in component blocks. 
*/
:root {
    /* Surfaces & Backgrounds */
    --bg-page:       #0d1117; /* Slate Black */
    --bg-card:       #161b22; /* Card Background */
    --bg-card-hover: #1c2330; /* Interactive hover state */
    --bg-header:     rgba(13, 17, 23, 0.88); /* Translucent Glass */
    --bg-pill:       #1c2330; /* Filter pill background */
    --bg-pill-hover: #21293a;
    --bg-input:      #1c2330;
    --bg-skeleton:   #1c2330;

    /* Typography */
    --text-primary:  #e6edf3;
    --text-secondary:#8b949e;
    --text-muted:    #586069;
    --text-inverse:  #0d1117;

    /* Borders & Outlines */
    --border:        #21262d;
    --border-focus:  #388bfd; /* SCCA Blue */

    /* Accent Palette */
    --accent-blue:   #388bfd;
    --accent-gold:   #d29922; /* FTD Highlight Gold */
    --accent-gold-lt:#e3b341;
    --accent-green:  #3fb950; /* Live Status Green */
    --accent-red:    #f85149; /* Error/Offline Red */
    --accent-purple: #a371f7;

    /* Leaderboard Rank Tints */
    --rank-1: #e3b341;
    --rank-2: #8b949e;
    --rank-3: #b87333;

    /* Effects & Shadows */
    --shadow-sm:  0 1px 3px rgba(0,0,0,.4);
    --shadow-md:  0 4px 12px rgba(0,0,0,.5);
    --shadow-lg:  0 12px 28px rgba(0,0,0,.6);
    --shadow-glow-gold: 0 0 16px rgba(210,153,34,.35);
    --shadow-glow-blue: 0 0 16px rgba(56,139,253,.35);

    /* Spacing & Radii */
    --r-sm:  6px;
    --r-md:  10px;
    --r-lg:  14px;
    --r-xl:  20px;
    --r-pill:99px;

    --gap-xs: .25rem;
    --gap-sm: .5rem;
    --gap-md: 1rem;
    --gap-lg: 1.5rem;
    --gap-xl: 2rem;

    /* Motion */
    --t-fast:  .15s ease;
    --t-base:  .25s ease;
    --t-slow:  .4s ease;

    /* Structural Constants */
    --header-h: 64px; /* Essential for sticky scroll-padding */
}

/* ── Light theme override ───────────────────────────────────── */
[data-theme="light"] {
    --bg-page:       #f6f8fa;
    --bg-card:       #ffffff;
    --bg-card-hover: #f0f2f5;
    --bg-header:     rgba(246,248,250,.92);
    --bg-pill:       #eaeef2;
    --bg-pill-hover: #dde1e6;
    --bg-input:      #ffffff;
    --bg-skeleton:   #eaeef2;

    --text-primary:  #24292f;
    --text-secondary:#57606a;
    --text-muted:    #8c959f;
    --text-inverse:  #f6f8fa;

    --border:        #d0d7de;
    --border-focus:  #0969da;

    --accent-blue:   #0969da;
    --accent-gold:   #9a6700;
    --accent-gold-lt:#bf8700;
    --accent-green:  #1a7f37;
    --accent-red:    #cf222e;
    --accent-purple: #8250df;

    --shadow-sm:  0 1px 3px rgba(0,0,0,.08);
    --shadow-md:  0 4px 12px rgba(0,0,0,.1);
    --shadow-lg:  0 12px 28px rgba(0,0,0,.12);
    --shadow-glow-gold: 0 0 16px rgba(154,103,0,.2);
    --shadow-glow-blue: 0 0 16px rgba(9,105,218,.2);
}

/* ── Reset ──────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
    font-family: 'Inter', system-ui, sans-serif;
    background: var(--bg-page);
    color: var(--text-primary);
    -webkit-font-smoothing: antialiased;
    line-height: 1.6;
    transition: background var(--t-base), color var(--t-base);
    min-height: 100dvh;
}

img, svg { display: block; max-width: 100%; }
button, input, select { font-family: inherit; }
ol, ul { list-style: none; }
a { color: var(--accent-blue); text-decoration: none; }

/* ── Utility ────────────────────────────────────────────────── */
.hidden   { display: none !important; }
.sr-only  { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; }
.muted-note { color: var(--text-muted); font-size: .875rem; padding: var(--gap-md) 0; }

.icon-gold   { color: var(--accent-gold); }
.icon-blue   { color: var(--accent-blue); }
.icon-green  { color: var(--accent-green); }
.icon-muted  { color: var(--text-muted); }

/* Icon buttons */
.icon-btn {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-secondary);
    border-radius: var(--r-pill);
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
    font-size: .9rem;
}
.icon-btn:hover { background: var(--bg-pill-hover); color: var(--text-primary); border-color: var(--accent-blue); }

/* Cross-page nav CTA — labeled pill that replaces the plain icon-btn links */
.nav-cta {
    display: flex;
    align-items: center;
    gap: var(--gap-xs);
    min-height: 40px;            /* touch target */
    padding: 0 var(--gap-md);
    border-radius: var(--r-pill);
    border: 1px solid transparent;
    font-family: inherit;
    font-size: .85rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast),
                border-color var(--t-fast);
}
.nav-cta i { font-size: .9rem; }

/* Primary (solid) — signals the brand-new Work page */
.nav-cta--primary {
    background: var(--accent-blue);
    color: var(--text-inverse);
    border-color: var(--accent-blue);
}
.nav-cta--primary:hover {
    background: color-mix(in srgb, var(--accent-blue) 88%, black);
}

/* Ghost (outlined) — quieter "return" action */
.nav-cta--ghost {
    background: none;
    color: var(--accent-blue);
    border-color: var(--border);
}
.nav-cta--ghost:hover {
    background: var(--bg-pill-hover);
    border-color: var(--accent-blue);
}

/* "New" badge — light-blue chip with blue text; stays in the blue family but
   contrasts against the solid blue pill behind it */
.nav-cta-badge {
    padding: .05rem .4rem;
    border-radius: var(--r-pill);
    background: color-mix(in srgb, var(--accent-blue) 22%, white);
    color: var(--accent-blue);
    font-size: .6rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
}

/* Collapse to a 40px icon-only square only on the smallest phones (<350px).
   Above this, the labeled CTA fits — the status chip moving to the event banner
   frees the header room. */
@media (max-width: 349px) {
    .nav-cta { padding: 0; width: 40px; justify-content: center; }
    .nav-cta-label,
    .nav-cta-badge { display: none; }
}

.text-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: .75rem;
    font-weight: 600;
    cursor: pointer;
    padding: .25rem .5rem;
    border-radius: var(--r-sm);
    transition: color var(--t-fast), background var(--t-fast);
    letter-spacing: .02em;
    text-transform: uppercase;
}
.text-btn:hover { color: var(--accent-red); background: rgba(248,81,73,.08); }

/* View-all link button (leaderboard panel headers) */
.view-all-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: .72rem;
    font-weight: 600;
    cursor: pointer;
    padding: .25rem .6rem;
    border-radius: var(--r-pill);
    transition: color var(--t-fast), background var(--t-fast);
    letter-spacing: .03em;
    text-transform: uppercase;
    display: flex;
    align-items: center;
    gap: .3rem;
    white-space: nowrap;
    font-family: inherit;
}
.view-all-btn i { font-size: .6rem; transition: transform var(--t-fast); }
.view-all-btn:hover { color: var(--accent-blue); background: var(--bg-pill); }
.view-all-btn:hover i { transform: translateX(2px); }


/* ═══════════════════════════════════════════════════════════════
   HEADER
   ═══════════════════════════════════════════════════════════════ */
.app-header {
    position: sticky;
    top: 0;
    z-index: 200;
    height: var(--header-h);
    background: var(--bg-header);
    backdrop-filter: blur(16px) saturate(180%);
    -webkit-backdrop-filter: blur(16px) saturate(180%);
    border-bottom: 1px solid var(--border);
    padding: 0 var(--gap-lg);
    display: flex;
    align-items: center;
    gap: var(--gap-md);
    transition: background var(--t-base), border-color var(--t-base);
}

.header-left  { display: flex; align-items: center; gap: var(--gap-sm); min-width: 0; flex-shrink: 0; }
.header-center{ flex: 1; min-width: 0; }
.header-right { display: flex; align-items: center; gap: var(--gap-sm); flex-shrink: 0; }

/* Logo — image + text */
.logo {
    display: flex;
    align-items: center;
    gap: .5rem;
    text-decoration: none;
    flex-shrink: 0;
}

.logo-img {
    height: 32px;
    width: auto;
    display: block;
    object-fit: contain;
    /* keep crisp on retina */
    image-rendering: -webkit-optimize-contrast;
    image-rendering: crisp-edges;
}

.logo-live {
    font-family: 'Outfit', sans-serif;
    font-weight: 700;
    font-size: 1.05rem;
    color: var(--text-primary);
    letter-spacing: .02em;
    white-space: nowrap;
}

/* Body search bar (used on index.html + work.html, moved out of the header) */
.page-search { margin-bottom: var(--gap-md); }
.page-search .search-wrapper { max-width: 560px; }
/* Bigger touch target than the header search — this is a primary action. */
.page-search #searchInput { padding: .7rem 2.6rem; font-size: .95rem; }
/* Hide the WebKit native ✕ on <input type="search"> — we ship our own #searchClear. */
.page-search input[type="search"]::-webkit-search-cancel-button,
.page-search input[type="search"]::-webkit-search-decoration {
    -webkit-appearance: none; appearance: none; display: none;
}

/* Search */
.search-wrapper {
    position: relative;
    max-width: 420px;
    margin: 0 auto;
}

.search-wrapper > i {
    position: absolute;
    left: .9rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-muted);
    font-size: .85rem;
    pointer-events: none;
}

#searchInput {
    width: 100%;
    padding: .55rem 2.4rem .55rem 2.5rem;
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    color: var(--text-primary);
    font-size: .875rem;
    outline: none;
    transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}
#searchInput::placeholder { color: var(--text-muted); }
#searchInput:focus {
    border-color: var(--border-focus);
    box-shadow: 0 0 0 3px rgba(56,139,253,.18);
    background: var(--bg-card);
}

.search-clear {
    position: absolute;
    right: .65rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    font-size: .8rem;
    padding: .2rem .4rem;
    border-radius: var(--r-sm);
    transition: color var(--t-fast);
}
.search-clear:hover { color: var(--text-primary); }

/* ── Autocomplete dropdown ─────────────────────────────────── */
.search-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 300;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    /* entrance animation */
    animation: dropdown-in .15s ease;
    max-height: 360px;
    overflow-y: auto;
    scrollbar-width: thin;
}
@keyframes dropdown-in {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

.search-dropdown-item {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    padding: .65rem var(--gap-md);
    cursor: pointer;
    transition: background var(--t-fast);
    border-bottom: 1px solid var(--border);
    text-align: left;
    width: 100%;
    background: none;
    border-left: none;
    border-right: none;
    border-top: none;
    color: var(--text-primary);
    font-family: inherit;
    font-size: .875rem;
}
.search-dropdown-item:last-child { border-bottom: none; }
.search-dropdown-item:hover,
.search-dropdown-item[aria-selected="true"] {
    background: var(--bg-card-hover);
}
.search-dropdown-item:focus {
    outline: 2px solid var(--border-focus);
    outline-offset: -2px;
    background: var(--bg-card-hover);
}

.sdi-icon {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--bg-page);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: .7rem;
    color: var(--text-muted);
}

.sdi-body { flex: 1; min-width: 0; }
.sdi-name {
    font-weight: 600;
    font-size: .875rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sdi-name mark {
    background: transparent;
    color: var(--accent-blue);
    font-weight: 800;
}
.sdi-meta {
    font-size: .72rem;
    color: var(--text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 1px;
}

.sdi-class-badge {
    flex-shrink: 0;
    font-size: .65rem;
    font-weight: 700;
    background: var(--bg-pill);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    padding: .15rem .5rem;
    color: var(--text-secondary);
    letter-spacing: .04em;
    text-transform: uppercase;
}

.search-dropdown-empty {
    padding: var(--gap-md) var(--gap-lg);
    color: var(--text-muted);
    font-size: .82rem;
    text-align: center;
}

/* Status chip */
.status-chip {
    display: flex;
    align-items: center;
    gap: .4rem;
    background: rgba(63,185,80,.12);
    border: 1px solid rgba(63,185,80,.3);
    color: var(--accent-green);
    border-radius: var(--r-pill);
    padding: .3rem .75rem;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    transition: all var(--t-base);
    white-space: nowrap;
}
.status-chip.offline {
    background: rgba(248,81,73,.12);
    border-color: rgba(248,81,73,.3);
    color: var(--accent-red);
}
/* Final/stale state — gray, no glow */
.status-chip.final {
    background: rgba(139,148,158,.12);
    border-color: rgba(139,148,158,.3);
    color: var(--text-secondary);
}

.status-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    animation: dot-pulse 2.5s ease infinite;
}
.status-chip.offline .status-dot,
.status-chip.final   .status-dot { animation: none; opacity: .5; }

@keyframes dot-pulse {
    0%, 100% { opacity: 1; box-shadow: 0 0 0 0 currentColor; }
    50%       { opacity: .7; box-shadow: 0 0 0 4px transparent; }
}

[hidden] { display: none !important; }


/* ═══════════════════════════════════════════════════════════════
   ERROR BANNER
   ═══════════════════════════════════════════════════════════════ */
.error-banner {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    background: rgba(248,81,73,.14);
    border-bottom: 1px solid rgba(248,81,73,.35);
    color: var(--accent-red);
    font-size: .82rem;
    font-weight: 600;
    padding: .65rem var(--gap-lg);
    animation: slide-down .25s ease;
}
@keyframes slide-down { from { transform: translateY(-100%); opacity: 0; } to { transform: none; opacity: 1; } }

.retry-countdown {
    margin-left: auto;
    font-size: .75rem;
    color: var(--text-muted);
    font-weight: 500;
}


/* ═══════════════════════════════════════════════════════════════
   MAIN LAYOUT
   ═══════════════════════════════════════════════════════════════ */
.app-container {
    max-width: 1280px;
    margin: 0 auto;
    padding: var(--gap-lg) var(--gap-lg) var(--gap-xl);
    display: flex;
    flex-direction: column;
    gap: var(--gap-xl);
}

/* Event banner — relocated from header into main body */
.event-banner {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: .75rem var(--gap-lg);
    font-size: .875rem;
    font-weight: 600;
    color: var(--text-primary);
    box-shadow: var(--shadow-sm);
    /* overflow:hidden removed — title span handles ellipsis; keeping it here
       would clip the status-dot glow when the chip sits at the right edge */
}
.event-banner > i {
    color: var(--accent-gold);
    flex-shrink: 0;
    font-size: .9rem;
}
.event-banner > span:first-of-type {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.event-banner-right {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .75rem;
    font-weight: 500;
    color: var(--text-muted);
    white-space: nowrap;
    flex-shrink: 0;
    margin-left: auto;
    padding-left: var(--gap-md);
}
.event-banner-right i { font-size: .7rem; }


/* ═══════════════════════════════════════════════════════════════
   PANEL (shared card container)
   ═══════════════════════════════════════════════════════════════ */
.panel {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--gap-md) var(--gap-lg);
    border-bottom: 1px solid var(--border);
}

.panel-title {
    font-size: 1rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: .5rem;
    letter-spacing: -.01em;
}


/* ═══════════════════════════════════════════════════════════════
   FAVORITES SECTION
   ═══════════════════════════════════════════════════════════════ */
#favoritesSection .cards-grid {
    padding: var(--gap-md) var(--gap-lg) var(--gap-lg);
}


/* ═══════════════════════════════════════════════════════════════
   LEADERBOARDS
   ═══════════════════════════════════════════════════════════════ */
.leaderboards-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: var(--gap-lg);
}

.leaderboard-panel { display: flex; flex-direction: column; }

.leaderboard-list {
    display: flex;
    flex-direction: column;
    padding: 2px var(--gap-sm);
    gap: 2px;
}


/* Leaderboard item */
.lb-item {
    display: flex;
    align-items: center;
    gap: var(--gap-md);
    padding: .45rem var(--gap-md);
    border-radius: var(--r-md);
    background: transparent;
    transition: background var(--t-fast), transform var(--t-fast);
    cursor: pointer;
}
.lb-item:hover { background: var(--bg-card-hover); }

/* Rank number */
.lb-rank {
    font-family: 'Outfit', sans-serif;
    font-weight: 800;
    font-size: 1rem;
    width: 24px;
    text-align: center;
    flex-shrink: 0;
    color: var(--text-muted);
}
.lb-item:nth-child(1) .lb-rank { color: var(--rank-1); }
.lb-item:nth-child(2) .lb-rank { color: var(--rank-2); }
.lb-item:nth-child(3) .lb-rank { color: var(--rank-3); }

/* Driver info in lb */
.lb-info { flex: 1; min-width: 0; }
.lb-name  { font-size: .85rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lb-meta  { font-size: .72rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 1px; }


/* Time chip */
.lb-time {
    font-family: 'Outfit', sans-serif;
    font-size: .95rem;
    font-weight: 800;
    color: var(--accent-blue);

    flex-shrink: 0;
    letter-spacing: -.01em;
}
.leaderboard-list .lb-item:nth-child(1) .lb-time { color: var(--rank-1); }

/* Skeleton rows */
.lb-skeleton {
    height: 52px;
    border-radius: var(--r-md);
    background: var(--bg-skeleton);
    animation: shimmer 1.6s linear infinite;
    background-size: 400% 100%;
    background-image: linear-gradient(90deg,
        var(--bg-skeleton) 0%,
        var(--bg-card-hover) 40%,
        var(--bg-skeleton) 80%
    );
}
@keyframes shimmer { to { background-position: -400% 0; } }

/* No-data state */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap-sm);
    padding: var(--gap-xl);
    color: var(--text-muted);
    font-size: .88rem;
    text-align: center;
}
.empty-state i { font-size: 1.8rem; opacity: .4; }

/* ── Phase 5.2: Empty class styles ─────────────────────────── */

/* Disabled pill for a class that has no drivers yet.
   pointer-events: none prevents clicking so the active state is never applied.
   This is set by JS when the backend reports an empty [] for that class. */
.pill--empty {
    opacity: 0.38;
    cursor: not-allowed;
    pointer-events: none;
}

/* Wraps an entire class block when it has no drivers.
   Reduces visual weight so populated classes stand out more clearly. */
.class-block--empty {
    opacity: 0.45;
}

/* Muted icon color inside an empty class heading */
.class-block--empty .class-heading {
    color: var(--text-muted);
}

/* "No entries" badge — dashed border + italic text signals this is a placeholder,
   not a real driver count. Mirrors .driver-count layout but uses a dashed border. */
.driver-count--empty {
    font-size: .72rem;
    font-weight: 500;
    color: var(--text-muted);
    background: transparent;
    border: 1px dashed var(--border);
    border-radius: var(--r-pill);
    padding: .1rem .55rem;
    margin-left: auto;
    font-style: italic;
}

/* ═══════════════════════════════════════════════════════════════
   HUB FILTER BAR
   ═══════════════════════════════════════════════════════════════ */
.hub-panel { 
    display: flex; 
    flex-direction: column; 
    overflow: visible; /* Must be visible for position: sticky to work on child */
}

.hub-filter-bar {
    position: sticky;
    top: var(--header-h);
    z-index: 100;
    background: var(--bg-card);
    border-top-left-radius: var(--r-lg);
    border-top-right-radius: var(--r-lg);
    border-bottom: 1px solid var(--border);
    padding: 0 var(--gap-md) var(--gap-sm) var(--gap-md); /* Consistent side margins */
    display: flex;
    flex-direction: column;
    gap: 0;
    transition: background var(--t-base);
}

.filter-row {
    display: flex;
    gap: var(--gap-xs);
    overflow-x: auto;
    padding-bottom: 2px;          /* room for scrollbar */
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}
/* Ensure elements with the 'hidden' attribute aren't forced visible by flexbox */
.filter-row[hidden] {
    display: none !important;
}
.filter-row::-webkit-scrollbar { height: 3px; }
.filter-row::-webkit-scrollbar-thumb { background: var(--border); border-radius: 99px; }

/* Row 1 (categories): wrap onto multiple lines so all categories are always visible.
   No horizontal scroll — users should see the full SCCA class map at a glance. */
.category-row {
    flex-wrap: wrap;
    overflow-x: visible;
    padding-top: var(--gap-md); /* Consistent 16px gap from the panel top */
    padding-bottom: 0.25rem;
}

.category-row .pill {
    flex-shrink: 1;
    margin-bottom: 0.4rem; /* Vertical gap when wrapped */
}

/* Row 2 (classes): also wrap onto multiple lines. This clarifies the total depth
   of the selected category and eliminates all horizontal scrolling. */
.class-row {
    flex-wrap: wrap !important;
    overflow-x: visible !important;
    padding-top: 0.25rem;
    padding-bottom: 0.5rem;
    border-top: 1px dashed var(--border); /* Subtly separate the two filter rows */
    margin-top: 0.25rem;
}

/* Pills — Shared base styles */
.pill {
    flex-shrink: 1;
    padding: .4rem 1rem;
    border-radius: var(--r-pill);
    border: 1px solid var(--border);
    background: var(--bg-pill);
    color: var(--text-secondary);
    font-size: .78rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    letter-spacing: .02em;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast), box-shadow var(--t-fast);
    -webkit-tap-highlight-color: transparent;
    user-select: none;
    margin-bottom: 0.4rem; /* Vertical gap when wrapped */
}
.pill:hover { background: var(--bg-pill-hover); color: var(--text-primary); border-color: var(--text-muted); }

/* Category Pills — Primary Hierarchy */
.cat-pill { 
    font-size: .8rem; 
    padding: .45rem 1.15rem; 
}
.cat-pill.active {
    background: var(--accent-blue);
    color: #fff;
    border-color: var(--accent-blue);
    box-shadow: 0 0 0 3px rgba(56,139,253,.22);
}

/* Class Pills — Secondary Hierarchy (Tags) */
.cls-pill {
    font-size: .72rem;
    padding: .32rem .85rem;
    border-radius: 6px; /* Slightly different shape for classes (more "tag" like) */
    font-weight: 500;
}
/* Use more specific selectors to ensure neutral gray overrides the base blue */
.pill.cls-pill.active {
    background: #4b5563 !important; /* Neutral / Indigo Gray */
    color: #fff !important;
    border-color: #4b5563 !important;
    box-shadow: 0 0 0 3px rgba(75, 85, 99, 0.15) !important;
}

/* Empty classes (no entries) */
.pill--empty {
    opacity: 0.4;
    pointer-events: none;
    border-style: dashed;
}


/* ═══════════════════════════════════════════════════════════════
   CLASSES CONTAINER & DRIVER CARDS
   ═══════════════════════════════════════════════════════════════ */
.classes-container {
    padding: var(--gap-lg);
    display: flex;
    flex-direction: column;
    gap: var(--gap-xl);
    scroll-margin-top: calc(var(--header-h) + 140px); /* Avoid sticky overlap */
}

/* Category block */
.category-block { display: flex; flex-direction: column; gap: var(--gap-lg); }
.category-heading {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-muted);
    padding-bottom: var(--gap-sm);
    border-bottom: 1px solid var(--border);
}

/* Class block */
.class-block { 
    display: flex; 
    flex-direction: column; 
    gap: var(--gap-md); 
    scroll-margin-top: calc(var(--header-h) + 140px);
}
.class-heading {
    display: flex;
    align-items: center;
    gap: .5rem;
    font-size: .9rem;
    font-weight: 700;
    color: var(--accent-blue);
    letter-spacing: -.01em;
}
.class-heading .driver-count {
    font-size: .72rem;
    font-weight: 500;
    color: var(--text-muted);
    background: var(--bg-pill);
    border: 1px solid var(--border);
    border-radius: var(--r-pill);
    padding: .1rem .55rem;
    margin-left: auto;
}

/* Cards grid.
   min(100%, 280px) inside minmax prevents overflow on very narrow screens:
   — above 280px available: behaves as normal auto-fill (2+ columns)
   — below 280px available: card shrinks to 100% width instead of forcing
     a hard 280px minimum that would cause horizontal scrolling/overflow. */
.cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
    gap: var(--gap-md);
}


/* ── Driver card ─────────────────────────────────────────────── */
.driver-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--gap-md);
    display: flex;
    flex-direction: column;
    gap: var(--gap-sm);
    position: relative;
    transition: box-shadow var(--t-base), border-color var(--t-base), transform var(--t-fast);
    will-change: transform;
    scroll-margin-top: calc(var(--header-h) + 160px);
}
.driver-card:hover {
    box-shadow: var(--shadow-md);
    border-color: var(--text-muted);
    transform: translateY(-2px);
}

/* Card header row */
.card-header {
    display: flex;
    align-items: flex-start;
    gap: var(--gap-sm);
}

.card-pos {
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--bg-page);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Outfit', sans-serif;
    font-weight: 800;
    font-size: .85rem;
    color: var(--text-secondary);
    transition: background var(--t-base), border-color var(--t-base), color var(--t-base);
}

/* Top 1 in class gets gold position badge */
.driver-card[data-pos="1"] .card-pos {
    background: linear-gradient(135deg, #e3b341, #b8860b);
    border-color: #b8860b;
    color: #fff;
}

.card-info { flex: 1; min-width: 0; }
.card-name {
    font-size: .95rem;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.3;
    display: flex;
    align-items: center;
    gap: .4rem;
    flex-wrap: wrap;
}
.card-meta {
    font-size: .72rem;
    color: var(--text-muted);
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.car-num { font-weight: 600; color: var(--text-secondary); margin-right: .25rem; }

/* Favorite button — min ~44px touch target (mobile-first) */
.fav-btn {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1rem;
    cursor: pointer;
    padding: .35rem;
    min-width: 44px;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--r-sm);
    transition: color var(--t-fast), transform var(--t-fast);
    line-height: 1;
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}
.fav-btn:hover,
.fav-btn.is-active { color: var(--accent-gold); transform: scale(1.15); }
.fav-btn.is-active i::before { content: "\f005"; /* fa-star solid */ }

/* Runs strip */
.runs-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
    align-items: center;
}
.run-chip {
    font-size: .68rem;
    font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
    background: var(--bg-page);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    padding: .1rem .4rem;
    color: var(--text-secondary);
    line-height: 1.4;
    transition: background var(--t-fast);
}
.run-chip.is-dnf  { color: var(--accent-red);    border-color: rgba(248,81,73,.3);   background: rgba(248,81,73,.08); }
.run-chip.is-best { color: var(--accent-green);   border-color: rgba(63,185,80,.35);  background: rgba(63,185,80,.1); font-weight: 700; }
.run-chip.is-rrn  { color: var(--text-muted);     font-style: italic; }

/* ── Card body: runs + best time side-by-side ─────────────────
   Horizontal flex container. The runs-strip wraps freely on the
   left (it has flex-wrap: wrap). The best-time-block is pushed
   to the right via space-between and never wraps because it has
   flex-shrink: 0. align-items: stretch gives the block the same
   height as the tallest row of run chips.
   ─────────────────────────────────────────────────────────── */
.card-body {
    display: flex;
    justify-content: space-between;
    align-items: stretch;
    gap: var(--gap-sm);
    margin-top: var(--gap-xs);
}

/* Penalty span — red inline text within a run chip.
   Only the cone count "(1)" turns red; the time digits
   next to it keep the normal chip color. */
.run-chip .penalty {
    color: var(--accent-red);
    font-weight: 700;
}

/* Best time block — right-anchored, never wraps */
.best-time-block {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    flex-shrink: 0;  /* Never shrinks — stays locked to the right edge */
    padding: .3rem .5rem;
    border-radius: var(--r-sm);
    border: 1px solid transparent;
    transition: background var(--t-base), border-color var(--t-base);
}

/* ── Thematic hierarchy on best-time-block ───────────────────
   .is-class-leader  = position 1 in class  → green tint
   .is-overall-leader = Top PAX or FTD      → gold tint (wins)
   ─────────────────────────────────────────────────────────── */
.best-time-block.is-class-leader {
    background: rgba(63, 185, 80, 0.10);
    border-color: rgba(63, 185, 80, 0.30);
}
[data-theme="light"] .best-time-block.is-class-leader {
    background: rgba(26, 127, 55, 0.08);
    border-color: rgba(26, 127, 55, 0.25);
}

.best-time-block.is-overall-leader {
    background: rgba(210, 153, 34, 0.15);
    border-color: rgba(210, 153, 34, 0.35);
    box-shadow: var(--shadow-glow-gold);
}
[data-theme="light"] .best-time-block.is-overall-leader {
    background: rgba(154, 103, 0, 0.08);
    border-color: rgba(154, 103, 0, 0.30);
}

.best-time-label { font-size: .65rem; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); font-weight: 600; }
.best-time-value {
    font-family: 'Outfit', sans-serif;
    font-size: 1.3rem;
    font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -.02em;
    line-height: 1.15;
}
.best-time-row {
    display: flex;
    align-items: baseline;
    gap: .35rem;
}
.best-time-diff {
    font-size: .72rem;
    color: var(--accent-red);
    font-weight: 600;
}

/* ── Micro-responsive shrink for the best-time-block ──────────
   On very narrow phones (≤ 400px), aggressively reduce font
   sizes and padding inside the block so it never wraps below
   the runs strip. flex-shrink: 0 is inherited and enforced.
   ─────────────────────────────────────────────────────────── */
@media (max-width: 400px) {
    .best-time-block {
        padding: .2rem .35rem;
    }
    .best-time-label {
        font-size: .55rem;
    }
    .best-time-value {
        font-size: 1rem;
    }
    .best-time-diff {
        font-size: .62rem;
    }
}

/* ── Compact card (OVERALL PAX / RAW scoreboard view) ───────── */
.driver-card.compact-card {
    padding: var(--gap-sm) var(--gap-md);
    gap: .35rem;
}
.driver-card.compact-card .card-header    { gap: var(--gap-sm); }
.driver-card.compact-card .card-pos       { font-size: .9rem; width: 22px; height: 22px; }
.driver-card.compact-card .card-name      { font-size: .82rem; }
.driver-card.compact-card .card-meta      { font-size: .67rem; }
.driver-card.compact-card .runs-strip     { gap: 3px; flex-wrap: nowrap; overflow-x: auto; min-width: 0; }
.driver-card.compact-card .run-chip       { font-size: .65rem; padding: .1rem .35rem; }
.driver-card.compact-card .best-time-value{ font-size: 1.05rem; }
.driver-card.compact-card .best-time-label{ font-size: .6rem; }
.driver-card.compact-card .fav-btn        { font-size: .75rem; }


/* Overall scoreboard section heading */
.overall-scoreboard-heading {
    display: flex;
    align-items: center;
    gap: var(--gap-sm);
    font-family: 'Outfit', sans-serif;
    font-size: 1rem;
    font-weight: 800;
    color: var(--text-primary);
    letter-spacing: -.01em;
    margin-bottom: var(--gap-sm);
}
.overall-scoreboard-heading i { font-size: .9rem; }
.overall-scoreboard-heading .osh-type {
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: .15rem .55rem;
    border-radius: var(--r-pill);
    border: 1px solid var(--border);
    background: var(--bg-pill);
    color: var(--text-secondary);
    margin-left: auto;
}


/* ── Gold highlight (Top PAX + Top RAW) ─────────────────────── */
.driver-card.is-gold-pax,
.driver-card.is-gold-raw {
    border-color: var(--accent-gold);
    box-shadow: var(--shadow-glow-gold);
    background: linear-gradient(160deg, var(--bg-card) 80%, rgba(210,153,34,.06) 100%);
}
.driver-card.is-gold-pax:hover,
.driver-card.is-gold-raw:hover {
    box-shadow: var(--shadow-glow-gold), var(--shadow-md);
}

/* ── Favorite card style ────────────────────────────────────── */
.driver-card.is-favorite {
    border-color: var(--accent-gold);
    box-shadow: 0 0 0 1px var(--accent-gold);
}

/* ── Pulse animation (live update) ─────────────────────────── */
@keyframes pulse-update {
    0%   { box-shadow: 0 0 0 0 rgba(63,185,80,.55), var(--shadow-sm); border-color: var(--accent-green); }
    40%  { box-shadow: 0 0 0 8px rgba(63,185,80,.0), var(--shadow-md); border-color: var(--accent-green); }
    100% { box-shadow: var(--shadow-sm); border-color: var(--border); }
}
.driver-card.pulse-update {
    animation: pulse-update 2.8s ease-out forwards;
}

/* ── Status badges ──────────────────────────────────────────── */
.badge {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    font-size: .62rem;
    font-weight: 800;
    letter-spacing: .06em;
    text-transform: uppercase;
    border-radius: var(--r-sm);
    padding: .15rem .45rem;
    line-height: 1.3;
    vertical-align: middle;
    flex-shrink: 0;
}
.badge-pax {
    background: rgba(210,153,34,.18);
    color: var(--accent-gold-lt);
    border: 1px solid rgba(210,153,34,.4);
}
.badge-ftd {
    background: rgba(56,139,253,.15);
    color: var(--accent-blue);
    border: 1px solid rgba(56,139,253,.35);
}

[data-theme="light"] .badge-pax {
    background: rgba(154,103,0,.1);
    color: var(--accent-gold);
    border-color: rgba(154,103,0,.3);
}
[data-theme="light"] .badge-ftd {
    background: rgba(9,105,218,.1);
    color: var(--accent-blue);
    border-color: rgba(9,105,218,.3);
}


/* ═══════════════════════════════════════════════════════════════
   LOADING STATE
   ═══════════════════════════════════════════════════════════════ */
.loading-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--gap-md);
    min-height: 200px;
    color: var(--text-muted);
    font-size: .875rem;
    padding: var(--gap-xl);
}

.spinner {
    width: 28px;
    height: 28px;
    border: 3px solid var(--border);
    border-top-color: var(--accent-blue);
    border-radius: 50%;
    animation: spin .8s linear infinite;
    flex-shrink: 0;
}
@keyframes spin { to { transform: rotate(360deg); } }


/* ═══════════════════════════════════════════════════════════════
   SCHEDULE PANEL
   ═══════════════════════════════════════════════════════════════ */
.schedule-panel { padding-bottom: var(--gap-lg); }
.schedule-panel .muted-note { padding: var(--gap-md) var(--gap-lg) 0; }


/* ═══════════════════════════════════════════════════════════════
   FOOTER
   ═══════════════════════════════════════════════════════════════ */
.app-footer {
    border-top: 1px solid var(--border);
    padding: var(--gap-lg) var(--gap-lg) calc(var(--gap-xl) + env(safe-area-inset-bottom, 0px));
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--gap-sm);
    text-align: center;
}
.footer-disclaimer {
    font-size: .72rem;
    color: var(--text-muted);
    max-width: 500px;
    line-height: 1.5;
}
.footer-branding {
    font-size: .72rem;
    color: var(--text-muted);
    display: flex;
    align-items: center;
    gap: .4rem;
}
.footer-branding strong { color: var(--text-secondary); }
.separator { opacity: .4; }


/* ═══════════════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 720px) {
    /* Ensure the sticky offset variable perfectly matches the single-row physical header height */
    :root { --header-h: 64px; } 

    .app-header {
        height: var(--header-h); /* Force physical height to prevent gap */
        padding: var(--gap-sm) var(--gap-md);
        gap: var(--gap-xs);
        align-items: center;
    }
    .header-left  { gap: var(--gap-sm); }
    .logo-live    { display: none; } /* show only logo image on small screens */
    
    /* Ensure search bar fits tightly on a single row */
    .header-center { 
        flex: 1; 
        min-width: 0; 
    }

    .search-wrapper { max-width: 100%; }
    /* Dropdown should still fit on mobile */
    .search-dropdown { max-height: 280px; }

    /* Event banner compact */
    .event-banner { padding: .6rem var(--gap-md); font-size: .8rem; }
    .event-banner-right { display: none; }  /* hide updated time on mobile (save space) */

    html { scroll-padding-top: 360px; } /* Increased threshold for anchor links on mobile */

    .app-container { padding: var(--gap-md); gap: var(--gap-lg); }
    .classes-container { 
        padding: var(--gap-md); /* Removed excessive 320px padding that created the whitespace gap */
        gap: var(--gap-lg); 
        scroll-margin-top: 360px !important; 
    }
    .cards-grid { grid-template-columns: 1fr; }
    .panel-header { padding: var(--gap-sm) var(--gap-md); }
    .hub-filter-bar { top: var(--header-h); }

    /* Content offsets for sticky hub */
    .class-block, .driver-card {
        scroll-margin-top: 360px !important;
    }
}

@media (max-width: 480px) {
    .leaderboards-row { grid-template-columns: 1fr; }
    .logo-img  { height: 26px; }
    .logo-live { font-size: .9rem; }
}

/* ── Live feed: progressive column hiding as viewport narrows ─────
   Hide order (least → most important):
     1. Timestamp  (≤ 680px) — takes the most horizontal space
     2. Run number (≤ 520px) — "R5" is contextual; hide before car/class truncates
     3. Driver name (≤ 380px) — last resort; only on very small phones

   Breakpoints are intentionally generous (wider than minimum needed)
   so columns disappear well before adjacent content starts truncating.

   Each breakpoint ALSO redeclares grid-template-columns to remove
   the hidden column's track. Without this, display:none on the cell
   still leaves an empty column gap in the grid.
   ─────────────────────────────────────────────────────────────── */

/* 1. Hide timestamp — 4 cols: name + car/class + run# + time */
@media (max-width: 560px) {
    .live-feed-row {
        grid-template-columns:
            1fr      /* driver name */
            5.5rem   /* car/class */
            2.5rem   /* run# */
            1fr;     /* time — right-aligned via .feed-time-cell */
    }
    .feed-timestamp { display: none; }
}

/* 2. Also hide run# — 3 cols: name + car/class + time */
@media (max-width: 400px) {
    .live-feed-row {
        grid-template-columns:
            1fr      /* driver name */
            5.5rem   /* car/class */
            1fr;     /* time — right-aligned via .feed-time-cell */
    }
    .feed-run { display: none; }
}

/* 3. Also hide driver name — 2 cols: car/class + time (last resort) */
@media (max-width: 320px) {
    .live-feed-row {
        grid-template-columns:
            5.5rem   /* car/class */
            1fr;     /* time */
    }
    .feed-driver { display: none; }
}




/* ── Reduced-motion ─────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}


/* ═══════════════════════════════════════════════════════════════
   LIVE RUN FEED
   A compact widget rendered above leaderboards showing the 5
   most recent Pronto run ticker entries. Polled every 5 s by
   fetchFeed() in app.js, completely independent of the main
   20-second data poll loop.
   ═══════════════════════════════════════════════════════════════ */

/* The "last polled" age label in the panel header — right-aligned */
.live-feed-age {
    font-size: .68rem;
    color: var(--text-muted);
    font-weight: 500;
    letter-spacing: .02em;
    margin-left: auto;
}

/* Ordered list — reset browser defaults */
.live-feed-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* ── Each row: 5-column CSS Grid ─────────────────────────────────
   IMPORTANT: width:100% on the row is required so that the grid
   container spans the full panel width. Without it, 1fr has no
   free space to fill and all columns collapse to min-content,
   which produces the equal-gaps-between-items look.

   Fixed rem widths for cols 1/3/4/5 pin those column LEFT EDGES
   at exactly the same horizontal position on every row, regardless
   of how long or short the content in that cell is.
   Col 2 (name) gets the remaining space via 1fr.
   ─────────────────────────────────────────────────────────────── */
.live-feed-row {
    display: grid;
    width: 100%;
    box-sizing: border-box;
    grid-template-columns:
        10rem    /* col 1: timestamp — fits "MM/DD/YYYY HH:MM:SS" */
        1fr      /* col 2: driver name — fills remaining space, truncates */
        5.5rem   /* col 3: car number + class code, e.g. "286 DS" */
        2.5rem   /* col 4: run number, e.g. "R5" */
        1fr;     /* col 5: time — fills remaining space; content right-aligned */
    align-items: center;
    column-gap: var(--gap-sm);
    padding: .5rem var(--gap-md);
    border-top: 1px solid var(--border);
    transition: background var(--t-fast);
    /* Required for the flash-entry animation to paint behind the cells */
    position: relative;
    overflow: hidden;
    /* All text inherits the theme-aware primary color by default */
    color: var(--text-primary);
}
.live-feed-row:first-child { border-top: none; }
.live-feed-row:hover { background: var(--bg-card-hover); }


/* ── Column cell styles ──────────────────────────────────────── */

/* Col 1 — Timestamp (small, muted) */
.feed-timestamp {
    font-size: .6rem;
    color: var(--text-muted);
    font-weight: 500;
    letter-spacing: .03em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Col 2 — Driver name (prominent).
   min-width: 0 is essential inside a 1fr grid cell — without it
   the cell's min-size is its content size and text-overflow won't
   kick in, breaking the fixed-column approach for long names. */
.feed-driver {
    font-size: .82rem;
    font-weight: 600;
    /* color inherits var(--text-primary) from .live-feed-row */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* Col 3 — Car number + Class code (matches driver name color) */
.feed-class {
    font-size: .72rem;
    font-weight: 700;
    color: inherit;
    letter-spacing: .03em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Col 4 — Run number (muted). Hidden on narrow screens via media query below. */
.feed-run {
    font-size: .65rem;
    color: var(--text-muted);
    white-space: nowrap;
    text-align: left;
}

/* Col 5 — Time + optional penalty inline.
   justify-content: flex-end pushes the number to the right edge of
   its 1fr column — standard score/leaderboard convention, and
   eliminates dead whitespace on the right side of the widget. */
.feed-time-cell {
    display: flex;
    align-items: baseline;
    gap: .25rem;
    justify-content: flex-end;
    white-space: nowrap;
}

/* The raw time number */
.feed-time {
    font-family: 'Outfit', sans-serif;
    font-size: .95rem;
    font-weight: 800;
    /* Default: var(--text-primary). JS adds .is-best to flip to green. */
    color: inherit;
    letter-spacing: -.02em;
}

/* Best-run highlight — JS adds this class when the time matches the
   driver's overall best in apiData.categories */
.feed-time.is-best {
    color: var(--accent-green);
}

/* Penalty badge (+1, +2 …) — red, slightly smaller than the time */
.feed-penalty {
    font-size: .72rem;
    font-weight: 700;
    color: var(--accent-red);
}

/* ── Flash-entry animation ───────────────────────────────────────
   Applied to any .live-feed-row whose timestamp was not in
   seenTimestamps on the previous poll cycle.
   Gold burst → subtle blue → transparent over 2.5 s.
   ─────────────────────────────────────────────────────────────── */
@keyframes feed-flash {
    0%   { background-color: rgba(210, 153, 34, 0.35); }
    60%  { background-color: rgba(56, 139, 253, 0.15); }
    100% { background-color: transparent; }
}

.live-feed-row.flash-entry {
    animation: feed-flash 2.5s ease-out forwards;
}

