/* ---- PAGE LAYOUT ----
   La página es solo la app de timing: una barra superior (GP, sesión y
   clima) y dos paneles, tabla y mapa (con el botón de pantalla completa). En
   escritorio ocupa exacto el alto de la ventana debajo del navbar, sin
   scroll de página; en pantallas angostas los paneles se apilan y la
   página scrollea normal (ver APP SHELL más abajo). --nav-h copia el alto
   del .navbar fijo de style.css. */
.live-body {
    --nav-h: 60px;
}

@media (max-width: 500px) {
    .live-body { --nav-h: 50px; }
}

/* ---- CIRCUIT MAP (Map View) ----
   Same asset convention as race.js: prefer the inline SVG layout, fall
   back to the PNG if that circuit doesn't have one yet. */
.circuit-map-wrap {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgb(20,20,30);
    border: 1px solid rgba(255,255,255,0.05);
    border-radius: 16px;
    padding: 24px;
    transition: border-color 0.25s ease;
}

.circuit-map-wrap:hover {
    border-color: rgba(255,255,255,0.14);
}

/* ---- TRACK MAP (SVG) ----
   Contenedor del mapa dibujado por live.js (drawTrackMap()): pista, curvas
   y autos en el mismo SVG y en el mismo sistema de coordenadas, así los
   autos caen exactamente sobre la línea. El inset coincide con el padding
   del wrap. */
.circuit-position-overlay {
    position: absolute;
    inset: 24px;
    pointer-events: none;
}

.track-svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

/* Pista: un borde gris oscuro ancho y, encima, la línea (de color por
   sector, o neutra mientras no hay tiempos de sector). Mismo lenguaje que
   el mapa oficial de F1. */
.track-outline,
.track-line,
.track-sector {
    fill: none;
    stroke-linejoin: round;
    stroke-linecap: round;
}

.track-outline {
    stroke: rgb(38,38,48);
}

.track-line {
    stroke: rgba(255,255,255,0.7);
}

/* Colores de sector del mapa oficial. */
.track-sector--s1 { stroke: rgb(232,0,45); }
.track-sector--s2 { stroke: rgb(0,161,255); }
.track-sector--s3 { stroke: rgb(255,211,1); }
/* Bandera a cuadros en la largada: grilla de cuadraditos (startFlagHTML()
   en live.js). */
.track-flag-white { fill: #fff; }
.track-flag-black { fill: #111; }

.track-direction {
    fill: var(--text-light);
}

/* Números de curva en circulitos. */
.track-corners circle {
    fill: rgb(24,24,32);
    stroke: rgba(255,255,255,0.35);
    /* stroke-width lo pone live.js en px de pantalla (1px) */
}

.track-corners text {
    fill: var(--text-light);
    font-family: 'F1-Regular', sans-serif;
    font-weight: 600;
    text-anchor: middle;
    dominant-baseline: central;
}

/* Cada auto se desliza a su posición nueva en vez de saltar: live.js
   recalcula cada 0.5s (updatePositionOverlay) y la transición dura lo
   mismo, así el movimiento queda continuo. */
.track-car {
    transition: transform 0.5s linear;
}

/* Aviso de que las posiciones son estimadas (sin Position.z, ver
   ESTIMATED CAR POSITIONS en live.js). Arriba a la izquierda del mapa (abajo
   a la izquierda va el estado de pista). */
.track-note {
    position: absolute;
    left: 16px;
    top: 16px;
    margin: 0;
    font-family: 'F1-Regular', sans-serif;
    font-size: 11px;
    letter-spacing: 0.5px;
    color: rgba(255,255,255,0.4);
    pointer-events: none;
}

.track-note[hidden] {
    display: none;
}

/* Punto del color del equipo con anillo oscuro (live.js le pone el grosor
   según el tamaño del punto), así se despega de la línea de color. */
.track-car circle {
    stroke: rgb(9,9,14);
}

.track-car text {
    fill: #fff;
    font-family: 'F1-Bold', sans-serif;
    paint-order: stroke;
    stroke: rgba(9,9,14,0.9);
    stroke-width: 0.3em;
    stroke-linejoin: round;
}

/* Con el mapa en SVG, el PNG queda solo de respaldo. */
.circuit-map-wrap.has-track .circuit-map-img {
    display: none;
}

/* Los layouts oficiales de F1 no son todos iguales: algunos (Hungaroring)
   ya vienen con un contorno blanco y se leen bien sobre fondo oscuro, y
   otros (Monza) son negro puro sobre transparente y prácticamente
   desaparecen. Los drop-shadow le dibujan ese halo claro a cualquiera de
   los dos siguiendo el alfa de la imagen, sin tener que retocar assets. */
.circuit-map-img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    filter: drop-shadow(0 0 1px rgba(255,255,255,0.85))
            drop-shadow(0 0 3px rgba(255,255,255,0.45));
}

/* Hasta que updateCircuitMap() sepa qué circuito es, el <img> no tiene
   src y el navegador dibuja su placeholder roto (un recuadro enorme, más
   el halo de arriba). Mejor que no ocupe nada. */
.circuit-map-img:not([src]) {
    display: none;
}

/* ---- SESSION CLOCK (label + countdown/stopwatch, next to the GP name) ---- */
.hero-session-status {
    display: flex;
    align-items: center;
    gap: 24px;
}

.hero-session-status:empty {
    display: none;
}

.hero-session-status .status-flag {
    font-family: 'F1-Regular', sans-serif;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 5px 10px;
    border-radius: 6px;
    background: rgba(255,255,255,0.08);
    color: var(--text-dim);
    white-space: nowrap;
}

.hero-session-status .status-flag--green {
    background: rgba(62, 224, 106, 0.16);
    color: #3ee06a;
}

.hero-session-status .status-flag--yellow {
    background: rgba(245, 183, 74, 0.18);
    color: #f5b74a;
}

.hero-session-status .status-flag--red {
    background: rgba(255, 0, 25, 0.18);
    color: #ff4d4d;
}

.hero-session-status .status-session-name {
    font-family: 'F1-Regular', sans-serif;
    font-weight: 600;
    font-size: 18px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--text-light);
    white-space: nowrap;
}

.hero-session-status .status-clock {
    font-family: 'F1-Regular', sans-serif;
    font-size: 18px;
    font-weight: 600;
    color: var(--text-light);
    letter-spacing: 0.5px;
    white-space: nowrap;
}

.hero-session-status .status-clock--paused {
    color: #f5b74a;
}

/* Reloj en pausa: los números y el ícono alineados al centro, con el ícono
   del mismo color y un poco más bajo que los dígitos (como en la tele). */
