/* ============================================================================
   Realtime OV — Designsysteem
   ----------------------------------------------------------------------------
   De interface is een kaart met zwevende panelen erboven, niet een pagina met
   een balk erboven. Alles wat je ziet ligt als een afgeronde kaart op het
   canvas: het zoekveld, het detailpaneel, de navigatierail, de statuschip.

   Alle klassen zijn geprefixt met `rt-` zodat ze niet botsen met de bestaande
   inline CSS van de pagina's. Kleuren komen uit de tokens die theme.js zet
   (--bg-card, --text-primary, --ns-yellow, ...), zodat elk van de acht
   thema's blijft werken. Wat hier extra bijkomt zijn de vorm-tokens:
   radii, schaduwen en de geometrie van de zwevende panelen.

   Kleurregel voor deze huisstijl: NS-geel is vlak en actieve staat, nooit
   tekst op wit — daar leest het niet. Navy draagt de tekstaccenten.
   ========================================================================= */

:root {
    /* Vorm en maat zijn opgemeten uit de referentie op 1600x812:
       paneel 335 breed op 13 marge, rail 70 breed, zoekbalk 359x43
       gecentreerd op het canvas, paneelstraal 14, interne marge 16. */
    --rt-r-panel: 12px;
    --rt-r-card: 8px;
    --rt-r-tile: 10px;
    --rt-r-pill: 999px;

    --rt-gap: 13px;
    /* De referentie houdt rechts bewust meer lucht dan links: het paneel plakt
       tegen de rand (13), de rail en de statuschip staan verder naar binnen
       (24). Dat geeft de kaart aan de rechterkant meer adem. */
    --rt-gap-r: 24px;
    --rt-panel-w: 370px;
    --rt-rail-w: 70px;
    --rt-bar-h: 48px;
    --rt-pad: 16px;

    /* Typeschaal. Vast, zodat alle zes de fontkeuzes hetzelfde ritme houden. */
    --rt-t-micro: 12px;
    --rt-t-small: 14px;
    --rt-t-body: 16px;
    --rt-t-lead: 16px;
    --rt-t-value: 22px;
    --rt-t-display: 30px;

    --rt-ease: cubic-bezier(.2, .7, .3, 1);
}

/* Licht en donker verschillen niet alleen in kleur maar in hoe een paneel
   loskomt van de ondergrond: op licht doet een schaduw dat werk, op donker
   leest een schaduw niet en neemt een lichte rand het over. */
:root {
    --rt-shadow: 0 2px 12px rgba(16, 24, 40, .08);
    --rt-shadow-sm: 0 1px 4px rgba(16, 24, 40, .04);
    --rt-panel-border: rgba(16, 24, 40, .07);
    --rt-scrim: rgba(255, 255, 255, .72);
}

html[data-rt-dark="1"] {
    --rt-shadow: 0 1px 2px rgba(0, 0, 0, .5), 0 10px 30px rgba(0, 0, 0, .45);
    --rt-shadow-sm: 0 1px 2px rgba(0, 0, 0, .45), 0 4px 12px rgba(0, 0, 0, .35);
    --rt-panel-border: rgba(255, 255, 255, .09);
    --rt-scrim: rgba(10, 13, 18, .72);
}

/* ── Canvas ──────────────────────────────────────────────────────────────── */

/* De kaart vult het scherm; alle chrome zweeft erboven. Pagina's zonder kaart
   gebruiken .rt-canvas als gewone achtergrond. */
.rt-canvas {
    position: fixed;
    inset: 0;
    background: var(--bg-deep);
}

.rt-map {
    position: fixed;
    inset: 0;
    z-index: 0;
}

/* Elk zwevend element zit in deze laag. pointer-events staat uit zodat de
   kaart eronder sleepbaar blijft; de kaarten zelf zetten hem weer aan. */
.rt-layer {
    position: fixed;
    inset: 0;
    z-index: 400;
    pointer-events: none;
}

.rt-layer > * { pointer-events: auto; }

/* ── Paneel ──────────────────────────────────────────────────────────────── */

.rt-panel {
    background: var(--bg-card);
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-panel);
    box-shadow: var(--rt-shadow);
    overflow: hidden;
}

/* Het detailpaneel links: volledige hoogte minus marge, met een eigen
   scrollgebied zodat kop en tabbalk blijven staan. */
.rt-panel-left {
    position: absolute;
    left: var(--rt-gap);
    top: var(--rt-gap);
    bottom: var(--rt-gap);
    width: var(--rt-panel-w);
    display: flex;
    flex-direction: column;
    max-width: calc(100vw - 2 * var(--rt-gap));
}

/* Niet elk paneel heeft een schermvullende inhoud. Een radarpaneel met drie
   secties hoort om zijn inhoud te sluiten in plaats van een halve kolom leeg
   te laten; een halteslijst mag juist wel doorlopen tot onderaan. */
.rt-panel-auto {
    bottom: auto;
    max-height: calc(100vh - 2 * var(--rt-gap));
}

.rt-panel-head {
    padding: 14px var(--rt-pad) 12px;
    border-bottom: 1px solid var(--border-subtle);
    flex: 0 0 auto;
}

.rt-panel-body {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 14px var(--rt-pad) 18px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.rt-panel-foot {
    flex: 0 0 auto;
    border-top: 1px solid var(--border-subtle);
    background: var(--bg-card);
}

/* Smalle scrollbar, zodat het paneel niet ineens 15px breder oogt. */
.rt-panel-body::-webkit-scrollbar { width: 8px; }
.rt-panel-body::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 999px;
    border: 2px solid transparent;
    background-clip: content-box;
}
.rt-panel-body::-webkit-scrollbar-track { background: transparent; }

/* ── Zoekbalk ────────────────────────────────────────────────────────────── */

.rt-search {
    position: absolute;
    top: var(--rt-gap);
    left: 50%;
    transform: translateX(-50%);
    width: min(360px, calc(100vw - 2 * var(--rt-gap)));
    display: flex;
    align-items: center;
    gap: 10px;
    height: var(--rt-bar-h);
    padding: 0 16px;
    background: var(--bg-card);
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-pill);
    box-shadow: var(--rt-shadow);
}

/* De zoekbalk blijft op het canvasmidden staan, ook met een paneel links.
   Zo gemeten in de referentie: het midden van de balk valt precies samen met
   het midden van het scherm. Alleen als het paneel er anders overheen zou
   vallen wijkt hij uit. */
@media (max-width: 1180px) {
    .rt-has-panel .rt-search {
        left: calc(var(--rt-gap) + var(--rt-panel-w) + var(--rt-gap));
        transform: none;
        width: calc(100vw - var(--rt-panel-w) - var(--rt-rail-w) - 5 * var(--rt-gap));
    }
}

.rt-search input {
    flex: 1;
    align-self: stretch;
    border: 0;
    background: transparent;
    color: var(--text-primary);
    font: inherit;
    font-size: var(--rt-t-lead);
    outline: none;
    min-width: 0;
}

.rt-search input::placeholder { color: var(--text-muted); }
.rt-search .rt-i { color: var(--text-muted); flex: 0 0 auto; }

/* ── Statuschip rechtsboven ──────────────────────────────────────────────── */

.rt-status {
    position: absolute;
    top: var(--rt-gap);
    right: calc(var(--rt-gap-r) + var(--rt-rail-w) + var(--rt-gap));
    display: flex;
    align-items: center;
    gap: 4px;
    height: var(--rt-bar-h);
    padding: 0 6px 0 16px;
    background: var(--bg-card);
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-pill);
    box-shadow: var(--rt-shadow);
}

/* Landelijke punctualiteit naast de klok, met de richting van de laatste tien
   minuten. Het cijfer blijft neutraal; alleen de pijl draagt kleur, zodat de
   chip rustig blijft en je toch in één blik ziet welke kant het op gaat. */
.rt-punct {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: var(--rt-t-lead);
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.rt-punct-arrow { color: var(--text-muted); }
.rt-punct[data-trend="omhoog"] .rt-punct-arrow { color: var(--accent-ontime); }
.rt-punct[data-trend="omlaag"] .rt-punct-arrow { color: var(--accent-cancel); }

.rt-punct-arrow svg { stroke-width: 2.4; }

/* ── Grafiekje onder de punctualiteit ────────────────────────────────────── */

/* Het percentage zegt waar je staat, de pijl welke kant het opgaat. Het
   verloop van de laatste twee uur laat zien of dat een uitschieter is of een
   lijn. Dat hoort niet permanent in beeld, dus het verschijnt bij hover en
   bij toetsenbordfocus. */
.rt-punct { position: relative; cursor: default; }

.rt-punct-venster {
    position: absolute;
    top: calc(100% + 12px);
    right: -12px;
    width: 264px;
    padding: 12px 14px 11px;
    background: var(--bg-card);
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-card);
    box-shadow: var(--rt-shadow);
    z-index: 20;
    cursor: default;
}

.rt-punct-venster[hidden] { display: none; }

@media (prefers-reduced-motion: no-preference) {
    .rt-punct-venster { animation: rt-punct-in .16s var(--rt-ease); }
    @keyframes rt-punct-in {
        from { opacity: 0; transform: translateY(-4px); }
        to   { opacity: 1; transform: none; }
    }
}

.rt-punct-kop {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 9px;
}

.rt-punct-span {
    font-size: var(--rt-t-micro);
    color: var(--text-muted);
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
}

.rt-punct-graf { display: block; width: 100%; height: auto; overflow: visible; }

.rt-punct-lijn {
    fill: none;
    stroke: var(--ns-yellow-dim);
    stroke-width: 2;
    stroke-linejoin: round;
    stroke-linecap: round;
}

html[data-rt-dark="1"] .rt-punct-lijn { stroke: var(--ns-yellow); }

.rt-punct-vlak {
    fill: color-mix(in srgb, var(--ns-yellow) 16%, transparent);
    stroke: none;
}

.rt-punct-punt {
    fill: var(--ns-yellow-dim);
    stroke: var(--bg-card);
    stroke-width: 2;
}

html[data-rt-dark="1"] .rt-punct-punt { fill: var(--ns-yellow); }

