/*
 * Das Regenradar (Spezifikation 9t, Paket 9).
 *
 * Eigene Datei und nicht in `weather.css`: die Seite teilt mit dem Dashboard
 * nur die Karte, und `weather.css` laedt auf jeder Dashboard-Ansicht mit.
 *
 * Die dunklen Werte stehen zweimal (CLAUDE.md 3.6): einmal hinter
 * `prefers-color-scheme` mit `:root:not([data-theme="hell"])`, einmal hinter
 * `:root[data-theme="dunkel"]`. CSS kann das nicht zusammenfassen;
 * `tests/test_ansicht.php` haelt beide Bloecke gegeneinander.
 */

:root {
    /*
     * Der Grund, auf dem das Radarbild liegt. Die Grundkarte des DWD zeichnet
     * **schwarze Linien auf durchsichtig** — sie braucht deshalb eine helle
     * Flaeche darunter, sonst steht sie im Nichts.
     */
    --app-radar-grund: #f4f7fd;

    /*
     * **Die Grundkarte wird im Dunkelmodus invertiert, nicht neu geholt.**
     * Der DWD liefert nur die eine, dunkle Strichfassung; eine zweite gibt es
     * nicht, und sie nachzufaerben ginge nur ueber `filter`. `invert(1)` macht
     * aus den schwarzen Linien weisse — auf der dunklen Flaeche genau richtig.
     * Der Wert steht als Variable, weil er im hellen Schema `none` sein muss:
     * `filter: invert(0)` erzeugt sonst eine unnoetige Kompositionsebene.
     *
     * **`hue-rotate(180deg)` gehoert zwingend dazu** und ist kein Beiwerk:
     * `invert()` allein dreht auch den Farbton, und die blauen Fluesse kamen
     * als **braune** Linien heraus — in einer Karte, in der Blau „Wasser"
     * heisst, ist das schlicht falsch. Die Farbdrehung stellt den Ton wieder
     * her; Grau bleibt Grau, weil es keinen Farbton hat.
     */
    --app-radar-karte-filter: none;
    --app-radar-karte-deckung: .55;
    /* Die Beschriftung darf kraeftiger sein als die Flaechenzeichnung: sie
     * liegt ueber dem Radar und muss sich gegen dessen Farben behaupten. */
    --app-radar-text-deckung: .75;
    /*
     * **Der Halo macht die Ortsnamen ueber Regen lesbar.** Grauer Text auf
     * gruener Radarflaeche lag knapp ueber der Lesbarkeitsgrenze; ein
     * `text-shadow` gibt es fuer ein Bild nicht, wohl aber `drop-shadow()` —
     * es folgt der Alphamaske und legt sich um die Buchstaben, nicht um das
     * Bildrechteck. Im Dunkelmodus steht er **hinter** der Invertierung, damit
     * er dunkel bleibt statt mitinvertiert zu werden.
     *
     * **Warum das eine eigene, vollstaendige Variable ist und nicht an
     * `--app-radar-karte-filter` angehaengt wird:** die traegt im hellen Schema
     * den Wert `none`, und `filter: none drop-shadow(...)` ist **ungueltige
     * CSS-Syntax — die ganze Filter-Liste faellt dann aus**. Genau so gebaut
     * und nachgemessen: mit und ohne Halo kamen **pixelgleiche** Screenshots
     * heraus (6 dunkle Textpixel von 150.000 in beiden Faellen). Ein Filter,
     * der nichts tut, meldet sich nicht — er sieht aus wie ein Effekt, der zu
     * schwach eingestellt ist.
     */
    --app-radar-text-filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0 2px #fff);

    /* Standortmarke und Entfernungsringe (nur angemeldet). */
    --app-radar-marke:  #d94a4a;
    --app-radar-ring:   rgba(93, 107, 149, .45);

    /*
     * Der Schieber ist zweigeteilt: bis „jetzt" gemessen, danach Vorhersage.
     * Die Grenze liegt bei der Haelfte, weil `RADAR_ZURUECK_SCHRITTE` und
     * `RADAR_VORAUS_SCHRITTE` gleich gross sind (`lib/radar.php`). Aendert
     * sich eines von beiden, gehoert der Prozentwert hier mitgeaendert — der
     * Testlauf haelt die beiden Konstanten gegen diesen Wert.
     */
    --app-radar-teiler: 50%;
    --app-radar-gemessen:  #2f6fd0;
    --app-radar-prognose:  #9b8bd0;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="hell"]) {
        --app-radar-grund: #151a24;
        --app-radar-karte-filter: invert(1) hue-rotate(180deg);
        --app-radar-karte-deckung: .5;
        --app-radar-text-deckung: .8;
        --app-radar-text-filter: invert(1) hue-rotate(180deg)
            drop-shadow(0 0 1px #000) drop-shadow(0 0 2px #000);
        --app-radar-marke: #ff7a7a;
        --app-radar-ring:  rgba(150, 163, 199, .38);
        --app-radar-gemessen: #5f93e0;
        --app-radar-prognose: #a99adb;
    }
}

