.table-scroll-container {
    max-height: 500px;
    overflow-y: auto;
    position: relative;
}

.table-scroll-container thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background-color: var(--surface-raised);
    color: var(--text);
}

/* Header labels ("Sector 1", "Car #", etc.) are short but were still wrapping mid-word on narrow
   mobile viewports where a table's columns get squeezed -- the horizontal-scroll container these
   tables already sit in exists precisely so columns don't have to shrink that far; let them scroll
   instead of wrapping. */
.table-responsive thead th {
    white-space: nowrap;
}

@media (max-width: 768px) {
    .table-scroll-container {
        max-height: 350px;
    }

    h1 { font-size: var(--fs-h1); }
    h2 { font-size: var(--fs-h2); }
    h3 { font-size: var(--fs-h3); }
    h4 { font-size: var(--fs-h4); }
    h5 { font-size: var(--fs-h5); }
    h6 { font-size: var(--fs-h6); }

    .content {
        padding-top: var(--space-2);
    }
}

@media (max-width: 576px) {
    .btn-group-sm > .btn {
        padding: 0.25rem 0.4rem;
        font-size: 0.75rem;
    }

    .table td, .table th {
        padding: 0.5rem 0.3rem;
        font-size: 0.85rem;
    }

    .start-line-countdown-value {
        font-size: 3rem;
    }
}

/* Start Line's launch countdown -- the only thing on that page the flag pill in the top bar
   doesn't already show, so it gets to be the one big, unmissable number on the page instead of a
   plain <h1>. Uses the same green as the green flag since it only ever shows while hot. */
.start-line-countdown-label {
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.9rem;
    font-weight: 600;
}

.start-line-countdown-value {
    font-size: 4.5rem;
    font-weight: 700;
    line-height: 1;
    color: var(--status-success);
}

/* Start Line's GO / WAIT signal for an event that launches when the car ahead crosses a marker. */
.launch-signal-value {
    font-size: 4.5rem;
    font-weight: 700;
    line-height: 1;
}

.launch-signal-go .launch-signal-value,
.launch-signal-car-ahead-dnf .launch-signal-value {
    color: var(--status-success);
}

.launch-signal-waiting-for-marker .launch-signal-value,
.launch-signal-waiting-for-gap .launch-signal-value {
    color: var(--status-warning);
}

.launch-signal-held .launch-signal-value {
    color: var(--text-muted);
}

.launch-signal-reason {
    color: var(--text-muted);
    font-size: 1rem;
}

/* The launch block (countdown, GO/WAIT/HELD signal) sits in its own row directly above the flag buttons' row. Without this its
   last line, in the WAIT state the reason text, touches the first flag button. */
.start-line-countdown,
.launch-signal {
    margin-bottom: var(--space-3);
}

@keyframes track-status-pulse {
    0% { opacity: 0.75; }
    50% { opacity: 1; }
    100% { opacity: 0.75; }
}

/* ===== Live Timing overview cards (LAPS COMPLETED/CARS ON LEAD LAP or ON TRACK/FINISHED, plus
   FASTEST/TOP SPEED) at the top of the busiest live pages -- RaceControl and the public
   Competitors page, rendered by LiveTimingCards.razor. Reuses data already on the page, no new
   fetches. */
.live-timing-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: var(--space-2);
}

.live-timing-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0.5rem;
    padding: 0.6rem var(--space-3);
    text-align: center;
}

.live-timing-card-clickable {
    color: inherit;
    cursor: pointer;
    font: inherit;
}

.live-timing-card-clickable:hover,
.live-timing-card-clickable:focus-visible {
    border-color: var(--accent);
}

/* Bootstrap 5.1 hides .offcanvas until its JS shows it; the drawer is toggled by Blazor instead. */
.event-metric-drawer {
    visibility: visible;
    background: var(--surface);
    color: var(--text);
    border-left: 1px solid var(--border);
}

.live-timing-card-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    font-weight: 700;
}

.live-timing-card-value {
    font-size: 1.85rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--text);
}

.live-timing-card-value-sub {
    font-size: 0.78rem;
    color: var(--text-muted);
    min-height: 1.1em;
}

.live-timing-card-live .live-timing-card-value {
    color: var(--accent);
    animation: track-status-pulse 1.6s ease-in-out infinite;
}

/* ===== Branded login screen -- the previous version was bare RemoteAuthenticatorView chrome, no
   logo/card/dark treatment at all despite being the first thing any admin sees. */