.rt-punct-as,
.rt-punct-voet {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: var(--rt-t-micro);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

.rt-punct-as { margin-top: 3px; }

.rt-punct-voet {
    margin-top: 9px;
    padding-top: 9px;
    border-top: 1px solid var(--border-subtle);
}

.rt-punct-voet b { color: var(--text-primary); font-weight: 700; }

.rt-punct-leeg {
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
    margin: 0;
}

/* De pijl schuift één keer de kant op die hij aanwijst, en blijft dan stil.
   Bewust geen lus: een indicator die permanent beweegt trekt de aandacht weg
   van de data en zegt na de eerste seconde niets meer. De beweging speelt
   alleen als het cijfer of de richting daadwerkelijk verandert. */
@media (prefers-reduced-motion: no-preference) {
    .rt-punct-arrow.rt-nudge[data-dir="omhoog"] {
        animation: rt-nudge-omhoog .6s cubic-bezier(.2, .75, .3, 1);
    }

    .rt-punct-arrow.rt-nudge[data-dir="omlaag"] {
        animation: rt-nudge-omlaag .6s cubic-bezier(.2, .75, .3, 1);
    }

    /* Bij "vrijwel gelijk" hoort geen beweging: er is niets aangewezen. */
    @keyframes rt-nudge-omhoog {
        0%   { transform: translateY(6px);  opacity: 0; }
        45%  { transform: translateY(-3px); opacity: 1; }
        70%  { transform: translateY(1px); }
        100% { transform: translateY(0);    opacity: 1; }
    }

    @keyframes rt-nudge-omlaag {
        0%   { transform: translateY(-6px); opacity: 0; }
        45%  { transform: translateY(3px);  opacity: 1; }
        70%  { transform: translateY(-1px); }
        100% { transform: translateY(0);    opacity: 1; }
    }
}

/* Het scheidingslijntje tussen klok en punctualiteit. */
.rt-status-sep {
    width: 1px;
    align-self: stretch;
    margin: 11px 10px;
    background: var(--border);
    flex: 0 0 auto;
}

/* Er stond hier een badge die permanent "Live" riep. Die zegt niets: als de
   verbinding het niet deed zou de klok ernaast allang stilstaan. Bovendien
   staat zoiets niet in de referentie.
   
   De toestand is nu onzichtbaar zolang alles werkt en verschijnt alleen bij
   een storing. Dat werkt met gewone broer-selectors, dus zonder :has() en
   zonder aanpassing aan de setStatus-code van elke pagina: die zet alleen
   de klasse `error` op het puntje. */
.rt-state {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--rt-t-small);
    font-weight: 600;
    color: var(--accent-cancel);
}

.rt-state .live-dot {
    width: 0;
    height: 0;
    margin: 0;
    border-radius: 50%;
    background: var(--accent-cancel);
    box-shadow: none;
}

.rt-state .live-dot + span { display: none; }

.rt-state .live-dot.error {
    width: 7px;
    height: 7px;
    margin-left: 10px;
}

.rt-state .live-dot.error + span { display: inline; padding-right: 4px; }

.rt-status-time {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--rt-t-lead);
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    padding-right: 0;
}

.rt-status-time .rt-i { color: var(--ns-yellow); }

/* ── Navigatierail rechts ────────────────────────────────────────────────── */

.rt-rail {
    position: absolute;
    z-index: 20;
    right: var(--rt-gap-r);
    top: 50%;
    transform: translateY(-50%);
    width: var(--rt-rail-w);
    padding: 8px 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--bg-card);
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-panel);
    box-shadow: var(--rt-shadow);
    max-height: calc(100vh - 2 * var(--rt-gap));
    /* Geen overflow-hidden of -auto hier: het uitklapmenu is een absoluut
       gepositioneerd kind en zou daardoor worden afgeknipt. */
    overflow: visible;
}

/* De "Meer"-knop is het enige railitem dat in een wikkel-div zit, en die wikkel
   is dus het flex-kind. De pagina's dragen daar nog `margin-left: auto` op mee
   uit de oude horizontale navigatiebalk, waar de knop naar het rechteruiteinde
   moest worden geduwd. In een verticale rail doet die automarge twee dingen
   fout: hij schuift de knop 26 px opzij, en hij schakelt het uitrekken over de
   volle breedte uit, waardoor de knop 30 px breed werd tegen 56 voor de rest. */
.rt-rail .nav-dropdown {
    /* The menu is anchored to the complete rail, not this single button. */
    position: static;
    margin: 0;
    width: 100%;
    display: flex;
    flex-direction: column;
}

.rt-rail .nav-dropdown > .rt-rail-item {
    width: 100%;
}

.rt-rail-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 7px;
    min-height: 58px;
    padding: 10px 2px;
    border-radius: var(--rt-r-panel);
    text-decoration: none;
    color: var(--text-secondary);
    transition: color .15s var(--rt-ease), background .15s var(--rt-ease);
}

.rt-rail-item:hover { color: var(--text-primary); background: var(--bg-hover); }

/* De "Meer"-knop is een button, geen link: die brengt zijn eigen useragent-
   stijl mee en moet expliciet worden teruggezet. Dit stond eerder als inline
   stijl in de markup en won daardoor van de actieve staat hieronder. */
button.rt-rail-item {
    width: 100%;
    background: none;
    border: 0;
    font: inherit;
    cursor: pointer;
}

.rt-rail-item .rt-i {
    width: 26px;
    height: 24px;
    display: grid;
    place-items: center;
}

.rt-rail-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0;
    text-align: center;
    line-height: 1.15;
}

/* De hele actieve tegel is gevuld, icoon en label samen wit. Zo staat het in
   de referentie en het leest sterker dan alleen een gekleurd icoonvlak. */
.rt-rail-item[aria-current="page"] {
    background: var(--ns-blue);
    color: #fff;
    border-radius: var(--rt-r-panel);
}

.rt-rail-item[aria-current="page"]:hover { background: var(--ns-blue); color: #fff; }

html[data-rt-dark="1"] .rt-rail-item[aria-current="page"],
html[data-rt-dark="1"] .rt-rail-item[aria-current="page"]:hover {
    background: var(--ns-yellow);
    color: #10151c;
}

/* ── Uitklapmenu in de rail ──────────────────────────────────────────────── */

/* De rail toont vier bestemmingen plus "Meer". De rest hangt in dit paneel,
   dat links van de rail openklapt. Het houdt bewust het id dat theme.js
   gebruikt om zijn instellingenknop aan te haken. */
.rt-menu {
    position: absolute;
    right: calc(var(--rt-rail-w) + var(--rt-gap) + 6px);
    bottom: 0;
    width: 280px;
    max-width: calc(100vw - 32px);
    max-height: min(640px, calc(100dvh - 100px));
    overflow-y: auto;
    overscroll-behavior: contain;
    min-width: 208px;
    padding: 6px;
    display: none;
    flex-direction: column;
    gap: 1px;
    background: var(--bg-card);
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-card);
    box-shadow: var(--rt-shadow);
    z-index: 10;
}

.rt-menu.open { display: flex; }

/* .nav-dropdown-item is de klasse die theme.js aan zijn eigen knop geeft;
   die styling hoort hier dus ook te staan, anders valt de instellingenknop
   visueel buiten het menu. */
.rt-menu a,
.rt-menu .nav-dropdown-item {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 11px;
    border-radius: 8px;
    text-decoration: none;
    color: var(--text-secondary);
    font-size: var(--rt-t-body);
    font-weight: 500;
    white-space: normal;
    min-height: 44px;
    cursor: pointer;
}

.rt-menu a:hover,
.rt-menu .nav-dropdown-item:hover { background: var(--bg-hover); color: var(--text-primary); }

.rt-menu-sep {
    height: 1px;
    background: var(--border-subtle);
    margin: 5px 4px;
}

.rt-menu-label {
    font-size: var(--rt-t-micro);
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: none;
    color: var(--text-muted);
    padding: 8px 11px 4px;
}

@media (max-width: 820px) {
    .rt-menu {
        right: var(--rt-gap);
        left: var(--rt-gap);
        bottom: calc(100% + 8px);
        min-width: 0;
    }
}

/* ── Keuzeknoppen en selects in het paneel ───────────────────────────────── */

/* Een segmented control: twee of drie opties waarvan er één aan staat. */
.rt-seg {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 3px;
    padding: 3px;
    background: var(--bg-card-alt);
    border: 1px solid var(--border-subtle);
    border-radius: 9px;
}

.rt-seg button {
    padding: 7px 8px;
    border: 0;
    border-radius: 7px;
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: var(--rt-t-small);
    font-weight: 600;
    cursor: pointer;
    transition: background .15s var(--rt-ease), color .15s var(--rt-ease);
}

.rt-seg button:hover { color: var(--text-primary); }

.rt-seg button.active {
    background: var(--bg-card);
    color: var(--text-primary);
    box-shadow: var(--rt-shadow-sm);
}

.rt-select {
    width: 100%;
    height: 36px;
    padding: 0 30px 0 11px;
    border-radius: 9px;
    border: 1px solid var(--border);
    background: var(--bg-card-alt);
    color: var(--text-primary);
    font: inherit;
    font-size: var(--rt-t-body);
    cursor: pointer;
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                      linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position: calc(100% - 15px) 15px, calc(100% - 10px) 15px;
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

.rt-select:hover { border-color: var(--text-muted); }

/* ── Legenda ─────────────────────────────────────────────────────────────── */

.rt-legend { display: flex; flex-direction: column; gap: 7px; }

.rt-legend-row {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
}

.rt-legend-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: 0 0 auto;
}

/* ── Zoomknoppen ─────────────────────────────────────────────────────────── */

.rt-zoom {
    position: absolute;
    right: var(--rt-gap-r);
    bottom: var(--rt-gap);
    display: flex;
    flex-direction: column;
    background: var(--bg-card);
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-card);
    box-shadow: var(--rt-shadow-sm);
    overflow: hidden;
}

.rt-zoom button {
    width: 34px;
    height: 32px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 0;
    color: var(--text-secondary);
    cursor: pointer;
    font: inherit;
}

.rt-zoom button:hover { background: var(--bg-hover); color: var(--text-primary); }
.rt-zoom button + button { border-top: 1px solid var(--border-subtle); }

/* ── Tabbalk onderin het paneel ──────────────────────────────────────────── */

.rt-tabs {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 4px;
    padding: 6px;
}