:root[data-theme="dunkel"] {
    --app-radar-grund: #151a24;
    --app-radar-karte-filter: invert(1) hue-rotate(180deg);
    --app-radar-karte-deckung: .5;
    --app-radar-text-deckung: .8;
    --app-radar-text-filter: invert(1) hue-rotate(180deg)
        drop-shadow(0 0 1px #000) drop-shadow(0 0 2px #000);
    --app-radar-marke: #ff7a7a;
    --app-radar-ring:  rgba(150, 163, 199, .38);
    --app-radar-gemessen: #5f93e0;
    --app-radar-prognose: #a99adb;
}

/* --- Die Buehne: drei Ebenen uebereinander --------------------------------- */

.app-radar-buehne {
    position: relative;
    /*
     * `aspect-ratio` statt fester Hoehe: die drei Ebenen bleiben so bei jeder
     * Breite deckungsgleich, ohne dass eine Medienabfrage je Geraet noetig
     * waere. Der angeforderte Ausschnitt ist quadratisch (RADAR_BREITE ==
     * RADAR_HOEHE), das Verhaeltnis also 1.
     */
    aspect-ratio: 1;
    width: 100%;
    max-width: 40rem;
    margin: 0 auto;
    border-radius: var(--app-radius);
    overflow: hidden;
    background: var(--app-radar-grund);
    border: 1px solid var(--app-border);
}

.app-radar-karte,
.app-radar-schicht,
.app-radar-beschriftung,
.app-radar-marke {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
}

.app-radar-karte {
    filter: var(--app-radar-karte-filter);
    opacity: var(--app-radar-karte-deckung);
    /* Die Karte ist Orientierung, nicht Inhalt — sie faengt keine Klicks. */
    pointer-events: none;
}

.app-radar-schicht {
    /*
     * Das Radarbild ist die Aussage der Seite und liegt deshalb ueber der
     * Karte. Es traegt seinen eigenen Alphakanal; ohne Regen ist es
     * vollstaendig durchsichtig — und genau so soll es aussehen.
     */
    pointer-events: none;
}

/*
 * Die Ortsnamen liegen **ueber** dem Radar (siehe `pages/radar.php`). Sie
 * tragen denselben Dunkelmodus-Filter wie die Basisebene — es ist dieselbe
 * Quelle in derselben Strichfarbe.
 */
.app-radar-beschriftung {
    filter: var(--app-radar-text-filter);
    opacity: var(--app-radar-text-deckung);
    pointer-events: none;
}

/*
 * Bleibt das Bild aus, verschwindet die Schicht ganz, statt ein zerbrochenes
 * Symbol zu zeigen. Der Hinweis daneben sagt, was los ist.
 */
.app-radar-schicht--leer {
    visibility: hidden;
}

.app-radar-marke {
    pointer-events: none;
}

.app-radar-ring {
    fill: none;
    stroke: var(--app-radar-ring);
    stroke-width: 1;
    stroke-dasharray: 3 4;
}

.app-radar-punkt {
    fill: var(--app-radar-marke);
    stroke: var(--app-surface);
    stroke-width: 1.5;
}

/*
 * Der Vorhersagebereich bekommt einen eigenen Rahmen — Farbe allein waere
 * keine Aussage (CLAUDE.md 1), aber zusammen mit der Wortmarke in der
 * Zeitzeile ist es die zweite, sofort sichtbare Ebene derselben Information.
 */
.app-radar-buehne--prognose {
    border-color: var(--app-radar-prognose);
    box-shadow: inset 0 0 0 1px var(--app-radar-prognose);
}

.app-radar-fehler {
    position: absolute;
    inset: auto 0 1rem 0;
    margin: 0;
    text-align: center;
    font-size: .85rem;
    color: var(--app-text-mute);
}

/* --- Zeitzeile und Regler -------------------------------------------------- */

.app-radar-zeit {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: .6rem;
    margin: 1rem 0 .35rem;
}

.app-radar-zeit strong {
    font-size: 1.35rem;
    font-variant-numeric: tabular-nums;
}

.app-radar-art {
    font-size: .8rem;
    color: var(--app-text-mute);
    padding: .1rem .5rem;
    border-radius: 999px;
    background: var(--app-surface-2);
}

.app-radar-art--prognose {
    /*
     * Dieselbe Machart wie `.app-alltag-stufe` aus Paket 8: die Signalfarbe
     * als schwache Flaeche hinter normaler Textfarbe, statt als Textfarbe
     * selbst. Auf Weiss gemessen erreichte der volle Ton nur 2,4 : 1 — als
     * 22-Prozent-Beimischung hinter `--app-text` sind es ueber 8 : 1 in
     * beiden Schemata.
     */
    background: color-mix(in srgb, var(--app-radar-prognose) 22%, var(--app-surface));
    color: var(--app-text);
}

.app-radar-regler {
    display: flex;
    align-items: center;
    gap: .75rem;
    max-width: 40rem;
    margin: 0 auto;
}

.app-radar-play {
    flex: 0 0 auto;
    min-width: 6.5rem;
    /* HIG-Trefferflaeche (Spezifikation 10.13): 44 px in beiden Richtungen. */
    min-height: 2.75rem;
}

/*
 * Der Schieber zeigt in seiner Spur, wo die Messung endet und die Vorhersage
 * beginnt — ein harter Uebergang, kein Verlauf: die Grenze ist ein Zeitpunkt,
 * kein Uebergangsbereich.
 *
 * **Der Verlauf gehoert auf die Spur-Pseudoelemente, nicht auf das `<input>`
 * selbst.** Bei der ersten Fassung stand er auf dem Element, und die Spur war
 * unsichtbar: `::-webkit-slider-runnable-track` zeichnet seine eigene, deckende
 * Flaeche darueber. Zu sehen war nur der Griff, der frei im Raum schwebte —
 * die ganze Zweiteilung fehlte, und **die Prüfkette merkt so etwas nicht**
 * (CLAUDE.md 11, „Eine grüne Prüfkette sagt nichts über das Bild").
 */
.app-radar-range {
    flex: 1 1 auto;
    appearance: none;
    -webkit-appearance: none;
    background: transparent;
    /* Trefferflaeche: die Spur ist duenn, der Griffbereich darf es nicht sein
     * (HIG 44 px, Spezifikation 10.13). */
    height: 2.75rem;
    cursor: pointer;
}

.app-radar-spur,
.app-radar-range::-webkit-slider-runnable-track {
    height: .4rem;
    border-radius: 999px;
    background: linear-gradient(
        to right,
        var(--app-radar-gemessen) 0,
        var(--app-radar-gemessen) var(--app-radar-teiler),
        var(--app-radar-prognose) var(--app-radar-teiler),
        var(--app-radar-prognose) 100%
    );
}

.app-radar-range::-moz-range-track {
    height: .4rem;
    border-radius: 999px;
    background: linear-gradient(
        to right,
        var(--app-radar-gemessen) 0,
        var(--app-radar-gemessen) var(--app-radar-teiler),
        var(--app-radar-prognose) var(--app-radar-teiler),
        var(--app-radar-prognose) 100%
    );
}

.app-radar-range::-webkit-slider-thumb {
    appearance: none;
    -webkit-appearance: none;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--app-surface);
    border: 2px solid var(--app-accent);
    box-shadow: var(--app-shadow-sm);
    cursor: pointer;
    /*
     * WebKit setzt den Griff an die Oberkante der Spur. Die halbe Differenz
     * aus Griff- und Spurhoehe zentriert ihn: (1,4 - 0,4) / 2 = 0,5rem.
     */
    margin-top: -.5rem;
}