.hero-session-status .status-clock--paused {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.status-clock-pause {
    width: 0.62em;
    height: 0.74em;
    flex-shrink: 0;
    fill: currentColor;
}

@media (max-width: 600px) {
    .hero-session-status { flex-wrap: wrap; }
    .hero-session-status .status-flag { font-size: 11px; padding: 4px 8px; }
    .hero-session-status .status-session-name { font-size: 13px; }
    .hero-session-status .status-clock { font-size: 17px; }
}

/* ---- SESSION WEATHER CARD BASE (copied verbatim from race.css — remove
   this block if results.css/style.css already define it site-wide) ---- */
.session-weather-card {
    background: rgb(20,20,30);
    border: 1px solid rgba(255,255,255,0.05);
    border-radius: 12px;
    padding: 28px 32px;
    display: flex;
    align-items: center;
    gap: 32px;
    flex-wrap: wrap;
    transition: border-color 0.25s ease;
}

.session-weather-card:hover {
    border-color: rgba(255,255,255,0.14);
}

.swc-condition {
    display: flex;
    align-items: center;
    padding-right: 24px;
    border-right: 1px solid rgba(255,255,255,0.08);
    white-space: nowrap;
}

.swc-condition-icon {
    font-size: 2.5rem;
    line-height: 1;
}

.swc-stats {
    display: flex;
    flex: 1;
    gap: 40px;
    flex-wrap: wrap;
}

.swc-stat {
    display: flex;
    flex-direction: column;
    min-width: 74px;
}

.swc-stat-value {
    font-family: 'F1-Regular', sans-serif;
    font-size: 20px;
    font-weight: 600;
    color: var(--text-light);
    line-height: 1;
}

.swc-stat-label {
    font-family: 'F1-Regular', sans-serif;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--text-dim);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.swc-wind-dir-value {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.swc-wind-compass-icon {
    width: 0.85em;
    height: 0.85em;
    color: var(--text-light);
    transition: transform 0.3s ease;
    flex-shrink: 0;
}

/* ---- ROW HEIGHT (overrides results.css's 56px, since live.css loads after it) ---- */
.live-table td {
    height: 32px;
}

.live-table th,
.live-table td {
    letter-spacing: 0.1px;
}

.live-table th {
    font-size: 14px;
}

.live-table td {
    font-size: 16px;
}

/* ---- COLUMN PADDING (class-based, not nth-child) ----
   Q/SQ reorders and drops columns (see live.js's MAIN_THEAD_QUALI /
   COMPACT_THEAD_QUALI + the row-building in render()), so padding tied to
   nth-child position would silently apply to the wrong column whenever the
   session type flips. These three classes carry the padding instead,
   applied directly on each th/td regardless of which column ends up where:
     .live-col-roomy       -> Pos / Driver / Gap / Interval / Tyres (15/15)
     .live-col-tight-first -> first cell of the lap-timing cluster (15/5)
     .live-col-tight-mid   -> middle cell(s) of that cluster (5/5)
     .live-col-tight-last  -> last cell of that cluster (5/15)
   The "lap-timing cluster" is Best Lap + Last Lap + S1 + S2 + S3 in Q/SQ,
   or just S1 + S2 + S3 + Last Lap otherwise — see render() for which cell
   gets which of the three tight-* classes in each case. */
.live-table .live-col-roomy {
    padding-left: 15px;
    padding-right: 15px;
}

.live-table .live-col-tight-first {
    padding-left: 15px;
    padding-right: 5px;
}

.live-table .live-col-tight-mid {
    padding-left: 5px;
    padding-right: 5px;
}

.live-table .live-col-tight-last {
    padding-left: 5px;
    padding-right: 15px;
}

/* FP1/FP2/FP3: Best Lap gets a little more room on its right. It carries
   .live-col-best (see buildTableColumns() in live.js) and body.is-fp-session
   (toggled in render()) scopes this to FP only. */
body.is-fp-session .live-table .live-col-best.live-col-tight-first {
    padding-right: 15px;
}

/* ---- DRIVER NUMBER (Customize table → Driver number) ----
   Calcado de .st-driver-num (championship.css): "#63" en el color del
   equipo, alineado a la derecha en un ancho fijo para que los nombres de
   abajo arranquen todos en la misma vertical. */
.live-driver-num {
    font-family: 'F1-Regular';
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 0.5px;
    line-height: 1;
    flex-shrink: 0;
    text-align: right;
    min-width: 32px;
}

/* ---- TEAM COLUMN (Customize table → Team: Name column) ----
   Nombre del equipo de teams.json, a la derecha del piloto (el padding
   lo da .live-col-roomy). En una sola línea: "Red Bull Racing" partido
   en dos rompería la altura de la fila. */
.live-table td.live-col-team {
    white-space: nowrap;
}

/* "George Russell" no se parte en dos líneas. */
.live-table td.live-col-driver {
    white-space: nowrap;
}

/* ---- DELTA INDICATOR (copied from race.css) ---- */
/* Scoped with .live-table th/td (not just the bare class) so this wins
   over results.css's general .results-table th/td padding. */
.live-table th.live-delta-col {
    width: 40px;
    padding: 0;
}

.live-table td.res-delta-cell {
    width: 40px;
    padding: 0;
    text-align: left;
}

.res-delta {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 4px;
    font-family: 'F1-Bold';
    font-size: 12px;
    letter-spacing: 0.5px;
    white-space: nowrap;
}

.res-delta-arrow {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.res-delta--up   { color: #22c55e; }
.res-delta--down { color: var(--primary-red); }

.res-delta--same,
.res-delta--none {
    color: rgba(255,255,255,0.2);
    font-family: 'F1-Regular', sans-serif;
    font-size: 14px;
    letter-spacing: 0;
}

/* ---- TEAM LOGO (copied from race.css — live.html doesn't link that file) ---- */
.res-team {
    display: flex;
    align-items: center;
    gap: 8px;
}

.res-team-logo {
    width: 22px;
    height: 22px;
    object-fit: contain;
    flex-shrink: 0;
    opacity: 0.9;
}

.res-team-logo-placeholder {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
}

.live-table td.res-pos {
    text-align: center;
}

/* ---- PODIUM COLORS (same convention as race.css .res-pos.top3) ---- */
#live-rows-2 tr:nth-child(1) .res-pos.top3 { font-family: 'F1-Bold'; color: #f7d774; }
#live-rows-2 tr:nth-child(2) .res-pos.top3 { font-family: 'F1-Bold'; color: #d6d6d6; }
#live-rows-2 tr:nth-child(3) .res-pos.top3 { font-family: 'F1-Bold'; color: #cd9a63; }

/* ---- ZEBRA ROWS ----
   Filas intercaladas para no perder la línea al leer de punta a punta
   (Driver → Tyres cruza toda la pantalla). "of .results-row" cuenta solo
   filas de pilotos: los separadores de corte de la Qualy no desfasan el
   patrón. La fila de vuelta rápida se excluye porque su violeta va en el
   <tr> y un fondo en los <td> lo taparía. */
.live-table--compact tbody tr.results-row:nth-child(even of .results-row):not(.live-row--fastest-map) td {
    background: rgba(255,255,255,0.045);
}

/* Hover bien marcado (results.css usa 0.035, que acá casi no se
   distinguiría de la fila gris). */
.live-table.live-table--compact tbody tr.results-row:not(.live-row--fastest-map):hover td {
    background: rgba(255,255,255,0.1);
}

/* Soft purple background for the compact Map View row of the session
   fastest lap holder. */
.live-table.live-table--compact tr.live-row--fastest-map {
    background: rgba(176, 56, 216, 0.2);
}

/* On hover, the session-fastest row in the compact Map View should use
   a subtle purple overlay instead of the default white tint used
   elsewhere. This selector targets only the compact table to avoid
   affecting the main (big) table's hover behaviour. */
.live-table.live-table--compact .results-row.live-row--fastest-map:hover td,
.live-table.live-table--compact tr.live-row--fastest-map:hover td {
    background: rgba(176,56,216,0.075);
}
/* Lap time convention (official F1 timing colors): purple = session
   fastest, green = personal best, yellow = neither (normal lap).
   Selectors are scoped to `.live-table td` (not just the bare class)
   so they win specificity over whatever sets the base cell text color. */
.live-table td.live-lap--fastest {
    color: rgb(176,56,216);
}

.live-table td.live-lap--pb {
    color: rgb(0, 212, 96);
}

.live-table td.live-lap--normal {
    color: rgb(255,212,0);
}

.live-row--retired {
    opacity: 0.35;
}

/* Frozen results shown below the outermost "eliminated" divider — P16 in
   Q2 (Q1 dropouts), P10 in Q3 (everyone out of Q1 or Q2) — softer dim than
   a retirement, just "not part of this fight anymore". */
.live-row--eliminated {
    opacity: 0.45;
}

/* ---- QUALIFYING ELIMINATION CUTOFF SEPARATOR (Q1/Q2/Q3 & SQ1/SQ2/SQ3) ---- */
/* Row injected between P15/P16 and/or P10/P11 by withQualySeparators() in
   live.js. Kept deliberately thin/low-contrast so it reads as a rule line,
   not a full extra data row. */
.live-qualy-separator td {
    height: 32px;
    min-height: 32px;
    max-height: 32px;
    line-height: 32px;
    padding: 0;
    overflow: hidden;
    box-sizing: border-box;
    background: rgba(255, 0, 25, 0.05);
    border-top: none;
    border-bottom: none;
}

/* The td stays a normal table-cell (so it keeps stretching across the full
   colspan width the way table layout expects) — the flex that centers the
   label and sizes the lines around it lives on this inner wrapper instead,
   where `width: 100%` actually has something real to resolve against. */
.live-qualy-separator-inner {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.live-qualy-separator-line {
    flex: 1 1 auto;
    min-width: 20px;
    height: 1px;
    background: rgba(255, 0, 25, 0.4);
}

.live-qualy-separator-label {
    flex: 0 0 auto;
    padding: 0 16px;
    white-space: nowrap;
    text-align: center;
    font-family: 'F1-Regular';
    font-size: 16px;
    letter-spacing: 0.6px;
    color: rgba(255, 255, 255, 0.5);
    text-transform: uppercase;
}

/* ELIMINATION ZONE (the P10 cut in Q2, still an active decision) stays red;
   every other separator label — Q1/Q2 CUTOFF, Q1/Q2 ELIMINATED — is now
   grey by default via .live-qualy-separator-label above. */
.live-qualy-separator-label--danger {
    color: var(--primary-red);
}

/* ---- TYRES ----
   Una insignia por stint: ícono del compuesto + vueltas hechas con ese
   juego, en el color del compuesto (tyreStintBadgeHTML() en live.js).
   "Current set" muestra solo la última; "All stints" las pone todas en
   fila, de la más vieja a la actual, con la misma letra y el mismo color.
   Plain flex, no height or vertical-align tricks — that's the structure
   that actually centers correctly inside a table cell. */
.tyre-stints {
    display: flex;
    align-items: center;
    gap: 16px;
    white-space: nowrap;
}

.tyre-fresh {
    display: flex;
    align-items: center;
    gap: 3px;
}

.tyre-icon-img {
    display: block;
    object-fit: contain;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
}

.tyre-icon-fallback {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    background: #0b0d10;
    border: 2.5px solid #888;
    font-family: 'F1-Bold', sans-serif;
    font-size: 11px;
    font-weight: 700;
    color: #ffffff;
}

.tyre-icon-unknown {
    display: inline-block;
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    background: rgba(255,255,255,0.06);
    border: 1.5px dashed rgba(255,255,255,0.2);
}

.tyre-fresh-label {
    font-family: 'F1-Regular', sans-serif;
    font-size: 16px;
    letter-spacing: 0.2px;
}

/* El número va del color del compuesto que tiene al lado. */
.tyre-fresh-label--soft   { color: rgb(254, 0, 0); }
.tyre-fresh-label--medium { color: rgb(255, 211, 1); }
.tyre-fresh-label--hard   { color: rgb(255, 255, 255); }
.tyre-fresh-label--inter  { color: rgb(0, 188, 66); }
.tyre-fresh-label--wet    { color: rgb(2, 87, 206); }

/* ---- MUTED CELL TEXT (Gap / Interval / tyre placeholder) ----
   Mismo look que .results-date de results.css, pero propio: esa clase se
   oculta en pantallas <=500px (columna Date del calendario), y al usarla
   acá la celda Gap desaparecía en el celular mientras el <th> seguía,
   corriendo todas las columnas una posición a la izquierda. */
.live-muted {
    color: rgba(255,255,255,0.6);
    font-size: 16px;
}

/* ---- STATUS TEXT ----
   In the mapview compact table, status badges are small bordered labels
   in the team color. */
/* Same pattern as .res-team: plain flex wrapper, no height or
   vertical-align tricks — that's what actually centers content
   vertically inside a table cell in this codebase. */
.live-status-wrap {
    display: flex;
    align-items: center;
}

.live-status-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 46px;
    padding: 4px 6px;
    border: 2px solid currentColor;
    border-radius: 6px;
    font-size: 11px;
    font-weight: bold;
    line-height: 1.1;
    text-transform: uppercase;
    letter-spacing: 1px;
}

/* Ya recibió la bandera a cuadros: blanco (no color de equipo) con una
   mini bandera a cuadros, mismo tamaño que PIT/OUT. */
.live-status-badge--chequered {
    gap: 4px;
    color: rgba(255, 255, 255, 0.9);
}

.live-chequered-icon {
    width: 10px;
    height: 10px;
    flex: none;
    border-radius: 1px;
    background-color: #fff;
    background-image: conic-gradient(#111 25%, transparent 0 50%, #111 0 75%, transparent 0);
    background-size: 5px 5px;
}

.live-status-team {
    font-weight: bold;
    text-transform: uppercase;
}

/* Mapview compact Status column should not inherit the normal roomy padding. */
.live-table td.live-col-status,
.live-table th.live-col-status {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* Mapview compact Driver column should use a smaller right padding. */
.live-table.live-table--compact td.live-col-driver,
.live-table.live-table--compact th.live-col-driver {
    padding-right: 5px !important;
}

.live-sector-col,
.live-sector-cell {
    text-align: left;
    white-space: nowrap;
    min-width: 4.2ch;
    padding: 0 6px;
}

.live-sector-col {
    font-size: 14px;
    opacity: 0.85;
}

.live-sector-cell {
    color: inherit;
}

/* ---- SECTOR WRAP ----
   Real container, same "one parent, two children" shape as .res-team:
   .live-sector-wrap is the parent, .live-microsectors and
   .live-sector-time are its two children.
   The two children are decoupled on purpose: .live-microsectors is
   pulled out of flow (position:absolute, see below) so it can pin to
   the row's exact top edge, while .live-sector-time is the ONLY thing
   left in normal flow — meaning align-items:center below centers it
   against the wrap's full height (100% of the row) with nothing else
   in the way. No magic numbers to keep in sync if the bar height ever
   changes; the two are fully independent. */
.live-sector-wrap {
    position: relative;
    display: flex;
    align-items: center;
    height: 100%;
}

/* ---- MINI-SECTOR BARS (FP only) ----
   position:absolute relative to .live-sector-wrap (which spans the full
   row via height:100% above) — top:0 puts it flush against the actual
   top edge of the table row, not just "near the top". Being out of flow
   means it can never affect .live-sector-time's centering, in either
   direction. Left/right:0 match the wrap's own width, which already
   sits inset by .live-sector-cell's padding, so the bars line up with
   the time's left/right edges. */
.live-microsectors {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    gap: 2px;
}

/* ---- SECTOR TIME TEXT ----
   The only normal-flow child of .live-sector-wrap (see above) — that's
   what lets align-items:center on the wrap center it against the row's
   full height, landing on the exact same vertical center as the
   plain-text Last Lap cell next to it, regardless of what
   .live-microsectors is doing above. */
.live-sector-time {
    display: block;
    line-height: 1;
}

.live-microsector {
    flex: 1 1 0;
    width: 8px;
    height: 4px;
    border-radius: 2px;
    background: rgba(255,255,255,0.12);
}

.live-microsector--yellow      { background: rgba(255,212,0,0.9); }
.live-microsector--green       { background: rgba(0,212,96,0.9); }
.live-microsector--purple      { background: rgba(176,56,216,0.9); }
.live-microsector--pitlane     { background: rgba(120,170,255,0.75); }
.live-microsector--unknown     { background: rgba(255,255,255,0.35); }
.live-microsector--unavailable { background: rgba(255,255,255,0.12); }


/* ---- APP SHELL ----
   Lo que antes era la vista "pantalla completa" de tabla + mapa ahora es
   la página entera. Fija debajo del navbar para que llene la ventana justa
   (los dos paneles usan TODO el alto restante, sin espacio muerto abajo),
   pegada y separada solo por líneas de 1px, como un dashboard de timing. */
.live-app {
    --app-bg: rgb(9,9,14);
    --app-panel: rgb(14,14,21);
    --app-line: rgba(255,255,255,0.09);
    /* Ancho de la columna derecha: la usan el panel del mapa y la celda
       del clima de la barra superior, así quedan exactamente alineados. */
    --app-side-col: clamp(340px, 31%, 640px);

    position: fixed;
    top: var(--nav-h);
    right: 0;
    bottom: 0;
    left: 0;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    background: var(--app-bg);
    overflow: hidden;
}

/* Pantalla completa: tapa también el navbar (z-index 100 en style.css).
   Donde hay Fullscreen API, live.js además esconde las barras del
   navegador; esto cubre el resto (iPhone) y el instante de transición. */
.live-app.is-fullscreen {
    top: 0;
    z-index: 999;
}

/* ---- HIDE SCROLLBARS (scroll keeps working, just no visible bar) ---- */
.live-app,
.mapview-panel--table .results-table-wrap {
    scrollbar-width: none;       /* Firefox */
    -ms-overflow-style: none;    /* old Edge/IE */
}

.live-app::-webkit-scrollbar,
.mapview-panel--table .results-table-wrap::-webkit-scrollbar {
    display: none;               /* Chrome/Safari/Edge (Chromium) */
}

/* ---- TOP BAR ----
   Una sola franja a lo ancho: bandera + nombre del GP y estado/reloj de
   sesión a la izquierda; clima a la derecha. Mismas columnas que
   .mapview-panels-row, así el clima queda justo encima del mapa, con el
   mismo ancho y la misma línea divisoria. */
.live-app-topbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--app-side-col);
    min-width: 0;
    min-height: 68px;
    background: var(--app-panel);
    border-bottom: 1px solid var(--app-line);
}

.mapview-fs-ident {
    display: flex;
    align-items: center;
    gap: 20px;
    min-width: 0;
    padding: 10px 20px;
}

/* Celda del clima: siempre existe (aunque todavía no haya datos) para que
   la columna y su divisoria no aparezcan y desaparezcan. */
.live-app-topbar-side {
    display: flex;
    align-items: center;
    min-width: 0;
    padding: 10px 16px;
    border-left: 1px solid var(--app-line);
}

.mapview-fs-session-status {
    gap: 16px;
    padding-left: 20px;
    border-left: 1px solid var(--app-line);
}

.mapview-fs-name {
    margin: 0;
    font-family: 'F1-Black', sans-serif;
    font-weight: normal;
    font-size: 36px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    line-height: 1;
    color: var(--text-light, #fff);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

img.emoji {
    margin-left: 0;
}

/* El clima no es una card acá: se integra en la barra (sin fondo, sin
   borde, sin radius). */
.mapview-fs-weather {
    flex: 1 1 auto;
    min-width: 0;
}

/* Reparte los datos a lo ancho de toda la columna, de borde a borde. */
.mapview-fs-weather .session-weather-card {
    width: 100%;
    justify-content: space-between;
    padding: 0;
    gap: 20px;
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    flex-wrap: nowrap;
}

.mapview-fs-weather .session-weather-card:hover {
    border-color: transparent;
}

.mapview-fs-weather .swc-condition {
    gap: 10px;
    padding-right: 20px;
    border-right: 1px solid var(--app-line);
}

.mapview-fs-weather .swc-condition-icon {
    font-size: 1.4rem;
}

.mapview-fs-weather .swc-stats {
    gap: 16px;
    flex-wrap: nowrap;
    justify-content: space-between;
}

.mapview-fs-weather .swc-stat {
    min-width: 0;
    gap: 4px;
}

.mapview-fs-weather .swc-stat-value {
    font-size: 20px;
}

.mapview-fs-weather .swc-stat-label {
    font-size: 14px;
    letter-spacing: 0.8px;
}

/* ---- MAP CONTROLS (Customize table + Full screen) ----
   Esquina inferior derecha del panel del mapa, como en YouTube. Una sola
   cápsula con los dos botones, separados por una línea finita, con el mismo
   lenguaje que el cartel de estado de pista (esquina de enfrente, misma
   altura) y la brújula: fondo oscuro translúcido, borde fino, sombra. Solo
   íconos; los tooltips los ponen el HTML y live.js. */
.live-map-controls {
    position: absolute;
    right: 16px;
    bottom: 16px;
    z-index: 20;
    display: flex;
    overflow: hidden;
    background: rgba(16,16,22,0.9);
    border: 1px solid rgba(255,255,255,0.14);
    border-radius: 10px;
    box-shadow: 0 4px 14px rgba(0,0,0,0.5);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    transition: opacity 0.4s ease;
}

/* Sin movimiento por unos segundos (initControlsAutoHide() en live.js):
   se desvanecen y dejan de recibir clics hasta que el mouse se mueva. */
.live-map-controls.is-idle {
    opacity: 0;
    pointer-events: none;
}

.live-ctrl-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 40px;
    padding: 0;
    margin: 0;
    color: rgba(255,255,255,0.75);
    background: transparent;
    border: none;
    border-radius: 0;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

/* Línea finita entre los dos botones. */
.live-ctrl-btn + .live-ctrl-btn {
    border-left: 1px solid rgba(255,255,255,0.12);
}

.live-ctrl-btn:hover,
.live-ctrl-btn:focus-visible {
    color: #fff;
    background: rgba(255,255,255,0.08);
}

/* Customize abierto: ícono rojo con un fondo rojizo suave. */
.live-view-btn[aria-expanded="true"] {
    color: var(--primary-red, #e10600);
    background: rgba(225,6,0,0.14);
}

.live-ctrl-btn:focus-visible {
    outline: 2px solid #fff;
    outline-offset: -3px;
}

.live-ctrl-btn svg {
    width: 19px;
    height: 19px;
    display: block;
    flex-shrink: 0;
}

/* Full screen: el ícono se da vuelta mientras está activo. */
.live-fs-btn .icon-collapse { display: none; }
.live-fs-btn.is-fullscreen .icon-expand { display: none; }
.live-fs-btn.is-fullscreen .icon-collapse { display: block; }

/* ---- CUSTOMIZE TABLE PANEL ----
   Tapa la columna derecha entera (mapa + Race Control, y también los
   botones: se cierra con Done, la X o Esc), así la tabla sigue a la vista
   y cada cambio se ve en vivo. En pantallas angostas pasa a ser una hoja
   fija desde abajo. */
.live-view-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    font-family: 'F1-Regular', sans-serif;
    background: var(--app-panel);
    border-bottom: 1px solid var(--app-line);
}

.live-view-panel[hidden] {
    display: none;
}

.live-view-panel:focus {
    outline: none;
}

/* Entrada suave al abrir (se desliza un poco desde la derecha). */
.live-view-panel:not([hidden]) {
    animation: lvp-enter 0.18s ease-out;
}

@keyframes lvp-enter {
    from { opacity: 0; transform: translateX(12px); }
    to   { opacity: 1; transform: none; }
}

/* Salida: el camino inverso, un poco más rápida. live.js oculta el panel
   recién cuando termina (ver close() en initViewPanel). */
.live-view-panel.is-closing {
    animation: lvp-exit 0.15s ease-in forwards;
    pointer-events: none;
}

@keyframes lvp-exit {
    from { opacity: 1; transform: none; }
    to   { opacity: 0; transform: translateX(12px); }
}

@media (prefers-reduced-motion: reduce) {
    .live-view-panel:not([hidden]),
    .live-view-panel.is-closing { animation: none; }
}

/* Encabezado: título + "Changes apply instantly" y la X. */
.lvp-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex: 0 0 auto;
    padding: 16px 16px 14px 20px;
    border-bottom: 1px solid var(--app-line);
}

.lvp-title {
    margin: 0;
    font-family: 'F1-Bold', sans-serif;
    font-weight: normal;
    font-size: 17px;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--text-light, #fff);
}

.lvp-subtitle {
    margin: 3px 0 0;
    font-size: 12px;
    color: rgba(255,255,255,0.45);
}

.lvp-close {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    padding: 0;
    color: rgba(255,255,255,0.7);
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 8px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.lvp-close:hover,
.lvp-close:focus-visible {
    color: #fff;
    background: rgba(255,255,255,0.1);
}

.lvp-close svg {
    width: 18px;
    height: 18px;
}

/* Cuerpo con scroll propio: tarjetas agrupadas por tema. */
.lvp-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 4px 16px 20px;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.15) transparent;
}

.lvp-section {
    margin-top: 16px;
}

.lvp-section-title {
    margin: 0 0 8px 4px;
    font-family: 'F1-Regular', sans-serif;
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: rgba(255,255,255,0.45);
}

.lvp-card {
    overflow: hidden;
    background: rgba(255,255,255,0.03);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 12px;
}

/* Fila: nombre a la izquierda, interruptor (o candado) a la derecha. Toda
   la fila es clickeable. */
.lvp-row {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 46px;
    padding: 8px 14px;
    font-size: 14px;
    color: var(--text-light, #fff);
    cursor: pointer;
    transition: background 0.15s ease;
}

.lvp-card > * + * {
    border-top: 1px solid rgba(255,255,255,0.06);
}

.lvp-row:hover {
    background: rgba(255,255,255,0.03);
}

.lvp-row.is-locked,
.lvp-row.is-disabled,
.lvp-row--stacked {
    cursor: default;
}

.lvp-row.is-locked:hover,
.lvp-row.is-disabled:hover,
.lvp-row--stacked:hover {
    background: transparent;
}

.lvp-row-label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.lvp-row.is-locked .lvp-row-label,
.lvp-row.is-disabled .lvp-row-label {
    color: rgba(255,255,255,0.5);
}

.lvp-row-note {
    font-size: 11.5px;
    line-height: 1.35;
    color: rgba(255,255,255,0.4);
}

.lvp-locked {
    display: flex;
    color: rgba(255,255,255,0.35);
}

.lvp-lock {
    width: 15px;
    height: 15px;
}

/* Interruptor: el checkbox real queda invisible pero enfocable; .lvp-switch
   es el dibujo (pista + perilla). */
.lvp-switch-input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    pointer-events: none;
}

.lvp-switch {
    position: relative;
    flex-shrink: 0;
    width: 36px;
    height: 20px;
    border-radius: 999px;
    background: rgba(255,255,255,0.16);
    transition: background 0.2s ease;
}

.lvp-switch::after {
    content: "";
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,0.4);
    transition: transform 0.2s ease;
}

.lvp-switch-input:checked + .lvp-switch {
    background: var(--primary-red, #e10600);
}

.lvp-switch-input:checked + .lvp-switch::after {
    transform: translateX(16px);
}

.lvp-switch-input:disabled + .lvp-switch {
    opacity: 0.35;
}

.lvp-switch-input:focus-visible + .lvp-switch {
    outline: 2px solid #fff;
    outline-offset: 2px;
}

/* Opción de formato debajo de su fila (p. ej. el estilo de Team). */
.lvp-option {
    padding: 10px 14px 14px;
    background: rgba(0,0,0,0.14);
}

.lvp-option[hidden] {
    display: none;
}

.lvp-option-label {
    display: block;
    margin-bottom: 8px;
    font-size: 12px;
    color: rgba(255,255,255,0.5);
}

/* Botones segmentados: una pista oscura con la opción elegida resaltada. */
.lvp-segmented {
    display: flex;
    gap: 2px;
    padding: 3px;
    background: rgba(0,0,0,0.35);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 9px;
}

.lvp-seg {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
    cursor: pointer;
}

.lvp-seg input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    pointer-events: none;
}

.lvp-seg span {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 32px;
    padding: 4px 6px;
    border-radius: 6px;
    font-size: 12.5px;
    line-height: 1.2;
    text-align: center;
    color: rgba(255,255,255,0.6);
    transition: background 0.15s ease, color 0.15s ease;
}

.lvp-seg:hover span {
    color: #fff;
}

.lvp-seg input:checked + span {
    color: #fff;
    background: var(--primary-red, #e10600);
    box-shadow: 0 1px 4px rgba(0,0,0,0.35);
}

.lvp-seg input:focus-visible + span {
    outline: 2px solid #fff;
    outline-offset: -2px;
}

/* TV sync: la fila lleva la explicación abajo y el control − / + a la
   derecha. */
.lvp-row--stacked {
    align-items: center;
}

.lvp-stepper {
    display: flex;
    align-items: stretch;
    flex-shrink: 0;
    background: rgba(0,0,0,0.35);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 9px;
    overflow: hidden;
}

.lvp-step {
    width: 36px;
    min-height: 34px;
    padding: 0;
    font-family: 'F1-Bold', sans-serif;
    font-size: 18px;
    line-height: 1;
    color: rgba(255,255,255,0.75);
    background: transparent;
    border: none;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.lvp-step:hover,
.lvp-step:focus-visible {
    color: #fff;
    background: rgba(255,255,255,0.08);
}

.lvp-step:focus-visible {
    outline: 2px solid #fff;
    outline-offset: -3px;
}

.lvp-delay-value {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 0 8px;
    border-left: 1px solid rgba(255,255,255,0.08);
    border-right: 1px solid rgba(255,255,255,0.08);
    font-size: 15px;
    color: var(--text-light, #fff);
}

.lvp-delay-value input {
    width: 3.5ch;
    padding: 0;
    font: inherit;
    text-align: right;
    color: inherit;
    background: transparent;
    border: none;
    -moz-appearance: textfield;
    appearance: textfield;
}

.lvp-delay-value input::-webkit-outer-spin-button,
.lvp-delay-value input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.lvp-delay-value input:focus-visible {
    outline: none;
}

.lvp-delay-value:focus-within {
    background: rgba(255,255,255,0.06);
}

/* Pie: "Reset to default" como texto, "Done" como botón principal. */
.lvp-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    flex: 0 0 auto;
    padding: 12px 16px;
    border-top: 1px solid var(--app-line);
    background: rgba(0,0,0,0.15);
}

.lvp-btn {
    height: 38px;
    padding: 0 18px;
    font-family: 'F1-Regular', sans-serif;
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 0.3px;
    text-transform: uppercase;
    color: var(--text-light, #fff);
    background: transparent;
    border: 1px solid transparent;
    border-radius: 9px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, filter 0.15s ease;
}

.lvp-btn--ghost {
    padding: 0 10px;
    color: rgba(255,255,255,0.55);
}

.lvp-btn--ghost:hover,
.lvp-btn--ghost:focus-visible {
    color: #fff;
    background: rgba(255,255,255,0.06);
}

.lvp-btn--primary {
    background: var(--primary-red, #e10600);
    box-shadow: 0 2px 8px rgba(225,6,0,0.3);
}

.lvp-btn--primary:hover,
.lvp-btn--primary:focus-visible {
    filter: brightness(1.12);
}

.lvp-btn:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 2px;
}


@media (max-width: 900px) {
    .live-view-panel {
        position: fixed;
        top: auto;
        bottom: 0;
        max-height: 80vh;
        z-index: 1000;
        border-top: 1px solid rgba(255,255,255,0.22);
        border-bottom: none;
        border-radius: 16px 16px 0 0;
        box-shadow: 0 -12px 40px rgba(0,0,0,0.6);
    }
}

/* Ni el valor ni la etiqueta se parten nunca ("1.5 km/h", "WIND SPEED"). */
.mapview-fs-weather .swc-stat-value,
.mapview-fs-weather .swc-stat-label {
    white-space: nowrap;
}

/* Con valores de 20px y etiquetas de 14px, los 5 datos en fila necesitan
   ~560px, y la columna del mapa (31% del ancho) recién llega a eso cerca
   de los 1900px. Por debajo pasan a 3 columnas en dos filas, con el ícono
   del cielo a la izquierda ocupando las dos. Columnas "auto" (del ancho
   de su contenido) y no iguales: con 1fr, "WIND SPEED" se pisaba con la
   columna de al lado. */
@media (min-width: 901px) and (max-width: 1880px) {
    .mapview-fs-weather .swc-stats {
        display: grid;
        grid-template-columns: repeat(3, auto);
        justify-content: space-between;
        gap: 8px 12px;
    }
}

/* Pantallas más chicas: todo baja en la misma proporción (valor/etiqueta)
   para que las dos filas sigan entrando en la columna. */
@media (max-width: 1400px) {
    .mapview-fs-weather .swc-stat-value { font-size: 18px; }
    .mapview-fs-weather .swc-stat-label { font-size: 12px; }
    .mapview-fs-name { font-size: 22px; }
}

@media (max-width: 1100px) {
    .mapview-fs-name { font-size: 18px; }
    .mapview-fs-weather .swc-stat-value { font-size: 16px; }
    .mapview-fs-weather .swc-stat-label { font-size: 11px; }
    /* Menos aire alrededor del ícono del cielo para que las dos columnas
       de etiquetas largas (WIND SPEED / WIND DIR) no se toquen. */
    .mapview-fs-weather .session-weather-card { gap: 12px; }
    .mapview-fs-weather .swc-condition { padding-right: 12px; }
}

/* ---- PANELS ROW ----
   Dos columnas que llenan el alto restante entero — sin gap, sin
   max-height, sin espacio muerto abajo. La única separación es el borde
   izquierdo del panel del mapa. */
.mapview-panels-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--app-side-col);
    min-height: 0;
    overflow: hidden;
}

.mapview-panel {
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    background: var(--app-bg);
    overflow: hidden;
}

.mapview-panel--map {
    position: relative;   /* ancla de los botones y del panel Customize */
    background: var(--app-panel);
    border-left: 1px solid var(--app-line);
}

/* Table panel: the inner wrap becomes the scroll container so the
   thead can stick to the top of the panel, not the whole viewport. */
.mapview-panel--table .results-table-wrap {
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
}

/* height:100% reparte el alto sobrante entre las filas en vez de dejar un
   hueco muerto abajo del último piloto (si el contenido no entra, la tabla
   crece igual y el wrap scrollea como siempre). */
.mapview-panel--table .live-table {
    border-collapse: collapse;
    border-spacing: 0;
    height: 100%;
}

/* Con las filas estiradas, las barras de microsectores pinchadas al tope
   de la fila quedaban lejísimo de su tiempo (parecían de la fila de
   arriba). Acá se anclan justo encima del número, no al borde. */
.mapview-panel--table .live-microsectors {
    top: 50%;
    transform: translateY(-16px);
}

/* Solo microsectores (sin tiempos): las barras vuelven al flujo normal y
   quedan centradas en la fila, más anchas para que se lean solas. */
.mapview-panel--table .live-sector-cell--micro-only .live-microsectors {
    position: static;
    transform: none;
}

/* Barras verticales: igual de finas que junto al tiempo (~5px, lo que
   mide cada una repartida sobre el ancho del número) y tan altas como el
   texto de la fila (16px). */
.mapview-panel--table .live-sector-cell--micro-only .live-microsector {
    flex: 0 0 auto;
    width: 5px;
    height: 16px;
}

/* Header pegado al tope del panel (no del viewport) y a la misma altura
   de fila que el resto de la tabla. */
.mapview-panel--table .live-table thead th {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--app-bg);
    height: 32px;
    box-shadow: inset 0 -1px 0 var(--app-line);
}

/* Map panel: strip circuit-map-wrap's own chrome so the panel is the
   only chrome — avoids a double frame. */
.mapview-panel--map .circuit-map-wrap {
    flex: 1 1 0;
    min-height: 0;
    border: none;
    border-radius: 0;
    background: transparent;
    margin: 0;
    padding: 20px;
}

.mapview-panel--map .circuit-position-overlay {
    inset: 20px;
}

/* ---- RACE CONTROL ----
   Debajo del mapa, en la misma columna: ~40% del alto, con scroll propio.
   El más nuevo arriba (renderRaceControl() en live.js). */
.race-control {
    flex: 0 0 40%;
    min-height: 0;
    overflow-y: auto;
    border-top: 1px solid var(--app-line);
    /* Mismo fondo que la tabla (su fila "negra"); ver ZEBRA más abajo. */
    background: var(--app-bg);
    scrollbar-width: none;
}

.race-control::-webkit-scrollbar {
    display: none;
}

.race-control[hidden] {
    display: none;
}

.rc-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.rc-item {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--app-line);
    font-family: 'F1-Regular', sans-serif;
}

/* Filas intercaladas negro / gris, los mismos colores que la tabla de
   posiciones (ZEBRA ROWS). Va por posición en la lista, así que cuando
   entra un mensaje nuevo arriba el patrón se reacomoda solo. */
.rc-item:nth-child(even) {
    background: rgba(255,255,255,0.045);
}

/* Recién llegado: arranca resaltado y se apaga solo. */
.rc-item.is-new {
    animation: rc-flash 4s ease-out;
}

@keyframes rc-flash {
    from { background: rgba(255,255,255,0.12); }
    to   { background: transparent; }
}

.rc-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    font-size: 12px;
    color: rgba(255,255,255,0.45);
    white-space: nowrap;
}

.rc-body {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
    min-width: 0;
}

.rc-text {
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.1px;
    color: var(--text-light);
    overflow-wrap: anywhere;
}

.rc-chip {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 14px 8px;
    border-radius: 4px;
    font-family: 'F1-Regular', sans-serif;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    white-space: nowrap;
    background: rgba(255,255,255,0.12);
}

.rc-chip--green     { background: rgba(62,224,106,0.18);  color: #3ee06a; }
.rc-chip--yellow    { background: rgba(255,211,1,0.18);   color: rgb(255,211,1); }
.rc-chip--red       { background: rgba(255,0,25,0.22);    color: #ff4d4d; }
.rc-chip--blue      { background: rgba(71,150,255,0.2);   color: rgb(110,170,255); }
.rc-chip--sc        { background: rgba(255,211,1,0.18);   color: rgb(255,211,1); }
.rc-chip--penalty   { background: rgba(255,0,25,0.22);    color: #ff4d4d; }
.rc-chip--drs       { background: rgba(255,255,255,0.1);  color: rgba(255,255,255,0.8); }
.rc-chip--info      { background: rgba(255,255,255,0.1);  color: rgba(255,255,255,0.8); }
.rc-chip--lap       { background: rgba(255,255,255,0.1);  color: rgba(255,255,255,0.8); }
.rc-chip--chequered { background: #fff;                   color: #000; }
.rc-chip--bw        { background: rgba(255,255,255,0.1);  color: #fff; }

.rc-empty {
    padding: 16px;
    font-family: 'F1-Regular', sans-serif;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-dim);
}

/* Tabla sin datos ("No session data yet" y los avisos de conexión): mismo
   estilo que el vacío de Race Control, arriba a la izquierda en vez de
   centrado en el medio de la tabla (results.css lo centra). */
.live-table td.results-empty {
    height: auto;
    padding: 16px;
    text-align: left;
    vertical-align: top;
    font-family: 'F1-Regular', sans-serif;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-dim);
}

/* ---- NARROW SCREENS ----
   Tabla y mapa lado a lado no entran: se apilan (tabla arriba, mapa
   abajo) y la página scrollea normal en vez de encajar en la ventana. */
@media (max-width: 900px) {
    .live-app {
        position: static;
        display: block;
        margin-top: var(--nav-h);
        overflow: visible;
    }

    .live-app.is-fullscreen {
        position: fixed;
        inset: 0;
        margin-top: 0;
        overflow-y: auto;
    }

    .live-app-topbar {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
        padding: 12px 16px;
    }

    .mapview-fs-ident {
        flex-wrap: wrap;
        row-gap: 8px;
        padding: 0;
    }

    .mapview-fs-session-status {
        padding-left: 0;
        border-left: none;
    }

    .live-app-topbar-side {
        padding: 0;
        border-left: none;
    }

    .live-app-topbar-side:has(.mapview-fs-weather:empty) {
        display: none;
    }

    .mapview-fs-weather .session-weather-card {
        justify-content: flex-start;
    }

    .mapview-fs-weather .session-weather-card,
    .mapview-fs-weather .swc-stats {
        flex-wrap: wrap;
    }

    .mapview-panels-row {
        display: flex;
        flex-direction: column;
        overflow: visible;
    }

    .mapview-panel {
        overflow: visible;
    }

    .mapview-panel--table .results-table-wrap {
        flex: none;
        overflow-x: auto;
        overflow-y: visible;
    }

    .mapview-panel--table .live-table {
        height: auto;
    }

    /* Dentro de un wrap con scroll horizontal el sticky no sirve de nada. */
    .mapview-panel--table .live-table thead th {
        position: static;
    }

    .mapview-panel--map {
        border-left: none;
        border-top: 1px solid var(--app-line);
    }

    .mapview-panel--map .circuit-map-wrap {
        flex: none;
        height: min(80vw, 440px);
    }

    .race-control {
        flex: none;
        max-height: 320px;
    }
}

@media (max-width: 500px) {
    .results-table th,
    .results-table td { padding: 0 12px; }
    .tyre-icon-img { width: 17px; height: 17px; }
    .tyre-icon-fallback { width: 17px; height: 17px; font-size: 10px; }
}

/* ---- MAP + RACE CONTROL: el mapa, con lo justo ----
   Con Race Control visible, el recuadro del mapa deja de estirarse a todo
   el alto disponible (quedaban franjas vacías enormes arriba y abajo de la
   pista) y mide lo que mide la pista: el SVG vuelve al flujo normal con
   height:auto, así su viewBox fija la proporción. Abajo queda solo la
   franja para los botones y el aviso de posiciones estimadas. Race Control
   se lleva el resto de la columna. Tope de 60vh por si un circuito es muy
   alargado. Va al final para pisar también la altura fija del celular. */
.mapview-panel--map.has-race-control .circuit-map-wrap.has-track {
    flex: 0 0 auto;
    height: auto;
    padding: 16px 20px 64px;
}

/* El wrap es flex centrado: sin ancho explícito, el contenedor se
   encogería al ancho por defecto de un SVG (300px) y la pista saldría
   chiquita en medio de la columna. */
.mapview-panel--map.has-race-control .circuit-map-wrap.has-track .circuit-position-overlay {
    position: static;
    flex: 1 1 auto;
    width: 100%;
}

.mapview-panel--map.has-race-control .circuit-map-wrap.has-track .track-svg {
    height: auto;
    max-height: 60vh;
}

.mapview-panel--map.has-race-control .circuit-map-wrap.has-track ~ .race-control {
    flex: 1 1 0;
}

/* ---- PANELS ON/OFF (Customize → Panels) ----
   Track map apagado: del mapa queda solo una franja finita al pie de la
   columna con los botones (Customize / Full screen), para poder volver a
   prenderlo. Race Control, si está, se lleva todo el alto. */
.mapview-panel--map.map-off .circuit-map-wrap,
.mapview-panel--map.map-off .circuit-map-wrap.has-track {
    order: 2;
    flex: 0 0 64px;
    height: 64px;
    padding: 0;
}

.mapview-panel--map.map-off .circuit-map-img,
.mapview-panel--map.map-off .circuit-position-overlay,
.mapview-panel--map.map-off .track-note {
    display: none;
}

.mapview-panel--map.map-off .race-control {
    flex: 1 1 0;
    border-top: none;
}

/* Mapa y Race Control apagados: la tabla ocupa todo el ancho. La columna
   derecha pasa a ser una capa transparente encima del costado derecho de
   la tabla, solo para los botones (abajo a la derecha) y para el panel
   Customize cuando se abre. */
.live-app.no-side .mapview-panels-row {
    position: relative;
    grid-template-columns: minmax(0, 1fr);
}

.live-app.no-side .mapview-panel--map {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--app-side-col);
    justify-content: flex-end;
    background: transparent;
    border: none;
    pointer-events: none;
}

.live-app.no-side .mapview-panel--map .circuit-map-wrap {
    background: transparent;
}

.live-app.no-side .live-map-controls,
.live-app.no-side .live-view-panel {
    pointer-events: auto;
}

@media (max-width: 900px) {
    /* En el celular la columna ya va debajo de la tabla: nada que superponer,
       solo la franja con los botones. */
    .live-app.no-side .mapview-panel--map {
        position: static;
        width: auto;
        pointer-events: auto;
    }
}

/* Chip "DELAY 30s" al lado del reloj de sesión (solo con demora > 0). */
.delay-indicator {
    display: inline-flex;
    align-items: center;
    height: 26px;
    padding: 0 10px;
    border-radius: 6px;
    font-family: 'F1-Regular', sans-serif;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.1px;
    text-transform: uppercase;
    white-space: nowrap;
    color: rgba(255,255,255,0.8);
    background: rgba(255,255,255,0.1);
}

.delay-indicator[hidden] {
    display: none;
}

/* ---- WIND ON THE MAP (updateWindOverlay() en live.js) ----
   Líneas finitas que cruzan el mapa hacia donde sopla el viento. El
   contenedor se gira al ángulo del viento y es más grande que el mapa, así
   al girarlo no quedan esquinas vacías; las líneas corren de izquierda a
   derecha dentro de él. Solo aparece con viento fuerte. */
.track-wind {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
}

.track-wind[hidden] {
    display: none;
}

.track-wind-field {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 170%;
    height: 170%;
    transform: translate(-50%, -50%) rotate(var(--wind-angle, 0deg));
}

.track-wind-streak {
    position: absolute;
    left: -15%;
    width: var(--len, 60px);
    height: 1px;
    border-radius: 1px;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,var(--wind-opacity, 0.25)), transparent);
    animation: track-wind-streak calc(var(--wind-duration, 4s) * var(--jitter, 1)) linear infinite;
    animation-delay: var(--delay, 0s);
}

@keyframes track-wind-streak {
    from { left: -15%; }
    to   { left: 105%; }
}

@media (prefers-reduced-motion: reduce) {
    .track-wind-streak { animation: none; left: 45%; }
}

/* Brújula, estilo apps de mapas: disco oscuro con anillo fino (como los
   botones del mapa); el dial (72 marcas y la punta roja) gira hacia el
   norte del circuito; la N del centro queda siempre derecha.
   Vive en la esquina de abajo a la derecha, la misma de los botones: solo
   se ve cuando ellos se esconden solos (.controls-idle, que pone
   initControlsAutoHide() en live.js) y se desvanece cuando vuelven. */
.track-compass {
    position: absolute;
    right: 16px;
    bottom: 12px;
    z-index: 5;
    width: 52px;
    height: 52px;
    pointer-events: none;
    filter: drop-shadow(0 2px 6px rgba(0,0,0,0.45));
    opacity: 0;
    transition: opacity 0.4s ease;
}

.circuit-map-wrap.controls-idle .track-compass {
    opacity: 1;
}

.track-compass[hidden] {
    display: none;
}

.track-compass svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.track-compass-bezel {
    fill: rgba(16,16,22,0.9);
    stroke: rgba(255,255,255,0.2);
    stroke-width: 1;
}

.track-compass-tick {
    stroke-linecap: round;
}

/* Cuatro largos/grosores (buildCompassTicks() en live.js). */
.track-compass-tick--cardinal { stroke: rgba(255,255,255,0.7);  stroke-width: 1.4; }
.track-compass-tick--major    { stroke: rgba(255,255,255,0.5);  stroke-width: 1.1; }
.track-compass-tick--minor    { stroke: rgba(255,255,255,0.35); stroke-width: 0.8; }
.track-compass-tick--fine     { stroke: rgba(255,255,255,0.2);  stroke-width: 0.6; }

.track-compass-pointer {
    fill: var(--primary-red, #e10600);
}

.track-compass-n {
    fill: var(--text-light);
    font-family: 'F1-Bold', sans-serif;
    font-size: 11px;
    text-anchor: middle;
    dominant-baseline: central;
}

/* Mapa apagado: tampoco viento ni brújula. */
.mapview-panel--map.map-off .track-wind,
.mapview-panel--map.map-off .track-compass {
    display: none;
}

/* ---- MAP ANNOTATIONS (MAP ANNOTATIONS en live.js) ---- */

/* Bandera amarilla en un tramo de comisarios: el tramo se pinta encima de
   la pista y titila; doble amarilla, más rápido. */
.track-flag-sector {
    fill: none;
    stroke: rgb(255,211,1);
    stroke-linecap: round;
    stroke-linejoin: round;
    animation: track-flag-blink 1.2s ease-in-out infinite;
}

.track-flag-sector--double {
    animation-duration: 0.6s;
}

@keyframes track-flag-blink {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.25; }
}

/* SC / VSC / roja: la pista entera se tiñe con un latido suave. */
.track-status-line {
    fill: none;
    stroke-linejoin: round;
    stroke-linecap: round;
    opacity: 0;
    pointer-events: none;
}

.track-status--sc .track-status-line,
.track-status--vsc .track-status-line {
    stroke: rgb(255,211,1);
    animation: track-status-pulse 2s ease-in-out infinite;
}

.track-status--red .track-status-line {
    stroke: rgb(255,40,40);
    animation: track-status-pulse 2s ease-in-out infinite;
}

@keyframes track-status-pulse {
    0%, 100% { opacity: 0.9; }
    50%      { opacity: 0.45; }
}

/* Estado de pista: esquina de abajo a la izquierda, a la altura de los
   botones de la otra esquina (updateTrackStatus() en live.js). */
.track-status-banner {
    position: absolute;
    left: 16px;
    bottom: 16px;
    z-index: 6;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    height: 40px;
    padding: 0 14px;
    border-radius: 8px;
    font-family: 'F1-Regular', sans-serif;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.1px;
    text-transform: uppercase;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 4px 14px rgba(0,0,0,0.5);
}

.track-status-banner[hidden] { display: none; }

/* Sectores afectados ("SECTOR 11"), más livianos que el nombre. */
.track-status-banner-detail {
    font-family: 'F1-Regular', sans-serif;
    font-weight: 600;
    opacity: 0.75;
}

.track-status-banner--sc,
.track-status-banner--vsc,
.track-status-banner--yellow { background: rgb(255,211,1); color: #111; }
.track-status-banner--red    { background: rgb(225,20,20); color: #fff; }

/* Bandera a cuadros: fondo blanco con un cuadradito a cuadros adelante. */
.track-status-banner--chequered { background: #fff; color: #111; }

.track-status-banner--chequered::before {
    content: "";
    width: 16px;
    height: 16px;
    border-radius: 2px;
    background: repeating-conic-gradient(#111 0% 25%, #fff 0% 50%) 0 0 / 8px 8px;
    box-shadow: 0 0 0 1px #111;
}

/* Peleas en pista: franja blanca sobre el tramo de pista entre los dos
   autos (el grosor lo pone live.js en px de pantalla). */
.track-battle {
    fill: none;
    stroke: rgba(255,255,255,0.85);
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Autos: se pueden señalar (tooltip) y cliquear (seguir). */
.track-car {
    pointer-events: auto;
    cursor: pointer;
}

.track-car-hit {
    fill: transparent;
}

.track-car-dot {
    transition: r 0.2s ease;
}

/* Seguido: anillo blanco alrededor del punto. Los demás, atenuados. */
.track-car.is-followed .track-car-dot {
    stroke: #fff;
}

.track-car.is-dimmed {
    opacity: 0.3;
}

/* Fila del piloto seguido en la tabla: franja del color de acento a la
   izquierda y fondo apenas más claro. */
.live-table tbody tr.is-followed td {
    background: rgba(255,255,255,0.1);
}

.live-table tbody tr.is-followed td:first-child {
    box-shadow: inset 3px 0 0 var(--primary-red, #e10600);
}

/* Tooltip de un auto: arriba del punto, con una flechita abajo. */
.track-tooltip {
    position: absolute;
    z-index: 7;
    transform: translate(-50%, calc(-100% - 12px));
    padding: 8px 10px;
    border-radius: 8px;
    background: rgba(16,16,22,0.96);
    border: 1px solid rgba(255,255,255,0.18);
    box-shadow: 0 6px 18px rgba(0,0,0,0.55);
    font-family: 'F1-Regular', sans-serif;
    white-space: nowrap;
    pointer-events: none;
}

.track-tooltip[hidden] { display: none; }

.track-tooltip::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -5px;
    width: 8px;
    height: 8px;
    transform: translateX(-50%) rotate(45deg);
    background: rgba(16,16,22,0.96);
    border-right: 1px solid rgba(255,255,255,0.18);
    border-bottom: 1px solid rgba(255,255,255,0.18);
}

.track-tooltip-name {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: 'F1-Bold', sans-serif;
    font-size: 14px;
    color: var(--text-light);
}

.track-tooltip-name .live-driver-num {
    min-width: 0;
}

.track-tooltip-info {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 4px;
    font-size: 13px;
    color: rgba(255,255,255,0.7);
}

.track-tooltip-tyre .tyre-icon-img {
    width: 18px;
    height: 18px;
}

.track-tooltip-tyre .tyre-fresh-label {
    font-size: 13px;
}

@media (prefers-reduced-motion: reduce) {
    .track-flag-sector,
    .track-status-line { animation: none; }
    .track-status--sc .track-status-line,
    .track-status--vsc .track-status-line,
    .track-status--red .track-status-line { opacity: 0.8; }
}