.rt-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    padding: 11px 4px 10px;
    background: transparent;
    border: 0;
    color: var(--text-muted);
    cursor: pointer;
    font: inherit;
    font-size: var(--rt-t-micro);
    font-weight: 600;
    transition: color .15s var(--rt-ease), background .15s var(--rt-ease);
}

.rt-tab:hover { color: var(--text-secondary); }

.rt-tab[aria-selected="true"],
.rt-tab.active {
    color: var(--text-primary);
    background: var(--bg-card-alt);
    border-radius: var(--rt-r-card);
}

.rt-tab[aria-selected="true"] .rt-i,
.rt-tab.active .rt-i { color: var(--ns-yellow-dim); }
html[data-rt-dark="1"] .rt-tab[aria-selected="true"] .rt-i,
html[data-rt-dark="1"] .rt-tab.active .rt-i { color: var(--ns-yellow); }

/* ── Koptekst en labels ──────────────────────────────────────────────────── */

.rt-eyebrow {
    font-size: var(--rt-t-micro);
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: none;
    color: var(--text-muted);
}

.rt-title {
    font-size: var(--rt-t-display);
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--text-primary);
    line-height: 1.08;
    font-variant-numeric: tabular-nums;
}

.rt-subtitle {
    font-size: var(--rt-t-body);
    color: var(--text-secondary);
}

.rt-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 8px;
}

/* ── Chips en pillen ─────────────────────────────────────────────────────── */

.rt-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 9px;
    border-radius: var(--rt-r-pill);
    font-size: var(--rt-t-micro);
    font-weight: 700;
    letter-spacing: .03em;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Statuskleuren dragen ook een eigen vorm-signaal in de markup (tekst als
   "+5 min" of "Uitval"), zodat kleur nooit de enige drager is. */
.rt-chip-ontime { background: color-mix(in srgb, var(--accent-ontime) 15%, transparent); color: var(--accent-ontime); }
.rt-chip-delay  { background: color-mix(in srgb, var(--accent-delay) 16%, transparent);  color: var(--accent-delay); }
.rt-chip-cancel { background: color-mix(in srgb, var(--accent-cancel) 15%, transparent); color: var(--accent-cancel); }
.rt-chip-warn   { background: color-mix(in srgb, var(--accent-warn) 17%, transparent);   color: var(--accent-warn); }
.rt-chip-brand  { background: color-mix(in srgb, var(--ns-yellow) 22%, transparent);     color: var(--ns-blue); }
.rt-chip-flat   { background: var(--bg-card-alt); color: var(--text-secondary); }

html[data-rt-dark="1"] .rt-chip-brand { background: var(--ns-yellow); color: #10151c; }

/* Live-hartslag. Alleen als de gebruiker beweging toestaat. */
.rt-live-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--accent-ontime);
    flex: 0 0 auto;
}

/* Geen knipperend lampje. Een statusindicator die permanent beweegt trekt
   de aandacht weg van de data en zegt niets extra's: de kleur draagt de
   boodschap al, en bij een storing verandert die. */

/* ── Stattegels ──────────────────────────────────────────────────────────── */

.rt-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(78px, 1fr));
    gap: 8px;
}

.rt-stat {
    background: var(--bg-card-alt);
    border: 1px solid var(--border-subtle);
    border-radius: var(--rt-r-tile);
    padding: 10px 8px 9px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    text-align: center;
    min-width: 0;
}

.rt-stat .rt-i { color: var(--text-muted); }

.rt-stat-label {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.rt-stat-value {
    font-size: var(--rt-t-lead);
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ── Reisbalk: vertrek, duur, aankomst ───────────────────────────────────── */

.rt-journey {
    background: var(--bg-card-alt);
    border: 1px solid var(--border-subtle);
    border-radius: var(--rt-r-card);
    padding: 12px 14px 13px;
}

.rt-journey-row {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 10px;
}

.rt-journey-time {
    font-size: 25px;
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
    line-height: 1.1;
}

.rt-journey-place {
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
    margin-top: 2px;
}

.rt-journey-mid { text-align: center; }

/* Het lijntje tussen vertrek en aankomst: vol tot waar de trein is, gestippeld
   daarna. Dat maakt voortgang zichtbaar zonder een extra label. */
.rt-journey-track {
    position: relative;
    height: 2px;
    background: var(--border);
    border-radius: 2px;
    margin: 7px 0 0;
}

.rt-journey-track::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: var(--rt-progress, 0%);
    background: var(--ns-yellow);
    border-radius: 2px;
}

/* Na de trein loopt de lijn gestippeld door: dat is nog niet gereden. */
.rt-journey-track {
    background: transparent;
    background-image: radial-gradient(circle, var(--border) 1px, transparent 1.2px);
    background-size: 5px 2px;
    background-repeat: repeat-x;
    background-position: left center;
}

.rt-journey-track::after {
    content: "";
    position: absolute;
    top: 50%;
    left: var(--rt-progress, 0%);
    width: 9px;
    height: 9px;
    margin: -4.5px 0 0 -4.5px;
    border-radius: 50%;
    background: var(--ns-yellow);
    box-shadow: 0 0 0 3px var(--bg-card-alt);
}

/* ── Meldingsstrook ──────────────────────────────────────────────────────── */

.rt-alert {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 10px 10px 13px;
    border-radius: var(--rt-r-card);
    background: color-mix(in srgb, var(--accent-warn) 13%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent-warn) 26%, transparent);
    font-size: var(--rt-t-body);
    color: var(--text-primary);
}

.rt-alert-cancel {
    background: color-mix(in srgb, var(--accent-cancel) 12%, transparent);
    border-color: color-mix(in srgb, var(--accent-cancel) 26%, transparent);
}

/* ── Halteslijst ─────────────────────────────────────────────────────────── */

.rt-stops { display: flex; flex-direction: column; }

.rt-stop {
    display: grid;
    grid-template-columns: 54px 20px 1fr;
    gap: 10px;
    padding: 7px 0;
    position: relative;
}

.rt-stop-times {
    text-align: right;
    font-size: var(--rt-t-small);
    font-variant-numeric: tabular-nums;
    line-height: 1.35;
    padding-top: 1px;
}

/* Doorgestreepte planning naast de werkelijke tijd: je ziet in één blik
   of er iets verschoven is en met hoeveel. */
.rt-stop-planned {
    color: var(--text-muted);
    text-decoration: line-through;
    margin-right: 4px;
}

.rt-stop-actual { color: var(--text-primary); font-weight: 600; }

.rt-stop-rail { position: relative; display: flex; justify-content: center; }

.rt-stop-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--bg-card);
    border: 2px solid var(--border);
    margin-top: 4px;
    z-index: 1;
}

.rt-stop-passed .rt-stop-dot { background: var(--ns-yellow); border-color: var(--ns-yellow); }
.rt-stop-here .rt-stop-dot {
    background: var(--ns-yellow);
    border-color: var(--ns-yellow);
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--ns-yellow) 28%, transparent);
}

/* Verbindingslijn tussen de punten; de laatste halte krijgt er geen. */
.rt-stop:not(:last-child) .rt-stop-rail::after {
    content: "";
    position: absolute;
    top: 13px;
    bottom: -11px;
    width: 2px;
    background: var(--border);
}

.rt-stop-passed:not(:last-child) .rt-stop-rail::after { background: var(--ns-yellow); }

.rt-stop-name {
    font-size: var(--rt-t-body);
    color: var(--text-primary);
    line-height: 1.3;
    padding-top: 1px;
}

.rt-stop-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 4px;
}


/* ── Pagina zonder kaart ─────────────────────────────────────────────────── */

/* Dashboards en tabellen hebben geen kaart als ondergrond en ook geen smal
   paneel: die inhoud is juist breed. Ze krijgen dezelfde zwevende taal, maar
   dan als kolom op het canvas, met ruimte vrij voor de rail rechts. */
.rt-page {
    position: relative;
    z-index: 1;
    padding: calc(var(--rt-gap) + var(--rt-bar-h) + 20px) calc(var(--rt-rail-w) + var(--rt-gap-r) + var(--rt-gap)) 52px 40px;
    max-width: 1560px;
}

/* Elke pagina bracht zijn eigen horizontale marge mee, van 1rem tot 2.5rem.
   Daardoor stond de titel links van de inhoud in plaats van erboven. De marge
   zit nu op paginaniveau; de containers eronder houden alleen hun verticale
   ritme. */
.rt-page > main,
.rt-page > .section,
.rt-page > footer {
    padding-left: 0 !important;
    padding-right: 0 !important;
    max-width: none !important;
}

/* De oude kopbalken hadden hun eigen flex- en positieregels; die duwen de
   titel naar rechts of maken hem sticky. Hier zetten we dat terug naar een
   gewone tekstkop, ongeacht wat de pagina zelf nog declareert. */
.rt-pagehead {
    display: block !important;
    position: static !important;
    background: none !important;
    border: 0 !important;
    padding: 0 !important;
    margin: 0 0 18px !important;
    text-align: left !important;
    backdrop-filter: none !important;
    box-shadow: none !important;
}

.rt-pagehead > * { text-align: left; }

.rt-pagetitle {
    font-size: clamp(26px, 3vw, 34px);
    font-weight: 700;
    letter-spacing: -.025em;
    color: var(--text-primary);
    margin: 5px 0 0;
    line-height: 1.1;
}

/* De bestaande kaarten van de pagina krijgen de vorm van het designsysteem
   zonder dat hun markup verandert. */
.rt-page .stat-card,
.rt-page .card,
.rt-page .chart-card,
.rt-page .table-card,
.rt-page .punctuality-bar {
    border-radius: var(--rt-r-card) !important;
    border: 1px solid var(--rt-panel-border) !important;
    box-shadow: none;
}

@media (max-width: 820px) {
    .rt-page {
        padding: calc(var(--rt-gap) + 42px + 46px) var(--rt-gap) calc(var(--rt-gap) + 84px);
    }
}

/* ── Lege staat ──────────────────────────────────────────────────────────── */

/* Een leeg paneel hoort te vertellen wat je hier kunt doen, niet alleen dat
   er niets is. Geen emoji: een line-icoon volgt de tekstkleur en werkt in
   allebei de thema's. */
.rt-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    text-align: center;
    padding: 48px 20px;
    margin: auto 0;
}

.rt-empty .rt-i {
    color: var(--text-muted);
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: var(--bg-card-alt);
    border: 1px solid var(--border-subtle);
    margin-bottom: 4px;
}