.auth-hero {
    min-height: 70vh;
    text-align: center;
}

.auth-hero-logo {
    max-width: 220px;
    height: auto;
}

.auth-hero-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    padding: var(--space-4);
    min-width: 20rem;
    max-width: 90vw;
}

/* "Happening Today" gets real visual weight (elevated/bordered), not just colored label text --
   it's the single most important thing EventSelect communicates. Past is dimmed further so the
   three tiers (Today/Upcoming/Past) are distinguishable without reading each row's date. */
.event-today-item {
    border: 2px solid var(--accent) !important;
    background: rgba(255, 138, 43, 0.08) !important;
}

.event-select-past-label {
    color: var(--text-muted);
    opacity: 0.65;
}

/* "Happening Today" live indicator on EventSelect */
.live-dot {
    display: inline-block;
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background-color: var(--status-danger);
    animation: track-status-pulse 1.6s ease-in-out infinite;
}

/* Toast host (#4) */
.toast-host-container {
    max-width: 92vw;
    pointer-events: none;
}

.toast-host-container .toast {
    min-width: 260px;
    pointer-events: auto;
}

/* Toasts previously applied Bootstrap's "show" class statically in markup, so its own fade
   transition (which needs a separate "fade" class + a later JS-driven class toggle) never
   actually played -- this replaces it with a plain CSS entrance animation that fires once per
   toast when its DOM node is first created (keyed by toast.Id so it doesn't replay on unrelated
   re-renders), no JS interop needed. */
.toast-enter {
    animation: toast-enter-anim 0.25s ease-out;
}

@keyframes toast-enter-anim {
    from { opacity: 0; transform: translateX(20px); }
    to { opacity: 1; transform: translateX(0); }
}

/* A "fade in new rows" animation on .table-scroll-container tbody tr / .list-group-flush items was
   tried here and reverted -- verified via a settled (4s-later) screenshot that it kept re-triggering
   on rows containing a LiveDuration (which ticks every second), leaving running-car rows stuck at
   low opacity indefinitely instead of a one-time entrance effect. Not worth chasing the exact
   Blazor-diffing mechanism under time pressure -- correctness on the most-viewed live pages beats
   the cosmetic flourish. The toast-enter animation below doesn't have this problem since toasts
   aren't tied to a ticking timer. */

/* Subtle hover-lift for a tactile, premium feel -- cards and buttons rise slightly rather than
   just recoloring. */
.card {
    transition: box-shadow 0.15s ease-out;
}

/* Shadow-only lift -- deliberately no `transform` here. Modals (DriverDetailModal, RunActions'
   mobile action modal) render as plain DOM descendants of whatever .card contains the row/button
   that opens them (Blazor doesn't portal them to <body>), and the mouse is still hovering that
   ancestor .card at the exact moment a click opens one. A `transform` on a fixed-position element's
   ancestor creates a new containing block for it, so the modal would collapse from full-viewport
   sizing down to that .card's own (much smaller) content box -- reproduced via getComputedStyle():
   .modal's height dropped from the viewport to ~294px, sized to the .card, with the rest of the
   modal's real content (still present in the DOM) invisibly clipped. Box-shadow alone still reads
   as "lifted" without touching layout/positioning context. */
.card:hover {
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35);
}

.btn {
    transition: transform 0.1s ease-out, box-shadow 0.1s ease-out, background-color 0.15s ease-out;
}

.btn:not(:disabled):hover {
    transform: translateY(-1px);
}

/* Run action buttons (#5) - bigger, spaced-out touch targets; compact again where a mouse is the input (STS-196) */
.run-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.run-actions .btn {
    min-width: 3rem;
    min-height: 2.75rem;
    padding: var(--space-2) 0.9rem;
    font-size: 0.95rem;
}

@media (max-width: 576px) {
    .run-actions .btn {
        min-height: 3rem;
        padding: 0.55rem 0.85rem;
        font-size: 1rem;
    }
}

.run-actions-trigger {
    min-width: 2.75rem;
    min-height: 2.75rem;
}

@media (min-width: 992px) {
    .run-actions {
        gap: 0.25rem;
    }

    .run-actions .btn {
        min-width: 0;
        min-height: 1.75rem;
        padding: 0.15rem 0.5rem;
        font-size: 0.8rem;
    }
}