.app-radar-range::-moz-range-thumb {
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--app-surface);
    border: 2px solid var(--app-accent);
    box-shadow: var(--app-shadow-sm);
    cursor: pointer;
}

.app-radar-range:focus-visible {
    outline: 2px solid var(--app-accent);
    outline-offset: 3px;
}

/* --- Legende und Quellen --------------------------------------------------- */

.app-radar-legende {
    display: flex;
    flex-direction: column;
    gap: .3rem;
    max-width: 40rem;
    margin: 1rem auto 0;
    font-size: .8rem;
    color: var(--app-text-mute);
}

.app-radar-legende-titel {
    font-weight: 600;
}

/*
 * Die Skala bildet die Farben der Quelle nach. Sie ist **keine eigene
 * Bewertung** — eine eigene Bänderung mit Millimeterangaben daneben zu
 * stellen hiesse, dem Bild eine Genauigkeit zu geben, die es nicht traegt.
 * Deshalb nur „wenig“ und „viel“ an den Enden.
 *
 * **Die elf Werte sind aus den Bildern der Quelle ausgezaehlt, nicht
 * geschaetzt** (CLAUDE.md 11, „Messen statt schaetzen“): drei
 * Deutschlandbilder vom 23., 24. und 25.08.2026 mit kraeftigem Niederschlag,
 * Pixel histogrammiert, Antialiasing-Mischtoene verworfen. **Die erste Fassung
 * dieser Legende war geraten** und trug ein kraeftiges Blau in der Mitte, das
 * im Radarbild ueberhaupt nicht vorkommt — sie behauptete eine Skala, die
 * die Quelle nicht hat.
 *
 * **Harte Stufen, kein weicher Verlauf:** die Skala der Quelle ist diskret.
 * Ein Verlauf gaukelte Zwischentoene vor, die es im Bild nicht gibt.
 */