.rt-empty .rt-i svg { width: 22px; height: 22px; }

.rt-empty-title {
    font-size: var(--rt-t-lead);
    font-weight: 600;
    color: var(--text-primary);
    margin: 0;
}

.rt-empty-hint {
    font-size: var(--rt-t-body);
    color: var(--text-secondary);
    margin: 0;
    max-width: 32ch;
    line-height: 1.5;
}

/* ── Knoppen ─────────────────────────────────────────────────────────────── */

.rt-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 32px;
    padding: 0 13px;
    border-radius: var(--rt-r-pill);
    border: 1px solid transparent;
    font: inherit;
    font-size: var(--rt-t-small);
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: background .15s var(--rt-ease), color .15s var(--rt-ease), border-color .15s var(--rt-ease);
}

.rt-btn-primary { background: var(--ns-yellow); color: #10151c; }
.rt-btn-primary:hover { background: var(--ns-yellow-dim); }

.rt-btn-quiet {
    background: var(--bg-card);
    color: var(--text-secondary);
    border-color: var(--border);
}
.rt-btn-quiet:hover { background: var(--bg-hover); color: var(--text-primary); }

.rt-btn-ghost { background: transparent; color: var(--text-secondary); }
.rt-btn-ghost:hover { background: var(--bg-hover); color: var(--text-primary); }

.rt-iconbtn {
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    border: 0;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
}
.rt-iconbtn:hover { background: var(--bg-hover); color: var(--text-primary); }

/* ── Iconen ──────────────────────────────────────────────────────────────── */

/* Line-iconen als inline SVG. currentColor zodat ze de tekstkleur volgen en
   in beide thema's vanzelf kloppen. Geen emoji in de interface. */
.rt-i {
    display: inline-grid;
    place-items: center;
    flex: 0 0 auto;
}

.rt-i svg {
    width: 17px;
    height: 17px;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: none;
}

.rt-i-lg svg { width: 20px; height: 20px; }
.rt-i-sm svg { width: 14px; height: 14px; }

/* ── Toetsenbord ─────────────────────────────────────────────────────────── */

.rt-layer :focus-visible,
.rt-panel :focus-visible {
    outline: 2px solid var(--ns-yellow);
    outline-offset: 2px;
    border-radius: 4px;
}


/* ── Focus: bestaande detailkaarten in een smal paneel ───────────────────── */

/* De inhoud van focus.html is ooit ontworpen voor een pagina van 1200px breed
   en staat nu in een paneel van 372px. Deze regels leggen die layout om naar
   één kolom en halen de royale binnenmarges terug, zodat de bestaande markup
   en JS ongewijzigd kunnen blijven werken.

   Alleen binnen #content, zodat geen andere pagina hier last van heeft. */

#content .focus-grid,
#content .graph-forecast-row,
#content .comp-info-grid {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

#content > *,
#content .hero,
#content .card,
#content .map-card { max-width: 100%; }

#content .hero {
    flex-wrap: wrap;
    gap: 10px;
    padding: 14px 16px;
    border-radius: var(--rt-r-card);
}

#content .hero-right {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    width: 100%;
}

#content .hero-train-number { font-size: 30px; letter-spacing: -.02em; }
#content .hero-destination { font-size: var(--rt-t-body); }

/* Afbeeldingen van materieel zijn breder dan het paneel; laten schalen in
   plaats van eruit steken. */
#content img,
#content svg:not(.rt-i svg) { max-width: 100%; height: auto; }

#content .comp-info-item,
#content .spec-item {
    padding: 9px 11px;
    border-radius: var(--rt-r-tile);
}

/* Alles wat horizontaal langer is dan het paneel krijgt zijn eigen
   scrollgebied, zodat het paneel zelf nooit zijwaarts schuift. */
#content .comp-train,
#content .composition-strip,
#content table { max-width: 100%; overflow-x: auto; }

/* ── Treininfo in het paneel ─────────────────────────────────────────────── */

/* Deze kaarten zijn ooit voor een donkere achtergrond getekend. Op wit ging
   dat mis: het treinnummer stond in NS-geel, en geel als tekst op wit leest
   niet. Datzelfde gold voor de type-badge, geel op lichtgeel.

   De regel is nu consequent: geel is vlak en actieve staat, nooit tekst op
   een lichte ondergrond. Het nummer staat in inkt, de badges hebben een
   verzadigde tekstkleur op een licht vlak van dezelfde tint. */

#content .hero {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    padding: 15px 16px 16px;
}

#content .hero-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 7px;
    margin-bottom: 9px;
}

#content .hero .type-badge {
    font-family: inherit;
    font-size: var(--rt-t-micro);
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    padding: 3px 9px;
    border-radius: var(--rt-r-pill);
    margin: 0;
}

/* Leesbare varianten in beide thema's, via color-mix op de tokens in plaats
   van vaste rgba-waarden die alleen op donker werkten. */
#content .hero .type-badge.ic,
#content .hero .type-badge.default {
    background: color-mix(in srgb, var(--ns-yellow) 26%, transparent);
    color: var(--ns-blue);
}

#content .hero .type-badge.spr {
    background: color-mix(in srgb, var(--accent-ontime) 15%, transparent);
    color: var(--accent-ontime);
}

html[data-rt-dark="1"] #content .hero .type-badge.ic,
html[data-rt-dark="1"] #content .hero .type-badge.default {
    background: var(--ns-yellow);
    color: #10151c;
}

#content .hero-type-text {
    font-size: var(--rt-t-body);
    font-weight: 600;
    color: var(--text-primary);
}

#content .hero-operator {
    font-size: var(--rt-t-small);
    color: var(--text-muted);
}

/* Het nummer is het anker van de kaart: groot, in inkt, cijfers uitgelijnd. */
#content .hero-train-number {
    font-family: inherit;
    font-size: 38px;
    font-weight: 700;
    letter-spacing: -.03em;
    line-height: 1;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    margin-bottom: 8px;
}

#content .hero-destination {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    font-size: var(--rt-t-body);
    line-height: 1.35;
    margin-bottom: 12px;
}

#content .hero-from { color: var(--text-secondary); }
#content .hero-to { color: var(--text-primary); font-weight: 600; }
#content .hero-destination .arrow { color: var(--text-muted); margin: 0; }

/* De statusmelding was een blok mono-tekst op 1.1rem; dat schreeuwde harder
   dan het treinnummer. Nu een gewone chip, in verhouding. */
#content .hero-delay {
    font-family: inherit;
    font-size: var(--rt-t-small);
    font-weight: 700;
    letter-spacing: .02em;
    padding: 4px 11px;
    border-radius: var(--rt-r-pill);
}

#content .hero-delay.ontime   { background: color-mix(in srgb, var(--accent-ontime) 15%, transparent); color: var(--accent-ontime); }
#content .hero-delay.warn     { background: color-mix(in srgb, var(--accent-warn) 17%, transparent);   color: var(--accent-warn); }
#content .hero-delay.severe   { background: color-mix(in srgb, var(--accent-delay) 16%, transparent);  color: var(--accent-delay); }
#content .hero-delay.cancelled{ background: color-mix(in srgb, var(--accent-cancel) 15%, transparent); color: var(--accent-cancel); }

/* ── ATB-chip ────────────────────────────────────────────────────────────── */

/* Stond op een verzadigd vlak met bijna-zwarte tekst erop. In daglicht is
   --accent-ontime een donkergroen, en donkergroen met zwarte letters leest
   niet. Zelfde aanpak als de andere chips: een licht vlak van de eigen tint
   met de verzadigde variant als tekstkleur. */
#content .atb-box {
    background: color-mix(in srgb, var(--ns-yellow) 26%, transparent) !important;
    color: var(--ns-blue) !important;
    border: 1px solid color-mix(in srgb, var(--ns-yellow) 45%, transparent);
    font-size: var(--rt-t-body);
    padding: 5px 12px;
    border-radius: var(--rt-r-pill);
}

#content .atb-box.high-speed {
    background: color-mix(in srgb, var(--accent-ontime) 16%, transparent) !important;
    color: var(--accent-ontime) !important;
    border-color: color-mix(in srgb, var(--accent-ontime) 38%, transparent);
}

#content .atb-box.loading {
    background: var(--bg-card-alt) !important;
    color: var(--text-muted) !important;
    border-color: var(--border-subtle);
}

#content .atb-box .atb-label { opacity: 1; color: var(--text-muted); }

html[data-rt-dark="1"] #content .atb-box { color: var(--ns-yellow) !important; }

/* ── Limiet op de balkmeter ──────────────────────────────────────────────── */

/* De balk zegt hoe hard je gaat; zonder markering zegt hij niet hoe hard je
   mág. Die streep maakt in één blik zichtbaar of er nog ruimte is of dat de
   trein op de limiet zit. */
#content .meter-balk-limiet {
    position: absolute;
    top: -4px;
    bottom: -4px;
    width: 2px;
    background: var(--text-primary);
    border-radius: 2px;
    opacity: .6;
}

#content .meter-balk-spoor { position: relative; overflow: visible; }

/* Staat in de schaalregel onder de balk, op dezelfde positie als de streep.
   De schaalcijfers eromheen zijn muted; deze is inkt, zodat hij eruit springt
   zonder een eigen kleur nodig te hebben. */
#content .meter-balk-limiet-label {
    position: absolute;
    top: 0;
    transform: translateX(-50%);
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .04em;
    color: var(--text-primary);
    white-space: nowrap;
    background: var(--bg-card);
    padding: 0 3px;
}

/* ── Materieelrij ────────────────────────────────────────────────────────── */

/* De rij per treindeel stond vol afkortingen op één regel en brak op rare
   plekken af. Nu een leesbare kop met het type, en de zitplaatsen voluit. */
#content .part-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    padding: 9px 11px;
}

#content .part-type {
    font-weight: 700;
    font-size: var(--rt-t-body);
    color: var(--text-primary);
    letter-spacing: .01em;
}

#content .part-nummer {
    font-family: var(--font-mono), monospace;
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
}

#content .part-dest { font-size: var(--rt-t-small); color: var(--text-secondary); }

#content .part-seats {
    display: flex;
    gap: 10px;
    margin-left: auto;
    white-space: nowrap;
}

#content .part-klas {
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
    white-space: nowrap;
}

