/* Einsatzdoku — Stylesheet
   ===========================================================================

   Neu geschrieben in P3 (Oberflächen-Redesign, mobil-first). Die Vorgängerin
   war über zwanzig Fassungen gewachsen: 1 468 Zeilen, 78 Hexwerte außerhalb
   von :root, 21 verschiedene Schriftgrößen, die Kopfhöhe fünfmal als 50px
   fest verdrahtet, sechs Schaltflächenvarianten und zwei Graufamilien
   nebeneinander. Sie war nicht schlecht gepflegt — sie hatte nur nie eine
   Stelle, an der ein Wert **einmal** steht.

   DIE DREI EBENEN (Konzept P3, E-P3-06):

     Token      Jeder Wert — Farbe, Größe, Abstand, Maß — steht in :root und
                nirgends sonst. Wer eine Farbe ändern will, ändert sie hier.
     Bausteine  Benannte Klassen mit Skelett in ui.php, von PHP **und** von
                den JS-Erzeugern verwendet. Eine Karte sieht überall gleich
                aus, weil es nur eine Karte gibt.
     Regel      Eine neue Seite setzt vorhandene Bausteine zusammen und
                definiert nichts Eigenes. Ein neuer Baustein wird vorher
                beschrieben, vorgelegt, freigegeben und in docs/Design.md
                aufgenommen.

   MOBIL-FIRST heißt hier wörtlich: Was ohne Media-Abfrage dasteht, gilt für
   das Handy. Die Abfragen bauen nach oben aus (min-width), nie nach unten
   ab. Das ist der Grund, warum die Datei überhaupt neu entstanden ist — die
   alte war für den Desktop geschrieben und nahm für schmale Geräte Regeln
   zurück, weshalb unter 720 px anderthalb Bildschirme Seitenleiste vor dem
   Inhalt standen.

   GLIEDERUNG. Die Abschnittsnummern stehen auch in docs/Design.md.

     1  Schriften                (@font-face, unverändert aus dem Bestand)
     2  Token                    (:root — alle Werte, sonst keiner)
     3  Grundlagen               (Reset, Körper, Typografie, Fokus, Symbole)

   Die Bausteine folgen in Abschnitt 4 ff. — sie entstehen in Arbeitspaket O2.
   Bis dahin ist diese Datei bewusst unvollständig: O1 legt das Fundament,
   O2 setzt die Bausteine darauf. Ein Zwischenstand, in dem die Anwendung roh
   aussieht, ist eingeplant (Konzept, O2 Punkt 6).

   PRÜFMITTEL. tools/vollstaendigkeit/ liest diese Datei und meldet jeden
   Hexwert, jede Schriftgröße und jedes Pixelmaß außerhalb von :root, dazu
   jede Klasse des alten Stylesheets, die weder eine neue Regel noch einen
   Eintrag auf der Streichliste hat. Der Stilvergleich (tools/stilvergleich/)
   ruht während P3 und wird in O12 neu geeicht.
*/