.app-radar-skala {
    display: block;
    height: .5rem;
    border-radius: 999px;
    background: linear-gradient(
        to right,
        #33ffff 0%,     #33ffff 9.1%,
        #1acc9a 9.1%,   #1acc9a 18.2%,
        #019934 18.2%,  #019934 27.3%,
        #4db31b 27.3%,  #4db31b 36.4%,
        #99cc01 36.4%,  #99cc01 45.5%,
        #cce601 45.5%,  #cce601 54.5%,
        #ffff01 54.5%,  #ffff01 63.6%,
        #ffc401 63.6%,  #ffc401 72.7%,
        #ff8901 72.7%,  #ff8901 81.8%,
        #ff4501 81.8%,  #ff4501 90.9%,
        #fb00ff 90.9%,  #fb00ff 100%
    );
}

.app-radar-legende-enden {
    display: flex;
    justify-content: space-between;
}

.app-radar-quelle {
    max-width: 40rem;
    margin: .9rem auto 0;
    font-size: .78rem;
    color: var(--app-text-mute);
}

.app-radar-ausweich {
    display: inline-block;
    margin-right: .35rem;
    padding: .1rem .45rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--app-warm) 26%, var(--app-surface));
    color: var(--app-text);
}

/* --- Schmale Geraete ------------------------------------------------------- */

@media (max-width: 30rem) {
    .app-radar-regler {
        flex-wrap: wrap;
    }

    .app-radar-play {
        width: 100%;
    }
}