#content .part-klas b {
    color: var(--text-primary);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* De voorzieningen stonden als een rij minuscule stipjes die niemand kon
   lezen. Iets groter, en met genoeg ruimte ertussen. */
#content .part-facilities {
    display: inline-flex;
    gap: 6px;
    align-items: center;
    opacity: .75;
}

#content .part-facilities svg,
#content .part-facilities img { width: 15px; height: 15px; }

/* ── Inklapbare secties ──────────────────────────────────────────────────── */

/* Het detailpaneel is een lange kolom. Niet iedereen gebruikt alles: wie de
   route volgt heeft de snelheidsmeter niet nodig. Vandaar inklapbaar, en in
   de instellingen te herschikken of uit te zetten. */
.rt-sec {
    border: 1px solid var(--border-subtle);
    border-radius: var(--rt-r-card);
    background: var(--bg-card);
    overflow: hidden;
}

.rt-sec-kop {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 10px 13px;
    background: transparent;
    border: 0;
    cursor: pointer;
    font: inherit;
    color: var(--text-secondary);
    text-align: left;
}

.rt-sec-kop:hover { background: var(--bg-hover); color: var(--text-primary); }

.rt-sec-titel {
    font-size: var(--rt-t-micro);
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: none;
}

.rt-sec-chevron { transition: transform .2s var(--rt-ease); }
.rt-sec.dicht .rt-sec-chevron { transform: rotate(-90deg); }

.rt-sec-body { padding: 0 11px 12px; }
.rt-sec.dicht .rt-sec-body { display: none; }

/* De kaarten binnen een sectie hebben hun eigen rand niet meer nodig: de
   sectie zelf is het kader geworden. */
.rt-sec-body > * {
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* ── Verstoringen op de kaart ────────────────────────────────────────────── */

.storing-weergave { max-width: 480px; margin: 0 0 14px; }

.storing-kaart-wrap {
    position: relative;
    border: 1px solid var(--border);
    border-radius: var(--rt-r-card);
    overflow: hidden;
    background: var(--bg-card);
}

.storing-kaart-wrap[hidden] { display: none; }

/* De kaartenlijst heeft `display: grid` in de pagina-CSS, en dat wint van het
   hidden-attribuut. Zonder deze regel bleef de lijst onder de kaart staan. */
#disruptions-grid[hidden] { display: none !important; }

/* Nederland is in deze projectie hoger dan breed. In een brede, lage kaart
   bepaalt de breedtegraad de zoom en zie je vervolgens van Ierland tot Polen.
   Hoger maken lost dat op zonder de kaart smal te hoeven maken. */
#storing-map { width: 100%; background: var(--bg-deep); }

.storing-legenda {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
    padding: 10px 14px;
    border-top: 1px solid var(--border-subtle);
    background: var(--bg-card);
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
}

.storing-legenda > span { display: flex; align-items: center; gap: 7px; }

.storing-legenda i {
    display: block;
    width: 20px;
    height: 3px;
    border-radius: 2px;
    flex: 0 0 auto;
}

.storing-legenda i.dik { height: 6px; }

/* Een gestreepte lijn in de legenda net als op de kaart: het patroon draagt
   hier betekenis, dus het moet in beide op elkaar lijken. */
.storing-legenda i.streep {
    background-image: repeating-linear-gradient(90deg,
        currentColor 0 5px, transparent 5px 9px) !important;
}

/* Alleen het zwaarste geval knippert: geen treinen, of veel minder treinen.
   Bij beweging-uit blijft de lijn gewoon staan; de dikte draagt de boodschap
   dan alleen. */
@media (prefers-reduced-motion: no-preference) {
    .storing-knippert { animation: storing-knipper 1.7s ease-in-out infinite; }
    @keyframes storing-knipper {
        /* Niet naar bijna-nul: de lijn moet op elk moment af te lezen blijven.
           Het knipperen is een accent, geen aan-uitschakelaar. */
        0%, 100% { stroke-opacity: .95; }
        50%      { stroke-opacity: .45; }
    }
}

/* ── Volledig scherm voor de storingenkaart ──────────────────────────────── */

.storing-kaart-wrap { position: relative; }

/* Rechtsboven zit de statuschip van de pagina; de knop staat dus links, waar
   niets anders ligt. */
.storing-schermknop {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 500;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 34px;
    padding: 0 13px;
    border-radius: var(--rt-r-pill);
    border: 1px solid var(--rt-panel-border);
    background: var(--bg-card);
    color: var(--text-secondary);
    box-shadow: var(--rt-shadow-sm);
    font: inherit;
    font-size: var(--rt-t-small);
    font-weight: 600;
    cursor: pointer;
}

.storing-schermknop:hover { color: var(--text-primary); background: var(--bg-hover); }

/* De kaart is de standaardweergave en vult de ruimte onder de kop, net als op
   de andere kaartpagina's. De pagina zelf scrolt dan niet: de kolom met
   meldingen heeft zijn eigen scrollgebied. */
body.storing-kaart-actief { overflow: hidden; }

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

/* Kolom en kaart naast elkaar, samen zo hoog als wat er onder de kop over is.
   Die 210 px is de paginakop plus de keuzeknoppen plus de onderrand. */
.storing-kaart-wrap {
    display: grid;
    grid-template-columns: 340px minmax(0, 1fr);
    height: calc(100vh - 210px);
    min-height: 420px;
}

.storing-kaart-wrap #storing-map { height: 100%; }

.storing-kaart-wrap .storing-legenda {
    position: absolute;
    left: calc(340px + 14px);
    bottom: 14px;
    z-index: 500;
    border: 1px solid var(--rt-panel-border);
    border-radius: var(--rt-r-card);
    box-shadow: var(--rt-shadow);
    padding: 9px 13px;
}

/* ── Kolom met de lijst ──────────────────────────────────────────────────── */

.storing-kolom {
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--bg-card);
    border-right: 1px solid var(--border-subtle);
}

.storing-kolom[hidden] { display: none; }

.storing-kolom-kop {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 13px 14px 12px;
    border-bottom: 1px solid var(--border-subtle);
    flex: 0 0 auto;
}

.storing-kolom-lijst {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.storing-regel {
    flex: 0 0 auto;
    display: flex;
    gap: 11px;
    width: 100%;
    padding: 10px 11px;
    text-align: left;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--rt-r-card);
    cursor: pointer;
    font: inherit;
}

.storing-regel:hover { background: var(--bg-hover); }

.storing-regel.actief {
    background: var(--bg-card-alt);
    border-color: var(--border);
}

/* Hetzelfde signaal als op de kaart: kleur voor soort, dikte voor ernst. */
.storing-regel-balk {
    width: 3px;
    border-radius: 2px;
    flex: 0 0 auto;
    background: var(--accent-cancel);
}

.storing-regel-balk[data-soort="werk"] { background: var(--ns-yellow-dim); }
.storing-regel-balk[data-zwaar="1"] { width: 6px; }

.storing-regel-tekst { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.storing-regel-titel {
    font-size: var(--rt-t-body);
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.3;
}

.storing-regel-oorzaak {
    font-size: var(--rt-t-small);
    font-weight: 600;
    color: var(--accent-cancel);
}

.storing-regel-balk[data-soort="werk"] ~ .storing-regel-tekst .storing-regel-oorzaak {
    color: var(--ns-blue);
}

html[data-rt-dark="1"] .storing-regel-balk[data-soort="werk"] ~ .storing-regel-tekst .storing-regel-oorzaak {
    color: var(--ns-yellow);
}

.storing-regel-desc {
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

@media (max-width: 820px) {
    .storing-kaart-wrap {
        grid-template-columns: 1fr;
        grid-template-rows: minmax(0, 1fr) 42vh;
        height: calc(100vh - 190px);
    }
    .storing-kaart-wrap .storing-kolom {
        order: 2;
        border-right: 0;
        border-top: 1px solid var(--border-subtle);
    }
    .storing-kaart-wrap #storing-map { order: 1; }
    .storing-kaart-wrap .storing-legenda { display: none; }
}

/* ── Busvervanging ───────────────────────────────────────────────────────── */

/* Geel is in deze huisstijl een vlak, geen tekstkleur. Het busje is daarom een
   gele schijf met donkere inkt erop: leesbaar op een lichte én een donkere
   kaart, zonder een eigen kleurregel per thema. */
.storing-bus-badge {
    display: inline-grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--ns-yellow);
    border: 2px solid var(--bg-card);
    box-shadow: var(--rt-shadow-sm);
}

.storing-bus-badge svg {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: #10151c;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.storing-bus-badge.klein { width: 18px; height: 18px; border-width: 1.5px; }
.storing-bus-badge.klein svg { width: 11px; height: 11px; stroke-width: 2.1; }

.storing-bus { background: none; border: 0; }

/* ── Popup van een verstoring ────────────────────────────────────────────── */

.storing-popup { font-size: var(--rt-t-body); max-width: 260px; }

.storing-popup-soort {
    display: inline-block;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    padding: 3px 8px;
    border-radius: var(--rt-r-pill);
    margin-bottom: 7px;
    background: color-mix(in srgb, var(--accent-cancel) 15%, transparent);
    color: var(--accent-cancel);
}

.storing-popup-soort[data-type="MAINTENANCE"] {
    background: color-mix(in srgb, var(--ns-yellow) 26%, transparent);
    color: var(--ns-blue);
}

html[data-rt-dark="1"] .storing-popup-soort[data-type="MAINTENANCE"] {
    background: var(--ns-yellow);
    color: #10151c;
}

.storing-popup h4 {
    margin: 0 0 5px;
    font-size: var(--rt-t-lead);
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.25;
}

.storing-popup p { margin: 0 0 5px; color: var(--text-secondary); line-height: 1.45; }
.storing-popup-oorzaak { color: var(--accent-cancel) !important; font-weight: 600; }
.storing-popup-periode { color: var(--text-muted) !important; font-size: var(--rt-t-small); }

@media (max-width: 720px) {
    #storing-map { height: 420px; }
    .storing-weergave { margin-left: 0; }
}

/* ── Opvallende treinen in de lege staat ─────────────────────────────────── */

/* Wie geen treinnummer paraat heeft, staat anders voor een leeg paneel. Deze
   kaarten zijn dezelfde records als op de cijferpagina, maar hier als
   snelkoppeling: klikken en je volgt die trein. */
.rt-records { margin-top: 4px; }

.rt-records-lijst { display: flex; flex-direction: column; gap: 7px; }

.rt-record {
    display: flex;
    align-items: center;
    gap: 11px;
    width: 100%;
    padding: 10px 11px;
    text-align: left;
    background: var(--bg-card-alt);
    border: 1px solid var(--border-subtle);
    border-radius: var(--rt-r-card);
    cursor: pointer;
    font: inherit;
    transition: background .15s var(--rt-ease), border-color .15s var(--rt-ease);
}

.rt-record:hover {
    background: var(--bg-hover);
    border-color: var(--border);
}

.rt-record-icoon {
    width: 32px;
    height: 32px;
    flex: 0 0 auto;
    border-radius: 9px;
    background: color-mix(in srgb, var(--ns-yellow) 22%, transparent);
    color: var(--ns-blue);
}

html[data-rt-dark="1"] .rt-record-icoon {
    background: color-mix(in srgb, var(--ns-yellow) 20%, transparent);
    color: var(--ns-yellow);
}

.rt-record-tekst {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1;
}

.rt-record-label {
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.rt-record-waarde {
    font-size: var(--rt-t-lead);
    font-weight: 700;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
}

.rt-record-sub {
    font-size: var(--rt-t-small);
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rt-record-pijl { color: var(--text-muted); flex: 0 0 auto; }
.rt-record:hover .rt-record-pijl { color: var(--text-primary); }

/* De lege staat vult niet langer de hele hoogte: er staat nu iets onder. */
#content:has(.rt-records:not([hidden])) .rt-empty {
    margin: 0 0 6px;
    padding: 22px 20px 16px;
}

/* ── Snelheidsmeters ─────────────────────────────────────────────────────── */

/* Drie vormen voor hetzelfde getal. De wijzerplaat leest als een instrument,
   de balk kost minder hoogte, en het cijfer is voor wie het paneel vooral
   als aflezing gebruikt. */

/* De kaart eromheen is een flex-kolom met align-items:center. Het flex-kind is
   #speedo-inner, niet de meter zelf; die moet dus stretchen, anders krimpt
   alles mee tot de breedte van het getal. */
#content #speedo-inner { width: 100%; align-self: stretch; }

#content .meter-balk,
#content .meter-cijfer {
    width: 100%;
    padding: 4px 2px 2px;
}

#content .meter-balk-kop,
#content .meter-cijfer-getal {
    display: flex;
    align-items: baseline;
    gap: 7px;
    margin-bottom: 10px;
}

#content .meter-balk .speedo-speed,
#content .meter-cijfer .speedo-speed {
    font-size: 40px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -.03em;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
}