/* == 1. SCHRIFTEN ==========================================================
 *
 * Wortgleich aus dem Bestand übernommen — an den Schriften ändert P3 nichts.
 *
 * Beide Schriften werden SELBST AUSGELIEFERT (assets/fonts/, Backlog Nr. 12).
 * Vorher kamen sie per @import von Google; das meldete bei jedem Seitenaufruf
 * die IP-Adresse der NutzerIn an Google — in einer Anwendung, deren ganzer
 * Zweck darin besteht, dass Patientendaten den Browser nicht unverschlüsselt
 * verlassen, war das ein Bruch in der Linie.
 *
 * Herkunft: npm-Pakete @fontsource/bricolage-grotesque 5.3.0 und
 * @fontsource/open-sans 5.3.0 (beide OFL-1.1), Unterverzeichnis files/.
 * Übernommen wurden ausschließlich die tatsächlich benutzten Schnitte:
 * Bricolage 500/600, Open Sans 400/600/700 — je in den Subsets latin und
 * latin-ext. Wer einen weiteren Schnitt braucht, legt die Datei dazu UND
 * trägt sie hier ein; ohne @font-face nutzt die Datei nichts.
 *
 * unicode-range trennt die beiden Subsets: latin-ext wird nur geladen, wenn
 * ein Zeichen daraus tatsächlich vorkommt (z. B. in osteuropäischen Namen).
 * font-display:swap zeigt sofort die Ersatzschrift und tauscht danach.
 */
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:500;
  font-display:swap;src:url(fonts/bricolage-grotesque-latin-500-normal.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:500;
  font-display:swap;src:url(fonts/bricolage-grotesque-latin-ext-500-normal.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,
    U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:600;
  font-display:swap;src:url(fonts/bricolage-grotesque-latin-600-normal.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Bricolage Grotesque';font-style:normal;font-weight:600;
  font-display:swap;src:url(fonts/bricolage-grotesque-latin-ext-600-normal.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,
    U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;
  font-display:swap;src:url(fonts/open-sans-latin-400-normal.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;
  font-display:swap;src:url(fonts/open-sans-latin-ext-400-normal.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,
    U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;
  font-display:swap;src:url(fonts/open-sans-latin-600-normal.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:600;
  font-display:swap;src:url(fonts/open-sans-latin-ext-600-normal.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,
    U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:700;
  font-display:swap;src:url(fonts/open-sans-latin-700-normal.woff2) format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:700;
  font-display:swap;src:url(fonts/open-sans-latin-ext-700-normal.woff2) format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,
    U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,
    U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}


/* == 2. TOKEN ==============================================================
 *
 * Hier steht jeder Wert der Oberfläche — und nur hier. Die
 * Vollständigkeitsprüfung meldet jeden Hexwert, jede Schriftgröße und jedes
 * Pixelmaß, das außerhalb dieses Blocks steht.
 *
 * FARBROLLEN (E-P3-15). Die Farbe sagt, worum es geht:
 *
 *   Orange       Handeln und „hier bin ich" — Primärknopf, aktiver
 *                Menüpunkt, Anlegen-Wege, Vorbelegungsstern, aktive Kachel,
 *                Zeilenhervorhebung.
 *   Rot          Aufmerksamkeit — Löschen, Fehler, offene Zuordnung,
 *                unvollständiger Einsatz, Fehleinsatz.
 *   Blau         Auswählen und Erklären — Textlinks, Sortierpfeil, gewählte
 *                Filter, Fokusring, Hinweis, Vollzug.
 *   Dunkelblau   Struktur — Kopfleiste, Überschriften, Häkchen, Symbole,
 *                Tabellenkopf.
 *   Sand/Grau    Mechanik — Winkel, Trennlinien, inaktive Symbole.
 *
 * Grün und Gelb gibt es nicht mehr. Beide waren markenfremd: Grün trug die
 * Vollzugsmeldung und die Passwortstärke, Gelb den Knopf „Bearbeiten" in den
 * Stammdaten — dieselbe Handlung, die anderswo orange war. Vollzug ist jetzt
 * Blau mit Haken (E-P3-16), „Bearbeiten" der neutrale Rahmenknopf.
 *
 * JE FARBE EIN TIEF UND EIN HELL. Das „Tief" ist die Schriftfassung und
 * erreicht auf Schnee die Kontrastschwelle; das „Hell" ist die Fläche. Die
 * Marke selbst (Orange FF8F1F, Blau 4280E5, Rot D63338) ist Fläche und
 * Strich, nicht Schrift.
 *
 * NACHGERECHNETE KONTRASTE (gegen Schnee FFFCFA, WCAG 2.1):
 *
 *   Asphalt          19,29:1     Dunkelblau auf Orange     5,97:1  Primärknopf
 *   Dunkelblau       13,33:1     Weiß auf Dunkelblau      13,62:1  Kopfleiste
 *   Gedämpft          5,66:1     Blau als Strich/Fokus     3,77:1
 *   Blau tief         7,82:1     Orange als Fläche         2,23:1  nie Schrift
 *   Rot tief          7,58:1     Rot D63338                4,68:1
 *   Orange tief       4,32:1  — nur ab 14 px fett oder 18 px (Schwelle 3:1)
 *
 * Drei Werte weichen von Anlage G des Konzepts ab, alle nach oben (Asphalt
 * 19,3 statt 17,5; Blau tief 7,8 statt 7,2; Rot tief 7,6 statt 7,1; Primärknopf
 * 6,0 statt 5,4). Die Rechnung steht in tools/screenshots/kontrast.py und
 * läuft bei jedem Screenshot-Lauf mit; die Tabelle in docs/Design.md wird
 * daraus erzeugt, nicht abgeschrieben.
 */

:root{
  /* ---- Flächen ---------------------------------------------------------
   * Schnee ist die Karte, Rauch die Seite darunter, Sand die Mechanik.
   * Weiß (#FFF) ist KEIN Token: In der Marke ist Weiß nur Logo- und
   * Schriftfarbe auf Dunkel. Im alten Stylesheet stand es vierzehnmal als
   * Fläche — das ist der Grund, warum die Oberfläche stellenweise kalt
   * wirkte, während der Rest warm war. */
  --schnee:#FFFCFA;
  --rauch:#F7F5ED;
  --sand:#D4C7AD;

  /* ---- Schrift ---------------------------------------------------------
   * Gedämpft ist die EINZIGE Graustufe. Der Bestand hatte daneben eine
   * zweite, kühle Familie (5B5F66, 9AA0A6, 8A96A8, C6CEDB …) — zwei
   * Grauwelten in einer Oberfläche. Sie ist ersatzlos fort. */
  --asphalt:#1A0500;
  --dunkelblau:#1A2E4D;
  --gedaempft:#6E6459;
  --auf-dunkel:#FFFFFF;                /* Schrift auf Dunkelblau, 13,62:1 */

  /* ---- Linien ----------------------------------------------------------
   * ZWEI Linien, und der Unterschied ist keine Geschmacksfrage:
   *
   *   --linie        aufgehelltes Sand, 1,36:1. Trennt, schmückt, umrandet
   *                  Karten. Rein zeichnerisch — WCAG 1.4.11 nimmt
   *                  dekorative Trenner ausdrücklich aus.
   *   --linie-stark  begrenzt BEDIENELEMENTE: Eingabefeld, neutraler Knopf,
   *                  Segmentwahl, Kästchen. Dort ist der Rand die einzige
   *                  Auskunft darüber, wo das Element anfängt und aufhört,
   *                  und dafür verlangt WCAG 3:1. Gedämpft erreicht 5,66:1
   *                  und ist ohnehin schon Token — ein neuer Farbwert war
   *                  dafür nicht nötig.
   *
   * Das ist der Fund F-P3-K: Anlage G führt für Ränder 3:1, nennt aber nur
   * Farben, die darunter liegen. Ohne die Trennung hätte jedes Eingabefeld
   * einen Rand von 1,4:1 — sichtbar für gute Augen, unsichtbar für andere. */
  --linie:#E3DAC6;
  --linie-stark:var(--gedaempft);

  /* ---- Orange — Handeln ------------------------------------------------ */
  --orange:#FF8F1F;
  --orange-tief:#C25A00;
  --orange-hell:#FFEBD6;

  /* ---- Blau — Auswählen und Erklären ----------------------------------- */
  --blau:#4280E5;
  --blau-tief:#1F4E9C;
  --blau-hell:#D9ECFD;

  /* ---- Rot — Aufmerksamkeit -------------------------------------------- */
  --rot:#D63338;
  --rot-tief:#9E2226;
  --rosa:#FCE2D6;

  /* ---- Primärknopf -----------------------------------------------------
   * Die eine Stelle, an der die Kontrastfrage entschieden wurde: Weiß auf
   * Orange sind 2,3:1 und damit unlesbar; Dunkelblau auf Orange sind 5,97:1.
   * Der Knopf trägt deshalb dunkelblaue Schrift (E-P3-15). Die Mockups
   * zeigen an dieser Stelle Weiß — der Entscheidungstext gilt, nicht die
   * Skizze (Konzept 3, Vorbemerkung). */
  --knopf-primaer-flaeche:var(--orange);
  --knopf-primaer-schrift:var(--dunkelblau);

  /* ---- Schriftfamilien -------------------------------------------------
   * Die Ersatzlisten sind NORMAL BREIT. Hier stand einmal 'Arial Narrow' an
   * zweiter Stelle; kam die Webschrift nicht durch, wurde die ganze
   * Oberfläche gedrungen, und es sah nach einem Gestaltungsfehler aus statt
   * nach einem fehlgeschlagenen Download. */
  --schrift-kopf:'Bricolage Grotesque',system-ui,-apple-system,'Segoe UI',
                 Roboto,'Helvetica Neue',Arial,sans-serif;
  --schrift-text:'Open Sans',system-ui,'Segoe UI',Roboto,
                 'Helvetica Neue',Arial,sans-serif;
  /* Schreibmaschinenschrift nur, wo sie die Aussage IST: Kopplungscode
   * (seit Web 13.1.0 im Eingabefeld, .feld-fest — er wird abgetippt, nicht
   * angezeigt), Wiederherstellungsschlüssel, Rechtstext-Editor. */
  --schrift-fest:ui-monospace,'SF Mono','Cascadia Mono','JetBrains Mono',
                 Consolas,monospace;

  /* ---- Schriftskala ----------------------------------------------------
   * Major Third (1,25) um die Grundgröße 15/16 px. Der Bestand hatte 21
   * verschiedene Größen und damit keine Skala, sondern eine Sammlung.
   *
   *   1  12  Kleinzeile, Plakette, Tabellenfuß
   *   2  13  Kleinzeile groß, Beschriftung, Meta
   *   3  15  Grundgröße der Oberfläche
   *   4  16  Fließtext (Lesespalte, Rechtstexte) — 15 × 1,067
   *   5  19  Kartentitel, Abschnittskopf        — 15 × 1,25
   *   6  24  Seitentitel klein, Kennzahl        — 19 × 1,25
   *   titel  Seitentitel: 28 mobil, 30 ab 720   — 24 × 1,25
   *
   * Der Seitentitel hat einen eigenen Namen statt --groesse-7, weil er als
   * einziger von der Fensterbreite abhängt. Das Konzept nennt in 5.2 sechs
   * Namen und sieben Werte; das ist die Auflösung (Fund F-P3-I). */
  --groesse-1:12px;
  --groesse-2:13px;
  --groesse-3:15px;
  --groesse-4:16px;
  --groesse-5:19px;
  --groesse-6:24px;
  --groesse-titel:28px;

  --zeile-eng:1.3;                     /* Titel, Kacheln */
  --zeile:1.55;                        /* Oberfläche */
  --zeile-lesen:1.6;                   /* Fließtext in der Lesespalte */

  /* ---- Abstände --------------------------------------------------------
   * Fünf Stufen, Vierer-Raster. Mehr braucht es nicht; weniger hätte den
   * Bestand nicht abgebildet. */
  --abstand-1:4px;
  --abstand-2:8px;
  --abstand-3:12px;
  --abstand-4:16px;
  --abstand-5:24px;

  /* ---- Radien ----------------------------------------------------------- */
  --radius-klein:6px;                  /* Plakette, Kästchen, Eingabefeld */
  --radius:10px;                       /* Knopf, Meldung */
  --radius-gross:12px;                 /* Karte, Blatt, Dialog */

  /* ---- Maße -------------------------------------------------------------
   * --kopf ist die Kopfhöhe und steht GENAU HIER. Im Bestand stand sie
   * fünfmal als 50px im Stylesheet (.layout min-height, .daylist top und
   * height, .filterspalte top und height) — und weil die tatsächliche Höhe
   * vom Umbruch des Markentexts abhing und das Demo-Banner sie zusätzlich
   * verschob, rutschte im Demo-Konto die Leiste unter der Kopfleiste hervor.
   * Das ist Fund F-P3-G; er ist mit diesem einen Token erledigt.
   *
   * --knopf ist 44 px, für JEDEN Knopf, mobil wie Desktop, auch für
   * Zeilenaktionen. Es gibt keine Kompaktvariante: Was kleiner ist, ist kein
   * Knopf, sondern ein Link mit Symbol (E-P3-22). */
  --kopf:56px;
  --knopf:44px;
  --leiste:260px;                      /* Seitenleiste ab 1200 */
  --leiste-schmal:220px;               /* Seitenleiste 1024–1199 */
  --leiste-filter:280px;               /* Filterleiste der Suche ab 1200 */
  --leiste-filter-schmal:240px;        /* Filterleiste 1024–1199 */
  --rahmen:1680px;                     /* Leiste und Inhalt als Einheit */
  --lesespalte:760px;                  /* Fließtext */
  --schublade:320px;                   /* Höchstbreite der mobilen Schublade */
  --blatt-zeile:50px;                  /* Zeilenhöhe im Aktionsblatt */
  --unterpunkt:28px;                   /* Sprungmarke unter dem Menüpunkt */
  --listensuche-breit:36rem;           /* Höchstbreite des Suchfelds einer Liste */
  --uebersicht-spalte:240px;           /* schmalste Spalte der Einstellungs-Übersicht */
  --suchfeld:48px;                     /* das große Suchfeld */
  --symbol-klein:16px;                 /* Zusatzzeichen an einer Beschriftung */
  /* Drei abgeleitete Symbolmasse aus der Mockup-Runde 9c (AP2, Nr. 42). Die
   * Skala ist geschlossen (`CLAUDE.md` 5), deshalb stehen sie als RECHNUNG da,
   * und die Rechnung ist ihre Herkunft:
   *   --symbol-winzig 12 px = --symbol-klein (16) minus --abstand-1 (4). So
   *     gross wie das Malzeichen, das es ersetzt (E-MR-14): Der 16-px-Vorschlag
   *     war „zu gross, zu dicht" und ist verworfen.
   *   --ziel-chip    28 px = --symbol-gross (24) plus --abstand-1 (4). Das
   *     TREFFZIEL um dieses Symbol, freigegeben als F-MR-6b. Es ist groesser
   *     als das der Filter-Plakette (20 px, .plakette-weg) — mit Absicht: Der
   *     Chip steht in einem Formular, die Plakette in einer Leiste, und ein
   *     Fehlgriff kostet hier einen Wert.
   *   --symbol-text  1em = so gross wie die Schrift, in der es steht. Das
   *     Warnzeichen im Satz einer Meldung waechst mit ihr (E-MR-10). */
  --symbol-winzig:calc(var(--symbol-klein) - var(--abstand-1)); /* 12 px, im Chip */
  --ziel-chip:calc(var(--symbol-gross) + var(--abstand-1));     /* 28 px, Treffziel */
  --symbol-text:1em;                   /* Symbol im Fliesstext */
  --symbol:20px;                       /* Symbolgröße in der Zeile */
  --symbol-gross:24px;                 /* Symbolgröße im Knopf und Kartenkopf */
  --strich:1px;                        /* Haarlinie */
  --strich-stark:2px;                  /* Aktivstrich, Randstrich, Fokus */
  --radius-rund:999px;                 /* Zähler, Griff, Punkt — voll rund */
  --schalter-breit:46px;               /* der Schalter aus E-P3-28 … */
  --schalter-hoch:26px;                /* … 26 hoch, damit er in eine */
  --schalter-punkt:20px;               /* 44-px-Zeile passt und greifbar bleibt */
  --geo-kreis:28px;                    /* Einsatzort-Kreis auf der Karte */
  --geo-schild:30px;                   /* Kästchen für Standort und Zielklinik */
  --geo-ring:3px;                      /* Randstärke des Farbrands Start/Ende */
  /* Zwei abgeleitete Maße aus M-S9-01 V1 (S9/AP3). Die Skala ist geschlossen
   * (`CLAUDE.md` 5), deshalb stehen sie nicht als neue Stufen da, sondern als
   * Rechnung — und die Rechnung IST ihre Herkunft:
   *   Ringpunkt 14 px = --abstand-4 (16) minus --strich-stark (2). Er ist der
   *     Ring ohne Schild und soll um genau eine Randstärke kleiner sein als
   *     das Rasterfeld, in dem er bisher saß.
   *   Symbol im Schild 18 px = --symbol (20) minus --strich-stark (2). Der
   *     Kasten schrumpft um 6 px; das Symbol gibt eine Randstärke ab, damit
   *     der Weißraum um es herum nicht auf null fällt.
   * Das Symbol IM KREIS bekommt kein eigenes Maß — es ist --symbol-klein. */
  --geo-ringpunkt:calc(var(--abstand-4) - var(--strich-stark)); /* Ring ohne Schild (14 px) */
  --geo-symbol:calc(var(--symbol) - var(--strich-stark)); /* Symbol im Kartenschild (18 px) */
  /* Speicherbalken (E-S8-18, Web 15.1.0). Zwei Maße, beide abgeleitet:
   * 8 px ist --abstand-2, also eine Stufe des Vierer-Rasters — ein Balken,
   * der eine Zeile Grafik ist und keine Fläche; 10 px ist --radius, die
   * kleinste Rundung, und ergibt einen Punkt, der neben 13-px-Text
   * (--groesse-2) lesbar ist, ohne ihn zu überragen. */
  --balken:8px;                        /* Höhe des Speicherbalkens */
  --logo-kachel:var(--kopf);           /* Vorschau-Kachel der Installation … */
  --balken-punkt:10px;                 /* Farbpunkt in seiner Legende */
  --anmeldekarte:400px;                /* Karte der Anmeldung (E-P3-38) */
  --zeile-frei:1.4em;                  /* Mindesthöhe der Zustandszeile */
  --balken-glied:28px;                 /* ein Segment des Passwortstärke- … */
  --strich-balken:6px;                 /* … balkens, vier davon (E-P3-16) */
  --karte-neben-breit:400px;           /* Kartenspalte ab 1600 px (E-P3-31) */

  /* ---- Karte (Leaflet) --------------------------------------------------- */
  --karte-mobil:160px;
  --karte-tablet:220px;
  --karte-desktop:300px;
  /* DIE DRITTE GROESSE (Backlog Nr. 45, M-MR-03, F-MR-7). Zwischen 300 px und
   * Vollbild lag nichts: Wer mehr von der Spur sehen wollte, musste die Seite
   * verlassen. `min()` statt einer festen Zahl, und beide Haelften haben einen
   * Grund — 60vh laesst auf jedem Geraet ein Drittel des Glases fuer die
   * Liste darunter uebrig, 520 px deckelt das auf einem hohen Schreibtisch-
   * bildschirm, wo 60vh sonst 800 px waeren und die Liste aus dem Bild
   * schoebe. Freigegeben am 14.09.2026. */
  --karte-gross:min(60vh, 520px);

  /* ---- Spurfarben (P3/O3, E-P3-40) --------------------------------------
   * Acht Farben für die Einsätze eines Tages, in Vergabereihenfolge. Bis
   * Web 9.1.1 stand die Liste als COLORS-Array in index.php und enthielt
   * fünf markenfremde Werte (F-P3-H). Jetzt: die drei Markenfarben,
   * Dunkelblau und vier ABGELEITETE Töne — jede Ableitung mit Herkunft:
   *   spur-5..7  die Tief-Töne der drei Markenfarben (stehen oben bereits
   *              als Schrifttöne; hier tragen sie Fläche auf der Karte)
   *   spur-8     Sand, von L 75 % auf 40 % abgedunkelt (4,6:1 auf Schnee)
   * Die Ruhespur ist Mechanik, keine Botschaft — sie fährt gedämpft.
   * JavaScript liest die Werte über getComputedStyle; eine zweite Liste im
   * Code gibt es nicht mehr. */
  --spur-1:var(--orange);
  --spur-2:var(--blau);
  --spur-3:var(--rot);
  --spur-4:var(--dunkelblau);
  --spur-5:var(--orange-tief);
  --spur-6:var(--blau-tief);
  --spur-7:var(--rot-tief);
  --spur-8:#867146;
  --spur-ruhe:var(--gedaempft);

  /* ---- Schwellen ---------------------------------------------------------
   * Diese vier Werte stehen hier zur AUSKUNFT — für JavaScript, für
   * docs/Design.md und für den, der die Datei liest. In @media-Abfragen
   * lassen sich Custom Properties nicht verwenden; dort stehen dieselben
   * Zahlen als Literale, und zwar ausschließlich dort. Die
   * Vollständigkeitsprüfung sieht Media-Präludien nicht an.
   *
   *   720   Handy → Tablet hoch: Kachel wird Tabelle
   *  1024   Schublade → feste Leiste, Hauptpunkte in der Kopfleiste
   *  1200   Zweispalter: Einsatzansicht, Formularkarten, Kontoseite
   *  1600   Karte neben Diensttag-Daten und Tabelle
   */
  --s-handy:720px;
  --s-leiste:1024px;
  --s-zwei:1200px;
  --s-karte-neben:1600px;

  /* ---- Bewegung ----------------------------------------------------------
   * Kurz und einheitlich. Wer Bewegung abbestellt hat, bekommt keine
   * (Abschnitt 3).
   *
   * SEIT WEB 19.6.0 SIND ES 240 ms, VORHER 180 (E-MR-22). Anlass war das
   * Aktionsblatt: Bei 180 ms war die Auffahrt aus der unteren Bildkante
   * eher ein Aufblitzen als eine Bewegung, und eine Bewegung, die man
   * nicht sieht, erklaert auch nichts. Der Wert gilt fuer ALLE Nutzer des
   * Tokens — Schublade und Schleier, Akkordeon-Winkel, Winkel am
   * „Aktionen"-Knopf, Schalter-Griff, Kennzahlen-Winkel und das Blatt.
   * Ein zweites Token nur fuers Blatt waere die Stelle, an der die
   * Anwendung anfaengt, verschieden schnell zu sein. */
  --dauer:.24s;
  --schleier:rgba(26,46,77,.55);       /* Dunkelblau, halbdurchsichtig */
  --schatten:0 2px 8px rgba(26,5,0,.10);
  --schatten-hoch:0 8px 28px rgba(26,5,0,.22);
  /* Auf der dunklen Kopfleiste: eine gedämpfte Fassung von Weiß für Hover
   * und Nebenangaben. Ein eigener Hexwert wäre hier falsch — die Fläche
   * darunter ist Dunkelblau, und der Ton soll mit ihr zusammen entstehen. */
  --auf-dunkel-leise:rgba(255,255,255,.55);
  --auf-dunkel-flaeche:rgba(255,255,255,.14);
  --auf-dunkel-strich:rgba(255,255,255,.35);
}

@media (min-width:720px){
  :root{ --groesse-titel:30px; }
}

/* ---- Die zweite Bedienhöhe: 36 px am Zeigergerät (E-S8-09, R76) ----------
 *
 * 44 px BLEIBT DIE VORGABE, und sie gilt überall dort, wo ein Finger tippt.
 * Die Zahl kommt aus WCAG 2.5.8 (Zielgröße mindestens 24 × 24 px) und aus
 * den Plattformvorgaben, die 44 beziehungsweise 48 nennen — sie ist für die
 * Fingerkuppe gerechnet, nicht für den Mauszeiger.
 *
 * WARUM ES AM SCHREIBTISCH ZU VIEL IST. Ein Zeiger trifft ein 36 px hohes
 * Ziel genauso sicher wie ein 44 px hohes; was er nicht hat, ist die
 * Ungenauigkeit, für die die acht Pixel da sind. Bezahlt werden sie in
 * Formularhöhe: Das Einsatzformular hat über dreissig Felder, und acht Pixel
 * je Zeile sind dort eine Bildschirmhöhe. Wer am Schreibtisch dokumentiert,
 * rollt sie bei jedem Einsatz.
 *
 * DREI BEDINGUNGEN, UND ALLE DREI MÜSSEN GELTEN:
 *
 *   hover: hover     das Gerät kann zeigen, ohne zu drücken
 *   pointer: fine    das primäre Zeigegerät ist genau (Maus, Trackpad, Stift)
 *   min-width 1024   und es ist der Schreibtisch, nicht ein grosses Tablet
 *
 * Die Breite allein genügt NICHT: Ein Touch-Laptop mit 1920 px ist ein
 * Fingergerät, und ein iPad im Querformat meldet 1024 px. Umgekehrt genügen
 * die Medienmerkmale allein auch nicht — ein Zeiger an einem schmalen Fenster
 * bekommt weiterhin die grosse Höhe, weil dort die Zeilen ohnehin knapp sind.
 *
 * WAS SICH NICHT ÄNDERT, weil es eigene Token hat: die Kopfleiste
 * (`--kopf`, 56), der Schalter (`--schalter-*`), die Zeile des Aktionsblatts
 * (`--blatt-zeile`, 50 — sie gilt nur unter 1024 px), das grosse Suchfeld
 * (`--suchfeld`, 48) und die Sprungmarke unter dem Menüpunkt
 * (`--unterpunkt`, 28). */
@media (hover: hover) and (pointer: fine) and (min-width:1024px){
  :root{ --knopf:36px; }
}


/* == 3. GRUNDLAGEN =========================================================
 *
 * Was hier steht, gilt für die ganze Anwendung und hängt an keinem Baustein:
 * Reset, Körper, Typografie, Fokus, Symbole, Bewegung. Alles Weitere sind
 * Bausteine und steht ab Abschnitt 4 (Arbeitspaket O2).
 */

*,*::before,*::after{box-sizing:border-box}

/* hidden gewinnt IMMER — auch gegen Bausteine mit eigenem display (flex,
 * grid). Ohne diese Regel überstimmt jede display-Angabe das Attribut, und
 * JS-Umschalter zeigen Lese- und Formularzustand gleichzeitig (Fund aus O3
 * am Diensttag-Umschalter). */
[hidden]{display:none !important}

/* Innenabstände und Ränder der Standardelemente auf null. Was Abstand
 * braucht, bekommt ihn vom Baustein — nicht vom Browser. */
body,h1,h2,h3,h4,p,figure,blockquote,dl,dd,ul,ol,fieldset,legend{margin:0;padding:0}
ul,ol{list-style:none}
fieldset{border:0;min-width:0}

html{
  /* Beim Sprung zu einem Anker nicht unter die klebende Kopfleiste rutschen. */
  scroll-padding-top:calc(var(--kopf) + var(--abstand-4));
  -webkit-text-size-adjust:100%;
}

body{
  background:var(--rauch);
  color:var(--asphalt);
  font-family:var(--schrift-text);
  font-size:var(--groesse-3);
  line-height:var(--zeile);
  /* Der Rahmen ist zentriert (E-P3-12); die Kopfleiste bleibt voll breit und
   * setzt ihr Inneres selbst auf dasselbe Raster. */
  min-height:100vh;
  min-height:100dvh;
}

/* ---- Überschriften -------------------------------------------------------
 *
 * Bricolage 600 für alles, was Titel ist. GESPERRTE VERSALIEN gibt es nur
 * noch für Abschnittsköpfe in den Leisten („Diensttage", „Filter",
 * „Administration") — im Bestand trugen sie acht Regeln, darunter jeder
 * Tabellenkopf, jede Legende und jeder Feldname. Auf 360 px war das die
 * teuerste Zeile der Anwendung.
 *
 * Nebenbei erledigt sich damit Fund F-P3-A: `.metanotes` erbte Versalien und
 * Sperrung vom umgebenden `summary` und setzte sie nicht zurück, sodass die
 * Notiz „Wetter: Nebel bis 9 Uhr" als gesperrte Versalzeile erschien. Wenn
 * das `summary` selbst keine Versalien mehr trägt, gibt es nichts mehr zu
 * erben. */
h1,h2,h3,h4{
  font-family:var(--schrift-kopf);
  font-weight:600;
  line-height:var(--zeile-eng);
  color:var(--dunkelblau);
  text-wrap:balance;
}
h1{font-size:var(--groesse-titel)}
h2{font-size:var(--groesse-6)}
h3{font-size:var(--groesse-5)}
h4{font-size:var(--groesse-4)}

p{margin:0}

/* ---- Zahlen --------------------------------------------------------------
 *
 * Tabellarische Ziffern überall, wo Zahlen untereinanderstehen. Open Sans
 * kann das über 'tnum' und hat dabei — anders als jede Schreibmaschinenschrift
 * auf dem Markt — eine GLATTE NULL. Die durchgestrichene Null der
 * Monospace-Familien sah in einer Uhrzeit aus wie ein Sonderzeichen; das war
 * der Grund, diese Familie in Web 7.0.0 aus den Tabellen zu nehmen. */
.zahl,td,th,time,output{font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1}

/* ---- Links ---------------------------------------------------------------
 *
 * Blau ist „Auswählen und Erklären". Textlinks tragen es; sie sind nicht
 * unterstrichen, solange sie in einer Zeile mit anderer Auszeichnung stehen,
 * aber im Fließtext schon — dort ist die Farbe allein zu wenig. */
a{color:var(--blau-tief);text-decoration:none}
a:hover{text-decoration:underline}

/* ---- Formularelemente erben die Schrift ----------------------------------
 * Ohne das nehmen sie die des Betriebssystems, und die Seite hat plötzlich
 * zwei Schriften. */
input,select,textarea,button{font:inherit;color:inherit}
button{background:none;border:0;padding:0;cursor:pointer}

img,svg,video{max-width:100%;height:auto}

/* ---- Fokus ---------------------------------------------------------------
 *
 * EIN Fokusring für die ganze Anwendung, in Blau, außen liegend. :focus-visible
 * statt :focus — der Ring erscheint bei Tastaturbedienung, nicht bei jedem
 * Mausklick auf einen Knopf.
 *
 * outline-offset ist wichtig: Ohne ihn verschwindet der Ring bei Elementen
 * mit eigenem Rand in dessen Farbe. */
:focus{outline:none}
:focus-visible{
  outline:var(--strich-stark) solid var(--blau);
  outline-offset:var(--strich-stark);
  border-radius:var(--radius-klein);
}

/* Textauswahl in der Markenfarbe statt im Systemblau. */
::selection{background:var(--orange-hell);color:var(--asphalt)}

/* ---- Symbole -------------------------------------------------------------
 *
 * Jedes Zeichen der Oberfläche liegt als eigene Datei unter
 * assets/images/symbole/ und wird per Verweis eingebunden:
 *
 *     <svg class="symbol"><use href="assets/images/symbole/haus.svg#i"></use></svg>
 *
 * WARUM DIE STRICHATTRIBUTE HIER STEHEN und nicht in der Datei: Der Verweis
 * holt das <g id="i"> — nicht das <svg> darum. Die Attribute fill="none",
 * stroke="currentColor" und stroke-width="2" stehen in der Datei aber am
 * <svg>, damit sie sich auch einzeln öffnen und ansehen lässt. Beim Verweis
 * sind sie deshalb nicht dabei, und ohne Ersatz malte der Browser schwarze
 * Klumpen statt Strichzeichnungen. Alle fünf Eigenschaften sind vererbbar
 * und fließen vom Wirts-<svg> über das <use> in den geklonten Baum.
 *
 * currentColor heißt: Das Symbol nimmt die Schriftfarbe seiner Umgebung an.
 * Ein Symbol in einem roten Knopf ist rot, ohne dass irgendwo eine zweite
 * Regel stünde. */
.symbol{
  width:var(--symbol);height:var(--symbol);
  flex:0 0 auto;
  fill:none;
  stroke:currentColor;
  stroke-width:2;
  stroke-linecap:round;
  stroke-linejoin:round;
  vertical-align:middle;
}
.symbol-gross{width:var(--symbol-gross);height:var(--symbol-gross)}
/* EIN SYMBOL IM FLIESSTEXT (E-MR-10, Mockup-Runde 9c / AP2). Es waechst mit
 * der Schrift, in der es steht — `1em`, nicht 16 oder 20 px —, und sitzt auf
 * der Grundlinie statt in der Zeilenmitte: `vertical-align:middle` laesst ein
 * Zeichen in einem Satz zu hoch schweben. Der Wert `-.15em` ist die
 * Unterlaenge der Grundschrift und kein Mass der Skala; er steht relativ zur
 * Schriftgroesse und geht deshalb mit ihr mit.
 *
 * WOFUER. Die Meldung „N Eintraege lassen sich nicht entschluesseln und sind
 * mit … gekennzeichnet" trug das Zeichen bis Web 19.4.1 als Unicode `⚠` —
 * damit sah es in jedem System anders aus und nahm die Schriftfarbe nicht an.
 * Jetzt ist es dasselbe Symbol wie die Marke in der Tabelle daneben. */
.symbol-text{
  width:var(--symbol-text);height:var(--symbol-text);
  vertical-align:-.15em;
}

/* Der Winkel liegt EINMAL vor (winkel.svg, zeigt nach unten) und wird
 * gedreht — statt vier Dateien für vier Richtungen. */
.symbol-links{transform:rotate(90deg)}
.symbol-rechts{transform:rotate(-90deg)}
.symbol-oben{transform:rotate(180deg)}

/* Der Stern wird gefüllt, wenn die Vorbelegung gesetzt ist. Dasselbe Zeichen,
 * zwei Zustände — kein zweites Symbol. */
.symbol-gefuellt{fill:currentColor}

/* Das Schloss an der Beschriftung eines verschlüsselten Feldes (F-N1-B). Es
 * steht NEBEN dem Wort, nicht davor: Die Beschriftung ist die Auskunft, das
 * Zeichen der Zusatz. Kleiner als ein gewöhnliches Symbol und in der Farbe
 * der Beschriftung — es soll gefunden werden, wenn man danach sucht, und
 * nicht auffallen, wenn man es nicht tut. */
/* SENKRECHT MITTIG ZUM TEXT (S3/AP6) — und der Wert ist gemessen, nicht
 * geraten. Das Schloss ist mit 16 px hoeher als die Versalhoehe des
 * 15-px-Wortes daneben; `baseline` stellt seinen Kasten auf die Schriftlinie
 * und schiebt es damit nach oben, `middle` (und ebenso `text-bottom` und
 * `sub`) um denselben Betrag nach unten. Nachgemessen an einer echten Zeile
 * der Einsatzansicht, Symbolmitte gegen die Mitte des Zeilenkastens:
 *
 *   baseline  -2,0 px      middle  +2,0 px
 *   -0.1em    -0,5 px      -0.15em +0,3 px      -0.2em  +1,0 px
 *
 * -0.1em trifft beide Bezugsgroessen auf einen halben Punkt genau (gegen die
 * Versalmitte +0,5 px) und ist damit die Wahl. Die Angabe haengt an der
 * Schriftgroesse der Zeile, nicht an einer festen Pixelzahl — sie stimmt
 * damit auch dort, wo das Schloss in einer anderen Groesse steht. */
.symbol-schutz{
  width:var(--symbol-klein);height:var(--symbol-klein);
  margin-left:var(--abstand-1);
  vertical-align:-0.1em;
}

/* ---- Nur für Screenreader ------------------------------------------------
 * Text, der gelesen, aber nicht gezeigt wird. Braucht jeder Symbolknopf, der
 * keine sichtbare Beschriftung trägt. */
.nur-vorlesen{
  position:absolute;width:1px;height:1px;
  padding:0;margin:-1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0;
}

/* ---- Bewegung abbestellt -------------------------------------------------
 * Wer im Betriebssystem „Bewegung reduzieren" gesetzt hat, meint es. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}


/* == 4. GERÜST =============================================================
 *
 * Kopfleiste, Rahmen, Leiste/Schublade, Inhalt, Fußzeile.
 *
 * DIE KOPFHÖHE IST --kopf UND SONST NICHTS. Im Bestand stand sie fünfmal als
 * 50px im Stylesheet, und die tatsächliche Höhe hing zusätzlich vom Umbruch
 * des Markentexts ab; das Demo-Banner verschob sie ein weiteres Mal. Ergebnis:
 * Im Demo-Konto rutschte die Leiste unter der Kopfleiste hervor. Jetzt gibt es
 * eine Zahl an einer Stelle, und der Demo-Hinweis steht innerhalb des Inhalts.
 *
 * MOBIL ZUERST. Was hier ohne Media-Abfrage steht, gilt für das Handy. Die
 * vier Schwellen (720, 1024, 1200, 1600) bauen nach oben aus.
 */

/* ---- Kopfleiste ---------------------------------------------------------- */
.kopf{
  position:sticky;top:0;z-index:40;
  background:var(--dunkelblau);color:var(--auf-dunkel);
  height:var(--kopf);
}
/* Der Inhalt der Kopfleiste sitzt auf demselben Raster wie Leiste und Inhalt
 * darunter — die Leiste selbst bleibt voll breit (E-P3-12). */
.kopf-innen{
  display:flex;align-items:center;gap:var(--abstand-2);
  height:var(--kopf);
  max-width:var(--rahmen);margin:0 auto;
  padding:0 var(--abstand-3);
}
.kopf .knopf{color:var(--auf-dunkel)}
/* .knopf-symbol:hover setzt sonst --rauch — ein heller Block auf der dunklen
 * Leiste. Hier gilt die gedämpfte Weißfläche. */
.kopf .knopf-symbol:hover,.kopf .kopf-zahnrad:hover{background:var(--auf-dunkel-flaeche)}
.kopf-menue{margin-left:calc(var(--abstand-2) * -1)}

.kopf-marke{
  display:flex;align-items:center;gap:var(--abstand-2);
  color:var(--auf-dunkel);text-decoration:none;
  min-width:0;flex:1 1 auto;
}
.kopf-marke:hover{text-decoration:none}
/* 34 px statt 26 (F-N1-D). Die Bildmarke ist das einzige Bild der Kopfleiste
 * und war darin das kleinste Element — kleiner als die Schrift daneben.
 * 34 px lassen in der 56 px hohen Leiste oben und unten je 11 px Luft. */
.kopf-marke img{height:34px;width:auto;flex:0 0 auto}
.kopf-name{
  font-family:var(--schrift-kopf);font-weight:600;
  font-size:var(--groesse-5);line-height:1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* Der Nutzername erscheint erst, wenn Platz dafür da ist. Auf dem Handy ist
 * die Kopfleiste für Menü, Marke und Zahnrad da — der eigene Name steht auf
 * der Einstellungs-Übersicht, wo man ihn sucht. */
.kopf-nutzer{display:none}

.kopf-punkte{display:flex;align-items:center;gap:var(--abstand-1);margin-left:auto}
.kopf-punkt{
  display:none;                        /* < 1024: nur Menüknopf und Zahnrad */
  align-items:center;gap:var(--abstand-2);
  height:var(--knopf);padding:0 var(--abstand-3);
  color:var(--auf-dunkel);text-decoration:none;
  border-bottom:var(--strich-stark) solid transparent;
  font-family:var(--schrift-kopf);font-weight:600;
}
.kopf-punkt:hover{text-decoration:none;border-bottom-color:var(--auf-dunkel-strich)}
.kopf-punkt.aktiv{border-bottom-color:var(--orange)}
/* Der Rückweg der öffentlichen Hülle („Zurück zur Anmeldung") gilt in jeder
 * Breite — .kopf-punkt ist unter 1024 px ausgeblendet, weil dort die
 * Schublade die Hauptpunkte trägt; einen Rückweg trägt sie nicht. */
.kopf-zurueck{display:inline-flex}
.kopf-zahnrad{margin-right:calc(var(--abstand-2) * -1)}
.kopf-zahnrad.aktiv{background:var(--auf-dunkel-flaeche);border-radius:var(--radius)}

/* ---- Rahmen: Leiste und Inhalt als Einheit, zentriert -------------------- */
.rahmen{
  max-width:var(--rahmen);margin:0 auto;
  display:flex;align-items:flex-start;
}
.inhalt{
  flex:1 1 auto;min-width:0;
  padding:var(--abstand-4) var(--abstand-3) var(--abstand-5);
}
.rahmen-lesespalte .inhalt{max-width:var(--lesespalte);margin:0 auto}

/* ---- Leiste und Schublade — EIN Markup ----------------------------------
 *
 * Unter 1024 px liegt die Leiste als Schublade von links über dem Inhalt,
 * darüber steht sie fest daneben. Der Unterschied ist ausschließlich hier.
 *
 * Das ist die Lehre aus der Vormerkliste von P0: Der Mechanismus hängt an der
 * KLASSE, nicht an der Funktion, die die Diensttage ausgibt — sonst bliebe
 * die Suchseite als einzige ohne mobiles Menü.
 */
.leiste{
  position:fixed;inset:0 auto 0 0;z-index:60;
  width:86%;max-width:var(--schublade);
  background:var(--schnee);
  border-right:var(--strich) solid var(--linie);
  display:flex;flex-direction:column;
  transform:translateX(-100%);
  transition:transform var(--dauer) ease-out;
  overscroll-behavior:contain;
}
.schublade-auf .leiste{transform:none}
.schleier{
  position:fixed;inset:0;z-index:50;
  background:var(--schleier);
  opacity:0;transition:opacity var(--dauer) ease-out;
}
.schublade-auf .schleier{opacity:1}
/* Der Körper scrollt nicht, solange die Schublade offen ist — sonst scrollt
 * unter dem Schleier der Inhalt weg. */
.schublade-auf{overflow:hidden}

.leiste-kopf{
  display:flex;align-items:center;gap:var(--abstand-2);
  height:var(--kopf);flex:0 0 auto;
  padding:0 var(--abstand-3);
  border-bottom:var(--strich) solid var(--linie);
  color:var(--dunkelblau);
}
.leiste-haupt{padding:var(--abstand-3) var(--abstand-2) 0;flex:0 0 auto}
.leiste-liste{flex:1 1 auto;overflow-y:auto;padding:var(--abstand-2)}
.leiste-fuss{
  flex:0 0 auto;padding:var(--abstand-2);
  border-top:var(--strich) solid var(--linie);
}
/* EINE STUFE GRÖSSER (F-N1-K). Mit 12 px war die Überschrift der Leiste das
 * kleinste Element darin — kleiner als die Gruppen, die sie überschreibt, und
 * kleiner als jede Beschriftung darunter. Eine Überschrift, die von allem
 * überragt wird, das sie ordnet, ordnet nichts.
 *
 * SEIT S3/AP4 (E-R43-2) EINE STUFE HOEHER: 15 px statt 13, --asphalt statt
 * --gedaempft. Die Rueckmeldung „wirkt verloren" war ein Problem von Groesse
 * und Kontrast, nicht von Ausrichtung — linksbuendig bleibt sie.
 *
 * VERSALIEN UND SPERRUNG SIND DABEI ENTFALLEN, und das ist am Bild
 * entschieden (E-S3-12 a): Bei 15 px in Bricolage 600 liest sich
 * „DIENSTTAGE" gesperrt als ETIKETT und steht dem Jahreseintrag „2026"
 * darunter an Lautstaerke kaum nach — zwei Ueberschriften statt einer
 * Ordnung. Gemischt gesetzt bleibt es eine Ueberschrift: praesent, aber
 * ersichtlich eine Ebene ueber dem, was es ordnet. Bei 13 px trug die
 * Sperrung noch, weil die Groesse allein nicht reichte; sie war der Ersatz
 * fuer die Groesse, die jetzt da ist. */
.leiste-kopfzeile{
  font-family:var(--schrift-kopf);font-size:var(--groesse-3);
  font-weight:600;
  color:var(--asphalt);
  padding:var(--abstand-3) var(--abstand-3) var(--abstand-2);
}
.leiste-leer{color:var(--gedaempft);padding:0 var(--abstand-3)}

/* ---- Die drei Blöcke des Einstellungsmenüs (E-S8-07) ---------------------
 * Ein `<details>` je Block, gebaut aus dem Akkordeon-Baustein. Diese Regeln
 * setzen nur, was die Blocküberschrift von einer Jahreszeile unterscheidet:
 * Schriftgrad und Farbe der bisherigen `.leiste-kopfzeile`. Der Rest — Winkel
 * links, Drehung, Trefferfläche, Innenabstand — kommt vom Baustein und bleibt
 * damit gleich wie in der Diensttage-Leiste.
 *
 * DIE ZAHL STEHT NUR AM ZUGEKLAPPTEN BLOCK. Sie sagt, was verborgen ist
 * („Betrieb · 7"); über einer offenen Liste wäre sie das Abzählen dessen, was
 * man sieht. `aria-hidden`, weil ein Vorleseprogramm die Einträge selbst
 * zählt und die Zahl sonst zweimal ansagt. */
.leiste-gruppe > .akkordeon-zeile{
  font-size:var(--groesse-3);
  color:var(--asphalt);
}
.leiste-gruppe > .akkordeon-inhalt{padding-left:0}

/* ---- Das APK-Fach auf dem Geräte-Reiter (S8/AP6, Mockup 10) --------------
 * Der Rückfall neben zwei Store-Wegen: zugeklappt sagt die Zeile, dass es ihn
 * gibt, ohne ihn anzubieten. Derselbe Akkordeon-Baustein wie in den Leisten,
 * nur mit dem Abstand einer Kartenzeile darüber. */
.apk-fach{margin-top:var(--abstand-3)}
.apk-fach > .akkordeon-zeile{font-size:var(--groesse-3);color:var(--blau-tief)}
.gruppen-zahl{color:var(--gedaempft);font-weight:400;font-size:var(--groesse-2)}
.leiste-gruppe[open] > .akkordeon-zeile .gruppen-zahl{display:none}

/* ---- Unterpunkte: die Karten der offenen Seite (E-S8-15) -----------------
 * Unter dem aktiven Menüpunkt stehen die Kartentitel der Seite als
 * Sprungmarken. Sie sind KEINE Menüpunkte zweiter Ordnung: 28 px statt 44,
 * eine Schriftstufe kleiner, ohne Symbol und ohne Randstrich. Wer sie für
 * Menüpunkte hält, sucht dahinter eine eigene Seite.
 *
 * `menue.js` erzeugt sie aus den Karten der Seite — deshalb steht hier keine
 * Regel für einen leeren Behälter: Ohne Karten entsteht keiner.
 *
 * DIE MARKIERUNG IST FETT, NICHT ORANGE. Orange heißt in dieser Oberfläche
 * „hier stehst du" und gehört dem aktiven Menüpunkt; die oberste sichtbare
 * Karte ist etwas Schwächeres — ein Hinweis, wo im Text man gerade liest. */
.eintrag-unterliste{
  display:flex;flex-direction:column;
  margin:0 0 var(--abstand-2) var(--abstand-5);
}
.eintrag-unter{
  display:block;min-height:var(--unterpunkt);line-height:var(--unterpunkt);
  padding:0 var(--abstand-2);
  border-radius:var(--radius-klein);
  font-size:var(--groesse-2);color:var(--gedaempft);
  text-decoration:none;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.eintrag-unter:hover{background:var(--rauch);color:var(--asphalt);text-decoration:none}
.eintrag-unter.hier{color:var(--dunkelblau);font-weight:600}

/* KEINE `scroll-margin-top` AN DER KARTE. Das Konzept sah eine vor — „gibt es
 * im Stylesheet noch nicht" — und das stimmte für den Namen, nicht für die
 * Sache: `html` trägt seit Langem `scroll-padding-top: --kopf + --abstand-4`
 * (Abschnitt 1), und das löst dasselbe Problem eine Ebene höher. Beides
 * zusammen addiert sich: gemessen landete die angesprungene Karte bei 140 px
 * statt bei 72, also 68 px zu tief. Die Regel ist deshalb wieder heraus; der
 * Sprung sitzt mit `scroll-padding-top` allein richtig (gemessen 72 px). */

/* ---- Fußzeile ------------------------------------------------------------
 * Zweizeilig, zentriert, unter dem Inhalt — und außerhalb von <main>. */
.fuss-seite{
  border-top:var(--strich) solid var(--linie);
  padding:var(--abstand-4) var(--abstand-3);
  text-align:center;
  color:var(--gedaempft);font-size:var(--groesse-2);
}
.fuss-zeile{margin:0;display:flex;flex-wrap:wrap;gap:var(--abstand-2);justify-content:center}
.fuss-rechts{margin-top:var(--abstand-1)}
.fuss-seite a{color:var(--blau-tief);font-weight:600}
/* --gedaempft, nicht --sand (O10). Auf --rauch ergab Sand 1,53:1 — die
 * Versionsnummer ist die Auskunft, mit der ein Fehlerbericht anfaengt, und
 * damit ein zu LESENDER Text. `kontrast.py` fuehrte „Sand auf Schnee" als
 * Ausnahme, begruendet aber nur den Akkordeon-Winkel („Mechanik, keine
 * Botschaft"); das trifft auf eine Zahl nicht zu, die man abtippen soll.
 * Jetzt 5,30:1. Die dunkle Fassung darunter bleibt, wie sie ist. */
.fuss-version{color:var(--gedaempft)}
.fuss-dunkel{
  background:var(--dunkelblau);color:var(--rauch);
  border-top:0;
}
.fuss-dunkel a{color:var(--auf-dunkel)}
.fuss-dunkel .fuss-version{color:var(--auf-dunkel-leise)}

/* ---- Was nur in der Schublade steht -------------------------------------- */
.nur-schublade{display:block}
.nur-breit{display:none}
.nur-schmal{display:inline-flex}


/* == 5. LEISTENINHALT ======================================================
 *
 * Akkordeon und Einträge. Beide Leisten — Diensttage und Einstellungen —
 * benutzen dieselben Klassen; bis Web 8.0.1 trug das Einstellungsmenü
 * buchstäblich die Klasse `.daylist` und erbte damit jede Regel der
 * Tagesleiste, einschließlich der 100-vh-Höhe.
 */

/* ---- Akkordeon -----------------------------------------------------------
 * DIE GANZE ZEILE KLAPPT, nicht nur das Dreieck (E-P3-09). Bisher war der
 * Text der Link auf die Jahresübersicht und nur das Dreieck der Schalter — auf
 * einem Touchgerät nicht zu unterscheiden. Der Weg in die Übersicht ist jetzt
 * ein eigenes Symbol rechts.
 *
 * Der Winkel steht in Sand: Er ist Mechanik, keine Botschaft.
 */
/* GRÖSSER ALS DIE FELDTITEL DARIN (F-N1-K). Beide standen auf 15 px und
 * unterschieden sich nur durch die Schrift — die Gruppe „Einsatz" war
 * genauso groß wie „Wochentage" darin, obwohl sie eine Ebene darüber steht.
 * 16 px, und mit Bricolage dazu ist der Unterschied auch ohne Nachmessen zu
 * sehen. */
.akkordeon-zeile{
  display:flex;align-items:center;gap:var(--abstand-2);
  min-height:var(--knopf);
  padding:0 var(--abstand-1) 0 var(--abstand-2);
  border-radius:var(--radius-klein);
  cursor:pointer;list-style:none;
  font-family:var(--schrift-kopf);font-weight:600;font-size:var(--groesse-4);
  color:var(--dunkelblau);
}
.akkordeon-zeile::-webkit-details-marker{display:none}
.akkordeon-zeile:hover{background:var(--rauch)}
/* winkel.svg zeigt nach UNTEN. Zugeklappt wird er nach rechts gedreht,
 * aufgeklappt steht er in Ruhelage — so zeigen es die Mockups 01/03/06:
 * „›" heißt zu, „⌄" heißt offen. Die erste Fassung hatte es umgekehrt
 * (offen = oben) — das ist die Konvention mancher Aufklappmenüs, aber nicht
 * die dieses Entwurfs (Fable-Kontrolle, F-P3-Q). */
.akkordeon-winkel{color:var(--sand);transition:transform var(--dauer) ease-out;
  transform:rotate(-90deg)}
details[open] > .akkordeon-zeile > .akkordeon-winkel{transform:none}
.akkordeon-text{flex:1 1 auto;min-width:0}
/* Der Weg in die Jahres- bzw. Monatsübersicht: eigenes Ziel, eigene
 * Trefferfläche, 44 px. ER STEHT IM <summary> — die erste Fassung hatte ihn
 * daneben, als Kind des <details>, und der Inhalt eines geschlossenen
 * <details> wird nicht gerendert: Der Link war an jeder zugeklappten Zeile
 * unsichtbar und unerreichbar, die Mockups zeigen ihn an jeder
 * (Fable-Kontrolle, F-P3-R). Weil ein Link im <summary> beim Klick auch das
 * Auf- und Zuklappen auslöste, fängt daylist.js ihn ab und navigiert selbst. */
.akkordeon-uebersicht{
  margin-left:auto;flex:0 0 auto;
  width:var(--knopf);height:var(--knopf);
  display:flex;align-items:center;justify-content:center;
  color:var(--sand);border-radius:var(--radius-klein);
}
.akkordeon-uebersicht:hover{color:var(--blau-tief);background:var(--rauch)}
.akkordeon-inhalt{padding-left:var(--abstand-3)}
.akkordeon-monat > .akkordeon-zeile{font-size:var(--groesse-3)}

/* ---- Eintrag -------------------------------------------------------------
 * Menüpunkt und Diensttag. Aktiv: hell orange mit orangem Strich links —
 * in BEIDEN Leisten gleich (E-P3-10).
 */
.eintrag{
  display:flex;align-items:center;gap:var(--abstand-2);
  min-height:var(--knopf);
  padding:0 var(--abstand-2);
  border-radius:var(--radius-klein);
  border-left:var(--abstand-1) solid transparent;
  color:var(--asphalt);text-decoration:none;
}
.eintrag:hover{background:var(--rauch);text-decoration:none}
.eintrag .symbol{color:var(--dunkelblau)}
/* Das Datum schrumpft NICHT. Beim ersten Anlauf hatten Datum und
 * Rettungsmittelname beide `flex:1 1 auto`, und bei 260 px Leistenbreite wurde
 * aus „27.12.2026" ein „27.12.20…" — abgeschnitten wurde also die Auskunft,
 * die den Eintrag überhaupt identifiziert. Der Name absorbiert die Restbreite
 * (E-P3-09: Ellipse am NAMEN, voller Name im Tooltip). */
/* NORMAL, NICHT FETT (S3/AP4). Alle Eintraege standen auf 600. In einer
 * Liste, in der JEDE Zeile fett ist, hebt das nichts hervor -- es macht nur
 * den Block schwer, und der aktive Punkt muss seine Erkennbarkeit allein aus
 * Flaeche und Randstrich holen. Die Auszeichnung wandert von „alle" zu
 * „einer": Grundschnitt 400, der aktive Punkt 600. Dieselbe Ueberlegung wie
 * bei den Blattzeilen (F-N1-F). */
.eintrag-text{
  flex:1 0 auto;min-width:0;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-family:var(--schrift-kopf);font-weight:400;
}
/* Lange Rettungsmittelnamen werden abgeschnitten („NEF Neubran…"); der volle
 * Name steht im Tooltip und im Seitentitel. Drei Zustände über die Breiten,
 * nicht zwei: In der Schublade (unter 1024 px, 320 px breit) steht der Name
 * seit jeher; im Band 1024–1199 px ist die Leiste 220 px schmal und zeigt
 * nur einen gesetzten Kurznamen (`.kurz`, S9/AP4a); ab 1200 px steht wieder
 * jeder Name. Das Artzeichen bleibt überall (E-P3-09). */
.eintrag-neben{
  flex:0 1 auto;min-width:0;
  color:var(--gedaempft);font-size:var(--groesse-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.eintrag.aktiv{background:var(--orange-hell);border-left-color:var(--orange)}
.eintrag.aktiv .eintrag-text{color:var(--dunkelblau);font-weight:600}

/* Der Fuß der Leiste: „Zuordnung offen" (rosa mit rotem Zähler, nur solange
 * etwas offen ist), „Diensttag anlegen" (orange), Papierkorb (gedämpft). */
.eintrag-offen{background:var(--rosa)}
.eintrag-offen .symbol{color:var(--rot-tief)}
.eintrag-offen .eintrag-text{color:var(--rot-tief)}
.eintrag-anlegen .symbol,
.eintrag-anlegen .eintrag-text{color:var(--orange-tief)}
/* `font-weight:400` stand hier, solange die Grundform 600 war; seit S3/AP4
 * ist 400 die Grundform und die Angabe waere eine Dublette (9.16). */
.eintrag-leise .symbol,
.eintrag-leise .eintrag-text{color:var(--gedaempft)}
.zaehler{
  flex:0 0 auto;
  min-width:var(--abstand-5);height:var(--abstand-5);padding:0 var(--abstand-1);
  display:inline-flex;align-items:center;justify-content:center;
  border-radius:var(--radius-rund);
  background:var(--rot);color:var(--auf-dunkel);
  font-size:var(--groesse-1);font-weight:700;
}
/* DREI TÖNE, DIESELBEN WIE DIE AMPEL (S8/AP5, Design.md 9.23). Rot bleibt die
 * Grundform — den Zähler gab es bis Web 15.3.3 nur für die offene Zuordnung,
 * und die ist rot. Orange heißt „braucht Aufmerksamkeit, arbeitet aber",
 * neutral „eine Zahl ohne Wertung": ausstehende Updates sind kein Fehler,
 * sondern Arbeit, die jemand auslösen muss.
 *
 * NEUTRAL STEHT AUF SAND, NICHT AUF ROT MIT WENIGER SÄTTIGUNG. Ein blasses
 * Rot liest sich als „fast schlimm"; die Zahl soll aber gar nichts bewerten. */
.zaehler-orange{background:var(--orange);color:var(--dunkelblau)}
.zaehler-neutral{background:var(--sand);color:var(--dunkelblau)}


/* == 6. KARTE, ZEILE, TITELZEILE ===========================================
 *
 * Jeder Inhaltsblock ist eine Karte mit Titel, optionaler Zahl und GENAU
 * EINER Kopfaktion rechts. Eine zweite gibt es nicht — was mehr braucht,
 * bekommt ein Aktionsmenü (E-P3-25).
 */

.karte{
  background:var(--schnee);
  border:var(--strich) solid var(--linie);
  border-radius:var(--radius-gross);
  margin-bottom:var(--abstand-5);
}
/* flex-wrap: Wird die Zeile zu eng (Titel + Zahl + Sortieren + Nachtragen bei
 * 360 px), bricht die Kopfaktion in eine zweite Zeile um. Ohne wrap schrumpft
 * die Titelspalte unter ihre Textbreite und der Text uebermalt die Zahl. */
.karte-kopf{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--abstand-2);
  padding:var(--abstand-3) var(--abstand-4);
  border-bottom:var(--strich) solid var(--linie);
  list-style:none;
}
.karte-kopf::-webkit-details-marker{display:none}
.karte-titel{
  font-size:var(--groesse-5);
  flex:0 1 auto;min-width:0;
}
.karte-zahl{color:var(--gedaempft);font-size:var(--groesse-2);flex:0 0 auto}
/* Die Kopfaktion ist ein LINK mit Symbol, kein Knopf: Was kleiner als 44 px
 * ist, ist kein Knopf (E-P3-22). Die Trefferfläche erreicht sie über den
 * Innenabstand trotzdem. */
.karte-aktion{
  margin-left:auto;flex:0 0 auto;
  display:inline-flex;align-items:center;gap:var(--abstand-2);
  min-height:var(--knopf);padding:0 var(--abstand-2);
  font-family:var(--schrift-kopf);font-weight:600;
}
.karte-aktion-blau{color:var(--blau-tief)}
.karte-aktion-orange{color:var(--orange-tief)}
.karte-inhalt{padding:var(--abstand-4)}
.karte-vorschau{
  margin-left:auto;color:var(--gedaempft);
  font-size:var(--groesse-2);text-align:right;
}
.karte-klappbar > .karte-kopf{cursor:pointer;border-bottom:0}
.karte-klappbar[open] > .karte-kopf{border-bottom:var(--strich) solid var(--linie)}
.karte-klappbar > .karte-kopf .akkordeon-winkel{color:var(--sand)}
.karte-klappbar[open] > .karte-kopf .akkordeon-winkel{transform:none}

/* ---- Zeile ---------------------------------------------------------------
 * Text links (fett plus Kleinzeile), Plaketten, Aktionen rechts. Am Desktop
 * sind die Aktionen Knöpfe; mobil ein „⋯" je Zeile (E-P3-26).
 */
.zeile{
  display:flex;align-items:center;gap:var(--abstand-3);
  padding:var(--abstand-3) 0;
  border-bottom:var(--strich) solid var(--linie);
}
/* DIE ZEILE ALS VERWEIS (S9/AP5, M-S9-06). Sie sieht aus wie jede andere
 * Zeile — der Unterschied ist der Winkel rechts und die Flaeche, die sich
 * anfassen laesst. Keine Unterstreichung: Die ganze Zeile ist der Link, und
 * ein unterstrichener Name daerinnen sagte, nur er sei es. */
/* „ZUM ANFANG" (S9/AP5): rechtsbuendig am Ende eines Abschnitts, mit Luft
 * darueber. Der Knopf selbst ist `.knopf knopf-leise` — die Klasse traegt
 * die Bedienhoehe und wird vom Bilderlauf gemessen. */
.nach-oben{margin:var(--abstand-4) 0 0;text-align:right}
a.zeile{text-decoration:none;color:inherit}
a.zeile:hover{background:var(--rauch);text-decoration:none}
a.zeile:hover .zeile-haupt{color:var(--blau-tief)}
a.zeile:focus-visible{outline:var(--strich-stark) solid var(--blau);outline-offset:var(--strich-stark);border-radius:var(--radius-klein)}
.zeile-weiter{color:var(--sand);flex:0 0 auto}
a.zeile:hover .zeile-weiter{color:var(--blau-tief)}
.zeile:last-child{border-bottom:0;padding-bottom:0}
.zeile:first-child{padding-top:0}
.zeile-text{flex:1 1 auto;min-width:0}
.zeile-haupt{font-weight:600;color:var(--asphalt)}
.zeile-text a{color:inherit}
.zeile-klein{display:block;color:var(--gedaempft);font-size:var(--groesse-2)}
.zeile-plaketten{display:flex;flex-wrap:wrap;gap:var(--abstand-1);flex:0 1 auto}
.zeile-aktionen{display:flex;gap:var(--abstand-2);flex:0 0 auto}
/* Zeile hervorgehoben — die Spurliste des Diensttages (S2/AP4).
 *
 * Kein neuer Farbwert und kein neues Mass: dieselbe Rauchflaeche, die schon
 * die neutrale Plakette traegt, plus ein orangener Balken links in
 * --strich-stark. Der Balken ist die Verbindung zur Karte, auf der die
 * zugehoerige Linie gleichzeitig dicker wird — beides ohne zusaetzliches
 * Element und ohne dass die Zeile ihre Hoehe aendert. */
.zeile-hervor{
  background:var(--rauch);
  box-shadow:inset var(--strich-stark) 0 0 var(--orange);
  padding-left:var(--abstand-2);
}
/* Kein eigener Fokusring: Es gibt EINEN fuer die ganze Anwendung
 * (`:focus-visible` weiter oben), und der greift auch hier. */
.spur-zeile{cursor:pointer}

/* DIE ANGESPRUNGENE ZEILE (S9/AP5, M-S9-05 und M-S9-07).
 *
 * Wer aus der Sprungliste kommt oder gerade etwas angelegt hat, landet auf
 * einer Zeile unter zwoelf gleich aussehenden. `:target` faerbt genau die,
 * deren Kennung in der Adresse steht — OHNE SKRIPT, und es ueberlebt den
 * Ruecksprung aus dem Verlauf. `.zeile-hervor` (weiter oben) sagt dasselbe,
 * wird aber von Hand gesetzt und ist nach einem Neuladen weg; sie bleibt der
 * Weg fuer eine Auswahl, die das Skript trifft (Spurliste), `:target` der
 * fuer eine, die in der Adresse steht.
 *
 * DER RAND DER FLAECHE: Die Zeile liegt in `.karte-inhalt`, und das hat
 * `--abstand-4` Innenabstand. Damit die Flaeche bis an den Kartenrand
 * reicht, ist der negative Aussenabstand GENAU dieser Wert — die Mockups
 * schreiben `--abstand-3` und lassen so je Seite 4 px Weiss stehen. */
.zeile:target{
  background:var(--orange-hell);
  margin:0 calc(var(--abstand-4) * -1);
  padding-left:var(--abstand-4);
  padding-right:var(--abstand-4);
}

/* ---- Titelzeile ---------------------------------------------------------- */
.titelzeile{margin-bottom:var(--abstand-4)}
.rueckweg{
  display:inline-flex;align-items:center;gap:var(--abstand-1);
  min-height:var(--knopf);
  color:var(--blau-tief);font-weight:600;
}
.titelzeile-haupt{display:flex;align-items:flex-start;gap:var(--abstand-3);flex-wrap:wrap}
/* flex-basis auto statt fester 14rem: Ein kurzer Titel („Einsatz 1") liess
 * sonst die Knoepfe umbrechen, obwohl alles in eine Zeile passt (O4). Lange
 * Titel sind mobil ohnehin kurz gefasst (wtag-kurz). */
.titelzeile-text{flex:1 1 auto;min-width:0}
.titelzeile-unter{color:var(--gedaempft);font-size:var(--groesse-2);margin-top:var(--abstand-1)}
.titelzeile-aktionen{display:flex;gap:var(--abstand-2);flex:0 0 auto;margin-left:auto}


/* == 7. KNOPF ==============================================================
 *
 * EINE HÖHE: 44 px, mobil wie Desktop, auch für Zeilenaktionen. Es gibt keine
 * Kompaktvariante — was kleiner ist, ist kein Knopf (E-P3-22). Der Bestand
 * hatte sechs Varianten und sechs ortsgebundene Größen; `.btn-primary` trug
 * global `width:100%` und wurde an zehn Stellen zurückgenommen.
 *
 * Die Vollständigkeitsprüfung liest die Höhenangabe nach: Sie muss aus
 * --knopf kommen.
 */
.knopf{
  display:inline-flex;align-items:center;justify-content:center;
  gap:var(--abstand-2);
  height:var(--knopf);
  padding:0 var(--abstand-4);
  border-radius:var(--radius);
  border:var(--strich-stark) solid transparent;
  font-family:var(--schrift-kopf);font-weight:600;
  font-size:var(--groesse-3);
  text-decoration:none;cursor:pointer;
  white-space:nowrap;
}
.knopf:hover{text-decoration:none}
.knopf[disabled],.knopf[aria-disabled="true"]{opacity:.5;cursor:default}

/* Dunkelblaue Schrift auf Orange: 5,97:1. Weiß auf Orange wären 2,3:1 und
 * damit unlesbar — die Mockups zeigen an dieser Stelle Weiß, der
 * Entscheidungstext gilt (E-P3-15, Fund F-P3-L). */
.knopf-primaer{
  background:var(--knopf-primaer-flaeche);
  color:var(--knopf-primaer-schrift);
  border-color:var(--knopf-primaer-flaeche);
}
.knopf-primaer:hover{background:var(--orange-tief);border-color:var(--orange-tief);color:var(--auf-dunkel)}
.knopf-neutral{
  background:var(--schnee);color:var(--dunkelblau);
  border-color:var(--linie-stark);
}
.knopf-neutral:hover{background:var(--rauch)}
.knopf-gefahr{background:var(--schnee);color:var(--rot-tief);border-color:var(--rot)}
.knopf-gefahr:hover{background:var(--rosa)}
.knopf-leise{background:none;color:var(--gedaempft);padding:0 var(--abstand-2)}
.knopf-leise:hover{color:var(--asphalt)}
.knopf-symbol{
  width:var(--knopf);height:var(--knopf);padding:0;
  background:none;color:inherit;border-color:transparent;
}
.knopf-symbol:hover{background:var(--rauch)}
.knopf-breit{width:100%}


/* == 8. PLAKETTE ===========================================================
 *
 * Plaketten tragen KEIN Häkchen: Ihr Vorhandensein ist das Häkchen. Und sie
 * sind keine Bedienelemente (E-P3-17).
 */
.plakette{
  display:inline-flex;align-items:center;gap:var(--abstand-1);
  padding:var(--abstand-1) var(--abstand-2);
  border-radius:var(--radius-klein);
  font-size:var(--groesse-1);font-weight:600;
  white-space:nowrap;
}
.plakette .symbol{width:14px;height:14px}
.plakette-neutral{background:var(--rauch);color:var(--gedaempft);border:var(--strich) solid var(--linie)}
.plakette-orange{background:var(--orange-hell);color:var(--asphalt)}
.plakette-blau{background:var(--blau-hell);color:var(--dunkelblau)}
.plakette-rot{background:var(--rosa);color:var(--rot-tief)}
.plakette-weg{
  display:inline-flex;align-items:center;justify-content:center;
  width:var(--symbol);height:var(--symbol);
  margin-right:calc(var(--abstand-1) * -1);color:inherit;
}


/* == 9. MELDUNG ============================================================
 *
 * Vier Töne mit Symbol und optionalem fettem Auftakt (E-P3-16). Grün ist
 * fort: Die Vollzugsmeldung ist jetzt blau wie der Hinweis und unterscheidet
 * sich durch das Symbol — Haken gegen Kreis-i. Farbe ist nie der einzige
 * Träger (Grundregel 3).
 *
 * Die Warnung trägt ihren Text in Asphalt, nicht in Orange tief: Orange tief
 * auf Orange hell sind 3,81:1 und damit unter der Schwelle für Fließtext.
 * Der fette Auftakt darf orange sein — für fette Schrift ab 14 px gilt 3:1.
 */
.meldung{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--abstand-3);
  padding:var(--abstand-3) var(--abstand-4);
  border-radius:var(--radius);
  margin-bottom:var(--abstand-5);
}
/* Der Text braucht eine Mindestbreite, unter der die Aktion in die naechste
 * Zeile umbricht — sonst quetscht ein breiter Knopf den Text auf ein Wort je
 * Zeile (Fund aus O3 am Geraetehinweis bei 390 px). */
.meldung p{flex:1 1 16rem;min-width:0}
.meldung .symbol{flex:0 0 auto}
.meldung-aktion{flex:0 0 auto}
.meldung-fehler{background:var(--rosa);color:var(--rot-tief)}
.meldung-fehler .symbol{color:var(--rot)}
.meldung-info{background:var(--blau-hell);color:var(--blau-tief)}
.meldung-info .symbol{color:var(--blau-tief)}
.meldung-ok{background:var(--blau-hell);color:var(--blau-tief)}
.meldung-ok .symbol{color:var(--blau-tief)}
/* SCHUTZ — rot, aber kein Fehler (S3, Rueckmeldung vom 01.09.2026). Fuer den
 * einen Fall, in dem eine Meldung dauerhaft steht und trotzdem die Farbe des
 * Ernstfalls braucht: ein Datenschutzhinweis an der Stelle, an der jemand
 * gleich Daten herunterlaedt. Er benutzt die Flaeche und die Schrift von
 * `fehler` — kein neuer Farbwert —, aber `role="status"` statt `alert`: Was
 * bei JEDEM Aufruf der Seite dasteht, darf einen Vorleser nicht jedes Mal
 * unterbrechen. Das Symbol ist das Schloss, nicht die Warnung: Es geht um
 * Schutzbeduerftigkeit, nicht um einen Fehlgriff. */
.meldung-schutz{background:var(--rosa);color:var(--rot-tief)}
.meldung-schutz .symbol{color:var(--rot)}
.meldung-schutz strong{color:var(--rot-tief)}
.meldung-warn{background:var(--orange-hell);color:var(--asphalt)}
.meldung-warn .symbol{color:var(--orange-tief)}
.meldung-warn strong{color:var(--orange-tief)}


/* == 10. AKTIONSMENÜ UND BLATT =============================================
 *
 * Mobil ein „⋯", das ein Blatt von unten öffnet; am Desktop derselbe Vorrat
 * als Aufklappmenü. EIN Markup für beide Formen — assets/blatt.js öffnet und
 * schließt nur, welche Form erscheint, sagt dieses Stylesheet (E-P3-27).
 */
.aktionen{position:relative}
.aktionen-knopf .symbol:last-child{transition:transform var(--dauer) ease-out}
.aktionen-knopf[aria-expanded="true"] .symbol:last-child{transform:rotate(180deg)}

/* DER OFFENE OEFFNER IST MARKIERT (Backlog Nr. 124, Weg b; E-MR-21, D4).
 *
 * Das Blatt deckt am Handy die untere Bildhaelfte ab, und der Knopf, aus dem
 * es kam, verschwand darin optisch — wer es wieder zumachen wollte, suchte.
 * Er traegt deshalb, solange sein Blatt offen ist, die Flaeche `--orange-hell`
 * mit `--orange-tief` darauf: 11,7:1 gegen den dunkelblauen Kartenkopf,
 * 3,8:1 fuer die Punkte gegen die Flaeche — ueber den 3:1, die WCAG 1.4.11
 * fuer ein Bedienelement verlangt (`kontrast.py`, Paar „Orange tief auf
 * Orange hell"). Zur Wahl standen vier Ringfassungen; keine ueberzeugte, der
 * Ring auf Blau-hell lag bei 1,9:1 (E-MR-17, E-MR-20).
 *
 * AM ATTRIBUT, NICHT AN DER KLASSE — und das ist der Kern. Oeffner gibt es in
 * vier Bauarten: `ui_aktionen()` (6 Aufrufe), `ui_zeilenaktionen()` (9), der
 * Pin-Knopf des Ortsfelds und drei handgeschriebene Sortierblatt-Knoepfe in
 * index.php, suche.php und zeitraum.php. Sie teilen genau ein Merkmal:
 * `data-blatt` und `aria-expanded`. Eine Regel daran erreicht alle vier, auch
 * die naechste — „Blatt offen" ist dieselbe Aussage, gleich an welchem Knopf
 * (E-MR-25).
 *
 * `border-radius` steht hier mit, weil nicht jeder Oeffner ein `.knopf` ist:
 * `.karte-sortieren` ist ein blanker Button, und ohne die Rundung bekaeme er
 * ein hartes oranges Quadrat. Die Spezifitaet (0,2,0) liegt ueber jeder
 * Knopfvariante und ueber deren `:hover`. */
[data-blatt][aria-expanded="true"]{
  background:var(--orange-hell);
  color:var(--orange-tief);
  border-color:var(--orange-hell);
  border-radius:var(--radius);
}

/* DAS BLATT FAEHRT AUF, STATT DAZUSTEHEN (Backlog Nr. 124, Weg b).
 *
 * Es liegt unten am Bildrand, und ein Menue, das dort ohne Bewegung
 * erscheint, liest sich wie ein Seitenwechsel: Die halbe Flaeche ist ploetzlich
 * eine andere, und niemand weiss, woher sie kam. Mit der Auffahrt sagt die
 * Bewegung, wo es herkommt und wohin es zurueckgeht.
 *
 * ZWEI ZUSTAENDE, EINE KLASSE. Im Ruhezustand steht es um seine eigene Hoehe
 * unter dem Bildrand (`translateY(100%)`); `.blatt-auf` holt es herauf.
 * `assets/blatt.js` setzt die Klasse im naechsten Frame nach `hidden=false` —
 * beides im selben Frame waere keine Bewegung, sondern ein Sprung.
 *
 * `hidden` BLEIBT DER SCHALTER fuer „da oder nicht da": Ein Blatt, das nur
 * verschoben ist, faenge weiter Klicks und stuende im Vorlesebaum. Das Skript
 * nimmt es deshalb erst NACH der Rueckfahrt aus dem Fluss.
 *
 * Bewegung abbestellt: Abschnitt 3 setzt jede `transition-duration` auf
 * 0,01 ms. Das Blatt erscheint dann ohne Fahrt — und `transitionend` feuert
 * trotzdem, worauf sich das Skript NICHT verlaesst (es hat einen Nachlauf). */
.blatt{
  position:fixed;inset:auto 0 0 0;z-index:70;
  background:var(--schnee);
  border-radius:var(--radius-gross) var(--radius-gross) 0 0;
  box-shadow:var(--schatten-hoch);
  padding:var(--abstand-3) var(--abstand-3) var(--abstand-5);
  max-height:80vh;overflow-y:auto;
  transform:translateY(100%);
  transition:transform var(--dauer) ease-out;
}
.blatt.blatt-auf{transform:none}
.blatt-griff{
  width:2.5rem;height:var(--abstand-1);margin:0 auto var(--abstand-3);
  border-radius:var(--radius-rund);background:var(--sand);
}
.blatt-titel{
  font-size:var(--groesse-5);text-align:center;
  margin-bottom:var(--abstand-2);
}
.blatt-liste{display:flex;flex-direction:column}
/* NORMAL STATT FETT (F-N1-F). Die Einträge standen auf 600 — dasselbe
 * Gewicht wie ein Kartentitel. In einem Menü, in dem JEDE Zeile so gesetzt
 * ist, hebt das nichts hervor; es macht nur den ganzen Block schwer.
 * Unterschieden wird hier ohnehin durch Symbol und Farbe (orange fürs
 * Anlegen, rot fürs Löschen), nicht durch das Gewicht.
 *
 * WARUM NICHT 500 als Mittelweg: Open Sans liegt in 400, 600 und 700 vor —
 * einen 500er-Schnitt gibt es nicht. Die Angabe fiele still auf 400 zurück,
 * und im Stylesheet stünde eine Zahl, die nichts bedeutet. Ein vierter
 * Schriftschnitt wäre eine weitere Datei für einen Menüeintrag. */
.blatt-zeile{
  display:flex;align-items:center;gap:var(--abstand-3);
  min-height:var(--blatt-zeile);
  padding:0 var(--abstand-3);
  border-radius:var(--radius-klein);
  color:var(--asphalt);font-weight:400;
}
.blatt-zeile:hover{background:var(--rauch);text-decoration:none}
.blatt-zeile .symbol{color:var(--dunkelblau)}
.blatt-anlegen,.blatt-anlegen .symbol{color:var(--orange-tief)}
/* Löschen steht rot UND durch eine Linie abgesetzt: Wer schnell tippt, soll
 * nicht danebengreifen. */
.blatt-gefahr{
  color:var(--rot-tief);
  margin-top:var(--abstand-2);padding-top:var(--abstand-2);
  border-top:var(--strich) solid var(--linie);
}
.blatt-gefahr .symbol{color:var(--rot)}
.blatt-abbrechen{width:100%;margin-top:var(--abstand-3)}


/* == 11. FORMULAR ==========================================================
 *
 * Feld, Schalter, Segmentwahl, Speichern-Leiste.
 *
 * Die Beschriftung steht in NORMALSCHRIFT. Im Bestand waren Feldnamen,
 * Tabellenköpfe und Legenden gesperrte Versalien — das prägende Stilmittel
 * und zugleich das, was auf 360 px am meisten Breite kostete (E-P3-21).
 */
/* EIN <fieldset>, DAS NUR GRUPPIERT (S3/AP10). Gebraucht fuer das
 * `disabled`-Attribut: Es sperrt ein ganzes Formular in einem Zug, statt an
 * jedem Feld ein Attribut zu setzen. Die Elementregeln fuer fieldset sind mit
 * O11 gefallen — ohne diese Ruecknahme brachte der Browser seinen eigenen
 * Rahmen und seine eigene Polsterung mit. `min-width:0` gehoert dazu: Ein
 * fieldset hat eine eingebaute Mindestbreite nach seinem Inhalt und sprengt
 * damit sonst jedes schmale Raster. */
.feldsatz-gesperrt{border:0;padding:0;margin:0;min-width:0}
.feldsatz-gesperrt[disabled]{opacity:.55}
.feld{margin-bottom:var(--abstand-3)}
.feld-label{display:block;font-weight:600;margin-bottom:var(--abstand-1)}
.feld-pflicht{color:var(--rot-tief)}
.feld-eingabe{
  display:block;width:100%;
  height:var(--knopf);
  padding:0 var(--abstand-3);
  background:var(--schnee);color:var(--asphalt);
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius-klein);
}
/* GESPERRT MUSS GESPERRT AUSSEHEN (F-S8-P-03, aufgenommen in S8/AP1).
 * `.feld-eingabe` setzt Flaeche und Schrift selbst und ueberschreibt damit
 * die Graufaerbung, die der Browser einem `disabled` gibt — ein einzeln
 * gesperrtes Feld war von einem bedienbaren nicht zu unterscheiden. Es
 * bekommt deshalb die Seitenflaeche statt der Kartenflaeche: dieselbe
 * Aussage wie beim gesperrten Feldsatz, aber ohne dessen `opacity`, die
 * auch den Rand aufhellt. Der Rand bleibt `--linie-stark` und damit ueber
 * den 3:1, die WCAG 1.4.11 fuer die Begrenzung eines Bedienelements
 * verlangt — gemessen 5,30:1 auf Rauch.
 *
 * DIE FLAECHE ALLEIN TRAEGT DIE AUSSAGE NICHT: Rauch auf Schnee sind
 * 1,07:1, sichtbar erst im Vergleich zweier Felder nebeneinander. Die
 * Aussage traegt die Schrift — 19,29:1 im bedienbaren Feld (Asphalt auf
 * Schnee) gegen 5,30:1 im gesperrten. Beides zusammen ist das Bild, das
 * ein Browser von Haus aus zeichnet und das `.feld-eingabe` uebermalt
 * hatte.
 *
 * Es GILT ZUSAETZLICH im gesperrten Feldsatz (`.feldsatz-gesperrt[disabled]`
 * vererbt `disabled` an seine Felder). Das ist gewollt: Die Deckkraft daempft
 * die ganze Gruppe, die Flaeche sagt, welches Element gemeint ist. */
.feld-eingabe:disabled{background:var(--rauch);color:var(--gedaempft);cursor:not-allowed}
.feld-mehrzeilig{height:auto;padding:var(--abstand-3)}
/* DAS DATEIFELD: sein Knopf hängt oben, solange ihn nichts in die Mitte holt.
 *
 * `input[type=file]` stellt den nativen Knopf auf die Textzeile. Die steht bei
 * `height:var(--knopf)` ohne senkrechte Polsterung am oberen Innenrand —
 * gemessen 0 px Luft darüber, 19 px darunter, und genau das ist als schiefer
 * „Browse…"-Knopf zu sehen.
 *
 * `display:flex;align-items:center` ändert daran NICHTS. Chromium legt den
 * Shadow-Inhalt eines Eingabefeldes nicht in einen Flex-Fluss; nachgemessen
 * blieb es bei 0/19. Die Zeilenhöhe auf den Innenraum zu setzen wirkt dagegen
 * und lässt die 44 px stehen — gemessen 10 px oben, 9 px unten (die 42 px
 * Innenraum sind ungerade, mittiger geht es nicht).
 *
 * Der Attributselektor ist nicht Zierde, sondern die Abgrenzung: Getroffen
 * werden nur die beiden Dateifelder (import.php, einstellungen.php). 77
 * Eigenschaftsmessungen über sieben Feldarten zeigten genau diese eine
 * Änderung und keine zweite. */
input[type=file].feld-eingabe{line-height:calc(var(--knopf) - 2*var(--strich))}
/* DAS AUSWAHLFELD: sein laengster Eintrag schiebt die SEITE, nicht sich selbst
 * (WebKit; gefunden in AP3b mit dem dreifachen Bilderlauf, Nr. 185).
 *
 * Gemessen auf `import.php` bei 360 px, angemeldet als Demo-Konto:
 *
 *     chromium  scrollWidth 360 = innerWidth 360
 *     firefox   scrollWidth 360 = innerWidth 360
 *     webkit    scrollWidth 366 > innerWidth 360      <-- 6 px Ueberlauf
 *
 * Der Verursacher liess sich nicht finden, weil er keiner ist: KEIN Element
 * der Seite ragt ueber 360 px hinaus — das Auswahlfeld ist 302 px breit und
 * endet bei 331. Was ueberlaeuft, ist die innere Breite des Feldes: WebKit
 * rechnet den laengsten EINTRAG in den Ueberlauf des Kastens mit, auch wenn
 * der Kasten ihn abschneidet. Nachgewiesen durch Kuerzen: Alle
 * Eintragstexte auf „x" gesetzt, und scrollWidth fiel von 366 auf 360;
 * zurueckgesetzt, und es waren wieder 366. Der laengste Eintrag hat 53
 * Zeichen („Bergwacht Hochkreuth · Luftrettungsstation Hochkreuth"), die
 * drei anderen Auswahlfelder derselben Seite haben 17, 17 und 30 — sie
 * laufen nicht ueber. Ab 390 px verschwindet der Ueberlauf.
 *
 * `overflow:clip` am Feld hilft NICHT (gemessen: 366), `max-width:100%`
 * ebenso wenig, `appearance:none` nur zur Haelfte (361). Was hilft, ist
 * Malbegrenzung: `contain:paint` nimmt den Eintragstext aus dem Ueberlauf
 * der Seite. Was sie KOSTET, ist nachgemessen und nicht geschaetzt — der
 * fokussierte Ausschnitt (318 x 60 px) vor und nach der Regel: in Firefox
 * bitgleich, in Chromium und WebKit **ein** Pixel Unterschied bei einer
 * Abweichung von 6 von 255, an der Rundung des Fokusrings. Der Fokusring
 * selbst bleibt vollstaendig stehen; er gehoert dem Feld und nicht seinem
 * Inhalt, und Malbegrenzung schneidet nur Inhalt.
 *
 * Nur `select`: Ein Textfeld hat keinen Inhalt, der breiter waere als sein
 * Kasten. */
select.feld-eingabe{contain:paint}
.feld-klein{color:var(--gedaempft);font-size:var(--groesse-2);margin-top:var(--abstand-1)}
.feld-reihe{display:flex;flex-wrap:wrap;gap:var(--abstand-3)}
.feld-reihe > .feld{flex:1 1 12rem;min-width:0}

/* ---- Schalter ------------------------------------------------------------
 * Aus einer echten Checkbox gebaut — Tastaturbedienung, Vorlesezustand und
 * Absenden kommen damit vom Browser und nicht aus einem Skript. */
.schalter{margin-bottom:var(--abstand-3)}
/* DER SELEKTOR IST ABSICHTLICH SO LANG — dieselbe Falle wie F-P3-AP, hier
 * in O11 nachgezogen. `.schalter-box` (0,1,0) verliert gegen
 * `input[type=checkbox]` in den Grundformen (0,1,1), die jedem Kästchen
 * 20 x 20 px gibt; gemessen war es genau das. Weder `.schalter` noch
 * `.wahlliste` setzen `position:relative`, das unsichtbare Kästchen lag also
 * auf seiner statischen Stelle über dem linken Rand der Beschriftung. */
input[type=checkbox].schalter-box{position:absolute;opacity:0;width:0;height:0;min-height:0}
.schalter-label{
  display:flex;align-items:center;gap:var(--abstand-3);
  min-height:var(--knopf);cursor:pointer;
}
/* DER GRIFF STEHT NEBEN DER BESCHRIFTUNG, NICHT AM RAND (Backlog Nr. 123,
 * gemeldet 05.09.2026 mit Bild). Bis Web 15.4.1 trug `.schalter-text`
 * `flex:1 1 auto` und drückte den Griff an den rechten Rand der Karte.
 * Gemessen: bei 1440 px lagen zwischen dem Ende von „Mein Kontopasswort
 * verwenden" und dem Griff **832 px**, bei 1920 px **1072 px** — mehr als
 * eine halbe Bildschirmbreite. Man sieht den Schalter dort nicht mehr als zu
 * dieser Zeile gehörig; man sieht ihn oft gar nicht.
 *
 * `flex:0 1 auto` lässt den Text nur so breit werden, wie er ist. Die
 * TREFFERFLÄCHE bleibt die ganze Zeile: Das `<label>` behält seine Breite,
 * nur sein Inhalt rückt zusammen. */
.schalter-text{flex:0 1 auto;font-weight:600}
.schalter-klein{display:block;font-weight:400;color:var(--gedaempft);font-size:var(--groesse-2)}
.schalter-griff{
  flex:0 0 auto;position:relative;
  width:var(--schalter-breit);height:var(--schalter-hoch);
  border-radius:var(--radius-rund);
  background:var(--sand);
  transition:background var(--dauer) ease-out;
}
.schalter-griff::after{
  content:"";position:absolute;
  top:calc((var(--schalter-hoch) - var(--schalter-punkt)) / 2);
  left:calc((var(--schalter-hoch) - var(--schalter-punkt)) / 2);
  width:var(--schalter-punkt);height:var(--schalter-punkt);
  border-radius:var(--radius-rund);
  background:var(--schnee);
  transition:transform var(--dauer) ease-out;
}
.schalter-box:checked + .schalter-label .schalter-griff{background:var(--orange)}
.schalter-box:checked + .schalter-label .schalter-griff::after{
  transform:translateX(calc(var(--schalter-breit) - var(--schalter-hoch)));
}
.schalter-box:focus-visible + .schalter-label .schalter-griff{
  outline:var(--strich-stark) solid var(--blau);outline-offset:var(--strich-stark);
}
/* AUSGEGRAUT — ein Schalter, den eine Einstellung darueber gesperrt hat
 * (S9/AP2, E-S9-05: die Installation ist die Obergrenze des Kontoschalters).
 * Dieselbe Sprache wie beim gesperrten Eingabefeld (`.feld-eingabe:disabled`):
 * gedaempfte Schrift, Rauch als Flaeche, `not-allowed` am Zeiger. Ein
 * ZWEITES Aussehen fuer denselben Zustand waere zwei Aussagen fuer eine
 * Sache. Warum er gesperrt ist, sagt der Absatz daneben — die Farbe kann das
 * nicht, und sie soll es nicht versuchen. */
.schalter-box:disabled + .schalter-label{cursor:not-allowed}
.schalter-box:disabled + .schalter-label .schalter-text{color:var(--gedaempft)}
.schalter-box:disabled + .schalter-label .schalter-griff{background:var(--rauch)}
.schalter-box:disabled + .schalter-label .schalter-griff::after{background:var(--sand)}
/* Abhängige Felder klappen darunter auf, eingerückt mit orangem Randstrich. */
.schalter-abhaengig{
  margin:var(--abstand-2) 0 var(--abstand-4) var(--abstand-3);
  padding-left:var(--abstand-4);
  border-left:var(--strich-stark) solid var(--orange);
}

/* ---- Segmentwahl ---------------------------------------------------------
 * Als Radiogruppe gebaut: Pfeiltasten, Vorlesezustand und Absenden kommen
 * damit vom Browser. */
.segment{
  display:flex;flex-wrap:wrap;
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius);
  overflow:hidden;
}
/* DER SELEKTOR IST ABSICHTLICH SO LANG (F-P3-AP, O9c). `.segment-box`
 * allein (0,1,0) verliert gegen `input[type=radio]` (0,1,1) in Abschnitt 15,
 * die jedem Radio 20 x 20 px gibt — und weil diese Regel spaeter steht, blieb
 * das Kaestchen 20 x 20 gross, nur durchsichtig. Absolut positioniert und
 * unsichtbar lag es damit UEBER der Umgebung und fing Klicks ab; gefunden
 * beim Bedienen der Wartungsseite („intercepts pointer events"). Es betraf
 * jede Segmentwahl der Anwendung — Zeitraum, Suchfilter, Reiter. */
input[type=radio].segment-box,
input[type=checkbox].segment-box{position:absolute;opacity:0;width:0;height:0;min-height:0}
/* DER RAND MUSS WEG (F-N1-L). Die Taste ist ein `<label>`, und die
 * Grundformen geben jedem `label` `margin-bottom: --abstand-3` — den Abstand
 * zum nächsten Feld. Innerhalb des Segmentrahmens ist das kein Abstand,
 * sondern ein toter Streifen: Der Rahmen war 58 px hoch, die Tasten 44, und
 * unter ihnen lagen 12 px Leere im Kasten. Betroffen war JEDE Segmentwahl der
 * Anwendung — Wochentage, Dreiwertfilter, Zeitraum-Reiter, Logo-Wahl.
 *
 * Das ist die Falle aus `Design.md` 9.16, in Reinform: Ein Baustein auf einem
 * Elementnamen, dessen Grundform er nicht zurücknimmt. */
.segment-taste{
  flex:1 1 auto;margin:0;
  display:flex;align-items:center;justify-content:center;
  min-height:var(--knopf);padding:0 var(--abstand-3);
  background:var(--schnee);color:var(--dunkelblau);
  font-family:var(--schrift-kopf);font-weight:600;
  cursor:pointer;text-align:center;
  border-right:var(--strich) solid var(--linie);
}
.segment-taste:last-of-type{border-right:0}
.segment-box:checked + .segment-taste{background:var(--orange);color:var(--knopf-primaer-schrift)}
.segment-box:focus-visible + .segment-taste{
  outline:var(--strich-stark) solid var(--blau);outline-offset:calc(var(--strich-stark) * -1);
}

/* ---- Speichern-Leiste ----------------------------------------------------
 * Klebt am unteren Rand und erscheint, sobald das Formular schmutzig ist.
 * KEIN „Verwerfen" — der Rückweg oben genügt, und ein Verwerfen-Knopf neben
 * einem Speichern-Knopf ist die Stelle, an der man sich vergreift (E-P3-29). */
.speichern{
  position:sticky;bottom:0;z-index:30;
  /* KARTENFORM (E-R43-1). Bis Web 12.2.2 brach die Leiste mit
   * `margin: … calc(var(--abstand-3) * -1)` seitlich aus dem Inhalt aus und
   * lief ohne Radius von Rand zu Rand — sie wirkte dadurch „eckig und
   * breiter" als die Karte darüber, obwohl sie zu ihr gehört. Jetzt Radius
   * und Breite wie die Karte; der Ausbruch ist ersatzlos entfallen.
   *
   * WAS BLEIBT, ist alles, was die FUNKTION traegt: der klebende Sitz, die
   * Trennlinie nach oben und der Schatten. Die Leiste soll auffallen, weil
   * sie folgt — nicht, weil sie anders geschnitten ist. */
  margin:var(--abstand-4) 0 0;
  padding:var(--abstand-3);
  background:var(--schnee);
  border-top:var(--strich) solid var(--linie);
  border-radius:var(--radius-gross);
  box-shadow:var(--schatten);
}
/* KNOPF RECHTS, ZAEHLUNG LINKS DANEBEN. Im Markup steht der Hinweis zuerst
 * (ui_speichern_leiste), damit die Vorlesereihenfolge stimmt: erst „12
 * ausgewaehlt", dann „Auswahl sichern". flex-end schiebt das Paar an den
 * rechten Rand — die Haupthandlung sitzt dort, wo die Hand sie sucht. */
.speichern-innen{
  display:flex;align-items:center;justify-content:flex-end;gap:var(--abstand-3);
  max-width:var(--rahmen);margin:0 auto;
}
.speichern-hinweis{display:none;color:var(--gedaempft);font-size:var(--groesse-2)}


/* == 12. KENNZAHL ==========================================================
 *
 * Wert in Bricolage mit Einheit, darunter die Beschriftung. Die Hervorhebung
 * eines Extremwerts war rot und ist jetzt orange: Rot heißt in dieser
 * Oberfläche „Aufmerksamkeit", und ein Höchstwert ist kein Fehler (E-P3-37).
 */
.kennzahl-raster{
  display:grid;gap:var(--abstand-3);
  grid-template-columns:repeat(2,minmax(0,1fr));
  margin-bottom:var(--abstand-4);
}
/* SENKRECHT MITTIG (S3/AP5). Die Kacheln stehen in einem Raster und werden
 * alle so hoch wie die hoechste — und die ist hoeher, sobald EINE
 * Beschriftung umbricht („Laengste Flugstrecke · 14.08."). Der Inhalt der
 * uebrigen klebte dann oben, und eine Reihe gleich hoher Kacheln zeigte
 * Werte auf verschiedenen Hoehen. `justify-content:center` verteilt die
 * Restluft nach oben und unten; die Kachel selbst bleibt, wie sie war. */
.kennzahl{
  position:relative;
  display:flex;flex-direction:column;justify-content:center;
  padding:var(--abstand-3);
  background:var(--schnee);
  border:var(--strich) solid var(--linie);
  border-radius:var(--radius);
}
.kennzahl.aktiv{background:var(--orange-hell);border-color:var(--orange)}
.kennzahl-wert{
  font-family:var(--schrift-kopf);font-weight:600;
  font-size:var(--groesse-6);line-height:var(--zeile-eng);
  color:var(--dunkelblau);
}
.kennzahl-einheit{font-size:var(--groesse-2);color:var(--gedaempft);margin-left:var(--abstand-1)}
.kennzahl-label{font-size:var(--groesse-2);color:var(--gedaempft)}
/* Der Tag des Extremwerts steht IN der Beschriftungszeile („Längste
 * Flugstrecke · 14.08.", Mockup 30), nicht darunter: Er gehört zur Aussage
 * der Kachel und nicht als zweite Zeile darunter. Bei schmalen Kacheln
 * bricht die Zeile um — das ist richtiger, als eine feste zweite Zeile zu
 * erzwingen, die bei den übrigen Kacheln leer bliebe. */
.kennzahl-tag{color:var(--orange-tief);font-weight:600;white-space:nowrap}
.kennzahl-extrem::after{
  content:"";position:absolute;top:var(--abstand-2);right:var(--abstand-2);
  width:var(--abstand-2);height:var(--abstand-2);
  border-radius:var(--radius-rund);background:var(--orange);
}


/* == 13. TEXT UND ÖFFENTLICHE HÜLLE ========================================
 *
 * Fließtext in der Lesespalte — Erklärtexte, Abbruchseite, Impressum und
 * Datenschutz (E-P3-12, E-P3-38).
 */
.text{max-width:var(--lesespalte)}
.text h1{margin-bottom:var(--abstand-2)}
.text h2{font-size:var(--groesse-5);margin:var(--abstand-5) 0 var(--abstand-2)}
.text h3{font-size:var(--groesse-4);margin:var(--abstand-4) 0 var(--abstand-2)}
.text p{font-size:var(--groesse-4);line-height:var(--zeile-lesen);margin-bottom:var(--abstand-3)}
.text ul,.text ol{margin:0 0 var(--abstand-3) var(--abstand-5);list-style:disc}
.text ol{list-style:decimal}
.text li{font-size:var(--groesse-4);line-height:var(--zeile-lesen);margin-bottom:var(--abstand-1)}
.text a{text-decoration:underline}
.text-stand{color:var(--gedaempft);font-size:var(--groesse-2);margin-top:var(--abstand-5)}

/* ---- Anmeldung ----------------------------------------------------------- */
.anmeldung-body{
  background:var(--dunkelblau);
  min-height:100vh;min-height:100dvh;
  display:flex;flex-direction:column;
}
.anmeldung{
  flex:1 1 auto;
  display:flex;align-items:center;justify-content:center;
  padding:var(--abstand-5) var(--abstand-3);
}
.anmeldung-karte{
  width:100%;max-width:var(--anmeldekarte);
  background:var(--schnee);
  border-radius:var(--radius-gross);
  padding:var(--abstand-5);
  box-shadow:var(--schatten-hoch);
}
.anmeldung-logo{display:block;height:56px;width:auto;margin:0 auto var(--abstand-4)}
.anmeldung-titel{text-align:center;font-size:var(--groesse-6)}
.anmeldung-unter{text-align:center;color:var(--gedaempft);margin-bottom:var(--abstand-5)}
/* LINKSBUENDIG, nicht zentriert (O10, Mockup 32). Der Link steht unter einem
 * 100 % breiten Knopf und ueber dem linken Rand der Feldbeschriftungen;
 * zentriert schwebt er zwischen beidem. Betrifft Anmeldung, „Passwort
 * vergessen" und die Abmeldeseite — alle drei tragen dieselbe Klasse. */
.anmeldung-neben{margin-top:var(--abstand-4)}

/* ---- Demo-Hinweis --------------------------------------------------------
 * Dauerhaft, nicht wegklickbar. Ein Hinweis, den man einmal schließt, ist
 * beim zweiten Besuch nicht mehr da — und genau dann wäre er nötig. */
.demo-hinweis{
  display:flex;align-items:center;gap:var(--abstand-3);
  padding:var(--abstand-3) var(--abstand-4);
  margin-bottom:var(--abstand-5);
  background:var(--orange-hell);
  border-radius:var(--radius);
  font-size:var(--groesse-2);
}
.demo-hinweis .symbol{color:var(--orange-tief)}


/* == 14. TABELLE UND KACHEL ================================================
 *
 * Das Gerüst; gefüllt wird es in O3 (Startseite und Kachelform) und O6/O7.
 *
 * Unter 720 px gibt es KEINE Tabelle: Die Einsätze erscheinen als dreizeilige
 * Kachel (E-P3-32). Der Grund steht im Befund — bei 360 px bekamen Einsatzort
 * und Diagnose null Pixel Breite und verschwanden ohne Hinweis, während sieben
 * Zahlenspalten stehen blieben.
 */
/* tabular-nums: Ziffern gleicher Breite, damit Zahlenspalten (Beginn, Dauer,
 * km) untereinander fluchten — die frühere mono-Klasse entfällt (Mockup 03
 * setzt die Textschrift, keine Schreibmaschine). */
.tabelle{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
/* SPALTENTITEL ZENTRIERT (F-N1-G). Vorher folgte der Titel der Ausrichtung
 * seiner Zellen: links über Text, rechts über Zahlen, mittig über Haken —
 * drei Ausrichtungen in einer Zeile. Der Kopf ist aber keine Zeile der
 * Daten, sondern ihre Beschriftung; einheitlich zentriert liest er sich als
 * das, was er ist. Die ZELLEN behalten ihre Ausrichtung: Zahlen fluchten
 * weiter rechts, Text steht weiter links. */
.tabelle th{
  text-align:center;font-weight:600;
  color:var(--dunkelblau);
  padding:var(--abstand-2) var(--abstand-2);
  border-bottom:var(--strich-stark) solid var(--linie);
  white-space:nowrap;
}
/* Die Hakenspalten tragen zusammengesetzte Wörter („Sekundärtransport") mit
 * weichem Trennzeichen. Sie dürfen umbrechen — sonst wäre die Spalte so
 * breit wie ihr Titel, obwohl in ihr nur ein Haken steht. */
.tabelle th.haken-spalte{white-space:normal}
.tabelle td{
  padding:var(--abstand-3) var(--abstand-2);
  border-bottom:var(--strich) solid var(--linie);
  vertical-align:middle;
}
.tabelle tr:last-child td{border-bottom:0}
.tabelle-scroll{overflow-x:auto}


/* == 15. DIALOG ============================================================
 *
 * Bestätigen, Entsperren, Rückspielen, Karte wählen, Stammdaten anlegen: eine
 * Karte im Schleier — **in jeder Breite**.
 *
 * HIER STAND „am Desktop eine Karte im Schleier, mobil ein Blatt von unten"
 * (E-P3-27, 5.3), und `Design.md` 9.11 sagte es nach. Es stimmt nicht und hat
 * nie gestimmt: Zu `.dialog` gibt es in diesem Stylesheet **keine einzige
 * Medienabfrage**. Das Blatt (`.blatt`, Abschnitt 10) ist ein eigener
 * Baustein mit eigenem Skript und eigenem Markup — es ersetzt keinen Dialog,
 * es steht neben ihm. Berichtigt in S9/AP5-4, als der Satz beim Bau der
 * Stammdaten-Dialoge zum ersten Mal jemanden in die Irre geführt hat.
 */
.dialog{
  border:0;padding:0;
  background:var(--schnee);
  border-radius:var(--radius-gross);
  box-shadow:var(--schatten-hoch);
  max-width:min(92vw,32rem);width:100%;
  color:var(--asphalt);
  /* EIN DIALOG, DER LÄNGER IST ALS DER BILDSCHIRM, ROLLT IN SICH (S9/AP5-4).
   * Bis Web 16.3.0 hatte `.dialog` keine Höhenangabe. Das ging so lange gut,
   * wie jeder Dialog aus zwei Sätzen und zwei Knöpfen bestand; der
   * Rettungsmittel-Dialog hat vier Felder, fünf Rollenhaken und zwei
   * Fähigkeitshaken und ist am Handy höher als das Glas. Ohne Angabe kappt
   * die Browservorgabe (`max-height: calc(100% - 6px - 2em)`) unten ab — und
   * unten steht der Fuß mit „Anlegen". Der Dialog war dann nicht zu
   * bedienen, ohne dass etwas fehlerhaft ausgesehen hätte.
   *
   * Kopf und Fuß stehen fest, der Inhalt rollt. `dvh` statt `vh`, weil die
   * Adressleiste mobiler Browser mitrechnet; die Seitenhülle macht es an
   * zwei Stellen schon so. */
  max-height:calc(100dvh - var(--abstand-5));
}
/* `display` GEHOERT AN `[open]` UND NICHT AN `.dialog` (Fund F-S9-U-27, beim
 * Bau der Stammdaten-Dialoge). Die Browservorgabe versteckt einen
 * geschlossenen Dialog mit `dialog:not([open]){display:none}` — eine
 * UA-Regel, und die verliert gegen JEDE Autorenregel, ganz gleich wie
 * spezifisch. `.dialog{display:flex}` machte damit alle fuenf Dialoge der
 * Standortseite sichtbar: als Kaesten am Seitenende, mit Feldern, die man
 * ausfuellen kann, und Knoepfen, die absenden. Aufgefallen ist es an einem
 * Vollseitenbild — im Fensterausschnitt standen sie unter der Falz.
 * Dieselbe Falle wie bei `.zeile-knoepfe` (Abschnitt 11, dort gegen
 * `.nur-ab-720`): Ein `display` in der Grundregel schlaegt das, was den
 * Baustein ein- und ausblendet. */
.dialog[open]{display:flex;flex-direction:column}
/* Fast jeder Dialog hat ein <form> zwischen sich und seinen drei Teilen; der
 * GPX-Dialog hat keins. Die Kette muss deshalb über beide Formen laufen. */
.dialog > form{display:flex;flex-direction:column;min-height:0}
.dialog::backdrop{background:var(--schleier)}
.dialog-kopf{padding:var(--abstand-4) var(--abstand-4) 0;flex:0 0 auto}
/* UNTERZEILE IM KOPF (S9/AP5-4, M-S9-07). Sie sagt, worauf sich der Dialog
 * bezieht — der Standort, zu dem das neue Rettungsmittel gehört. Das gehört
 * nicht in den Titel („Rettungsmittel an Standort Talwang anlegen" wäre eine
 * Zeile, die umbricht) und nicht ins Formular (es ist kein Feld, es ist der
 * Zusammenhang). Dieselbe Rolle wie `.titelzeile-unter` an einer Seite. */
.dialog-kopf .unterzeile{
  margin:var(--abstand-1) 0 0;
  color:var(--gedaempft);font-size:var(--groesse-2);
}
/* Der Inhalt ist der Teil, der rollt — `min-height:0`, weil ein Flexkind
 * sonst nicht unter seine Inhaltshoehe schrumpft und dann gar nichts rollt. */
.dialog-inhalt{padding:var(--abstand-4);overflow-y:auto;min-height:0}
/* Ein erklärender Absatz vor den Feldern braucht Luft nach unten — sonst
 * klebt die erste Beschriftung an ihm (O9, Rückspieldialog). Der letzte
 * Absatz bekommt keine: Er steht ohnehin vor dem Fuß mit eigenem Abstand. */
.dialog-inhalt p{margin:0 0 var(--abstand-3)}
.dialog-inhalt p:last-child{margin-bottom:0}
.dialog-fuss{
  display:flex;gap:var(--abstand-3);justify-content:flex-end;
  padding:0 var(--abstand-4) var(--abstand-4);
  flex:0 0 auto;
}
.dialog-fuss .knopf{flex:1 1 auto}


/* == 16. KARTENANSICHT (Leaflet) ===========================================
 *
 * Höhe nach Token, Position nach Schwellen. Der Marker-Satz entsteht in O3.
 */
.geo{
  height:var(--karte-mobil);
  border-radius:var(--radius);
  overflow:hidden;
  background:var(--rauch);
  margin-bottom:var(--abstand-5);
  /* EIGENER STAPELKONTEXT. Leaflet vergibt intern z-index bis 1000 — seine
   * Bedienelemente zeichneten über Schublade (60) und Schleier (50), der
   * Kartenpin stand mitten im Menü (Fable-Kontrolle, F-P3-Y). position und
   * z-index:0 sperren die inneren Werte in die Karte ein; kein Wettrüsten
   * der z-Indizes nötig. */
  position:relative;z-index:0;
}


/* == 17. GRUNDFORMEN ======================================================
 *
 * Bis Web 9.11.1 hieß dieser Abschnitt ROHSCHICHT und war ausdrücklich ein
 * ÜBERGANG: P3 baute die Seiteninhalte Paket für Paket um (O3 bis O11), und
 * bis dahin stand auf jeder noch nicht umgebauten Seite Markup mit
 * Klassennamen, für die es keine Regel mehr gab. Dieser Übergang ist mit
 * O11 zu Ende, und was ihn ausmachte, ist weg:
 *
 *   .alert-Familie  Die eine begründete Klassen-Ausnahme (F-P3-T). Ersetzt
 *                   durch den Meldungs-Baustein `.meldung` — in PHP über
 *                   ui_meldung_markup(), in JS über dasselbe Markup
 *                   (import_ui.js, einstellungen.php, patient.js).
 *   .muted          Die zweite Ausnahme, zuletzt 16 Stellen. Ersetzt durch
 *                   `.feld-hinweis` (Absatz), `.feld-klein` (Absatz unter
 *                   einem Feld), `.feld-klein-inline` (Zusatz in einer
 *                   Beschriftung) und `.dash` (Tabellenzelle) — vier Rollen,
 *                   die eine Klasse vorher gemeinsam trug.
 *   table/th/td     Die Notbremse gegen waagerechten Überlauf. Es gibt keine
 *                   Tabelle mehr, die ihre Gestaltung von hier bezieht: Die
 *                   letzte (`.imp-table` im Import — eine Klasse, die selbst
 *                   nie eine Regel hatte) trägt jetzt `.tabelle` und liegt wie
 *                   die übrigen in `.tabelle-scroll`.
 *   fieldset/legend Null Verwendungen — die letzten fünf standen im
 *                   Einrichter und sind in O10 zu Karten geworden.
 *   hr              Null Verwendungen — der letzte Trenner stand auf der
 *                   Wartungsseite und ist in O11 mit den Karten entfallen.
 *
 * WAS BLEIBT, IST KEIN ÜBERGANG MEHR, sondern die Grundform der Elemente,
 * auf denen die Bausteine aufsetzen. Ein `.feld` ist eine Beschriftung mit
 * Eingabefeld — aber ein `<input>` gibt es auch außerhalb davon (im
 * Suchfeld, im Auswahlkästchen einer Zeile, in einem Filter), und es muss
 * dort dieselbe Höhe, denselben Rahmen und dieselbe Farbe haben. Diese
 * Regeln setzen das, und zwar an Elementnamen, damit keine Stelle sie
 * vergessen kann.
 *
 * Die label-Regeln bleiben mit: Das Muster `<label>Text <input></label>` ist
 * gültiges HTML und steht an 46 Stellen — die Filterreihen der Suche, das
 * Einsatzformular, die Anmeldung. Sie zu tilgen hieße, jede dieser Stellen
 * in eine `.feld`-Hülle umzubauen; das wäre ein Umbau der beiden
 * kompliziertesten Seiten der Anwendung für eine Regel, die nichts falsch
 * macht. `.feld` ist der BAUSTEIN für ein beschriftetes Feld, nicht das
 * Gebot, dass jede Beschriftung einer sein müsse.
 *
 * DIE EINTRITTSKARTE BLEIBT ENG: Hier stehen ausschließlich Elementnamen.
 * Eine KLASSE hier einzutragen hieße, das Redesign zurückzunehmen — dafür
 * gibt es die Bausteine in den Abschnitten davor.
 */
input,select,textarea{
  max-width:100%;
  padding:var(--abstand-2) var(--abstand-3);
  min-height:var(--knopf);
  background:var(--schnee);color:var(--asphalt);
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius-klein);
}
/* Kästchen und Radios sind keine Textfelder: feste Größe statt Mindesthöhe.
 * ACHTUNG, DRITTE FALLE DIESER ART (F-P3-AP, F-P3-AZ): Diese Regel hat
 * Spezifität (0,1,1) und schlägt damit jede bloße Klasse. Wer ein solches
 * Kästchen ausblenden will, braucht `input[type=checkbox].meine-klasse` —
 * `.meine-klasse` allein verliert. */
input[type=checkbox],input[type=radio]{
  min-height:0;width:var(--symbol);height:var(--symbol);accent-color:var(--orange);
}
/* Das Muster `<label>Text <input></label>`: Beschriftung oben, Feld darunter
 * in voller Breite. Ohne diese Regel liefe die Eingabe neben der Beschriftung
 * her und bräche auf schmalen Geräten an unvorhersehbaren Stellen um. */
label{display:block;margin-bottom:var(--abstand-3)}
label > input:not([type=checkbox]):not([type=radio]),
label > select,
label > textarea{display:block;width:100%;margin-top:var(--abstand-1)}
label:has(> input[type=checkbox]),
label:has(> input[type=radio]){
  display:flex;align-items:center;gap:var(--abstand-2);
  min-height:var(--knopf);margin-bottom:var(--abstand-3);
}
summary{cursor:pointer}
code,kbd,pre{font-family:var(--schrift-fest);font-size:var(--groesse-2)}
pre{overflow-x:auto;background:var(--rauch);padding:var(--abstand-3);border-radius:var(--radius-klein)}


/* == 18. SCHWELLEN =========================================================
 *
 * Die vier Schwellen aus Anlage G des Konzepts, und NUR hier stehen sie als
 * Zahlen: Custom Properties funktionieren in Media-Abfragen nicht. Zur
 * Auskunft liegen dieselben Werte als --s-handy, --s-leiste, --s-zwei und
 * --s-karte-neben in :root.
 *
 *    720   Handy → Tablet hoch: Kachel wird Tabelle, Karte 220 px
 *   1024   Schublade → feste Leiste, Hauptpunkte in der Kopfleiste
 *   1200   Leiste 260 px, Zweispalter, Formularkarten nebeneinander
 *   1600   Karte neben Diensttag-Daten und Tabelle
 */

/* ---- ab 720: Tablet hoch ------------------------------------------------- */
@media (min-width:720px){
  .inhalt{padding:var(--abstand-5) var(--abstand-4)}
  .geo{height:var(--karte-tablet)}
  .kennzahl-raster{grid-template-columns:repeat(4,minmax(0,1fr))}
  .speichern-hinweis{display:block}
  .speichern .knopf-breit{width:auto}
  .segment{display:inline-flex}
}

/* ---- ab 1024: die Leiste steht fest -------------------------------------
 * Ab hier ist die Schublade fort und die Leiste ein Teil des Rasters. Das
 * Markup ist dasselbe; nur diese Regeln unterscheiden sich. */
@media (min-width:1024px){
  .leiste{
    /* REIHENFOLGE IST HIER DIE SACHE (F-N1-A). `inset` ist die Kurzform fuer
       alle vier Seiten und setzt ein davor stehendes `top` wieder auf `auto`.
       Genau das ist passiert: Die Leiste klebte gar nicht, sondern scrollte
       mit — bei 600 px Scrollhoehe gemessen auf -544 px, also weit ueber der
       Kopfleiste. `inset` steht deshalb ZUERST und `top` danach.

       Und der z-index muss zurueck: 60 stammt aus der Schubladen-Regel, wo er
       ueber dem Schleier liegen muss. Hier liegt die Kopfleiste bei 40 — mit
       60 malte die Leiste ueber sie. Ab 1024 px ist sie ein Teil des Rasters
       und braucht gar keine eigene Ebene. */
    inset:auto;
    position:sticky;top:var(--kopf);z-index:1;
    width:var(--leiste-schmal);max-width:none;
    height:calc(100vh - var(--kopf));
    transform:none;
    flex:0 0 auto;
  }
  .schleier{display:none}
  .schublade-auf{overflow:visible}
  .kopf-menue{display:none}
  .kopf-punkt{display:inline-flex}
  .kopf-nutzer{
    /* MITTE AUF MITTE (F-N1-D). Beide sitzen als Flex-Kinder in .kopf-marke
       und sind damit lotrecht zentriert — optisch aber nicht, solange das
       eine `line-height:1` trägt und das andere die geerbte 1,55: Die höhere
       Zeilenbox verschiebt die Grundlinie nach unten. Dieselbe Zeilenhöhe
       für beide, und die Mitten liegen übereinander.
       15 px statt 13: Der Name ist eine Auskunft, kein Kleingedrucktes. */
    display:inline-block;color:var(--sand);
    font-size:var(--groesse-3);font-weight:400;line-height:1;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .nur-schublade{display:none}
  .nur-breit{display:inline-flex}
  .nur-schmal{display:none}

  /* Die Filterleiste der Suche ist breiter als die Tagesliste: Sie traegt
     Auswahlfelder und Zahlenpaare („von … bis"), nicht Zeilen. Die Werte
     kommen aus Anlage G des Konzepts; die beiden Token lagen bis O12
     ungenutzt in :root (F-P3-BC). */
  .leiste-filter{width:var(--leiste-filter-schmal)}

  /* IN DIESEM BAND IST DIE LEISTE 220 PX SCHMAL. Der volle
     Rettungsmittelname bliebe hier ohnehin nur eine Ellipse — er entfällt,
     das Artzeichen bleibt (E-P3-09). Ein gesetzter KURZNAME steht dagegen
     (S9/AP4a, Freigabe M-S9-08 Variante 2; Platz nach M-S9-11 Weg 2).
     WIE VIEL VON IHM, HÄNGT AM DATUM DANEBEN. `.eintrag-text` schrumpft
     nicht (`flex:1 0 auto`), und seine Breite schwankt: Bricolage Grotesque
     setzt Ziffern PROPORTIONAL — die Regel `tabular-nums` (Abschnitt 3)
     nennt `.zahl,td,th,time,output`, nicht diesen `<span>`. Gemessen an den
     dreizehn Datumsangaben des Prüfbestands bei 1024 und bei 1199 px steht
     dem Nebentext zur Verfügung: ohne die beiden Regeln darunter 48–63 px,
     mit der Einrückung allein 56–71, mit beiden 64–79. „BW Hoch" braucht 55,
     „NEF 76/1" 53 — die stehen damit an JEDEM Datum ganz, „RTH Murnau" (76)
     an den meisten. Ein Auslassungszeichen bleibt möglich und ist kein
     Fehler: Der Tooltip nennt die volle Bezeichnung.
     Der Zustand darunter — Schublade, 320 px — bleibt unberührt: Dort greift
     dieser Block nicht, und der volle Name steht dort weiterhin. */
  .eintrag-neben{display:none}
  .eintrag-neben.kurz{display:block}

  /* ZWEIMAL VIER PIXEL, ZWEIMAL WIRKSAM (Freigabe M-S9-11, Weg 2).
     Die Einrückung wirkt je Akkordeonebene (Jahr, Monat), der Abstand je
     Zwischenraum der Zeile (Zeichen–Datum, Datum–Name): 12 → 4 px und
     8 → 4 px bringen dem Nebentext zusammen 16 px.

     DIE EINRÜCKUNG GILT UNGESCOPED, DER ABSTAND NICHT — und beides mit
     Grund. `.leiste-gruppe > .akkordeon-inhalt{padding-left:0}` weiter oben
     ist spezifischer (0-2-0 gegen 0-1-0) und hält das Einstellungsmenü von
     der Einrückung heraus; wer hier `.leiste .akkordeon-inhalt` schriebe,
     überholte diese Ausnahme und rückte das Menü von 0 auf 4 px ein.
     Für den Abstand gibt es keine solche Ausnahme: `.eintrag` tragen auch
     der Leistenfuß, die Hauptpunkte der Schublade und jede Zeile des
     Einstellungsmenüs. Sie haben keinen Nebentext und damit kein
     Platzproblem — eine ungescopte `gap`-Regel rückte sie ohne Not
     zusammen. Deshalb `:not(.leiste-gruppe)`: Es trifft die Diensttage,
     nicht das Menü. */
  .akkordeon-inhalt{padding-left:var(--abstand-1)}
  .akkordeon:not(.leiste-gruppe) .eintrag{gap:var(--abstand-1)}

  /* Das Aktionsmenü wird ein Aufklappmenü statt eines Blattes.
     KEINE FAHRT HIER. `translateY(100%)` hiesse am Aufklappmenü „um die
     eigene Höhe nach unten" — es stünde neben der Sache statt unter dem
     Bildrand. Das Mockup M-MR-04 sagt zum Schreibtisch ausdrücklich
     „unverändert"; die Markierung des Öffners gilt dagegen in beiden Formen,
     und der Winkel dreht weiter. */
  .blatt{
    position:absolute;inset:auto 0 auto auto;top:calc(var(--knopf) + var(--abstand-1));
    width:16rem;
    border-radius:var(--radius);
    padding:var(--abstand-2);
    border:var(--strich) solid var(--linie);
    transform:none;transition:none;
  }
  .blatt-griff,.blatt-titel,.blatt-abbrechen{display:none}
  .blatt-zeile{min-height:var(--knopf)}
}

/* ---- ab 1200: breite Leiste ---------------------------------------------- */
@media (min-width:1200px){
  .leiste{width:var(--leiste)}
  .leiste-filter{width:var(--leiste-filter)}
  .eintrag-neben{display:block}
  /* Ab hier ist die Leiste 260 px — Einrückung und Abstand gehen auf ihr
     normales Maß zurück (Gegenstück zu den beiden 4-px-Regeln im 1024er
     Block). */
  .akkordeon-inhalt{padding-left:var(--abstand-3)}
  .akkordeon:not(.leiste-gruppe) .eintrag{gap:var(--abstand-2)}
  .geo{height:var(--karte-desktop)}

  /* ---- Karten, die sich selbst auf zwei Spalten verteilen (E-S8-15) -------
   *
   * DER UNTERSCHIED ZU `.form-raster`: Dort entscheidet die Seite, welche
   * Karte in welche Spalte gehört, und schreibt dafür zwei Behälter ins
   * Markup. Hier fließen die Karten selbst — der Umbruch fällt beim
   * Zeichnen, und eine Karte, die dazukommt, braucht keine Zuordnung.
   *
   * Deshalb Mehrspaltensatz und nicht Grid: Grid bräuchte die Zuordnung
   * wieder. `break-inside:avoid` hält jede Karte zusammen; ohne das reißt der
   * Satz sie mitten im Text auseinander, und zwar ohne Fehlermeldung.
   *
   * WANN. Ab 1200 px. Das Konzept nannte „mehr als vier Karten"; gemessen
   * ist die Zahl nicht die Frage, sondern die Höhe. Von den sieben dort
   * genannten Seiten stehen Status, Statistik und Konto-Backups längst
   * zweispaltig (`.form-raster`, mit einer thematischen Zuordnung von Hand,
   * die eine automatische Verteilung verschlechtern würde) — seit
   * Web 19.3.0 auch die Installation, die dafür bis dahin eine zweite,
   * gleichlautende Regel `.zweispalter` hatte (Backlog Nr. 125) —, und
   * Hintergrundjobs (3 Karten) wie Geräte (2) haben zu wenige. Übrig bleibt Updates mit vier: 1206 px hoch einspaltig,
   * 977 px zweispaltig — 229 px, und damit passt die Seite auf einen
   * üblichen Bildschirm. Die Regel gilt also für vier Karten aufwärts, wenn
   * sie keine thematische Ordnung haben. */
  .karten-raster{columns:2;column-gap:var(--abstand-4)}
  .karten-raster > .karte{break-inside:avoid}
}

/* ---- ab 1600: die Karte steht neben Daten und Tabelle -------------------- */
@media (min-width:1600px){
  .karte-neben{display:grid;grid-template-columns:1fr var(--karte-neben-breit);
    gap:var(--abstand-4);align-items:start}
}


/* == 19. ÜBERSICHTSZEILE ===================================================
 *
 * Die Einstellungs-Übersicht (E-P3-11): Symbol, Text, Winkel. Auf dem Handy
 * ist sie der einzige Weg, der zeigt, WAS es im Bereich gibt.
 */
.uebersicht-zeile{
  display:flex;align-items:center;gap:var(--abstand-3);
  min-height:calc(var(--knopf) + var(--abstand-3));
  padding:0 var(--abstand-2);
  border-bottom:var(--strich) solid var(--linie);
  color:var(--asphalt);text-decoration:none;
}
.uebersicht-zeile:last-child{border-bottom:0}
.uebersicht-zeile:hover{background:var(--rauch);text-decoration:none}
.uebersicht-zeile .symbol{color:var(--dunkelblau)}
.uebersicht-text{
  flex:1 1 auto;min-width:0;
  font-family:var(--schrift-kopf);font-weight:600;font-size:var(--groesse-4);
}
.uebersicht-winkel{color:var(--sand)}
/* Blocküberschrift ÜBER einer Karte („Administration") — Mockup 07 zeigt sie
 * als gesperrte Versalzeile außerhalb der Karte, nicht als Kartentitel. */
.uebersicht-block{
  font-family:var(--schrift-kopf);font-size:var(--groesse-1);
  font-weight:600;letter-spacing:.08em;text-transform:uppercase;
  color:var(--gedaempft);
  margin:var(--abstand-5) 0 var(--abstand-2) var(--abstand-1);
}
/* GESTAPELT KEINE ÜBERSCHRIFT AM ERSTEN BLOCK (Konzept AP5 (6)): Sie stünde
 * unmittelbar unter der Seitenüberschrift „Einstellungen" und sagte dasselbe
 * noch einmal. Nebeneinander benennt sie die Spalte und muss da sein — sonst
 * stünde eine namenlose neben zwei benannten. Im Markup steht sie immer,
 * damit ein Vorleseprogramm alle drei Blöcke gleich benennt. */
.uebersicht-block-erst{display:none}
/* Ohne Überschrift beginnt die erste Karte oben; der Abstand der übrigen
 * Blöcke gehört zur Überschrift und entfällt mit ihr. */
.uebersicht-gruppe:first-child > .uebersicht-block + .karte{margin-top:0}

/* AM SCHREIBTISCH DREI SPALTEN. `auto-fit` füllt nach Rolle: eine Spalte für
 * eine NutzerIn, zwei für eine Admin, drei für eine BetreiberIn — ohne dass
 * das Stylesheet die Rolle kennen müsste. Die 240 px sind die Breite, unter
 * der „Rettungsmittel" mit Symbol und Winkel umbricht. */
@media (min-width:1024px){
  .uebersicht-block-erst{display:block}
  .uebersicht-raster{
    display:grid;
    grid-template-columns:repeat(auto-fit,minmax(var(--uebersicht-spalte),1fr));
    gap:0 var(--abstand-4);
    align-items:start;
  }
  .uebersicht-gruppe > .uebersicht-block{margin-top:0}
}

/* Die Anmeldekarte des Einrichters und der Passwortvergabe ist breiter: Dort
 * stehen Formulare mit Feldgruppen, nicht zwei Zeilen. */



/* == 20. TAGESÜBERSICHT UND EINSATZLISTE (O3) ==============================
 *
 * Kachel, Tabelle mit Farbstreifen, Diensttag-Daten als Lesezustand und das
 * Raster, das die Karte ab 1600 px neben Daten und Tabelle stellt.
 */

/* ---- Sichtbarkeitsschwelle 720 -------------------------------------------
 * Unter 720 px gibt es KEINE Einsatztabelle, sondern die Kachel (E-P3-32).
 * Zwei Hilfsklassen tragen den Wechsel; sie blenden nur AUS und lassen die
 * Grundform des Elements unangetastet. */
.nur-ab-720{display:none}
@media (min-width:720px){
  /* revert statt block: Die Utility soll die GRUNDFORM wiederherstellen —
   * ein <span> (Titelzusatz „· 07:34 Uhr") wurde mit block zur eigenen
   * Zeile (Fund aus O4). */
  .nur-ab-720{display:revert}
  /* Doppelt geschrieben, um jede Baustein-Regel gleicher Spezifität zu
   * schlagen (der Sortier-Knopf traegt .karte-sortieren mit display:flex —
   * eine Klasse gegen eine Klasse verloere nach Reihenfolge). */
  .nur-unter-720.nur-unter-720{display:none}
}

/* ---- Kachel (E-P3-32, Mockup 10) ---------------------------------------- */
.kachelliste{display:flex;flex-direction:column}
.kachel{
  display:flex;gap:var(--abstand-3);
  padding:var(--abstand-3) 0;
  border-bottom:var(--strich) solid var(--linie);
  color:var(--asphalt);text-decoration:none;
}
.kachel:last-child{border-bottom:0;padding-bottom:0}
.kachel:first-child{padding-top:0}
.kachel:hover{text-decoration:none;background:var(--rauch)}
.kachel-streifen{
  flex:0 0 auto;width:var(--abstand-1);
  border-radius:var(--radius-rund);
  /* Die Farbe kommt je Einsatz aus den Spur-Token (style-Attribut aus JS —
   * ein Wert, kein Stil; die Ausnahme steht in tools/vollstaendigkeit). */
}
.kachel-zeit{
  flex:0 0 auto;
  font-family:var(--schrift-kopf);font-weight:600;
  color:var(--dunkelblau);
  min-width:3.2em;
}
.kachel-rumpf{flex:1 1 auto;min-width:0}
.kachel-kopf{display:flex;align-items:baseline;gap:var(--abstand-2)}
.kachel-ort{
  flex:1 1 auto;min-width:0;
  font-weight:600;font-size:var(--groesse-4);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.kachel-km{flex:0 0 auto;color:var(--gedaempft);font-size:var(--groesse-2)}
.kachel-dx{
  color:var(--asphalt);
  display:-webkit-box;-webkit-box-orient:vertical;
  -webkit-line-clamp:2;line-clamp:2;overflow:hidden;
}
/* In Suche und Zeitraum eine Zeile mit Abschneiden (E-P3-32). */
.kachel-knapp .kachel-dx{-webkit-line-clamp:1;line-clamp:1}
.kachel-fuss{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:var(--abstand-1) var(--abstand-2);
  margin-top:var(--abstand-1);
  color:var(--gedaempft);font-size:var(--groesse-2);
}
/* Artzeichen und Datum als erstes Element (Suche, Zeitraum). */
.kachel-art{flex:0 0 auto;color:var(--dunkelblau);align-self:center}
.kachel-datum{
  flex:0 0 auto;
  font-family:var(--schrift-kopf);font-weight:600;color:var(--dunkelblau);
}
/* Warnzeichen „vorhanden, aber nicht lesbar" in der Kachel. */
.kachel .patfehler{color:var(--rot-tief)}

/* ---- Tabelle: Verfeinerungen (E-P3-32, Mockup 04) ------------------------
 * Der Baustein .tabelle steht in Abschnitt 14; hier kommt dazu, was die
 * EINSATZtabelle braucht: display:table gegen die Übergangsregel (der
 * Überlauf gehört dem Behälter .tabelle-scroll), Farbstreifen, blauer
 * Sortierpfeil, dunkelblaue Haken, die klickbare Zeile. */
.tabelle{display:table}
.tabelle-scroll{overflow-x:auto}
.tabelle th.sortable{cursor:pointer;white-space:nowrap}
.tabelle th.sortable:hover{color:var(--blau-tief)}
.tabelle .arrow{color:var(--blau);vertical-align:middle}
.tabelle .arrow .symbol{width:var(--groesse-2);height:var(--groesse-2)}
.tabelle .tabelle-haken{color:var(--dunkelblau)}
.tabelle .streifen{
  display:inline-block;width:var(--abstand-1);height:var(--abstand-5);
  border-radius:var(--radius-rund);vertical-align:middle;
}
.tabelle .streifen-spalte{width:var(--abstand-3)}
.tabelle tr.clickable{cursor:pointer}
.tabelle tr.clickable:hover td{background:var(--rauch)}
.tabelle tr.clickable:focus-visible{outline-offset:calc(var(--strich-stark) * -1)}
.tabelle td.dash,.tabelle .patfehler{color:var(--gedaempft)}
.tabelle .patfehler .symbol{color:var(--rot-tief)}
/* EIN ZEILENKOPF IST EINE BESCHRIFTUNG, KEINE SPALTENÜBERSCHRIFT (S8/AP4).
 * `.tabelle th` steht auf `text-align:center` — richtig für die Kopfzeile,
 * falsch für die erste Spalte einer Kennzahlentabelle, in der links die
 * Beschriftung und rechts die Zahlen stehen. Die Regel greift NUR bei
 * `scope="row"`; bis Web 15.3.0 gab es keine solche Tabelle. */
.tabelle th[scope="row"]{text-align:left;font-weight:600}
.tabelle td.zahl-spalte{text-align:right}
.tabelle td.haken-spalte{text-align:center}
/* Eine Dauer wie „1h 06min" ist EINE Angabe und wird nicht getrennt. */
.tabelle td.zeit-spalte{white-space:nowrap}
/* MITTIG — die dritte Zellenausrichtung neben links (Text) und rechts (Zahl).
 * Sie ist fuer Spalten da, deren Inhalt WEDER Flietext noch eine Groesse zum
 * Vergleichen ist: eine Rolle, ein Datum, eine Plakette, eine laufende
 * Nummer. Solche Werte fluchten nicht sinnvoll an einer Kante, und der
 * zentrierte Spaltentitel (F-N1-G) stand ueber ihnen im Leeren.
 * ALS KLASSE, nicht als :nth-child — Spalten der Kontentabelle erscheinen
 * datengetrieben, und eine Zaehlung rutschte still auf die falsche. */
.tabelle td.mitte-spalte{text-align:center}

/* Sortieren-Link im Kartenkopf — nur dort, wo es keine Spaltenköpfe gibt. */
.karte-sortieren{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:var(--knopf);min-height:var(--knopf);
  color:var(--blau-tief);flex:0 0 auto;
}
.blatt-zeile.aktiv{background:var(--orange-hell);color:var(--dunkelblau)}

/* ---- Wochentag im Titel: lang ab 720, kurz darunter (E-P3-31) ------------ */
.wtag-lang{display:none}
.wtag-kurz{display:inline}
@media (min-width:720px){
  .wtag-lang{display:inline}
  .wtag-kurz{display:none}
}

/* ---- Diensttag-Daten: Lesezustand (E-P3-31, Mockups 02/03) --------------- */
.tag-lese{display:block}
.tagfeld{
  display:grid;grid-template-columns:minmax(7em,auto) 1fr;
  gap:var(--abstand-1) var(--abstand-4);
  padding:var(--abstand-1) 0;
}
.tagfeld dt{color:var(--gedaempft)}
.tagfeld dd{margin:0;min-width:0;overflow-wrap:anywhere}
.tag-lese-leer{color:var(--gedaempft)}
/* Standort und Rettungsmittel entfallen mobil — sie stehen dort schon in der
 * Unterzeile des Titels (Mockup 02). */
.tagfeld-doppelt{display:none}
@media (min-width:720px){
  .tagfeld-doppelt{display:grid}
}
.tag-form-fuss{display:flex;align-items:center;gap:var(--abstand-3)}
@media (min-width:720px){
  .tag-lese{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:0 var(--abstand-5)}
  /* BESATZUNG UND NOTIZEN UEBER BEIDE SPALTEN (F-N1-E). Standort und
     Rettungsmittel sind zwei Wörter und teilen sich die Zeile; die Besatzung
     ist eine Aufzählung aus bis zu sieben Rollen mit Namen und brach in der
     halben Breite auf zwei bis drei Zeilen um — neben einer leeren rechten
     Spalte. Notizen sind Fließtext und haben dasselbe Problem. */
  .tagfeld-breit{grid-column:1 / -1}
}

/* ---- Das Raster der Tagesübersicht (E-P3-31) -----------------------------
 * Unter 1600 px gewöhnlicher Fluss: Daten, Karte, Einsätze. Ab 1600 rückt
 * die Karte in eine rechte Spalte und läuft von der Höhe der Diensttag-Daten
 * bis unter die Tabelle. */
@media (min-width:1600px){
  .tag-raster{
    display:grid;
    grid-template-columns:minmax(0,1fr) var(--karte-neben-breit);
    grid-template-areas:"daten karte" "einsaetze karte";
    grid-template-rows:auto 1fr;
    gap:0 var(--abstand-4);
    align-items:start;
  }
  .tag-raster > .karte-daten{grid-area:daten}
  .tag-raster > .geo-spalte{grid-area:karte;align-self:stretch}
  .tag-raster > .karte-einsaetze{grid-area:einsaetze}
  .geo-spalte .geo{height:100%;min-height:var(--karte-desktop)}
}


/* == 21. KARTENMARKER (O3, E-P3-40, Mockup 26) =============================
 *
 * Der Marker-Satz gilt für alle drei Kartenseiten und entsteht in
 * assets/geo.js. Die Zeichnung: Schilder (Haus, Klinik) als weiße Kästchen;
 * der Einsatzort als oranger Kreis mit Pin; Start und Ende als blauer bzw.
 * roter Rand am Schild des Ortes, an dem die Spur beginnt oder endet —
 * beides am selben Ort als Doppelrand. Richtungspfeile erscheinen erst ab
 * einer Zoomstufe, bei der sie nicht gedrängt stehen.
 *
 * DER FARBRING IST SEIT S9/AP3 DER RAND (M-S9-01 V1, E-S9-12). Bis Web
 * 15.8.0 lag er als zweiter und dritter `box-shadow` AUSSERHALB des
 * dunkelblauen Randes; ein Standort mit Doppelring maß dadurch 60 px und
 * deckte auf der Handykarte mehr als ein Drittel der Höhe. Jetzt ersetzt der
 * Farbrand den dunkelblauen: 38 px beim Doppelrand, 32 px sonst. Ohne
 * Aufzeichnung bleibt der Rand dunkelblau — er sagt dann nichts über die
 * Spur, sondern trennt nur.
 *
 * AUSSEN LIEGT IMMER 1 px SCHNEE (F6), am Schild und nur dort. Er trennt die
 * Farbe von der Karte, damit Blau nicht auf Grün und Rot nicht auf Braun
 * stößt. Der Einsatzort-Kreis bekommt ihn NICHT: Er ist orange auf einer
 * Karte, die kein Orange trägt, und die freigegebene Maßleiste des Mockups
 * nennt für ihn 28 px — mit Trennlinie wären es 30.
 *
 * DIE SCHATTENANGABEN TRAGEN DEN SCHLAGSCHATTEN MIT. Bis Web 15.8.0
 * überschrieben die drei Ringregeln `box-shadow` vollständig; ein beringtes
 * Schild hatte deshalb keinen Schatten, ein unberingtes schon. Das war
 * niemandem aufgefallen, weil beide Zustände selten nebeneinander stehen.
 */
/* KEIN NAMENSSCHILD MEHR (S3/AP7). Die Spalte traegt seit S3 genau ein Kind;
 * `gap` und `flex-direction` bleiben trotzdem stehen, weil die Ringklassen
 * darauf aufsetzen und ein Marker mit zwei Kindern jederzeit wiederkommen
 * kann — dann aber mit ausdruecklichem `iconSize` (siehe geo.js). */
.geo-schild{display:flex;flex-direction:column;align-items:center;gap:var(--abstand-1)}
/* ENGER, ZWEITE STUFE (S9/AP3): 30 statt 36 px, davor 44. Die 44 kamen von
 * `--knopf` — der Kasten ist aber kein Bedienelement, sondern eine Zeichnung,
 * und die 44-px-Regel gilt fuer das, was man DRUECKT (R76 gilt hier nicht,
 * S3/AP7). Untergrenze am Finger ist WCAG 2.5.8 mit 24 px; 30 px liegen
 * darueber. Das Symbol gibt eine Randstaerke ab (--geo-symbol, 18 px), damit
 * der Weissraum ringsum nicht auf null faellt. */
.geo-schild-kasten{
  display:flex;align-items:center;justify-content:center;
  width:var(--geo-schild);height:var(--geo-schild);
  background:var(--schnee);color:var(--dunkelblau);
  border:var(--strich-stark) solid var(--dunkelblau);
  border-radius:var(--radius);
  box-shadow:0 0 0 var(--strich) var(--schnee),var(--schatten);
}
.geo-schild-kasten .symbol{width:var(--geo-symbol);height:var(--geo-symbol)}
/* DER FARBRAND ERSETZT DEN DUNKELBLAUEN, er liegt nicht darum herum. Der
 * Doppelrand ist innen blau (Start) und aussen rot (Ende): blauer Rand, 1 px
 * Schnee, 2 px Rot, 1 px Schnee — 38 px statt frueher 60. Die Schnee-Angabe
 * VOR der roten liegt oben und laesst von deren 3 px Spread 2 px stehen. */
.geo-ring-start .geo-schild-kasten{border-color:var(--blau);border-width:var(--geo-ring)}
.geo-ring-ende  .geo-schild-kasten{border-color:var(--rot);border-width:var(--geo-ring)}
.geo-ring-beide .geo-schild-kasten{
  border-color:var(--blau);border-width:var(--geo-ring);
  box-shadow:0 0 0 var(--strich) var(--schnee),
             0 0 0 var(--geo-ring) var(--rot),
             0 0 0 calc(var(--geo-ring) + var(--strich)) var(--schnee),
             var(--schatten);
}
/* OHNE WEISSE UMRANDUNG UND KLEINER (S3/AP7, S9/AP3). Der weisse Rand war ein
 * Rest aus der Zeit vor dem Schatten: Er sollte den Kreis von der Karte
 * abheben. Das tut der Schatten, und der Rand machte den Kreis zusaetzlich
 * um 4 px breiter, als er aussah. 28 px, davor 32, davor 36. */
.geo-kreis{
  display:flex;align-items:center;justify-content:center;
  width:var(--geo-kreis);height:var(--geo-kreis);
  background:var(--orange);color:var(--dunkelblau);
  border-radius:var(--radius-rund);
  box-shadow:var(--schatten);
}
.geo-kreis .symbol{width:var(--symbol-klein);height:var(--symbol-klein)}
/* DER PUNKT BRAUCHT EINEN KASTEN, sonst hat er keinen (Backlog Nr. 153,
 * S9/AP3). Er ist ein <span> (geo.js, markerPunkt), und an einem nicht
 * ersetzten Inline-Element wirken `width` und `height` NICHT: Gemessen in
 * der Tagesuebersicht am 07.09.2026 stand er auf 4 x 18 px statt 16 x 16 —
 * uebrig blieben die beiden 2-px-Raender als weisser Strich, und die
 * Spurfarbe im `background` lag in einem 0 px breiten Inhaltskasten und war
 * nie zu sehen. Derselbe Fehler wie beim Pfeil eine Regel weiter unten. */
.geo-punkt{
  display:block;
  width:var(--abstand-3);height:var(--abstand-3);
  border-radius:var(--radius-rund);
  border:var(--strich-stark) solid var(--schnee);
}
/* DER PFEIL BRAUCHT EINEN KASTEN, DAMIT ER SICH DREHEN KANN (Backlog Nr. 72,
 * S9/AP3). `geo.js` setzt die Laufrichtung als `transform:rotate(Ndeg)` auf
 * diesen <span>; `transform` wirkt aber nicht auf ein nicht ersetztes
 * Inline-Element, und die Regel hier setzte bis Web 15.8.0 nur die Farbe.
 * Jeder Pfeil zeigte deshalb nach Norden, und auf Nord-Sued-Abschnitten sah
 * das richtig aus.
 *
 * DER BERECHNETE WERT LUEGT DABEI: `getComputedStyle` meldet die
 * Drehmatrix auch am Inline-Element. Nachweisbar ist der Fehler nur an der
 * Geometrie — ein 20-px-Kasten mit `rotate(45deg)` misst 28,3 px, wenn die
 * Drehung greift, und 20 px, wenn nicht. Gemessen am 07.09.2026: 20 px,
 * Bildschirmmatrix des SVG a=0,833 b=0 c=0 d=0,833 bei behauptetem 90-Grad.
 *
 * `display:flex` MIT AUSDRUECKLICHER GROESSE, nicht `inline-block`: Der
 * Drehpunkt muss auf `iconAnchor: [10, 10]` aus geo.js treffen. Bei einem
 * Inline-Block haengt die Kastenhoehe an der Zeilenhoehe der Karte
 * (leaflet.css setzt 12px/1.5) und an `vertical-align` des Symbols — der
 * Pfeil drehte sich dann um einen Punkt, der bei der naechsten
 * Schriftaenderung woanders liegt. `--symbol` ist dieselbe Zahl, die
 * geo.js als `iconSize` uebergibt. */
.geo-pfeil{
  display:flex;align-items:center;justify-content:center;
  width:var(--symbol);height:var(--symbol);
  color:var(--dunkelblau);
}
.geo-pfeil .symbol{
  filter:drop-shadow(0 0 var(--strich) var(--schnee))
         drop-shadow(0 0 var(--strich) var(--schnee));
}
/* Leaflet-DivIcons bringen eine eigene Klasse mit weißem Hintergrund mit —
 * unsere Marker zeichnen sich selbst. */
.leaflet-div-icon{background:none;border:0}


/* == 22. EINSATZANSICHT (O4, E-P3-33, Mockups 19/20/21) ====================
 *
 * Vier Karten (Einsatz, PatientIn, Transport, Reanimation) plus Besatzung;
 * die DOM-Reihenfolge ist die MOBILE (Angaben, Karte, Phasen, Reanimation).
 * Ab 1200 px ordnet das Raster um: Karte und Einsatzphasen wandern in eine
 * klebende rechte Spalte, die Reanimation in die linke — Mockup 20.
 */
@media (min-width:1200px){
  .einsatz-raster{
    display:grid;
    grid-template-columns:minmax(0,1fr) var(--karte-neben-breit);
    grid-template-areas:
      "einsatz neben" "patientin neben" "transport neben"
      "besatzung neben" "reanimation neben" ". neben";
    grid-template-rows:repeat(5,min-content) 1fr;
    gap:0 var(--abstand-4);
  }
  .karte-block-einsatz{grid-area:einsatz}
  .karte-block-patientin{grid-area:patientin}
  .karte-block-transport{grid-area:transport}
  .karte-block-besatzung{grid-area:besatzung}
  .karte-block-reanimation{grid-area:reanimation}
  .einsatz-neben{
    grid-area:neben;
    position:sticky;top:calc(var(--kopf) + var(--abstand-4));
    align-self:start;
  }
  .einsatz-neben .geo{height:var(--karte-desktop)}
}

/* Die Leseansicht der Einsatz-Karten ist einspaltig — anders als die
 * Diensttag-Daten, deren Zweispalter volle Inhaltsbreite hat. */
.einsatz-raster .tag-lese{display:block}

/* Kleinzeile unter einem Lesewert: Höhe, Luftlinie und Strecke unter dem
 * Einsatzort, das Alter unter dem Geburtsdatum (Mockup 19). */
.lese-klein{display:block;color:var(--gedaempft);font-size:var(--groesse-2)}

/* Die Plaketten am Fuß der Einsatz-Karte — dieselben wie auf der Kachel. */
.karte-inhalt .zeile-plaketten{margin-top:var(--abstand-3)}

/* ---- Einsatzphasen als Zeilenliste (Mockup 19) ---------------------------
 * Nummer gedämpft, Name, rechts die Uhrzeit mit dem Minutenabstand zur
 * vorigen Phase klein darunter. Die angetippte Zeile leuchtet orange und
 * hebt ihr Teilstück auf der Karte hervor (einsatz.php). */
.phasen-zeile{
  display:grid;
  grid-template-columns:var(--symbol-gross) minmax(0,1fr) auto;
  gap:var(--abstand-3);align-items:center;
  padding:var(--abstand-2) var(--abstand-4);
  border-top:var(--strich) solid var(--linie);
  cursor:pointer;
}
.phasen > .phasen-zeile:first-child{border-top:0}
.phasen-nr{color:var(--gedaempft)}
.phasen-zeit{text-align:right;font-weight:600;color:var(--dunkelblau)}
.phasen-abstand{
  display:block;font-weight:400;
  color:var(--gedaempft);font-size:var(--groesse-2);
}
.phasen-zeile.hl{background:var(--orange-hell)}
.phasen-zwischentitel{
  font-size:var(--groesse-3);color:var(--dunkelblau);
  padding:var(--abstand-3) var(--abstand-4) 0;
}

/* ---- Phasenmarker auf der Karte (Bestand, neu eingekleidet) --------------
 * Kleine Nummernschilder an den GPS-Positionen der Phasen; der Umschalter
 * ist ein Leaflet-Control mit Text — Leaflets eigene 26-px-Knopfbreite
 * würde ihn abschneiden. */
.pm-chip{
  display:flex;align-items:center;justify-content:center;
  width:var(--symbol-gross);height:var(--symbol-gross);
  background:var(--schnee);color:var(--dunkelblau);
  border:var(--strich) solid var(--dunkelblau);
  border-radius:var(--radius-klein);
  font:600 var(--groesse-1)/1 var(--schrift-text);
  box-shadow:var(--schatten);
}
.pm-chip.hl{background:var(--orange);border-color:var(--orange-tief)}
.geo .map-ctrl-phase a{
  width:auto;height:auto;
  padding:var(--abstand-1) var(--abstand-2);
  font:600 var(--groesse-1)/var(--zeile) var(--schrift-text);
  color:var(--dunkelblau);
}
/* Der Vollbildknopf teilt den aktiven Zustand mit dem Phasenumschalter — ein
 * Selektor mehr, keine zweite Regel (O11). Vorher hatte `a.active` am
 * Vollbildknopf gar keine: Der Knopf hiess im Vollbild „Vollbild verlassen"
 * und sah aus wie vorher. */
.geo .map-ctrl-phase a.active,
.geo .map-ctrl-fs a.active{background:var(--orange-hell)}

/* ---- VOLLBILD (O11) ------------------------------------------------------
 *
 * ZWEI WEGE, EIN AUSSEHEN. `map_fullscreen.js` nimmt die Fullscreen-API,
 * wenn es sie gibt, und sonst einen CSS-Rueckfall — „relevant v. a. iOS
 * Safari, das requestFullscreen() fuer beliebige Elemente nicht
 * unterstuetzt" (Dateikopf des Skripts).
 *
 * DER RUECKFALL WAR TOT. Die Klassen `map-fs` und `map-fs-lock` hatten seit
 * dem Neubau des Stylesheets (Web 9.0.0, O1) keine Regel mehr — auf einem
 * iPhone passierte beim Druck auf „Vollbild" NICHTS: Die Karte blieb, wie
 * sie war, nur der Knopf hiess jetzt „Vollbild verlassen". Vier Monate
 * unbemerkt, weil der Weg nur dort genommen wird und die Bildaufnahme den
 * Vollbildzustand nie herstellt.
 *
 * Der Selektor heisst jetzt `.geo`, nicht mehr `.map`: Der Kartenbehaelter
 * wurde in O1 umbenannt. Die alten Zeilen zurueckzukopieren haette den
 * Fehler stehen lassen.
 *
 * z-index 70 statt der alten 2000: Das ist die Ebene des Blatts. Hoehere
 * Werte braucht die Anwendung nicht mehr, seit `.geo` einen eigenen
 * Stapelkontext hat (Abschnitt 16, oben).
 *
 * Die `:fullscreen`-Zeile ist auch am Schreibtisch noetig: Das UA-Blatt
 * setzt Groesse und Rand mit `!important`, den `border-radius` von `.geo`
 * aber nicht — die Karte haette im Vollbild abgerundete Ecken auf schwarzem
 * Grund. */
.geo.map-fs{
  position:fixed;inset:0;z-index:70;
  width:100%;height:100%;
  margin:0;border-radius:0;
}
body.map-fs-lock{overflow:hidden}
.geo:fullscreen{margin:0;border-radius:0}

/* ---- Ring ohne Schild: Start/Ende der Spur abseits von Standort/Ziel -----
 *
 * ER STEHT HIER UND NICHT IN ABSCHNITT 21, wo der uebrige Marker-Satz liegt —
 * eine alte Einordnung, die stehenbleibt: Ihn zu verschieben waere eine
 * Reihenfolgeaenderung im Stylesheet und damit ein Fall fuer den
 * Stilvergleich, der waehrend P3 ausgesetzt ist. Wer Abschnitt 21 aendert,
 * aendert hier mit (S9/AP3: 16 -> 14 px, Rand 3 -> 2 px nach M-S9-01 V1).
 * Seine Groesse steht auch in geo.js (`iconSize`), und die Legende des
 * Kartendialogs benutzt dieselben Klassen — siehe dort. */
/* DIE ANTIPPFLAECHE UM DEN RING (S9/AP3, geo.js `RINGFELD_PX`). Sie ist
 * durchsichtig und 24 px gross — die Untergrenze aus WCAG 2.5.8, die E-S9-12
 * im selben Absatz nennt, in dem es den Ring auf 14 px setzt. Die Zeichnung
 * bleibt 14 px; nur der Finger bekommt mehr. */
.geo-ringpunkt-feld{
  display:flex;align-items:center;justify-content:center;
  width:100%;height:100%;
}
.geo-ringpunkt{
  display:block;
  width:var(--geo-ringpunkt);height:var(--geo-ringpunkt);
  border-radius:var(--radius-rund);
  background:var(--schnee);
  border:var(--strich-stark) solid var(--blau);
  box-shadow:var(--schatten);
}
.geo-ringpunkt-ende{border-color:var(--rot)}
.geo-ringpunkt-beide{
  border-color:var(--blau);
  box-shadow:0 0 0 var(--strich) var(--schnee),
             0 0 0 var(--geo-ring) var(--rot);
}


/* == 23. EINSATZFORMULAR (O5, E-P3-34, Mockups 22/23/25) ===================
 *
 * Karten statt Rahmengruppen; Ja/Nein als Schalter mit eingerückten
 * Detailfeldern; Phasen- und Reanimationszeilen mit 44-px-Zeitfeld und
 * rotem Entfernen-Knopf; Ortsfeld mit Lupe und Pin; Speichern-Leiste unten.
 * Ab 1200 px zwei Kartenspalten: links PatientIn, Einsatz, Transport —
 * rechts der Rest (die DOM-Reihenfolge ist die mobile).
 */
@media (min-width:1200px){
  .form-raster{
    display:grid;
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:0 var(--abstand-4);
    align-items:start;
  }
}

/* Zwei kurze Felder in einer Zeile (Nachname/Vorname, Geburtsdatum/Alter) —
 * auch mobil, wie im Mockup. */
.fld-reihe,.patname{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 var(--abstand-3);
}

/* Detailfelder eines Schalters: eingerückt hinter einer orangen Linie
 * (Mockup 22 Mitte — Cycles unter dem Windeneinsatz). */
.childfields{
  margin:0 0 var(--abstand-3) var(--abstand-2);
  padding-left:var(--abstand-4);
  border-left:var(--strich-stark) solid var(--orange);
}
.fld-sub{margin-left:0}

/* Hinweistexte im Formular. Sie hiessen bis Web 9.11.1 „muted small" und
 * bezogen Farbe und Groesse aus der Uebergangsschicht; seit deren Auflösung
 * (O11) steht beides hier. */
.feld-hinweis{color:var(--gedaempft);font-size:var(--groesse-2)}
/* Steht der Hinweis VOR einem Feld (Gefahrenzone der Kontoseite: erst die
 * Folgen, dann die Eingabe), braucht er Abstand nach unten — p hat global
 * keinen. Steht er danach, ist der Abstand des Feldes schon da. */
.feld-hinweis + .feld,.feld-hinweis + form{margin-top:var(--abstand-3)}

/* KLEINTEXT GEHOERT ZU DEM FELD UEBER IHM (F-N1-I). `label` traegt
 * `margin-bottom: --abstand-3` als Abstand zum NAECHSTEN Feld. Folgt ein
 * `.feld-klein` („Zufahrt, Besonderheiten, Lage vor Ort"), stand der Hinweis
 * damit 16 px unter seinem eigenen Feld und 4 px ueber dem naechsten — er
 * las sich als Ueberschrift des folgenden statt als Erlaeuterung des
 * vorigen. Der Abstand wandert vom Feld hinter den Hinweis. */
label:has(+ .feld-klein){margin-bottom:0}
label + .feld-klein{margin-bottom:var(--abstand-3)}

/* ---- Ortsfeld: Feld + Lupe + Pin (E-P3-34) ------------------------------- */
/* DIESELBE NAEHE WIE UEBERALL SONST (F-N1-I). Beim Muster
 * `<label>Text <input></label>` liegen 4 px zwischen Beschriftung und Feld
 * (`label > input{margin-top: --abstand-1}`). Das Ortsfeld kann dieses Muster
 * nicht benutzen — sein Feld steht in einer Zeile mit Lupe und Pin —, und so
 * griff nur `label{margin-bottom: --abstand-3}`: 12 px statt 4. „Einsatzort"
 * hing dadurch zwischen den Feldern, statt zu seinem zu gehoeren. */
.loc-widget > label{margin-bottom:var(--abstand-1)}
/* Und der Block als Ganzes braucht den Abstand nach unten, den ein `label`
 * mitbraechte — sonst klebte „Beschreibung Einsatzort" am Koordinaten-Chip. */
/* `position:relative`, seit die Trefferliste ueber dem folgenden Inhalt
 * schwebt statt ihn zu verschieben (S9/AP1): Ohne einen positionierten
 * Vorfahren haengte sie am Seitenanfang. */
.loc-widget{margin-bottom:var(--abstand-3);position:relative}
.ortsfeld-zeile{display:flex;gap:var(--abstand-2);align-items:stretch}
.ortsfeld-zeile input{flex:1 1 auto;min-width:0}
.ortsfeld-zeile .knopf-symbol{flex:0 0 auto}
.ortsfeld-aktionen{position:relative;display:inline-flex}

.locstate{color:var(--gedaempft);font-size:var(--groesse-2);margin:var(--abstand-1) 0 0}
.locstate:empty{display:none}
.locstate-fehler{color:var(--rot-tief)}

/* ---- Chips (Koordinaten am Ortsfeld, gewählte Rettungsmittel) ------------ */
.rmchips{display:flex;flex-wrap:wrap;gap:var(--abstand-1);align-items:center}
.rmchip{
  display:inline-flex;align-items:center;
  background:var(--blau-hell);color:var(--dunkelblau);
  border-radius:var(--radius-rund);
  font-size:var(--groesse-2);font-weight:600;
  /* GLEICH VIEL ABSTAND ZUM TEXT WIE ZUM RAND (E-MR-18, Skizze des
   * Auftraggebers): 6 px beidseits des Symbols. 6 px ist keine Stufe des
   * Vierer-Rasters — es ist anderthalb `--abstand-1`, und genau so steht es
   * da, damit die Zahl ihre Herkunft behaelt. Links bleibt `--abstand-2`:
   * Dort steht Text an einer runden Kante und braucht mehr Luft. */
  gap:calc(var(--abstand-1) * 1.5);
  padding:var(--abstand-1) calc(var(--abstand-1) * 1.5)
          var(--abstand-1) var(--abstand-2);
}
/* DAS ENTFERNEN-ZIEL IST GROESSER ALS DAS, WAS MAN SIEHT — und das ist der
 * ganze Punkt von Backlog Nr. 42 (M-MR-02, Variante C).
 *
 * Bis Web 19.4.1 stand hier das Malzeichen `×` als TEXT, und das Ziel war so
 * gross wie das Zeichen: gemessen 11 x 15 px. Auf einem Handy mit Handschuhen
 * ist das kein Bedienelement, sondern ein Glueckspiel — und ein Fehlgriff
 * loescht eine Koordinate oder ein Rettungsmittel.
 *
 * WARUM EIN PSEUDOELEMENT UND KEIN GROESSERER KNOPF: Ein 28 px hoher Knopf
 * machte den Chip 28 px hoch, und der soll bei 26 bleiben. Das `::before`
 * liegt ABSOLUT ueber dem Symbol, vergroessert die Trefferflaeche des Knopfes
 * (sie gehoert zu ihm, nicht zum Chip) und nimmt keinen Platz im Fluss. Der
 * Chip behaelt seine Hoehe, das Ziel ragt unsichtbar darueber hinaus.
 *
 * EINE REGEL FUER BEIDE CHIPS (E-MR-11): Koordinaten (`ortsfeld.js`) und
 * beteiligte Rettungsmittel (`einsatz_form.php`) teilen sich `.rmchip`/`.rmx`.
 * Bis hierher setzten sie dasselbe Zeichen auf zwei Arten — einmal als
 * Zeichen, einmal als JavaScript-Escape; die zweite hat die
 * Vollstaendigkeitspruefung nie gesehen. */
.rmx{
  position:relative;
  display:inline-flex;align-items:center;justify-content:center;
  width:var(--symbol-winzig);height:var(--symbol-winzig);
  border:0;background:none;color:inherit;cursor:pointer;
  min-height:0;padding:0;
}
.rmx .symbol{width:var(--symbol-winzig);height:var(--symbol-winzig)}
.rmx::before{
  content:"";position:absolute;
  width:var(--ziel-chip);height:var(--ziel-chip);
  border-radius:var(--radius-rund);
}
/* Rueckmeldung ohne neue Flaeche: der Ton wird kraeftiger. Eine Fuellung
 * haette eine zweite Blauflaeche auf der ersten bedeutet. */
.rmx:hover{color:var(--blau-tief)}
/* Eingabefeld mit Chips darin (Weitere Rettungsmittel, Mockup 22). */
.rmbox{position:relative}
.rmfeld{
  display:flex;flex-wrap:wrap;gap:var(--abstand-1);align-items:center;
  background:var(--schnee);
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius-klein);
  padding:var(--abstand-1) var(--abstand-2);
  min-height:var(--knopf);
}
.rmeingabe,.rmfeld .rmeingabe{
  flex:1 1 8rem;min-width:0;border:0;min-height:0;
  padding:var(--abstand-1);background:none;
}

/* ---- Vorschlagsliste: EIN Baustein unter jedem Feld (S9/AP1, E-S9-07) ----
 *
 * Sie ersetzt drei Fassungen auf einmal: `.loc-suggest` (Photon-Liste des
 * Ortsfelds), `.rmlist`/`.rmopt` (weitere Rettungsmittel) und jede native
 * `<datalist>`. Rahmen, Schatten und Radius sind die der alten
 * `.loc-suggest`; neu sind die Gruppenzeile, das Symbol je Eintrag, die
 * gedaempfte Nebenzeile und die Markierung, die Zeiger und Pfeiltaste teilen.
 * Mockup M-S9-03, freigegeben 07.09.2026.
 *
 * SIE SCHWEBT (`position:absolute`), sie schiebt nicht. Die alte
 * `.loc-suggest` stand im Fluss und drueckte beim Tippen alles darunter nach
 * unten — auf einem 390-px-Schirm sprang das halbe Formular. Der Behaelter
 * traegt dafuer `position:relative`: `.loc-widget`, `.rmbox`,
 * `.feld-vorschlag`.
 *
 * IHRE EBENE IST 35, UND DAS IST EINE ENTSCHEIDUNG. Sie stand zuerst auf 20 —
 * dem Wert der alten `.rmlist`, die als einzige schwebte. Damit lag sie UNTER
 * der klebenden Speichern-Leiste (30), und die deckte beim Tippen genau die
 * untersten Trefferzeilen zu: gemessen 61 px Ueberlappung, und
 * `elementFromPoint` traf in der Schnittflaeche die Leiste. Gefunden hat es
 * der Auftraggeber am Bild, kein Pruefmittel — ein Bild zeigt die Ueberdeckung
 * nur, wenn die Scrollposition zufaellig passt. Die Klickprobe misst sie
 * jetzt (`ap1-liste-ueber-speichern-leiste`).
 *
 * NACH OBEN IST SIE EBENSO BEGRENZT: Die Kopfleiste liegt auf 40 und bleibt
 * darueber — eine Vorschlagsliste, die ueber die Kopfleiste malt, verdeckt
 * den Weg aus der Seite heraus. 35 ist der Platz dazwischen, und er ist der
 * einzige.
 *
 * KEIN EIGENES HOEHENTOKEN. Die Zeile ist `--knopf` hoch und folgt damit
 * beiden Bedienhoehen von selbst (44 px am Finger, 36 px am Zeigergeraet ab
 * 1024 px, R76). */
.vorschlaege{
  position:absolute;left:0;right:0;z-index:35;
  margin:var(--abstand-1) 0 0;padding:0;list-style:none;
  background:var(--schnee);
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius-klein);
  box-shadow:var(--schatten);
  overflow:hidden;
}
/* Die Gruppenzeile sagt, WOHER die Eintraege darunter kommen. Sie ist keine
 * Zeile zum Anfassen und traegt deshalb keine Bedienhoehe. */
.vorschlaege-gruppe{
  padding:var(--abstand-1) var(--abstand-3);
  font-family:var(--schrift-kopf);font-weight:600;font-size:var(--groesse-1);
  letter-spacing:.06em;text-transform:uppercase;color:var(--gedaempft);
  background:var(--rauch);border-top:var(--strich) solid var(--linie);
}
.vorschlaege-gruppe:first-child{border-top:0}
.vorschlag{
  display:flex;align-items:center;gap:var(--abstand-2);
  min-height:var(--knopf);padding:var(--abstand-1) var(--abstand-3);
  border-left:var(--abstand-1) solid transparent;cursor:pointer;
}
.vorschlag .symbol{color:var(--gedaempft)}
.vorschlag-text{flex:1 1 auto;min-width:0}
/* Eine Zeile je Zeile: Ein umbrechender Ortsname schoebe die naechste
 * Zeile aus der Bedienhoehe. */
.vorschlag-haupt{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vorschlag-neben{
  display:block;color:var(--gedaempft);font-size:var(--groesse-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* Zeiger und Pfeiltaste teilen sich EINE Markierung — sonst haette die
 * Tastaturbedienung ein zweites Aussehen fuer dieselbe Aussage. */
.vorschlag:hover,.vorschlag.aktiv{background:var(--rauch);border-left-color:var(--orange)}
/* Die freie Eingabe ist eine HANDLUNG, kein Datensatz. */
.vorschlag-neu .vorschlag-haupt{
  color:var(--orange-tief);font-family:var(--schrift-kopf);font-weight:600;
}
.vorschlag-neu .symbol{color:var(--orange-tief)}
/* Behaelter eines Textfeldes mit Vorschlagsliste (Besatzungsfelder). Das
 * Ortsfeld und die Rettungsmittelbox bringen ihren eigenen mit. */
.feld-vorschlag{position:relative}

/* ---- Phasen- und Reanimationszeilen (Mockup 22/25) ----------------------- */
.phasen-eingabe{
  display:grid;
  grid-template-columns:minmax(0,1fr) calc(var(--knopf) * 2) var(--knopf);
  gap:var(--abstand-2);align-items:center;
  margin-bottom:var(--abstand-3);
}
.phasen-eingabe .zeitfeld{text-align:center;width:auto}
.phasen-eingabe label{margin:0}
.rea-sitzung{
  border:var(--strich) solid var(--linie);
  border-radius:var(--radius);
  padding:var(--abstand-3);
  margin-bottom:var(--abstand-3);
}
.rea-ereignisse{margin-left:var(--abstand-2);padding-left:var(--abstand-3);
  border-left:var(--strich-stark) solid var(--orange)}
.zeile-weg{color:var(--rot)}

/* ---- Schneide-Bereich (S4/A2b, E-S4-17) -----------------------------------
 *
 * Der aufklappbare Bereich unter einer Ruhesegment-Zeile: Aus dem Segment
 * wird ein Einsatz herausgeschnitten. Er GEHÖRT ZUR ZEILE DARÜBER, und das
 * sagt der orange Randstrich — dieselbe Form wie `.rea-ereignisse`, kein
 * neuer Gedanke (E-P3-28).
 *
 * Kein eigener Farbwert und keine eigene Größe: Alles hier kommt aus den
 * vorhandenen Token. Die Zeitleiste benutzt `--sand` für die volle Dauer und
 * `--orange` für das Gewählte — dieselbe Aussage wie überall sonst („dieser
 * Teil ist gemeint"). */
.schnitt-bereich{
  margin:var(--abstand-2) 0 var(--abstand-4) var(--abstand-2);
  padding:var(--abstand-3) 0 var(--abstand-3) var(--abstand-3);
  border-left:var(--strich-stark) solid var(--orange);
}
/* Untereinander, ab 720 px nebeneinander und gleich breit — dieselbe Form und
 * dieselbe Schwelle wie `.listen-form-felder`. `grid-auto-flow:column` statt
 * einer festen Spaltenzahl, weil die Reihe mal zwei und mal drei Felder trägt;
 * eine feste Grundbreite in Pixeln bräuchte eine Zahl, die in keinem Token
 * steht. */
.schnitt-felder{display:grid;gap:var(--abstand-3)}
.schnitt-felder .feld{min-width:0}
@media (min-width:720px){
  .schnitt-felder{grid-auto-flow:column;grid-auto-columns:1fr}
}

/* Die Zeitleiste. Sie ist eine ANZEIGE und keine Bedienung: Geführt wird über
 * die Zeitfelder, die Leiste zeigt das Ergebnis. Deshalb kein Ziehen an den
 * Griffen — es gäbe eine zweite Eingabe für dieselbe Zahl, und die beiden
 * liefen auseinander (Mockup A0, Vorschlag 2).
 *
 * SIE IST HTML UND KEIN SVG, und das war eine Korrektur: Ein SVG mit
 * `viewBox` skaliert seine Beschriftung mit der Breite. Auf 1280 px stand sie
 * richtig, auf 390 px war sie sechs Pixel hoch und unlesbar — dieselbe Zahl
 * in zwei Größen, je nach Fenster. Mit Prozentbreiten auf gewöhnlichen
 * Elementen bleibt der Text der Text und nur der Balken skaliert. */
.schnitt-vorschau{
  background:var(--rauch);
  border-radius:var(--radius);
  padding:var(--abstand-3) var(--abstand-3) var(--abstand-2);
  margin-bottom:var(--abstand-3);
}
/* Die Leiste IST der Balken — die Beschriftungen hängen mit `bottom:100%`
 * darüber und mit `top:100%` darunter. Das erspart gerechnete Versätze, und
 * damit die einzigen Zahlen, für die es hier kein Token gäbe. Der obere
 * Abstand hält den Platz für die Griffbeschriftung frei. */
.schnitt-leiste{position:relative;height:var(--abstand-4);margin-top:var(--abstand-5)}
.schnitt-bahn{
  position:absolute;inset:0;
  background:var(--sand);border-radius:var(--radius-rund);
}
.schnitt-wahl{
  position:absolute;top:0;bottom:0;
  background:var(--orange);border-radius:var(--radius-rund);
}
/* Schon einmal Geschnittenes: dieselbe Fläche, aber blasser — es ist kein
 * zweiter gewählter Bereich, sondern einer, der nicht mehr da ist. Ein
 * zweiter Vollton hieße „auch das ist gemeint". */
.schnitt-weg{
  position:absolute;top:0;bottom:0;
  background:var(--gedaempft);opacity:.35;
}
/* Der Griff ragt oben und unten über den Balken hinaus, damit die Kante auch
 * dort sichtbar ist, wo Balken und Auswahl dieselbe Höhe haben. */
.schnitt-griff{
  position:absolute;top:calc(-1 * var(--abstand-1));
  bottom:calc(-1 * var(--abstand-1));
  width:var(--strich-stark);background:var(--dunkelblau);
}
/* Die Beschriftung am Griff: mittig darüber, und `translateX(-50%)` statt
 * einer gerechneten Verschiebung — die Textbreite kennt nur der Browser. */
.schnitt-marke{
  position:absolute;bottom:calc(100% + var(--abstand-1));
  transform:translateX(-50%);
  white-space:nowrap;font-size:var(--groesse-2);color:var(--dunkelblau);
}
.schnitt-raender{
  display:flex;justify-content:space-between;
  font-size:var(--groesse-2);color:var(--gedaempft);
  margin-top:var(--abstand-2);
}

/* Orange Anlegen-Wege in Kartenfüßen („+ Phase hinzufügen"). */
.anlegen-link{
  display:inline-flex;align-items:center;gap:var(--abstand-2);
  min-height:var(--knopf);
  color:var(--orange-tief);font-family:var(--schrift-kopf);font-weight:600;
}
.karte-fussweg{margin:0}

/* ---- Kartendialog der Ortswahl (Fadenkreuz, E-P3-34) --------------------- */
.dialog-karte{width:min(92vw, calc(var(--karte-neben-breit) * 1.4))}
.ortswahl-karte{position:relative}
.ortswahl-karte .geo{height:var(--karte-desktop);margin-bottom:0}
.ortswahl-kreuz{
  position:absolute;left:50%;top:50%;
  width:var(--symbol-gross);height:var(--symbol-gross);
  transform:translate(-50%,-50%);
  pointer-events:none;z-index:1;
}
.ortswahl-kreuz::before,.ortswahl-kreuz::after{
  content:"";position:absolute;background:var(--dunkelblau);
  box-shadow:0 0 0 var(--strich) var(--schnee);
}
.ortswahl-kreuz::before{left:50%;top:0;bottom:0;width:var(--strich-stark);
  transform:translateX(-50%)}
.ortswahl-kreuz::after{top:50%;left:0;right:0;height:var(--strich-stark);
  transform:translateY(-50%)}

/* ---- Suchfeld im Dialogkopf (S9/AP2, E-S9-06; Mockup M-S9-04) ------------
 *
 * Der Behaelter traegt `position:relative`, weil die Trefferliste
 * (`.vorschlaege`, 9.28) darin schwebt — dieselbe Anforderung wie bei
 * `.loc-widget` und `.rmbox`. Die Zeile selbst ist die des Ortsfelds
 * (`.ortsfeld-zeile`, Feld plus Lupe): Dasselbe Bedienelement soll nicht
 * zweimal aussehen. */
.dialog-suche{position:relative;margin-bottom:var(--abstand-3)}
/* Das Suchfeld steht im KOPF (M-S9-04). Damit die Karte unmittelbar darunter
 * beginnt, faellt der obere Innenabstand des Inhalts weg — sonst stuende
 * zwischen Feld und Karte zweimal Luft: der Abstand des Feldes und der des
 * Inhalts. Auf den Kartendialog begrenzt; jeder andere Dialog behaelt seinen. */
.dialog-karte .dialog-inhalt{padding-top:0}

/* ---- Legende unter der Karte (S9/AP2) ------------------------------------
 *
 * Eine Zeile, gedaempft: „Aufzeichnung · Start · Ende". Sie erscheint nur,
 * wenn eine Spur gezeichnet wurde — eine Legende ohne Gegenstueck erklaert
 * nichts. Die Ringpunkte sind dieselben wie auf der Karte (`.geo-ringpunkt`,
 * blau = Start, `.geo-ringpunkt-ende` rot = Ende) und brauchen hier keine
 * eigene Regel — sie tragen ihre Groesse selbst. */
.legende{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--abstand-3);
  color:var(--gedaempft);font-size:var(--groesse-2);
}
.legende > span{display:inline-flex;align-items:center;gap:var(--abstand-1)}
.legende-linie{
  display:inline-block;width:var(--abstand-5);height:var(--abstand-1);
  background:var(--spur-1);border-radius:var(--radius-klein);
}

/* Blatt-Zeilen gibt es seit O5 auch als <button> (Ortswahl) — dieselbe
 * Gestalt wie die Verweise, ohne Knopf-Grundform. */
button.blatt-zeile{
  width:100%;background:none;border:0;text-align:left;cursor:pointer;
  border-radius:0;
}


/* == 24. SUCHE (O6, E-P3-36, Mockups 27/28) ================================
 *
 * Die Filterspalte IST die Leiste (O2) — hier steht nur, was ihren Inhalt
 * ausmacht: Akkordeongruppen mit einer Zahl im Kopf, von/bis nebeneinander,
 * Wochentage und Dreiwert als Segmentwahl, der Fuß mit „Zurücksetzen" und —
 * nur in der Schublade — „n Treffer zeigen".
 */
.filtergruppe > .akkordeon-zeile{padding:0 var(--abstand-3)}
.filterzahl{flex:0 0 auto;margin-left:auto}
.filtergruppe .akkordeon-text{flex:1 1 auto}
.filterfelder{padding:var(--abstand-2) var(--abstand-3) var(--abstand-4)}
/* HIER STAND `.filterfelder label{margin-bottom:var(--abstand-3)}` — und
 * setzte damit GENAU DEN WERT, den die Grundform `label` schon setzt. Eine
 * Regel ohne eigene Wirkung, aber mit höherer Spezifität (0,1,1): Sie schlug
 * jedes `.segment-taste{margin:0}` (0,1,0) und hielt den toten Streifen unter
 * den Segmenttasten der Filterleiste fest, nachdem er überall sonst fort war
 * (F-N1-L). Eine Dublette ist nie harmlos — sie tut nichts, bis sie etwas
 * verhindert. */

/* Ab 1024 px ist die Segmentwahl inline (E-P3-30) — in der Filterleiste
 * soll sie die Spaltenbreite füllen wie jedes Feld darüber. */
.filterfelder .segment{display:flex;width:100%}
/* Am UNTEREN Rand ausrichten — als Netz, nicht als Reparatur: Seit die
 * Paare „von"/„bis" heißen und ihren Namen über sich tragen (F-N1-J), sind
 * beide Beschriftungen gleich kurz und stehen ohnehin auf einer Höhe. Bliebe
 * eine künftig doch einmal länger, stünden die Felder trotzdem nebeneinander
 * und nicht versetzt. */
.filterfelder .fld-reihe{gap:0 var(--abstand-2);align-items:end}
.filterfelder .fld-reihe label{display:flex;flex-direction:column;justify-content:flex-end}

/* Beschriftung über einer Gruppe von Bedienelementen (Segmentwahl), dort wo
 * ein <label> nicht taugt: Es kann nur EIN Element beschriften. Die
 * Beschriftung selbst ist `.feld-label` aus Abschnitt 11 — hier stand sie
 * bis S3/AP2 ein zweites Mal, mit demselben Wert und ohne font-weight, und
 * setzte damit nichts, was die erste Regel nicht schon gesetzt hätte. Eine
 * Änderung am Abstand wäre an einer der beiden Stellen hängengeblieben. */
.feldblock{margin-bottom:var(--abstand-3)}

/* Segmentwahl in der Filterspalte: leiser als die Segmentwahl im Inhalt —
 * hell orange mit orangem Rahmen statt voller Fläche (Mockup 27/28). Bis zu
 * sieben davon stehen untereinander; sieben orange Balken wären ein Alarm,
 * und gemeint ist eine Einstellung. */
.segment-filter .segment-taste{padding:0 var(--abstand-2)}
.segment-filter .segment-box:checked + .segment-taste{
  background:var(--orange-hell);color:var(--asphalt);
  box-shadow:inset 0 0 0 var(--strich-stark) var(--orange);
}
/* Mehrfachwahl (Wochentage): dieselben Tasten, aber Kästchen statt
 * Radioknöpfen — mehrere Tage gleichzeitig sind der Regelfall. Sieben Tasten
 * müssen nebeneinander in die 260 px breite Leiste passen; deshalb ohne
 * Innenabstand und mit gleicher Breite. */
.segment-mehrfach .segment-taste{
  padding:0 var(--abstand-1);flex:1 1 0;min-width:0;
  font-size:var(--groesse-2);
}

.filterfuss{display:flex;flex-direction:column;gap:var(--abstand-2)}

/* ---- Suchzeile: Feld und Filterknopf (Mockup 27) ------------------------- */
.suchzeile{display:flex;gap:var(--abstand-2);align-items:stretch;margin-bottom:var(--abstand-3)}
.suchfeld{position:relative;flex:1 1 auto;display:flex;align-items:center}
.suchfeld input{
  width:100%;min-height:var(--suchfeld);
  padding-left:calc(var(--abstand-3) * 2 + var(--symbol-gross));
  padding-right:calc(var(--abstand-3) * 2 + var(--symbol-gross));
  font-size:var(--groesse-4);
}
.suchfeld-lupe{
  position:absolute;left:var(--abstand-3);
  color:var(--gedaempft);pointer-events:none;
}
.suchfeld-x{
  position:absolute;right:var(--abstand-2);
  display:flex;align-items:center;justify-content:center;
  width:var(--knopf);height:var(--knopf);
  border:0;background:none;color:var(--gedaempft);cursor:pointer;
}
.suchfeld-x:hover{color:var(--asphalt)}
.filterknopf{flex:0 0 auto;min-height:var(--suchfeld)}

.suchhinweis{margin-bottom:var(--abstand-3)}
/* Ein Link mitten im Fließtext, der aufklappt statt zu navigieren. */
.leiser-link{
  border:0;background:none;padding:0;cursor:pointer;
  color:var(--blau-tief);font:inherit;font-weight:600;
}
.suchsyntax{
  background:var(--schnee);
  border:var(--strich) solid var(--linie);
  border-radius:var(--radius);
  padding:var(--abstand-3) var(--abstand-4);
  margin-bottom:var(--abstand-3);
}
.suchsyntax li{margin-bottom:var(--abstand-1)}
.suchsyntax code{
  background:var(--rauch);border-radius:var(--radius-klein);
  padding:0 var(--abstand-1);
}

.filterplaketten{margin-bottom:var(--abstand-3)}

/* ---- Trefferkarte -------------------------------------------------------- */
.sortieren-aktion{margin-left:auto;position:relative}
.karte-treffer .karte-aktion{margin-left:0}
/* Das Trefferwort hell orange hinterlegt (E-P3-36) — die Fläche trägt hier
 * keine Bedeutung allein, sie zeigt nur, wo der Begriff steht; der Text
 * bleibt Asphalt und damit voll lesbar. */
mark.treffer{background:var(--orange-hell);color:inherit;border-radius:var(--radius-klein)}

/* Die Nachladezeile unter der Tabelle (missiontable.js, 200 Zeilen je Seite). */
.mehrzeile{
  display:flex;flex-wrap:wrap;gap:var(--abstand-3);
  padding:var(--abstand-3) var(--abstand-4) 0;
}

/* Artzeichen, Datum und Beginn der Kachel stehen in einer Zeile (Mockup 27);
 * das Zeichen sitzt vor dem Datum und nimmt die Farbe der Zeile an. */
.kachel-art{margin-right:var(--abstand-1);color:var(--dunkelblau)}
.kachel-art .symbol{vertical-align:-.15em}
.kachel-datum{white-space:nowrap}
/* Mit Datum braucht die Zeitspalte mehr Platz als die reine Uhrzeit. */
.kachel-zeit:has(.kachel-datum){min-width:0;flex:0 0 auto}


/* ===========================================================================
 * 25  ZEITRAUM                                              (P3/O7, E-P3-37)
 *
 * Die Übersicht eines Monats oder Jahres. Neu daran ist weniger die
 * Gestaltung als der ZUSCHNITT: „Gemischt" zeigt vier Kennzahlen statt acht,
 * und unter 720 px sind von jedem Satz vier sichtbar, der Rest steht hinter
 * „Weitere Statistik".
 *
 * Die Kachel selbst ist der Baustein aus O1 (`.kennzahl`, ui_kennzahl) — hier
 * stehen nur Raster, mobile Kappung und die Segmentwahl in der Titelzeile.
 * ======================================================================== */

/* DREI SPALTEN, IN JEDER BREITE (S9/AP5, M-S9-07): das Inhaltsverzeichnis
 * der Standortseite. Die Regel steht mit Absicht OHNE Medienabfrage und
 * NACH der Vierspalten-Regel des 1024er Bandes — nur so gewinnt sie in jeder
 * Breite. Im 720er Block darunter waere sie am Handy wirkungslos, und dort
 * stuenden zwei Kacheln nebeneinander und eine allein; das freigegebene
 * Mockup zeigt die drei auch bei 376 px in einer Reihe. Drei Kacheln zu je
 * rund 110 px sind schmal — sie tragen eine Zahl und ein Wort, und mehr
 * sollen sie nicht. */
.kennzahl-raster-3{grid-template-columns:repeat(3,minmax(0,1fr))}

/* Spaltenzahl folgt dem Satz: vier Kacheln in vier Spalten, acht in zwei
 * Reihen zu vier, zehn in zwei Reihen zu fünf — so bleibt keine Reihe halb
 * leer. Unter 720 px sind es immer zwei (Grundregel von .kennzahl-raster). */
@media (min-width:720px){
  .kennzahl-raster-4{grid-template-columns:repeat(4,minmax(0,1fr))}
  .kennzahl-raster-5{grid-template-columns:repeat(5,minmax(0,1fr))}
}

/* MOBIL VIER (E-P3-37). Die übrigen Kacheln stehen im Markup und sind nur
 * verborgen — nicht ausgelassen: Der Knopf „Weitere Statistik" klappt sie
 * auf, ohne dass etwas nachgeladen oder neu gerechnet würde. Deshalb
 * `display:none` und nicht das `hidden`-Attribut: Letzteres gehört dem
 * Zustand „gibt es nicht", nicht dem Zustand „gerade eingeklappt". */
.kennzahl-mehr{display:none}
.kennzahl-raster-offen .kennzahl-mehr{display:block}
.kennzahl-mehr-knopf{
  display:flex;align-items:center;gap:var(--abstand-1);
  margin:calc(-1 * var(--abstand-2)) 0 var(--abstand-4);
}
/* Der Winkel zeigt im Ruhezustand nach unten — winkel.svg tut das von sich
 * aus (Abschnitt 5), es braucht dafür keine Drehung. Beim Aufklappen dreht
 * er sich nach oben. */
.kennzahl-mehr-knopf .symbol{transition:transform var(--dauer)}
.kennzahl-mehr-knopf.offen .symbol{transform:rotate(180deg)}

@media (min-width:720px){
  /* Ab hier gibt es nichts zu verbergen: Der ganze Satz steht da, und der
     Knopf ist ohnehin `nur-unter-720`. */
  .kennzahl-mehr{display:block}
}

/* Die Segmentwahl steht in den AKTIONEN der Titelzeile: ab 720 px rechts
 * neben dem Titel (Mockup 29), darunter vollbreit unter dem Titel
 * (Mockup 31). `width:100%` an der Wahl allein genügt dafür nicht —
 * `.titelzeile-aktionen` ist ein Flex-Kind mit `flex:0 0 auto` und schrumpft
 * auf die Breite seines Inhalts. Der Aktionsblock muss deshalb mobil selbst
 * umbrechen und die volle Breite nehmen; die drei Segmente teilen sie sich
 * dann zu gleichen Teilen. */
.titelzeile-aktionen:has(.segment-art){flex:1 0 100%;margin-left:0}
.segment-art{width:100%}
.segment-art .segment-taste{flex:1 1 0;text-align:center}
@media (min-width:720px){
  .titelzeile-aktionen:has(.segment-art){flex:0 0 auto;margin-left:auto}
  .segment-art{width:auto}
  .segment-art .segment-taste{flex:0 0 auto}
}

/* DIE MARKIERUNG DES ANGEZEIGTEN ZEITRAUMS in der Leiste (E-P3-37). Sie
 * sitzt auf der Zeile des Akkordeons, nicht auf dem `<details>` selbst —
 * sonst färbte sich auch der aufgeklappte Inhalt. Dieselben Farben wie beim
 * aktiven Diensttag (`.eintrag.aktiv`), damit „hier stehe ich" überall
 * gleich aussieht. */
.akkordeon.aktiv > .akkordeon-zeile{
  background:var(--orange-hell);
  box-shadow:inset var(--strich-stark) 0 0 var(--orange);
}
.akkordeon.aktiv > .akkordeon-zeile .akkordeon-text{color:var(--dunkelblau)}

/* Die Zeile des Extremwert-Trägers, hell orange statt rot (E-P3-37): Rot
 * heißt in dieser Oberfläche „Aufmerksamkeit" — ein Höchstwert ist kein
 * Fehler. Gilt für die Tabellenzeile ab 720 px und die Kachel darunter. */
.hl-extrem{background:var(--orange-hell)}
tr.hl-extrem td{background:var(--orange-hell)}


/* ===========================================================================
 * 26  EINSTELLUNGEN UND VERWALTUNGSLISTEN                   (P3/O8, E-P3-35)
 * ======================================================================== */

/* WAHLLISTE (.wahlliste) — eine aus vieren, untereinander, 44 px hoch.
 * Freigegeben mit Mockup 13. Die Radios selbst sind unsichtbar; die Zeile
 * ist das Bedienelement, und der Punkt links wird gezeichnet — so lässt er
 * sich färben und auf Größe bringen, was ein Systemradio nicht zulässt.
 *
 * SCHLICHTE LISTE STATT UMRANDETER EINZELZEILEN (S3/AP8). Jede Zeile trug
 * einen eigenen Rahmen auf eigener Fläche und stand mit 8 px Abstand zur
 * nächsten — vier Kästchen untereinander, die aussahen wie vier Karten und
 * nur eine Wahl sind. Die Auswahl braucht diese Umrandung nicht: Sie zeigt
 * sich am Punkt links und, bei der gewählten Zeile, an der Fläche.
 * Was bleibt, sind die 44 px Zeilenhöhe und der gezeichnete Punkt. */
.wahlliste{display:flex;flex-direction:column}
input[type=radio].wahl-box{position:absolute;opacity:0;width:0;height:0;min-height:0}
.wahl-zeile{
  display:flex;align-items:center;gap:var(--abstand-3);
  min-height:var(--knopf);
  padding:var(--abstand-2) var(--abstand-3);
  border-radius:var(--radius-klein);
  cursor:pointer;
}
.wahl-zeile:hover{background:var(--rauch)}
.wahl-punkt{
  flex:0 0 auto;width:var(--symbol);height:var(--symbol);
  border:var(--strich-stark) solid var(--linie-stark);
  border-radius:var(--radius-rund);
  background:var(--schnee);
}
.wahl-text{flex:1 1 auto;font-weight:600;color:var(--dunkelblau)}
.wahl-zusatz{flex:0 0 auto;color:var(--gedaempft);font-size:var(--groesse-2)}

/* Gewählt: hell orange mit orangem Rahmen und gefülltem Punkt — dieselbe
 * Sprache wie die aktive Kennzahl-Kachel und der aktive Leisteneintrag. */
.wahl-box:checked + .wahl-zeile{background:var(--orange-hell)}
.wahl-box:checked + .wahl-zeile .wahl-punkt{
  border-color:var(--orange);
  box-shadow:inset 0 0 0 var(--strich-stark) var(--schnee);
  background:var(--orange);
}
/* Der Fokusring gehört an die ZEILE, nicht an das versteckte Radio: Sonst
 * ist die Tastaturbedienung unsichtbar. */
.wahl-box:focus-visible + .wahl-zeile{outline:var(--strich-stark) solid var(--blau);outline-offset:var(--strich-stark)}

/* Unter 480 px rutscht der Zusatz unter den Text — „zurzeit Hubschrauber
 * (RTH)" neben „Standard der Installation" sprengt sonst jede Zeile. */
@media (max-width:479px){
  .wahl-zeile{flex-wrap:wrap}
  .wahl-zusatz{flex:1 0 100%;padding-left:calc(var(--symbol) + var(--abstand-3))}
  /* DAS WORTZEICHEN EINE STUFE KLEINER (F-N1-D). „Gen-EM Einsatzdoku" braucht
     bei 19 px genau 193 px; bei 360 px Fenster bleiben neben Menüknopf, Logo
     und Zahnrad 187 übrig — sechs zu wenig, und die Marke endete auf einer
     Ellipse. Bei 16 px sind es 163 px und damit Luft. Die Stufe steht in der
     Skala; eine Zwischengröße gäbe es dafür nicht. */
  .kopf-name{font-size:var(--groesse-4)}
}

/* PASSWORTSTÄRKE als Balken (E-P3-16, Mockup 11). Vier Segmente, gefüllt
 * nach Stufe; die Farbe verstärkt nur, was die Zahl der Segmente schon
 * sagt. Vorher war es eine Textzeile in fünf Farben, darunter Grün und
 * Gelb — zwei Töne, die es in der Marke nicht gibt. */
.pwstaerke{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:var(--abstand-2);
  font-size:var(--groesse-2);color:var(--gedaempft);
}
.pwstaerke:empty{display:none}
.pwstaerke-balken{display:flex;gap:var(--abstand-1);flex:0 0 auto}
.pwstaerke-balken > span{
  width:var(--balken-glied);height:var(--strich-balken);
  border-radius:var(--radius-klein);
  background:var(--linie);
}
.pwstaerke-text{font-weight:600;color:var(--dunkelblau)}
/* Der Hinweissatz steht in eigener Zeile — er ist zwei Zeilen lang und
 * schöbe die Stufe sonst aus dem Bild. */
.pwstaerke-hinweis{flex:1 0 100%}

/* Rot bis Stufe 0, orange für 1–2, Dunkelblau ab 3: dieselbe Bedeutung wie
 * überall — Rot ist ein Halt, Orange ein Hinweis, Dunkelblau die Ruhe. */
.pwq-0 .pwstaerke-balken > span.an{background:var(--rot)}
.pwq-0 .pwstaerke-text{color:var(--rot-tief)}
.pwq-1 .pwstaerke-balken > span.an,
.pwq-2 .pwstaerke-balken > span.an{background:var(--orange)}
.pwq-1 .pwstaerke-text,
.pwq-2 .pwstaerke-text{color:var(--orange-tief)}
.pwq-3 .pwstaerke-balken > span.an,
.pwq-4 .pwstaerke-balken > span.an{background:var(--dunkelblau)}

/* VERWALTUNGSLISTEN (E-P3-35). Erklärtext auf drei Zeilen unter dem Titel,
 * dann die Karte mit Zeilen und darunter — IN derselben Karte — das
 * Formular zum Anlegen. */
.seiten-erklaerung{
  max-width:var(--lesespalte);
  margin:calc(-1 * var(--abstand-2)) 0 var(--abstand-4);
  color:var(--gedaempft);
}
/* Der negative Rand oben ist auf die TITELZEILE abgestimmt, die ihren eigenen
 * Abstand nach unten mitbringt. Steht die Erklärung dagegen direkt unter einem
 * blanken <h1> — öffentliche Seiten und Einrichter, die kein Gerüst und damit
 * keine Titelzeile haben —, zieht er sie an die Überschrift heran (O10). */
h1 + .seiten-erklaerung{margin-top:0}

/* Das Formular unter der Liste, durch eine Linie abgesetzt: Es gehört zur
 * Karte, ist aber eine andere Art von Inhalt als die Zeilen darüber. */
.listen-form{
  border-top:var(--strich) solid var(--linie);
  padding-top:var(--abstand-4);
  margin-top:var(--abstand-3);
}
.listen-form-titel{
  font-family:var(--schrift-kopf);font-weight:600;
  font-size:var(--groesse-3);color:var(--dunkelblau);
  margin:0 0 var(--abstand-2);
}
.listen-form-felder{display:grid;gap:var(--abstand-3)}
.listen-form-fuss{display:flex;flex-wrap:wrap;gap:var(--abstand-2);margin-top:var(--abstand-4)}

/* Ab 720 px stehen Name und Lage nebeneinander (Mockup 08) — sie gehören
 * zusammen und passen in eine Zeile. */
@media (min-width:720px){
  .listen-form-felder{grid-template-columns:1fr 1fr;align-items:start}
}

/* Der Vorbelegungsstern in der Zeile: orange, weil er eine Auszeichnung ist
 * und keine Warnung. */
.zeile-stern{color:var(--orange)}

/* Die Knopfreihe der Zeilenaktionen (Desktop). Mobil steht dort das „⋯",
 * das der Aktionsblatt-Baustein mitbringt.
 *
 * KEIN `display` in der Grundregel: `.nur-ab-720` blendet mit `display:none`
 * aus und stellt ab 720 px die Grundform mit `revert` wieder her. Eine
 * eigene `display:flex`-Regel gleicher Spezifität, die später steht, schlägt
 * beides — und dann stehen unter 720 px die Knöpfe UND das „⋯" nebeneinander.
 * Die Flex-Eigenschaften gehören deshalb in die 720er-Regel; sie greifen
 * genau dort, wo die Reihe überhaupt sichtbar ist. */
@media (min-width:720px){
  .zeile-knoepfe{display:flex;flex-wrap:wrap;gap:var(--abstand-2);justify-content:flex-end}
}

/* „Als Vorbelegung" ist leise UND orange (Mockup 11): Sie ist eine
 * Auszeichnung, kein Hauptweg — ein voller Orangeknopf neben „Bearbeiten"
 * und „Löschen" behauptete, sie sei die zu erwartende Handlung. */
.knopf-leise-orange{color:var(--orange-tief)}
.knopf-leise-orange .symbol{color:var(--orange)}

/* Die Listen innerhalb einer Standort-Karte (Rettungsmittel, Besatzung,
 * Zielkliniken, weitere Rettungsmittel, Bergwacht). Sie sind Abschnitte,
 * keine eigenen Karten: Zwei Rahmen um dieselbe Sache trennen, was
 * zusammengehört — die zweite Ebene ordnet nur. */
/* ABSTAND AUCH VOR DER ERSTEN LISTE (F-N1-M). Die Regel setzte den Abstand
 * nur ZWISCHEN zwei Listen. Steht davor etwas anderes — der Hinweis
 * „[systemweit] Dieser Standort wird von der Administration gepflegt" —,
 * klebte die Überschrift „Rettungsmittel" unmittelbar daran. */
.sd-liste{margin-top:var(--abstand-4)}
.sd-liste:first-child{margin-top:0}
.sd-liste + .sd-liste{
  border-top:var(--strich) solid var(--linie);
  margin-top:var(--abstand-5);
  padding-top:var(--abstand-4);
}

/* ART NEBENEINANDER (F-N1-N). „luftgebunden" und „bodengebunden" sind zwei
 * Wörter und standen untereinander — zwei Zeilen für eine Entweder-oder-Wahl,
 * neben der die halbe Formularbreite leer blieb. Sie umbrechen weiterhin,
 * wenn der Platz nicht reicht. Dieselbe Überlegung wie bei den beiden Haken
 * des Einsatzformulars („nebeneinander" im Feldkatalog). */
.vehkind{display:flex;flex-wrap:wrap;gap:0 var(--abstand-4)}
.vehkind label{margin-bottom:0}
.sd-titel{
  display:flex;align-items:center;gap:var(--abstand-2);
  font-family:var(--schrift-kopf);font-weight:600;
  font-size:var(--groesse-4);color:var(--dunkelblau);
  margin:0 0 var(--abstand-2);
}
.sd-zahl{
  font-family:var(--schrift-text);font-weight:400;
  font-size:var(--groesse-2);color:var(--gedaempft);
}
/* Die Rolle innerhalb der Besatzungsliste — eine Ebene tiefer als der
 * Listentitel, deshalb kleiner und ohne eigene Linie. */
.sd-rolle{
  font-family:var(--schrift-kopf);font-weight:600;
  font-size:var(--groesse-3);color:var(--dunkelblau);
  margin:var(--abstand-4) 0 var(--abstand-2);
}
/* Der Klammerzusatz an einer Feldbeschriftung („(optional)"). */
.feld-klein-inline{font-weight:400;color:var(--gedaempft);font-size:var(--groesse-2)}

/* CODEBLOCK — Geräte-ID, API-Schlüssel, Wiederherstellungsschlüssel,
 * Cron-Zeile, Serverschlüssel. Werte, die von einem Bildschirm abgeschrieben
 * oder herauskopiert werden, oft unter Zeitdruck: groß, in Festbreite, mit
 * Abstand zwischen den Zeichen.
 *
 * DER KOPPLUNGSCODE STEHT SEIT WEB 13.1.0 NICHT MEHR HIER. Er wandert seit S5
 * in die andere Richtung — das Gerät zeigt ihn, ein Mensch tippt ihn im Web
 * ein —, und dafür ist ein Eingabefeld zuständig (.feld-fest). Der Baustein
 * bleibt: sechs andere Stellen benutzen ihn. */
.codeblock{
  background:var(--rauch);
  border:var(--strich) solid var(--linie);
  border-radius:var(--radius);
  padding:var(--abstand-3);
  margin:var(--abstand-3) 0;
}
.codeblock-titel{
  font-size:var(--groesse-2);color:var(--gedaempft);
  margin:0 0 var(--abstand-1);
}
.codeblock-titel:not(:first-child){margin-top:var(--abstand-3)}
.codeblock-wert{
  font-family:var(--schrift-fest);
  font-size:var(--groesse-5);font-weight:600;
  color:var(--dunkelblau);
  letter-spacing:.06em;
  word-break:break-all;
  margin:0;
}

/* ZWEITE STUFE FÜR LANGE WERTE (E-S8-10, Backlog Nr. 78, Web 15.1.0).
 *
 * Die große Stufe darüber ist für sechs Zeichen gemacht — Geräte-ID,
 * Wiederherstellungsschlüssel. Benutzt wurde sie auch für die Cron-Zeile, die
 * Token-Adresse, den Setz-Link und die Serverschlüssel-Zeile: Werte mit
 * sechzig bis hundert Zeichen, die in dieser Größe über drei Zeilen brechen
 * und dabei aussehen, als seien sie zum Vorlesen gedacht.
 *
 * Zwei Stufen also, ein Kasten. Die kleine trägt kein Sperrmaß (letter-spacing
 * hilft beim Abschreiben von sechs Zeichen und schadet beim Lesen von
 * hundert), bricht an beliebiger Stelle und steht neben einem leisen Knopf
 * „Kopieren" — weil ein hundertstelliges Geheimnis abgeschrieben ein
 * Tippfehler ist.
 *
 * KEIN SYMBOL AM KNOPF: Der Vorrat hat keines für „kopieren", und ein neues
 * bräuchte Freigabe mit Mockup (Design.md 9). Das Wort tut es. */
.codeblock-lang{display:flex;align-items:flex-start;gap:var(--abstand-2)}
.codeblock-text{flex:1 1 auto;min-width:0}
.codeblock-lang .knopf{flex:0 0 auto}
.codeblock-wert-lang{
  font-family:var(--schrift-fest);
  font-size:var(--groesse-2);font-weight:400;
  color:var(--dunkelblau);
  word-break:break-all;
  line-height:1.5;
  margin:0;
}

/* SPEICHERBALKEN — Belegung nach Art (E-S8-18, Mockup 07, Web 15.1.0).
 *
 * WOFÜR. Zwei Fragen, die eine Zahlenreihe nicht beantwortet: Wie voll ist es,
 * und woraus besteht das? „1,3 GB von 2 GB" sagt das Erste; erst die Segmente
 * sagen, dass davon 0,9 GB Konto-Backups sind und 0,4 GB Komplett-Stände —
 * und damit, an welcher Schraube man dreht.
 *
 * ACHT PIXEL HOCH UND OHNE BESCHRIFTUNG IM BALKEN. Er ist eine Zeile Grafik
 * neben einer Zeile Text, kein Diagramm: Die Zahlen stehen in der Legende
 * darunter und in der Überschrift darüber. Ein Balken mit Text darin bräuchte
 * Kontrast gegen fünf verschiedene Untergründe.
 *
 * DIE FARBEN SIND KLASSEN, NICHT INLINE. Die Breite eines Segments ist
 * gerechnet und steht deshalb am Element; die Farbe darf es nicht — sonst
 * stünde ein Token im Markup (`CLAUDE.md` 5). Dieselbe Art hat in beiden
 * Balken dieselbe Farbe: Wer von „Backups" nach „Installation gesamt" schaut,
 * soll die Konto-Backups wiedererkennen.
 *
 * DER SCHWELLENSTRICH ist ein leeres Segment mit fester Breite, kein absolut
 * positionierter Zeiger: Er sitzt damit im selben Fluss wie die Segmente und
 * verrutscht nicht, wenn der Balken schmaler wird. */
.speicher-balken{
  height:var(--balken);
  border-radius:var(--radius-rund);
  background:var(--linie);
  overflow:hidden;
  display:flex;
  margin:var(--abstand-2) 0 var(--abstand-1);
}
.speicher-balken > span{display:block;height:100%}
.speicher-luecke{background:transparent}
.speicher-marke{width:var(--strich-stark);background:var(--gedaempft)}
.speicher-legende{
  display:flex;flex-wrap:wrap;gap:var(--abstand-3);
  font-size:var(--groesse-2);color:var(--gedaempft);
  /* Abstand nach unten am BAUSTEIN, nicht an der Überschrift darunter:
   * `.listen-form-titel` steht auf vielen Seiten und braucht dort keinen
   * oberen Abstand. Wer zwei Balken untereinander stellt, braucht ihn hier. */
  margin-bottom:var(--abstand-3);
}
.speicher-legende i{
  display:inline-block;
  width:var(--balken-punkt);height:var(--balken-punkt);
  border-radius:var(--radius-rund);
  margin-right:var(--abstand-1);
  vertical-align:middle;
}
/* Die vier Arten und „frei". Blau und Dunkelblau für die beiden Backup-Arten
 * (sie gehören zusammen), Orange für die Datenbank (sie wächst und ist der
 * Grund, warum die Grenze NICHT für sie gilt), Sand für die Dateien. */
.sb-konto{background:var(--blau)}
.sb-komplett{background:var(--dunkelblau)}
.sb-db{background:var(--orange)}
.sb-dateien{background:var(--sand)}
.sb-frei{background:var(--linie)}

/* ZUSTANDSZEILE — Fortschritt und Ergebnis einer langen Handlung (Backup,
 * Import). Sie hält ihre Höhe frei, damit der Kasten beim Erscheinen der
 * ersten Meldung nicht springt; ein Ergebnis erscheint darin als
 * Meldungs-Baustein, Fortschritt als schlichte Zeile. */
.zustandszeile{
  min-height:var(--zeile-frei);
  margin-top:var(--abstand-3);
  color:var(--gedaempft);
  font-size:var(--groesse-2);
}
.zustandszeile .meldung{margin:0}


/* ===========================================================================
 * 27  ADMINISTRATION                                        (P3/O9, E-P3-41)
 *
 * Kontoseite, NutzerInnen-Liste, Backup-Regeln. Fast alles daran sind
 * vorhandene Bausteine — Karte, Zeile, Zeilenaktionen, Kennzahl, Dialog.
 * Neu ist nur die GEFAHRENZONE: eine Karte, die von weitem als solche zu
 * erkennen ist.
 * ======================================================================== */

/* GEFAHRENZONE (.karte-gefahr) — Mockup 40, Karte „Konto löschen". Roter
 * Rand, roter Titel, sonst eine gewöhnliche Karte. Kein roter GRUND: Eine
 * rot geflutete Fläche zwingt jeden Text darin auf einen zweiten Kontrastwert
 * und macht das Formular darin schwerer lesbar — die Warnung soll den Rahmen
 * betreffen, nicht die Eingabe. */
.karte-gefahr{border-color:var(--rot)}
.karte-gefahr .karte-titel{color:var(--rot-tief)}


/* ---- Statuskacheln mit Ton (O9b, Mockup 41) ------------------------------
 * Eine Kachel, die einen Befund meldet, ist eingefärbt: Orange für „das will
 * angesehen werden", Rot für „das fehlt". Dieselben zwei Töne wie bei der
 * Plakette, dieselbe Bedeutung. Als Verweis behält sie ihre Farben und
 * bekommt beim Überfahren nur den Rahmen. */
.kennzahl-orange{background:var(--orange-hell);border-color:var(--orange)}
.kennzahl-rot{background:var(--rosa);border-color:var(--rot)}
.kennzahl-rot .kennzahl-wert{color:var(--rot-tief)}
a.kennzahl{display:block;text-decoration:none;color:inherit}
a.kennzahl:hover{border-color:var(--blau);text-decoration:none}


/* ---- Kopf einer langen Liste: Suche und Filter --------------------------- */
.listenkopf{display:flex;flex-direction:column;gap:var(--abstand-3);
  margin-bottom:var(--abstand-4)}
/* DAS SUCHFELD STEHT IN EIGENER ZEILE, IN JEDER BREITE (E-S8-08, Backlog
 * Nr. 73). Bis Web 15.4.0 rückten Suche und Filter ab 1024 px NEBENEINANDER
 * (Mockup 41 aus P3), das Suchfeld auf `flex:0 1 26rem`. Gemessen an
 * `admin_users.php` mit fünf Filtern: Bei 1440, 1280 und 1024 px fiel der
 * letzte Filter allein in eine zweite Zeile — ein Umbruch, der wie ein Unfall
 * aussah, weil die erste Zeile halb leer blieb. Genau das war die gemeldete
 * Beobachtung.
 *
 * Untereinander ist der Umbruch der Filterreihe Absicht: Sie beginnt links,
 * füllt die Breite und bricht am Ende. Das Suchfeld bekommt eine
 * Höchstbreite — über 36 rem wird ein Eingabefeld nicht besser lesbar,
 * sondern nur breiter.
 *
 * Es gilt für JEDE Liste mit Suche und Filtern, nicht für diese eine Seite. */
.listensuche{display:flex;gap:var(--abstand-2);align-items:center;
  max-width:var(--listensuche-breit)}

/* FILTERREIHE (.filterreihe) — Verweise, keine Knöpfe im Formular: Ein Filter
 * ändert die angezeigte Liste, und das ist eine Navigation. So trägt jeder
 * Filter eine eigene Adresse (teilbar, im Verlauf, mit der Zurück-Taste
 * erreichbar), und er funktioniert ohne Skript. Der aktive ist orange
 * hinterlegt — dieselbe Auszeichnung wie die aktive Kennzahl. */
.filterreihe{display:flex;flex-wrap:wrap;gap:var(--abstand-2)}
/* AUCH DIESER NAME IST NICHT FREI: `.filterknopf` gehoert seit O6 dem Knopf,
 * der auf der Suchseite die Filterschublade oeffnet — und der ist 48 px hoch,
 * weil er neben dem 48-px-Suchfeld steht (die einzige benannte Ausnahme von
 * der 44-px-Regel). Eine zweite Regel gleichen Namens weiter unten haette ihn
 * auf 44 px gesetzt. Gemeldet hat es der Bilderlauf, nicht der Verstand:
 * „15-suche · Filter 0 · 44 px (soll 48)", achtmal, in jeder Breite. */
.listenfilter{
  display:inline-flex;align-items:center;gap:var(--abstand-2);
  min-height:var(--knopf);padding:0 var(--abstand-3);
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius);
  background:var(--schnee);color:var(--dunkelblau);
  font-family:var(--schrift-kopf);font-weight:600;
  text-decoration:none;white-space:nowrap;
}
.listenfilter:hover{background:var(--rauch);text-decoration:none}
.listenfilter.aktiv{background:var(--orange-hell);border-color:var(--orange)}
/* Die Zahl ist eine eigene Fläche, damit sie sich vom Wort abhebt, ohne eine
 * zweite Schriftgröße zu brauchen.
 *
 * SIE HEISST NICHT `.filterzahl`. Diese Klasse ist seit O6 vergeben — die
 * Suche hängt sie als `filterzahl plakette plakette-blau` in den Kopf jeder
 * Filtergruppe (suche.php). Eine zweite Regel gleichen Namens weiter unten im
 * Stylesheet hätte deren Hintergrund und Schriftfarbe überschrieben, weil die
 * spätere Regel gleicher Spezifität gewinnt: Aus den blauen Zählern der
 * Suchseite wären graue geworden, und zwar auf einer Seite, die dieses Paket
 * gar nicht anfasst. */
.listenfilter-zahl{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:calc(var(--symbol) + var(--abstand-1));
  padding:0 var(--abstand-1);
  border-radius:var(--radius-klein);
  background:var(--rauch);color:var(--gedaempft);
  font-size:var(--groesse-1);
}
.listenfilter.aktiv .listenfilter-zahl{background:var(--orange);color:var(--knopf-primaer-schrift)}


/* ---- Kontentabelle ------------------------------------------------------- */
/* Name und Adresse stehen untereinander in EINER Zelle (Mockup 41): Zwei
 * Spalten dafür kosteten Breite und träfen doch nie beide zugleich zu — ein
 * Konto ohne Namen hat nur die Adresse. */
.konto-name{display:block;font-weight:600;color:var(--dunkelblau)}
.konto-mail{display:block;color:var(--gedaempft);font-size:var(--groesse-2)}
.tabelle-konten .wahl-spalte{width:var(--knopf);text-align:center}
.tabelle-konten .oeffnen-spalte{width:1%;text-align:right;white-space:nowrap}
.tabelle-konten th.sortable a{
  display:inline-flex;align-items:center;gap:var(--abstand-1);
  color:inherit;text-decoration:none;
}
.tabelle-konten th.sortable a:hover{color:var(--blau-tief);text-decoration:none}
.oeffnen{
  display:inline-flex;align-items:center;gap:var(--abstand-1);
  min-height:var(--knopf);color:var(--blau-tief);
  font-family:var(--schrift-kopf);font-weight:600;
}

/* Das Kästchen vor dem Text einer Zeile (mobile Fassung derselben Liste). */
.zeile-vorn{flex:0 0 auto;display:flex;align-items:center}


/* ---- Fuß einer langen Liste: Zählung und Seitenwechsel -------------------- */
.listenfuss{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:var(--abstand-3);
  margin-top:var(--abstand-4);padding-top:var(--abstand-3);
  border-top:var(--strich) solid var(--linie);
}
.listenzahl{color:var(--gedaempft);font-size:var(--groesse-2)}
.seitenwahl{display:flex;flex-wrap:wrap;gap:var(--abstand-1)}
/* Die Seitenknöpfe sind quadratisch und 44 px hoch wie jeder Knopf — sie
 * werden auf dem Handy mit dem Daumen getroffen (E-P3-22). */
.seitenknopf{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:var(--knopf);min-height:var(--knopf);padding:0 var(--abstand-2);
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius);
  background:var(--schnee);color:var(--dunkelblau);
  font-family:var(--schrift-kopf);font-weight:600;
  text-decoration:none;
}
.seitenknopf:hover{background:var(--rauch);text-decoration:none}
.seitenknopf.aktiv{background:var(--orange-hell);border-color:var(--orange)}
/* Der Pfeil am Rand bleibt STEHEN, wenn es nichts mehr gibt, statt zu
 * verschwinden: Ein Knopf, der sich beim Blättern in Luft auflöst, verschiebt
 * die übrigen unter dem Finger weg. */
.seitenknopf.aus{color:var(--sand);border-color:var(--linie);cursor:default}
.seitenknopf.aus:hover{background:var(--schnee)}
.seitenluecke{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:var(--knopf);min-height:var(--knopf);color:var(--gedaempft);
}

/* Die Zahl der Sammelleiste ist IMMER sichtbar (der Hinweis eines schmutzigen
 * Formulars erscheint erst ab 720 px). Sie ist die ganze Aussage der Leiste. */
.speichern-zahl{display:block;color:var(--asphalt);font-weight:600}


/* ===========================================================================
 * 28  RECHTSTEXTE                                       (P3/O10, E-P3-38, R32)
 *
 * Impressum und Datenschutzerklärung — die beiden öffentlichen Seiten und
 * ihr Editor. Erstaunlich wenig eigenes: Die Seiten sind Lesespalte
 * (`.rahmen-lesespalte`) plus eine Karte plus `.text`, der Editor ist das
 * Kartenraster (`.form-raster`, seit Web 19.3.0 — davor eine zweite,
 * gleichlautende Regel `.zweispalter`) mit zwei Karten und je einem
 * Textfeld. Was hier steht, sind
 * die drei Dinge, für die es im Bestand nichts gab.
 * ======================================================================== */

/* Monospace im Textfeld (Mockup 35). Das Token gibt es seit O1
 * (--schrift-fest), benutzt haben es bisher nur `code, kbd, pre` und
 * `.codeblock-wert` — ein <textarea> erbt von keinem der beiden.
 *
 * Die Klasse hängt an der HÜLLE, nicht am Feld: ui_feld() setzt $o['klasse']
 * an `.feld`. Ein Nachfahrenselektor kommt damit ohne jede Änderung am
 * Baustein aus. */
.feld-fest .feld-eingabe{font-family:var(--schrift-fest)}

/* Der Vorschaukasten (Mockup 35). GESTRICHELT, und das ist der ganze Zweck:
 * Er sagt „das hier ist nicht die Seite, sondern ein Blick darauf". Ein
 * durchgezogener Rahmen sähe aus wie eine zweite Karte. `dashed` kommt
 * sonst nirgends im Stylesheet vor — deshalb steht es hier und nicht als
 * Zusatz an `.karte`. */
.vorschau{
  border:var(--strich) dashed var(--linie-stark);
  border-radius:var(--radius);
  padding:var(--abstand-4);
  margin-top:var(--abstand-3);
}
.vorschau > h4{margin-bottom:var(--abstand-2)}
/* Der Fließtext darin ist `.text` — aber ohne dessen Lesebreite: Der Kasten
 * IST schon schmal, und eine zweite Begrenzung darin ließe ihn links kleben. */
.vorschau .text{max-width:none}

/* Die Fußzeile einer Editorkarte: Plakette und Pfad nebeneinander. */
.rechtstext-fuss{
  display:flex;align-items:center;gap:var(--abstand-3);
  margin-top:var(--abstand-3);flex-wrap:wrap;
}

/* ---- Logo-Vorschau der Installation (S8/AP3, Mockup 09) -------------------
 * Kachel links, Erklärung rechts. Die Kachel ist so hoch wie die Kopfleiste
 * (--logo-kachel = --kopf) und dunkelblau wie sie — das Logo soll dort zu
 * sehen sein, wo man es täglich sieht, und nicht auf einem Weiß, auf dem es
 * nirgends steht. Bei schmalem Raum bricht die Erklärung unter die Kachel. */
.logo-vorschau{
  display:flex;align-items:center;gap:var(--abstand-3);
  margin-bottom:var(--abstand-4);flex-wrap:wrap;
}
.logo-kachel{
  flex:0 0 auto;
  width:var(--logo-kachel);height:var(--logo-kachel);
  border-radius:var(--radius);
  background:var(--dunkelblau);
  display:flex;align-items:center;justify-content:center;
}
/* Die Erklärung nimmt den Rest der Zeile — ohne das bliebe sie bei kurzem
 * Text schmal neben der Kachel stehen und bräche mitten im Satz. */
.logo-vorschau > .feld-hinweis{flex:1 1 12rem;margin:0}

/* ---- Sprungliste und Kartenfilter (S9/AP5, M-S9-05 und M-S9-06) ----------
 *
 * Zwei Hilfsmittel für eine LANGE Liste in einer Karte, beide ab sechs
 * Einträgen (`SD_HILFE_AB`, stammdaten_ui.php): die Sprungliste führt zu
 * einem bestimmten Eintrag, der Filter blendet die übrigen aus. Sie stehen
 * nebeneinander in derselben Datei, weil sie dieselbe Frage beantworten —
 * „wie finde ich hier etwas?" — und weil die Wahl zwischen ihnen davon
 * abhängt, ob die Einträge ein Zeichen haben, an dem man sie erkennt.
 *
 * KEIN NEUES TOKEN. Alles kommt aus der Skala: --knopf für die Höhe (44 px
 * am Finger, 36 px am Zeiger ab 1024 px), --symbol-klein für das Artzeichen,
 * --radius-rund für die Pille, --groesse-2 für ihre Schrift. */

/* DIE PILLE IST EIN VERWEIS UND SIEHT AUS WIE EIN ZIEL, nicht wie ein Wert:
 * Schnee auf --linie-stark, nicht Blau. Der Koordinaten-Chip (.rmchip) macht
 * es umgekehrt, und das ist der Unterschied — er TRÄGT etwas, sie FÜHRT
 * irgendwohin. Voll rund, damit sie sich von der eckigen Plakette daneben
 * unterscheidet.
 *
 * DIE HÖHE IST --knopf, und der Bilderlauf misst sie: `.sprungziel` steht
 * seit S9/AP5 in seiner Auswahl (aufnehmen.mjs). Ohne das wäre die 44/36
 * hier eine Zusage ohne Prüfmittel — genau der Fall, der `.listenfilter`
 * vier Monate lang ungemessen gelassen hat. */
.sprungliste{display:flex;flex-wrap:wrap;gap:var(--abstand-1);
  margin:0 0 var(--abstand-3)}
.sprungziel{
  display:inline-flex;align-items:center;
  height:var(--knopf);padding:0 var(--abstand-3) 0 var(--abstand-2);
  border:var(--strich) solid var(--linie-stark);
  border-radius:var(--radius-rund);
  background:var(--schnee);color:var(--dunkelblau);
  font-family:var(--schrift-kopf);font-weight:600;font-size:var(--groesse-2);
  text-decoration:none;white-space:nowrap;
}
/* Ohne Artzeichen steht der Text sonst zu weit links an der Rundung. */
.sprungziel > .sprungziel-text:first-child{padding-left:var(--abstand-1)}
.sprungziel .symbol{
  width:var(--symbol-klein);height:var(--symbol-klein);
  margin-right:var(--abstand-1);color:var(--gedaempft);flex:0 0 auto;
}
.sprungziel:hover{background:var(--rauch);text-decoration:none}
/* `.aktiv` und nicht `.ziel` — ein Name für „hier stehst du", derselbe wie an
 * Kennzahl, Listenfilter, Leisteneintrag und Seitenknopf. */
.sprungziel.aktiv{background:var(--orange-hell);border-color:var(--orange)}
.sprungziel.aktiv .symbol{color:var(--orange-tief)}

/* DER FILTER HEISST `.kartenfilter` UND NICHT `.filterfeld`: `.filterfelder`
 * (Mehrzahl) ist seit P3 der Innenabstand einer aufgeklappten Filtergruppe
 * der Suchseite. Zwei Klassen, die sich um ein „r" unterscheiden und
 * Verschiedenes meinen, sind derselbe Fehler, den `.listenfilter-zahl` weiter
 * oben ausdrücklich umgangen hat.
 *
 * ER IST 44/36 HOCH UND NICHT 48. Die 48 (--suchfeld) gehören dem großen
 * Suchfeld, das die Haupthandlung SEINER Seite ist; ein Filter in einer von
 * sechs Karten ist das nicht. Hier gilt die Regel, nicht die Ausnahme.
 *
 * DIE LUPE HAT KEIN `top`. Der Behälter zentriert senkrecht
 * (`align-items:center`), und damit sitzt sie in BEIDEN Bedienhöhen mittig.
 * Das Mockup schreibt `top:12px`; das stimmt bei 44 px und sitzt bei 36 px
 * 4 px zu tief. Dieselbe Lösung wie bei `.suchfeld-lupe`. */
.kartenfilter{position:relative;display:flex;align-items:center;
  margin:0 0 var(--abstand-3)}
.kartenfilter input{
  width:100%;min-height:var(--knopf);
  padding-left:calc(var(--abstand-3) + var(--symbol) + var(--abstand-2));
  padding-right:calc(var(--abstand-2) + var(--knopf));
}
/* Das browsereigene Kreuz von `type="search"` abstellen: Es sitzt je nach
 * Browser woanders, und daneben stünde unseres. */
.kartenfilter input::-webkit-search-cancel-button{display:none}
.kartenfilter-lupe{
  position:absolute;left:var(--abstand-3);
  color:var(--gedaempft);pointer-events:none;
}
.kartenfilter-x{
  position:absolute;right:0;
  display:flex;align-items:center;justify-content:center;
  width:var(--knopf);height:var(--knopf);
  border:0;background:none;color:var(--gedaempft);cursor:pointer;
}
.kartenfilter-x:hover{color:var(--asphalt)}
/* Der Leerzustand ist ein gewöhnlicher Hinweis; er braucht nur den Abstand,
 * den die weggefilterten Zeilen hinterlassen. */
.kartenfilter-leer{margin:var(--abstand-3) 0 0}


/* ===========================================================================
 * 29  IMPORTVORSCHAU                      (Mockup-Runde 9c, M-MR-01, E-MR-09)
 *
 * Die Vorschau des CSV-Imports gruppiert ihre Zeilen nach Diensttagen. Der
 * Gruppenkopf ist eine Tabellenzeile ueber die volle Breite — und sah bis
 * Web 19.3.1 aus wie eine Datenzeile: Text in `<strong>`, sonst nichts.
 * `imp-daygroup` und `imp-warn` standen deshalb seit O11 als `[offen]` in
 * `ohne-regel.md`; Backlog Nr. 41 ist der Eintrag dazu.
 *
 * WAS DIE REGEL TUT. Sie macht aus der Datenzeile eine Ueberschrift: Flaeche
 * in Rauch, kraeftige Oberlinie, das Datum in Kopfschrift und Dunkelblau,
 * der Rest gedaempft und eine Stufe kleiner. Damit traegt der Kopf dieselbe
 * Sprache wie jede andere Zwischenueberschrift der Anwendung.
 *
 * WARUM `imp-warn` NICHT AUCH EINE REGEL BEKOMMT (F-MR-1, Variante A). Die
 * Warnung „abweichende Crew" ist ein Zustand, der Aufmerksamkeit will — und
 * dafuer gibt es den Baustein schon: `.plakette-orange` mit dem Symbol
 * `warnung`. Eine zweite Darstellung fuer dieselbe Aussage waere eine
 * Darstellung zu viel; die Klasse ist deshalb ersatzlos gestrichen und steht
 * mit Begruendung auf `streichliste.md`. Dieselbe Kopfzeile traegt die
 * Gruppe „Nicht zuordenbar", dort mit `.plakette-rot` (F-MR-3, E-MR-13).
 *
 * DIE ZEILE BRICHT UM — ABER ERST SEIT WEB 19.4.1, und der Umweg dorthin ist
 * der Kern dieses Abschnitts (Backlog Nr. 182, M-MR-05, F-MR-14 = Weg B).
 *
 * Web 19.4.0 hat `flex-wrap` gesetzt und geglaubt, damit sei es getan. Es war
 * es nicht: Die Zelle ist so breit wie die TABELLE, nicht wie das
 * Sichtfenster — gemessen 2653 px gegen 342 px am Handy. In einer 2653 px
 * breiten Zeile bricht nichts um, und alles hinter dem Datum stand ausserhalb
 * des Sichtfensters. Die Plakette „abweichende Crew" war damit in KEINER
 * Breite zu sehen, ohne waagerecht zu scrollen — eine Plakette, die
 * Aufmerksamkeit will und keine bekommt.
 *
 * DIE LOESUNG IST EINE CONTAINER-ABFRAGE, und sie braucht kein JavaScript.
 * `.imp-roll` (der Rollbereich der Vorschau) wird zum Groessencontainer;
 * `100cqi` ist damit die SICHTBARE Breite, nicht die der Tabelle. Der Inhalt
 * der Kopfzeile heftet sich mit `position:sticky; left:0` an den linken Rand
 * des Rollbereichs und bleibt stehen, waehrend die Datenzeilen darunter
 * waagerecht durchlaufen. Erst dadurch greift `flex-wrap` ueberhaupt.
 *
 *   WARUM NICHT `width:100%`: Das waere die Breite der ZELLE — 2653 px.
 *   WARUM NICHT EINE GEMESSENE ZAHL AUS JAVASCRIPT: Weil es sie nicht
 *     braucht. Beide Fassungen sind bei sechs Fensterbreiten (360 bis
 *     1920 px) auf den Pixel gleich gemessen worden; die CSS-Fassung kommt
 *     ohne `ResizeObserver` aus.
 *   WARUM NICHT AN `.tabelle-scroll`: Die Klasse traegt neun Stellen auf
 *     sechs Seiten, und `container-type` bringt `contain: layout
 *     inline-size` mit. Eine global gesetzte Eigenschaft fuer ein oertliches
 *     Problem waere falsch — deshalb die eigene Klasse `.imp-roll`, die
 *     `import.php` neben `tabelle-scroll` setzt.
 *
 * DIE FLAECHE BLEIBT DURCHGEHEND. Das Polster wandert von der Zelle in die
 * Kopfzeile; Rauch und Oberlinie bleiben an der Zelle und laufen damit ueber
 * die ganze Tabellenbreite. Das Band hoert also nicht auf halber Strecke auf,
 * nur sein Inhalt folgt dem Blick.
 * ======================================================================== */
.imp-roll{container-type:inline-size}
.imp-daygroup td{
  background:var(--rauch);
  border-top:var(--strich-stark) solid var(--linie);
  padding:0;
}
.imp-kopfzeile{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--abstand-2);
  position:sticky;left:0;
  width:100cqi;box-sizing:border-box;
  padding:var(--abstand-2) var(--abstand-3);
}
/* KOPFSCHRIFT, NICHT NUR FETT. Der Unterschied zwischen Ueberschrift und
 * Datenzeile ist in dieser Anwendung die Schriftfamilie, nicht das Gewicht —
 * `<strong>` allein hat genau deshalb nicht gereicht. */
.imp-tag{
  font-family:var(--schrift-kopf);font-weight:600;
  font-size:var(--groesse-3);color:var(--dunkelblau);
}
.imp-rest{color:var(--gedaempft);font-size:var(--groesse-2)}
/* DIE EINE ABWEICHUNG VOM BAUSTEIN, und sie ist noetig: `.plakette` steht auf
 * `white-space:nowrap`, weil eine Plakette sonst ueblicherweise ein einzelnes
 * Wort ist („freigegeben", „kein Ende"). Hier traegt sie den Konflikttext,
 * und der waechst mit der Zahl der abweichenden Rollen — „HEMS: Weber ->
 * Muster, P1: Berger -> Beispiel". Bei 360 px waere das eine Plakette, die
 * breiter ist als das Geraet. Sie darf deshalb umbrechen; alles andere am
 * Baustein bleibt. */
.imp-kopfzeile .plakette{white-space:normal}


/* ===========================================================================
 * 30  DRITTE KARTENGROESSE                 (Mockup-Runde 9c, M-MR-03, AP3)
 *
 * Die Karte der Tagesuebersicht hatte zwei Zustaende: ihre Hoehe nach Breite
 * (160 / 220 / 300 px) und Vollbild. Dazwischen lag nichts — wer mehr von der
 * Spur sehen wollte, musste die Seite verlassen und wiederkommen. Backlog
 * Nr. 45 fuellt die Luecke mit EINEM Zustand und EINEM Knopf.
 *
 * ZWEI WIRKUNGEN JE BREITE (E-MR-16, F-MR-9 geaendert). Bis 1599 px wird die
 * Karte HOEHER — `--karte-gross`, also min(60vh, 520px). Ab 1600 px steht sie
 * ohnehin in einer eigenen Spalte und ist dort schon hoch; dort wird sie
 * stattdessen BREIT: Das Raster faellt auf eine Spalte, und die Karte rueckt
 * zwischen Diensttag-Daten und Einsatzliste — dorthin, wo sie unter 1600 px
 * immer steht. Die DOM-Reihenfolge ist bereits Daten, Karte, Liste; es genuegt
 * deshalb, das Raster abzuschalten.
 *
 * WARUM `:has()` UND KEINE ZWEITE KLASSE AM RASTER. Der Zustand gehoert der
 * Karte, nicht dem Raster — `blatt.js` und `map_fullscreen.js` setzen ihn
 * dort, und eine zweite Klasse an einem Vorfahren waere eine zweite Stelle,
 * die auseinanderlaufen kann. `:has()` steht seit P3 an sechs Stellen im
 * Stylesheet; die Browsergeneration ist damit ohnehin vorausgesetzt.
 * ======================================================================== */
.geo-gross{height:var(--karte-gross)}

/* DER KNOPF TRAEGT BEIDE ZEICHEN, das Stylesheet zeigt je Breite eins
 * (E-MR-19). Ein Knopf, der sein Symbol per JavaScript tauscht, haette die
 * Schwelle 1600 ein zweites Mal im Code — sie steht in dieser Anwendung
 * ausschliesslich hier. */
.karte-groesse .symbol-breit{display:none}

@media (min-width:1600px){
  /* Vorrang vor `.geo-spalte .geo{height:100%}` aus Abschnitt 20 — gleiche
   * Spezifitaet, spaeter in der Datei. */
  .geo-spalte .geo-gross{height:var(--karte-gross)}
  .tag-raster:has(.geo-gross){display:block}
  .karte-groesse .symbol-hoch{display:none}
  .karte-groesse .symbol-breit{display:inline-block}
}

/* ===========================================================================
 * 26. DRUCK — und die eine Seite, die dafür gemacht ist (S10/AP3, E-S10-10)
 *
 * DAS IST DER ERSTE `@media print`-BLOCK DIESER ANWENDUNG. Bis Web 20.0.0 gab
 * es keinen: Nachgezählt am 14.09.2026 ergab `grep -c '@media print'` genau 0.
 * Es gab bis dahin auch nichts zu drucken — eine Einsatzliste sieht man am
 * Bildschirm an, und ein Ausdruck davon wäre eine zweite, ungepflegte Fassung
 * der Daten.
 *
 * DAS SCHLÜSSELBLATT IST DIE AUSNAHME, und es ist die einzige, die es geben
 * soll: Es ist eine Seite, deren ZWECK der Ausdruck ist. `config.php` ist seit
 * S10 Schlüsselträger der ganzen Installation, und ein zweiter Ort für ihre
 * beiden Geheimnisse muss das überleben, was die Datei nicht überlebt. Papier
 * tut das; eine heruntergeladene Datei liegt im selben Unglück.
 *
 * DREI REGELN, MEHR NICHT. Was hier steht, ist absichtlich knapp — ein
 * Druck-Stylesheet, das jede Seite umgestaltet, ist eine zweite Oberfläche mit
 * eigenen Fehlern. Gestaltet wird die eine Seite, die gedruckt werden soll.
 * ======================================================================== */

/* Was nur am Bildschirm Sinn ergibt. Zwei Knöpfe auf einem Ausdruck sind zwei
 * Kästen, die nichts tun. */
@media print {
  .nur-bildschirm { display: none !important; }

  /* KEINE FLÄCHE AUF PAPIER. Die Flächenfarbe der Anwendung (`--schnee`,
   * `--rauch`) druckt als grauer Kasten und kostet Tinte; auf Papier ist der
   * Kontrast des Druckers der einzige, der zählt.
   *
   * `none` UND NICHT WEISS. Ein weisser Hexwert wäre ein Farbwert in einer
   * Regel — die Skala ist geschlossen, und einen Token für Weiss gibt es
   * nicht (`--schnee` ist #FFFCFA, kein Weiss). `background: none` setzt die
   * Fläche auf durchsichtig zurück; was durchscheint, ist das Papier. So
   * braucht diese Regel überhaupt keine Farbe. */
  .blatt-seite,
  .blatt-seite .rahmen,
  .blatt-seite .inhalt { background: none; }

  /* KEIN SEITENUMBRUCH MITTEN IM WERT. Ein Schlüssel, der über zwei Blätter
   * läuft, ist beim Abtippen die eine Stelle, an der eine Gruppe verlorengeht
   * — und ein halb abgetippter Schlüssel sieht aus wie ein falscher. */
  .blatt-wert { break-inside: avoid; page-break-inside: avoid; }
  h2 { break-after: avoid; page-break-after: avoid; }
}

/* Der Wert auf dem Blatt: 64 Hexzeichen in sechzehn Vierergruppen.
 *
 * ER BENUTZT `.codeblock-wert` als Grundlage und ändert genau zwei Dinge: Er
 * darf umbrechen (sechzehn Gruppen passen in keine Zeile von 210 mm), und er
 * bricht NUR ZWISCHEN den Gruppen um — `word-break:break-all` zerschnitte eine
 * Gruppe mitten durch, und dann zählt beim Abtippen niemand mehr nach. */
.blatt-wert {
  white-space: normal;
  word-break: keep-all;
  overflow-wrap: normal;
  line-height: 1.9;
}