#content .meter-balk .speedo-unit,
#content .meter-cijfer .speedo-unit {
    font-size: var(--rt-t-small);
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: .06em;
    text-transform: uppercase;
}

#content .meter-balk-spoor {
    height: 8px;
    border-radius: 999px;
    background: var(--bg-card-alt);
    border: 1px solid var(--border-subtle);
    overflow: hidden;
}

#content .meter-balk-vul {
    height: 100%;
    border-radius: 999px;
    transition: width .5s var(--rt-ease);
}

/* De schaalstreepjes staan absoluut op hun eigen waarde, zodat ze kloppen
   ongeacht de breedte van het paneel. */
#content .meter-balk-as {
    position: relative;
    height: 15px;
    margin-top: 5px;
}

#content .meter-balk-as span {
    position: absolute;
    transform: translateX(-50%);
    font-size: 9.5px;
    font-weight: 600;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

#content .meter-balk-as span:first-child { transform: none; }
#content .meter-balk-as span:last-child { transform: translateX(-100%); }

#content .meter-cijfer-lijn {
    height: 3px;
    border-radius: 999px;
    background: var(--bg-card-alt);
    overflow: hidden;
}

#content .meter-cijfer-lijn > div {
    height: 100%;
    border-radius: 999px;
    transition: width .5s var(--rt-ease);
}

/* ── Materieel beknopt of uitgebreid ─────────────────────────────────────── */

/* In de beknopte stand blijft staan wat je onderweg nodig hebt: welk type,
   welk nummer, hoeveel zitplaatsen. De specificaties van de fabrikant zijn
   leuk maar niet waarvoor je de app opent. */
#content[data-materieel="beknopt"] .part-specs { display: none; }

.rt-secset-keuze { margin: 12px 0 4px; }

.rt-secset-keuze-titel {
    font-size: var(--rt-t-micro);
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: none;
    color: var(--text-muted);
    margin-bottom: 6px;
}

/* ── Instellingen voor de secties ────────────────────────────────────────── */

.rt-secset {
    background: var(--bg-card-alt);
    border: 1px solid var(--border);
    border-radius: var(--rt-r-card);
    padding: 13px 14px 14px;
}

.rt-secset-rij {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 7px 0;
    border-top: 1px solid var(--border-subtle);
}

.rt-secset-rij:first-of-type { border-top: 0; }

.rt-secset-naam {
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: var(--rt-t-body);
    color: var(--text-primary);
    cursor: pointer;
}

.rt-secset-naam input { accent-color: var(--ns-blue); width: 15px; height: 15px; cursor: pointer; }
html[data-rt-dark="1"] .rt-secset-naam input { accent-color: var(--ns-yellow); }

.rt-secset-knoppen { display: flex; gap: 3px; }

.rt-secset-knoppen button {
    width: 26px;
    height: 26px;
    border-radius: 7px;
    border: 1px solid var(--border);
    background: var(--bg-card);
    color: var(--text-secondary);
    cursor: pointer;
    font: inherit;
    line-height: 1;
}

.rt-secset-knoppen button:hover:not(:disabled) { background: var(--bg-hover); color: var(--text-primary); }
.rt-secset-knoppen button:disabled { opacity: .35; cursor: default; }

/* ── Leaflet in deze huisstijl ───────────────────────────────────────────── */

/* De eigen zoomknoppen en attributie van Leaflet passen niet in de zwevende
   laag; we verbergen ze en zetten er onze eigen versie neer. */
.leaflet-control-zoom { display: none !important; }

.leaflet-control-attribution {
    background: var(--rt-scrim) !important;
    color: var(--text-muted) !important;
    font-size: 10px !important;
    border-radius: 6px 0 0 0;
    backdrop-filter: blur(6px);
}

.leaflet-control-attribution a { color: var(--text-secondary) !important; }

.leaflet-popup-content-wrapper {
    background: var(--bg-card) !important;
    color: var(--text-primary) !important;
    border-radius: var(--rt-r-card) !important;
    box-shadow: var(--rt-shadow) !important;
    border: 1px solid var(--rt-panel-border);
}

.leaflet-popup-tip { background: var(--bg-card) !important; }

/* ── Smaller dan een laptop ──────────────────────────────────────────────── */

/* Onder 1100px is er geen ruimte meer voor paneel plus rail plus kaart. Het
   paneel gaat dan onderaan liggen als een blad over de kaart, en de rail
   wordt een horizontale balk. Dat is dezelfde taal, andere opstelling. */
@media (max-width: 1100px) {
    :root { --rt-panel-w: 320px; }
    .rt-has-panel .rt-search {
        left: calc(var(--rt-gap) + var(--rt-panel-w) + var(--rt-gap));
        width: calc(100vw - var(--rt-panel-w) - var(--rt-rail-w) - 5 * var(--rt-gap));
    }
}



/* ════════════════════════════════════════════════════════════════════════════
   Telefoon en kleine tablet
   ----------------------------------------------------------------------------
   Op een breed scherm zweven paneel, rail en kaart naast elkaar. Op een
   telefoon is daar geen ruimte voor en wordt het een gestapelde indeling:
   de rail als onderbalk, het paneel als blad daarboven, de kaart eronder.

   De railhoogte staat als variabele vast en wordt overal gebruikt om ruimte
   vrij te houden. Eerder stond daar een geschat getal, en dat klopte niet:
   het paneel liep twintig pixels onder de balk door en de laatste regel van
   de legenda was onleesbaar.
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 820px) {
    :root {
        --rt-gap: 16px;
        --rt-rail-w: auto;
        --rt-rail-h: calc(72px + env(safe-area-inset-bottom, 0px));
        --rt-panel-w: auto;
    }

    /* ── Zoeken en status bovenaan ─────────────────────────────────────── */

    .rt-search,
    .rt-has-panel .rt-search {
        left: var(--rt-gap);
        right: var(--rt-gap);
        width: auto;
        transform: none;
        height: 48px;
        padding: 0 6px 0 14px;
    }

    .rt-search input { font-size: 16px; }   /* onder 16px zoomt iOS het veld in */

    .rt-status {
        top: var(--rt-gap);
        right: var(--rt-gap);
        height: 38px;
        padding: 0 12px;
    }

    /* Staat er ook een zoekbalk, dan schuift de statuschip eronder. */
    .rt-has-panel .rt-status {
        top: calc(var(--rt-gap) + 44px + 8px);
    }

    .rt-status-time { font-size: var(--rt-t-body); }
    .rt-punct { font-size: var(--rt-t-body); }
    .rt-punct-venster { right: 0; width: min(264px, calc(100vw - 2 * var(--rt-gap))); }

    /* ── Paneel als blad onderaan ──────────────────────────────────────── */

    .rt-panel-left,
    .rt-panel-left.rt-panel-auto {
        left: var(--rt-gap);
        right: var(--rt-gap);
        width: auto;
        top: auto;
        bottom: calc(var(--rt-rail-h) + var(--rt-gap));
        max-height: min(46vh, 400px);
        max-width: none;
    }

    .rt-panel-head { padding: 12px 14px 10px; }
    .rt-panel-body { padding: 12px 14px 16px; }

    /* ── Rail als onderbalk ────────────────────────────────────────────── */

    .rt-rail {
        top: auto;
        bottom: 0;
        left: 0;
        right: 0;
        width: auto;
        transform: none;
        flex-direction: row;
        justify-content: space-between;
        gap: 0;
        padding: 6px 8px calc(6px + env(safe-area-inset-bottom, 0px));
        max-height: none;
    }

    /* De "Meer"-knop zit in een wrapper-div, en die is ook een flex-kind. Zonder
       dezelfde flex-regels eiste hij alle ruimte op en werden de vier links tot
       nul geknepen: vier iconen bovenop elkaar in de linkerhoek. */
    .rt-rail-item,
    .rt-rail .nav-dropdown {
        flex: 1 1 0;
        min-width: 0;
    }

    .rt-rail-item {
        min-height: 0;
        padding: 7px 2px;
        gap: 4px;
        border-radius: var(--rt-r-card);
    }

    .rt-rail-label { font-size: 12px; }
    .rt-rail-item .rt-i { width: 22px; height: 20px; }

    .rt-menu {
        right: var(--rt-gap);
        left: var(--rt-gap);
        bottom: calc(100% + 10px);
        min-width: 0;
        width: auto;
        max-height: min(640px, calc(100dvh - var(--rt-rail-h) - env(safe-area-inset-top, 0px) - 32px));
        overflow-y: auto;
    }

    /* ── Zoomknoppen uit de weg ────────────────────────────────────────── */

    /* Rechtsonder botsen ze met het paneel. Op een aanraakscherm knijp je
       toch; ze staan hier alleen nog als alternatief, rechtsboven onder de
       statuschip. */
    .rt-zoom {
        right: var(--rt-gap);
        bottom: auto;
        top: calc(var(--rt-gap) + 38px + 8px);
    }

    .rt-has-panel .rt-zoom {
        top: calc(var(--rt-gap) + 44px + 8px + 38px + 8px);
    }

    /* ── Pagina's zonder kaart ─────────────────────────────────────────── */

    .rt-page {
        padding: calc(var(--rt-gap) + 44px + 14px) var(--rt-gap)
                 calc(var(--rt-rail-h) + 2 * var(--rt-gap)) var(--rt-gap);
    }

    .rt-pagetitle { font-size: 24px; }

    /* ── Verstoringen ──────────────────────────────────────────────────── */

    /* De paginakop at op een telefoon van 568 px bijna 200 px op, waarvan de
       helft aan een aanhef die over twee regels brak. Op een kaartpagina is
       die ruimte de kaart zelf. */
    p.rt-eyebrow { display: none; }
    .rt-pagehead { margin-bottom: 10px; }
    .storing-weergave { max-width: none; }

    /* Vier keuzeknoppen naast elkaar passen niet op 320 px zonder ze tot
       onleesbaar te knijpen; ze mogen zijwaarts schuiven. */
    .storing-weergave .rt-seg {
        overflow-x: auto;
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;
    }
    .storing-weergave .rt-seg::-webkit-scrollbar { display: none; }
    .storing-weergave .rt-seg > * { flex: 0 0 auto; white-space: nowrap; }

    body.storing-kaart-actief {
        display: flex;
        flex-direction: column;
        height: 100dvh;
        overflow: hidden;
        padding-bottom: calc(var(--rt-rail-h) + var(--rt-gap));
    }

    body.storing-kaart-actief .app.rt-page,
    body.storing-kaart-actief main {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
        padding-bottom: 0;
    }

    /* De bronvermelding staat in kaartmodus buiten beeld en zou alleen hoogte
       kosten; de kaart draagt zijn eigen attributie. */
    body.storing-kaart-actief > .app.rt-page footer,
    body.storing-kaart-actief > footer { display: none; }

    body.storing-kaart-actief #view-kaart {
        display: flex;
        flex-direction: column;
        flex: 1 1 auto;
        min-height: 0;
    }

    .storing-kaart-wrap {
        grid-template-columns: 1fr;
        grid-template-rows: minmax(0, 1fr) minmax(0, 42%);
        flex: 1 1 auto;
        height: auto;
        min-height: 0;
    }

    .storing-kaart-wrap #storing-map { order: 1; }

    .storing-kolom {
        order: 2;
        border-right: 0;
        border-top: 1px solid var(--border-subtle);
    }

    .storing-kaart-wrap .storing-legenda { display: none; }

    /* ── Focus ─────────────────────────────────────────────────────────── */

    #content .hero-train-number { font-size: 32px; }
    #content .meter-balk .speedo-speed,
    #content .meter-cijfer .speedo-speed { font-size: 34px; }
}

/* Heel smal: de raillabels vallen weg, de iconen blijven. Onder 360 px, want
   op een telefoon van 390 px passen vijf labels nog prima. */
@media (max-width: 360px) {
    .rt-rail-label { display: block; font-size: 11px; }
    .rt-rail-item { padding: 10px 2px; }
    .rt-status-time span:not(.rt-i) { font-size: var(--rt-t-small); }
}

/* ════════════════════════════════════════════════════════════════════════════
   Brede datatabellen op een telefoon
   ----------------------------------------------------------------------------
   De punctualiteitstabellen op index en history hebben zeven kolommen. Op een
   scherm van 320 px paste daar minder dan de helft van, en de rest was in de
   praktijk onbereikbaar: het scrollgebied gaf geen enkele hint dat er kolommen
   naast stonden.

   Onder 620 px wordt elke rij daarom een kaartje. De eerste cel is de kop van
   het kaartje, de rest staat als label-waardepaar eronder. De labels komen uit
   tabel-mobiel.js, dat de <thead> naar data-label op elke cel kopieert.
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 620px) {
    .table-wrap {
        overflow: visible;
        background: transparent;
        border: 0;
        display: flex;
        flex-direction: column;
        gap: 8px;
    }

    .table-wrap table,
    .table-wrap thead,
    .table-wrap tbody,
    .table-wrap tr,
    .table-wrap td {
        display: block;
        width: auto;
        min-width: 0;
    }

    /* De kop zit nu in elke cel; als tabelkop is hij overbodig geworden.
       clip in plaats van display:none houdt hem leesbaar voor schermlezers. */
    .table-wrap thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .table-wrap tbody tr {
        background: var(--bg-card);
        border: 1px solid var(--border-subtle);
        border-radius: var(--radius, 10px);
        padding: 10px 12px;
    }

    /* Eerste cel is de titel van het kaartje: de vervoerder of de datum. */
    .table-wrap tbody tr > *:first-child {
        font-size: var(--rt-t-lead, 15px);
        font-weight: 700;
        color: var(--text-primary);
        padding: 0 0 8px;
        margin-bottom: 8px;
        border-bottom: 1px solid var(--border-subtle);
        text-align: left;
    }

    .table-wrap tbody tr > *:not(:first-child) {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 3px 0;
        text-align: right;
        border: 0;
    }

    .table-wrap tbody tr > *:not(:first-child)::before {
        content: attr(data-label);
        flex: 0 0 auto;
        font-size: var(--rt-t-small, 14px);
        font-weight: 600;
        letter-spacing: 0;
        text-transform: none;
        color: var(--text-muted);
        text-align: left;
    }

    /* De punctualiteitsbalk mag de volle breedte houden. */
    .table-wrap .pct-cell { flex: 1 1 auto; justify-content: flex-end; }
    .table-wrap .pct-bar-wrap { width: 100%; max-width: 120px; }

    /* Een rij met colspan is een laad- of legemelding en blijft één blok. */
    .table-wrap tbody tr[data-vol] { padding: 0; }
    .table-wrap tbody tr[data-vol] > * {
        border: 0;
        margin: 0;
        text-align: center;
        font-weight: 400;
        font-size: var(--rt-t-body, 13px);
    }
}

/* ════════════════════════════════════════════════════════════════════════════
   Raakvlakken en leesbaarheid op een telefoon
   ----------------------------------------------------------------------------
   Losse links stonden op 12 tot 17 px hoog. Dat is met een vinger niet te
   raken; de richtlijn is 44 px, en dat haal je zonder de opmaak te verbouwen
   door de link zelf verticale ruimte te geven.
   ════════════════════════════════════════════════════════════════════════ */

@media (max-width: 820px) {
    .back-link,
    footer a,
    .footer-text a {
        display: inline-block;
        padding: 6px 2px;
    }

    /* Tekst onder de 10 px is op een telefoon niet meer te lezen. Deze
       waarden stonden nog op de desktopmaat uit het oorspronkelijke ontwerp. */
    .stat-label { font-size: 14px !important; }
    .badge,
    .chart-stat-value { font-size: 11px !important; }
    .train-label { font-size: 10px !important; }
    .rt-record-label { font-size: 12px; }
    .category-toggle-btn { font-size: 11px; }
}

/* Spoor: inhoudelijke hiërarchie en bediening, gedeeld door de pagina's. */
body { font-variant-numeric: tabular-nums; }
button, input, select, summary { font: inherit; }
button, a, summary { -webkit-tap-highlight-color: transparent; }
:focus-visible { outline: 3px solid var(--ns-blue); outline-offset: 3px; }
[hidden] { display: none !important; }
.rt-page h2 { font: 600 20px/1.3 var(--font-body); color: var(--text-primary); }
.rt-method { font-size: 14px; line-height: 1.55; color: var(--text-secondary); margin: 12px 0 20px; }
.rt-method a { color: var(--ns-blue); text-underline-offset: 3px; }
.rt-method summary { cursor: pointer; min-height: 44px; padding: 12px 0; }
.rt-method p { max-width: 65ch; }
.rt-page .section { padding-top: 16px; padding-bottom: 20px; }
.rt-page .national-pct { background: var(--bg-card); border: 0; border-left: 4px solid var(--ns-blue); border-radius: 0; padding: 24px; gap: 24px; box-shadow: none; }
.rt-page .national-pct::before, .rt-page .national-pct::after { display: none; }
.rt-page .national-pct-value { font: 600 56px/1 var(--font-body); color: var(--text-primary); }
.rt-page .national-pct-label { font-size: 18px; color: var(--text-primary); }
.rt-page .national-pct-stats { font: 400 14px/1.6 var(--font-body); }
.rt-summary { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; padding: 16px 0 24px; }
.rt-summary .stat-card { padding: 0 16px; border: 0 !important; border-left: 1px solid var(--border) !important; border-radius: 0 !important; background: none; box-shadow: none; }
.rt-summary .stat-card:first-child { padding-left: 0; border: 0 !important; }
.stat-label { font: 500 14px/1.4 var(--font-body); color: var(--text-secondary); }
.stat-value { font: 600 28px/1.3 var(--font-body); color: var(--text-primary); margin: 6px 0; overflow-wrap: anywhere; }
.stat-detail { font: 400 14px/1.45 var(--font-body); color: var(--text-secondary); }
.rt-stat-list { border-top: 1px solid var(--border); }
.rt-stat-list .stat-card { display: grid; grid-template-columns: minmax(150px, 1fr) minmax(130px, .8fr) minmax(180px, 1.5fr); align-items: center; gap: 16px; padding: 16px 0; border: 0 !important; border-bottom: 1px solid var(--border) !important; border-radius: 0 !important; background: transparent; box-shadow: none; }
.rt-stat-list .stat-value { font-size: 22px; margin: 0; }
.rt-stat-list a:hover { background: var(--bg-hover); }
.rt-operator-list { display: none; }
.rt-operator { border-bottom: 1px solid var(--border); padding: 12px 0; }
.rt-operator summary { display: flex; gap: 12px; align-items: center; justify-content: space-between; min-height: 44px; cursor: pointer; list-style: none; font-size: 16px; }
.rt-operator summary::after { content: '+'; font-size: 20px; }
.rt-operator[open] summary::after { content: '−'; }
.rt-operator summary strong { flex: 1; }
.rt-operator-out { color: var(--text-secondary); font-size: 14px; }
.rt-operator dl { display: grid; grid-template-columns: 1fr auto; gap: 8px 12px; margin-top: 16px; font-size: 14px; }
.rt-operator dd { margin: 0; text-align: right; }
.rt-field { display: grid; gap: 8px; font-size: 14px; color: var(--text-secondary); }
.rt-field input { width: 100%; min-height: 48px; padding: 10px; border-radius: 8px; border: 1px solid var(--border); background: var(--bg-card); color: var(--text-primary); font-size: 16px; }
.rt-radar-panel .rt-panel-head { display: flex; align-items: center; gap: 12px; justify-content: space-between; }
.rt-radar-panel .rt-panel-head p { display: block; }
.rt-radar-panel .rt-title { font-size: 24px; }
.rt-radar-panel { overflow-y: auto; }
.rt-radar-options > summary, .rt-radar-list > summary { cursor: pointer; min-height: 48px; padding: 14px 16px; font-size: 14px; font-weight: 600; }
.rt-radar-list { border-top: 1px solid var(--border-subtle); }
.rt-radar-list .rt-field { margin: 0 16px 12px; }
.rt-radar-options .rt-panel-body { overflow: visible; }
.rt-search-results { max-height: 38dvh; overflow-y: auto; background: var(--bg-card); color: var(--text-primary); font-size: 14px; overscroll-behavior: contain; }
.rt-search-results > p { padding: 16px; }
.rt-search-result { display: flex; flex-direction: column; gap: 6px; width: 100%; min-height: 64px; text-align: left; padding: 14px 16px; border: 0; border-bottom: 1px solid var(--border-subtle); background: none; color: var(--text-primary); text-decoration: none; cursor: pointer; }
.rt-search-result:hover { background: var(--bg-hover); }
.rt-search-result span { color: var(--text-secondary); }
.rt-search-popover { position: absolute; top: calc(100% + 8px); left: 0; right: 0; border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--rt-shadow); z-index: 700; }
.rt-focus-page .rt-search { z-index: 600; }
.rt-sheet-toggle { display: none; }
.rt-focus-page #content .hero { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.rt-focus-page #content .hero-meta { order: 0; }
.rt-focus-page #content .hero-destination { order: 1; font-size: 22px; line-height: 1.25; flex-wrap: wrap; }
.rt-focus-page #content .hero-train-number { order: 2; font: 500 16px/1.4 var(--font-body); color: var(--text-secondary); }
.rt-focus-page #content .hero-train-number::before { content:var(--i18n-train,'Trein '); }
.rt-focus-page #content .hero-delay { order: 3; }
#rt-next-stop { order: 4; display: flex; flex-direction: column; gap: 6px; padding: 16px 0 0; margin-top: 6px; border-top: 1px solid var(--border); width: 100%; font-size: 16px; }
#rt-next-stop > span:last-child { color: var(--text-secondary); font-size: 14px; }
.rt-focus-page .route-table { min-width: 0; width: 100%; font-size: 14px; }
.rt-focus-page .route-table td { padding: 12px 6px; }
.rt-focus-page .rt-sec-kop { min-height: 48px; }
.rt-disruption-controls { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin-bottom: 16px; }
.rt-disruption-controls .rt-seg { flex: 1 1 260px; }
.rt-disruption-controls .rt-seg:last-child { flex: 0 1 180px; }
.rt-disruption-controls button { min-height: 44px; font-size: 14px; }
.rt-disruption-page .disruptions-grid { display: block; }
.rt-disruption-page .disruption-card { border: 0; border-bottom: 1px solid var(--border); border-radius: 0; background: var(--bg-card); padding: 20px; margin: 0; box-shadow: none; }
.rt-disruption-page .disruption-card::before { display: none; }
.rt-disruption-page .disruption-title { font: 600 18px/1.35 var(--font-body); }
.rt-disruption-page .disruption-description { font-size: 16px; line-height: 1.5; }
.rt-disruption-page .disruption-meta, .rt-disruption-page .disruption-cause { font-size: 14px; line-height: 1.5; }
.rt-disruption-group { font-size: 16px; margin: 28px 0 12px; }
.rt-disruption-page .disruption-stations { display: none; }
.rt-disruption-page .disruption-header { align-items: flex-start; }
.rt-disruption-page .disruption-meta { flex-direction: column; align-items: flex-start; gap: 4px; }
.rt-disruption-page .storing-regel { min-height: 64px; }
.rt-disruption-page .storing-regel-titel { font-size: 16px; }
.rt-disruption-page .storing-regel-desc { font-size: 14px; }
.rt-refresh-note { font-size: 12px; color: var(--text-secondary); }
@media (max-width: 820px) {
    .rt-rail { border-radius: 0; border-left: 0; border-right: 0; border-bottom: 0; box-shadow: none; }
    .rt-rail-item { min-height: 54px; }
    .rt-search { border-radius: 8px; }
    .rt-iconbtn, .rt-btn, .rt-select, .rt-zoom button, .rt-seg button { min-height: 44px; }
    .rt-iconbtn, .rt-zoom button { min-width: 44px; }
    .rt-status { box-shadow: none; height: 32px; border-radius: 4px; top: calc(12px + env(safe-area-inset-top, 0px)); }
    .rt-page { padding-top: calc(60px + env(safe-area-inset-top, 0px)); }
    .rt-search, .rt-has-panel .rt-search { top: calc(12px + env(safe-area-inset-top, 0px)); }
    .rt-has-panel .rt-status { top: calc(68px + env(safe-area-inset-top, 0px)); }
    .rt-has-panel .rt-zoom { top: calc(112px + env(safe-area-inset-top, 0px)); }
    .rt-radar-page .rt-has-panel .rt-status { top: calc(12px + env(safe-area-inset-top, 0px)); }
    .rt-radar-page .rt-has-panel .rt-zoom { top: calc(56px + env(safe-area-inset-top, 0px)); }
    .rt-page .national-pct { align-items: flex-start; flex-direction: column; padding: 20px; gap: 12px; }
    .rt-page .national-pct-value { font-size: 48px; }
    .rt-page .national-pct-stats { gap: 6px 14px; }
    .rt-summary .stat-card { padding: 0 10px; }
    .rt-summary .stat-value { font-size: 24px; }
    .rt-summary .stat-detail { font-size: 12px; }
    .rt-stat-list .stat-card { grid-template-columns: 1fr auto; gap: 6px 12px; }
    .rt-stat-list .stat-detail { grid-column: 1 / -1; }
    .rt-stat-list .stat-value { font-size: 20px; text-align: right; max-width: 150px; }
    .rt-operator-list { display: block; }
    .rt-operator-table { display: none; }
    .rt-page .section-header { flex-wrap: wrap; }
    .rt-radar-panel { max-height: min(62dvh, 540px) !important; }
    .rt-focus-panel { max-height: none !important; height: 48dvh; transition: height .18s ease; }
    .rt-focus-panel[data-size="full"] { height: calc(100dvh - var(--rt-rail-h) - 130px - env(safe-area-inset-top, 0px)); }
    .rt-focus-panel[data-size="compact"] { height: 64px; }
    .rt-sheet-toggle { display: block; border: 0; background: var(--bg-card); color: var(--ns-blue); min-height: 44px; padding: 8px; font-size: 14px; cursor: pointer; margin-left: auto; }
    .rt-focus-page .route-table thead { position: absolute; clip-path: inset(50%); width: 1px; height: 1px; overflow: hidden; }
    .rt-focus-page .route-table tbody { display: block; }
    .rt-focus-page .route-table tr { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); border-left: 2px solid var(--border); margin-left: 6px; padding: 0 0 12px 12px; position: relative; }
    .rt-focus-page .route-table td { border: 0; min-width: 0; padding: 4px 2px; font-size: 14px !important; }
    .rt-focus-page .route-table td:first-child { grid-column: 1 / -1; font-size: 16px !important; font-weight: 600; }
    .rt-focus-page .route-table td:nth-child(2)::before { content:var(--i18n-scheduled,'Gepland '); color: var(--text-secondary); }
    .rt-focus-page .route-table td:nth-child(3)::before { content:var(--i18n-expected,'Verwacht '); color: var(--text-secondary); }
    .rt-focus-page .route-table td:nth-child(4) { grid-column: 1; }
    .rt-focus-page .route-table td:nth-child(5)::before { content:var(--i18n-platform,'Spoor '); color: var(--text-secondary); }
    .rt-focus-page .route-table td:nth-child(5) { text-align: right; }
    .rt-focus-page .station-indicator { white-space: normal; }
    .rt-focus-page .station-dot-route { position: absolute; left: -6px; }
    .rt-focus-page #content .hero-from { font-size: 14px; }
    .rt-search-results { max-height: 42dvh; }
}
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

.rt-focus-panel { z-index: 2; }
.rt-focus-page #content .hero { border: 0; border-radius: 0; padding: 0 0 16px; box-shadow: none; }
.rt-dashboard-page .rt-punct { display: none; }
.rt-radar-page .leaflet-control-attribution { position: fixed; bottom: calc(var(--rt-rail-h, 0px) + 2px); right: 0; font-size: 10px; }
/* Live data should appear immediately, without staggered entrance effects. */
.rt-page .stat-card, .rt-page .national-pct, .rt-page .section, .fade-up { animation: none !important; opacity: 1; transform: none; }
