/*
 * ======================================================================
 * DIE FARBWELT DER PLATTFORM - HIER UND SONST NIRGENDS
 * ======================================================================
 * Diese Werte gelten fuer Portal, Alarmmonitor und beide Apps. Die
 * Kopien tragen dieselben Namen und verweisen hierher:
 *
 *   App-Android/.../ui/Theme.kt          AlarmPunktFarben
 *   App/AlarmPunkt/Helpers/Farben.swift  Farben
 *   C# - Alarmmonitor/.../MonitorColors.cs und die XAML-Vorlagen
 *
 * Wer hier etwas aendert, aendert es dort mit. Vier Oberflaechen in
 * zwei Grautoenen sieht jeder sofort und kann meist nicht sagen, woran
 * es liegt - genau das ist das Unangenehme daran.
 *
 * ======================================================================
 * DER STAND SEIT DEM 11.09.2026 (Betreiber)
 * ======================================================================
 * Drei Dinge auf Anordnung nachgezogen:
 *
 * 1. DAS AKZENTBLAU IST HELLER. #0054B4 stand auf dem Grund #464646 bei
 *    1,9:1 - unterhalb dessen, was die WCAG fuer Bedienelemente
 *    verlangt (3:1). Knoepfe, aktive Reiter und Verweise waren auf dem
 *    Telefon im Sonnenlicht kaum vom Hintergrund zu trennen. #2F6FD0
 *    auf dem neuen Grund sind 3,6:1.
 *
 * 2. DIE GRAUTOENE HABEN ABSTAND UND EINEN HAUCH BLAU. Vorher lagen
 *    vier voellig neutrale Stufen dicht beieinander (70/52/40/30); eine
 *    Karte war vom Grund kaum zu unterscheiden. Jetzt tragen sie einen
 *    leichten Blaustich, der den Akzent aufnimmt, und stehen weiter
 *    auseinander.
 *
 * 3. ROT, GRUEN UND GELB SIND KRAEFTIGER. Sie sind die einzigen Farben,
 *    die etwas BEDEUTEN - Status, Mangel, Ablauf. Auf einem Telefon im
 *    Sonnenlicht trennten sie sich schlecht voneinander.
 *
 * Was NICHT angefasst wurde: --text, --text-soft, --text-muted und
 * --accent-text. Die Schrift stand nie zur Debatte, und jede Aenderung
 * daran haette den Kontrast zu allem anderen mitverschoben.
 */
:root {

    --bg-main: rgb(58, 61, 66);
    --bg-card: rgb(33, 36, 41);
    --bg-card-2: rgb(23, 25, 29);
    --bg-elevated: rgb(44, 47, 52);
    --bg-overlay: rgba(0, 0, 0, 0.6);

    --accent: #2F6FD0;
    --accent-hover: #5A93E8;
    --accent-soft: rgba(47, 111, 208, 0.20);
    /* Knopf unter weisser Schrift beim Ueberfahren: --accent-hover hatte
       dort 3,1:1. Dunkler statt heller, wie --danger-fill-hover. */
    --accent-fill-hover: #285FB3; /* 6,2:1 */
    --accent-text: #9cc7ff;

    --danger: #DC3F3F;
    --danger-hover: #F05555;
    /* Flaeche unter weisser Schrift (Knopf, Zaehler, Marke): --danger hat
       dort 4,35:1, --danger-hover 3,4:1 - unter WCAG AA. Die Schriftfarbe
       --danger bleibt, auf dunklem Grund ist sie hell genug. */
    --danger-fill: #D13838;       /* 4,8:1 */
    --danger-fill-hover: #B93030; /* 6,0:1 */
    --success: #2fd96e;
    --warning: #ffad1f;

    --text: #ffffff;
    --text-soft: #d1d5db;
    --text-muted: #9ca3af;

    --border: #4A4E55;
    --border-soft: rgba(255, 255, 255, 0.08);

    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;
    --space-9: 56px;

    --gutter: 16px;

    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 20px;
    --radius-pill: 999px;

    --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.15);
    --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.35);
    --shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.5);

    --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
    --text-xs: 12px;
    --text-sm: 13px;
    --text-base: 15px;
    --text-md: 16px;
    --text-lg: clamp(17px, 1.4vw, 19px);
    --text-h3: clamp(17px, 2.2vw, 20px);
    --text-h2: clamp(20px, 3vw, 26px);
    --text-h1: clamp(22px, 4vw, 30px);

    --tap: 44px;
    --tap-lg: 48px;

    --header-height: 60px;
    --bottom-nav-height: 60px;

    --safe-top: env(safe-area-inset-top, 0px);
    --safe-right: env(safe-area-inset-right, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --safe-left: env(safe-area-inset-left, 0px);

    --z-sticky: 100;
    --z-header: 1000;
    --z-dropdown: 1200;
    --z-drawer: 1400;
    --z-modal: 1600;

    --transition: 0.18s ease;
}

@media (min-width: 600px) {
    :root {
        --gutter: 24px;
    }
}

@media (min-width: 1024px) {
    :root {
        --header-height: 68px;
    }
}

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

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {

    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

body {
    margin: 0;
    min-height: 100vh;
    background: var(--bg-main);
    color: var(--text);
    font-family: var(--font-body);
    font-size: var(--text-md);
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
    overflow-wrap: break-word;
}

body.no-scroll {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
    overflow: hidden;
}

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

img {
    display: block;
}

a {
    color: var(--accent-text);
}

/* Die Quellenangabe der Karten steht im Fliesstext - ein Link muss dort
   auch ohne Farbe erkennbar sein (WCAG 1.4.1, P4-17). */
/* Mit .leaflet-container davor: leaflet.css kommt spaeter und setzt
   "none" mit gleicher Spezifitaet. */
.leaflet-container .leaflet-control-attribution a {
    text-decoration: underline;
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--accent-text);
    outline-offset: 2px;
}

p,
li,
td,
th,
dd,
dt {
    hyphens: auto;
}

hr {
    border: none;
    border-top: 1px solid var(--border);
    margin: var(--space-5) 0;
}

pre,
code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

pre {
    white-space: pre-wrap;
    word-break: break-word;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

:target {
    scroll-margin-top: calc(var(--header-height) + var(--space-4));
}

/*
 * ======================================================================
 * hidden HEISST VERSTECKT - AUCH GEGEN EINE KLASSE
 * ======================================================================
 * Gemeldet vom Betreiber am 07.09.2026: In `admin/baum.php` stand oben
 * ein "Abbrechen", das nichts abbricht.
 *
 * Der Grund war nicht der Knopf, sondern diese Zeile hier, die fehlte.
 * Das Markup war richtig:
 *
 *     <div id="verschiebeleiste" class="baum-hinweisleiste" hidden>
 *
 * `[hidden]` bringt der Browser mit `display: none` mit. Aber
 * `.baum-hinweisleiste { display: flex }` hat dieselbe Gewichtung (eine
 * Klasse gegen ein Attribut) und steht spaeter - also gewinnt sie. Die
 * Leiste war immer da.
 *
 * Nachgemessen waren es ZWANZIG solcher Stellen: Ergebniskaesten,
 * Formularfelder, Hinweisleisten. Jede davon zeigte etwas, das niemand
 * sehen sollte, und der naechste `display: flex` an einer neuen Klasse
 * haette die einundzwanzigste erzeugt.
 *
 * Deshalb hier und mit `!important`: Es gibt keinen Fall, in dem ein
 * Element mit `hidden` sichtbar sein soll. Wer eines zeigen will,
 * entfernt das Attribut (`el.hidden = false`) - so macht es der Code an
 * jeder Stelle bereits.
 */
[hidden] {
    display: none !important;
}

h1,
h2,
h3,
h4,
h5,
h6 {
    margin: 0 0 var(--space-3);
    color: var(--text);
    line-height: 1.25;
    text-wrap: balance;
}

h1,
.h1 {
    font-size: var(--text-h1);
    font-weight: 700;
}

h2,
.h2 {
    font-size: var(--text-h2);
    font-weight: 700;
}

h3,
.h3 {
    font-size: var(--text-h3);
    font-weight: 600;
}

h4 {
    font-size: var(--text-lg);
    font-weight: 600;
}

.card > h1:first-child,
.card > h2:first-child,
.card > h3:first-child {
    margin-top: 0;
}

p {
    margin: 0 0 var(--space-3);
}

p:last-child {
    margin-bottom: 0;
}

small {
    font-size: var(--text-sm);
}

strong,
b {
    font-weight: 600;
}

ul,
ol {
    margin: 0 0 var(--space-3);
    padding-left: 20px;
}

ul:last-child,
ol:last-child {
    margin-bottom: 0;
}

li {
    margin-bottom: var(--space-1);
}

.text-soft {
    color: var(--text-soft);
}

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

.text-center {
    text-align: center;
}

.text-sm {
    font-size: var(--text-sm);
}

.nowrap {
    white-space: nowrap;
}

.truncate {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/*
 * Das unsichtbare Feld der oeffentlichen Formulare (formularFalleFelder()).
 * Nicht display:none - manche Programme lassen solche Felder aus.
 */
.formularfalle {
    position: absolute;
    left: -10000px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

@media (min-width: 961px) {
    .only-mobile {
        display: none !important;
    }
}

@media (max-width: 960px) {
    .only-desktop {
        display: none !important;
    }
}

.scroll-x {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* -------------------------------------------------------------------
   Symbole

   Ein Symbol nimmt die Schriftgroesse und die Farbe seiner Umgebung an.
   Dadurch passt es in eine Zeile, ohne dass man es je Stelle nachstellen
   muss - und in beiden Farbwelten stimmt der Kontrast von selbst.
   ------------------------------------------------------------------- */

.icon {
    width: 1.15em;
    height: 1.15em;
    flex: none;
    vertical-align: -0.16em;
}

/* In Ueberschriften etwas zurueckgenommen: das Wort traegt, nicht das
   Bild daneben. */
h1 .icon,
h2 .icon,
h3 .icon {
    opacity: .72;
    margin-right: .35em;
}

/*
 * Lange Listen bekommen einen eigenen Scrollbereich. (Betreiber,
 * 28.09.2026: "bei allen langen Listen mit Namen ... in einen eigenen
 * Scroller so wie bei Alarmieren, da sonst die Seiten sehr lang sind")
 *
 * .scroll-liste       - Auswahl- und Namenslisten innerhalb einer Seite,
 *                       gleiche Hoehe wie die Personenliste beim
 *                       Alarmieren (.alarm-personen, 320 px).
 * .scroll-liste-gross - die Hauptliste einer Seite (Benutzer, Mitglieder,
 *                       Einladungen, Rueckmeldungen) - hoeher, damit mehr
 *                       als eine Handvoll Zeilen zu sehen ist.
 *
 * Kurze Listen sehen aus wie vorher; die Leiste erscheint erst, wenn die
 * Liste die Hoehe uebersteigt. Fuer Haken-Listen in Formularen gibt es
 * weiter .checkbox-list (mit Rahmen, components/forms.css).
 */
.scroll-liste,
.scroll-liste-gross {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

.scroll-liste {
    max-height: 320px;
}

.scroll-liste-gross {
    max-height: min(65vh, 44rem);
    max-height: min(65dvh, 44rem);
}

/* Ist die Liste eine Flex-Spalte (.personliste, .maengel-personen), wuerden
   die Zeilen sonst auf die begrenzte Hoehe zusammengedrueckt. */
.scroll-liste > *,
.scroll-liste-gross > * {
    flex-shrink: 0;
}

/* Tabellen im Scrollbereich: Kopfzeile bleibt stehen. */
.scroll-liste thead th,
.scroll-liste-gross thead th {
    position: sticky;
    top: 0;
    z-index: 1;
}

.wrapper {
    width: 100%;
    max-width: 1400px;
    margin: 0 auto;
    padding: var(--gutter);
    padding-left: max(var(--gutter), var(--safe-left));
    padding-right: max(var(--gutter), var(--safe-right));
}

/*
 * Der breite Rahmen (G7, 04.10.2026, Betreiber) - fuer Seiten mit Listen
 * und Tabellen ueber die ganze Breite: Struktur, Einsatzkatalog,
 * Mängelmelder, Dokumente, Galerie. Bis dahin stand er nur in
 * pages/struktur.css und galt damit nur dort.
 */
.wrapper.wrapper-weit {
    max-width: 1800px;
}

body.has-bottom-nav .wrapper {
    padding-bottom: calc(var(--gutter) + var(--bottom-nav-height) + var(--safe-bottom));
}

.section {
    margin-top: var(--space-6);
}

.headerline,
.topbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
    flex-wrap: wrap;
}

.headerline > h1,
.headerline > h2,
.topbar > h1,
.topbar > h2 {
    margin-bottom: 0;
    min-width: 0;
}

.topbar-left,
.topbar-right {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}

.topbar a {
    color: var(--text);
    text-decoration: none;
}

.topbar a:hover {
    color: var(--accent-text);
}

.filters,
.actions,
.rowactions,
.ticket-actions {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
    align-items: center;
}

.ticket-actions {
    margin-top: var(--space-5);
}

.kv {
    display: grid;
    grid-template-columns: minmax(140px, 200px) 1fr;
    gap: var(--space-3);
    align-items: center;
}

.kv label {
    font-size: var(--text-sm);
    color: var(--text-soft);
}

/*
 * Erklaerung unter einem Eingabefeld - fuer Felder, bei denen die
 * Schreibweise zaehlt und ein falscher Wert stillschweigend ins Leere
 * laeuft (etwa die Subgruppe, die exakt verglichen wird).
 *
 * Steht in der zweiten Spalte, also buendig unter dem Feld und nicht
 * unter der Beschriftung.
 */
.kv .kv-hint {
    grid-column: 2;
    margin: calc(var(--space-2) * -1) 0 0;
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.kv .kv-hint code {
    padding: 0 4px;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.08);
    font-size: var(--text-xs);
}

/*
 * Die Kachelreihen des Dashboards.
 *
 * Die Spaltenzahl setzt index.php als --dash-spalten, weil nur die
 * Seite weiss, wie viele Kacheln es diesmal gibt (Bereiche und
 * Fahrzeuge sind nicht bei jedem da). Ziel sind zwei gleich lange
 * Reihen statt einer vollen und einer angebrochenen.
 *
 * minmax(0, 1fr) und nicht 1fr: Sonst waechst eine Spalte an ihrem
 * laengsten Wort auf, und lange Gruppennamen schieben die Kachel
 * ueber den Rand.
 */
.dashboard-grid {
    display: grid;
    grid-template-columns: repeat(var(--dash-spalten, 3), minmax(0, 1fr));
    gap: var(--space-5);
}

/* Schmaler Schirm: hoechstens zwei, damit eine Kachel lesbar bleibt. */
@media (max-width: 1100px) {
    .dashboard-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 960px) {

    .headerline,
    .topbar {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-3);
    }

    .filters,
    .actions,
    .rowactions {
        width: 100%;
    }

    .filters > *,
    .actions > .btn,
    .actions > button,
    .rowactions > .btn,
    .rowactions > button {
        flex: 1 1 180px;
    }

    .kv {
        grid-template-columns: 1fr;
        gap: var(--space-1);
    }

    /* Einspaltig gibt es keine zweite Spalte mehr, in die der Hinweis
       ruecken koennte. */
    .kv .kv-hint {
        grid-column: 1;
        margin-top: 0;
    }

    .kv label {
        margin-top: var(--space-2);
    }

    .kv > label:first-child {
        margin-top: 0;
    }
}

@media (max-width: 600px) {

    .section {
        margin-top: var(--space-5);
    }

    .dashboard-grid {
        /* minmax(0, …) und nicht 1fr - sonst zieht ein langer
           Gruppenname die Spalte auf und die Seite waechst nach
           rechts. Dieselbe Falle wie im Chat. */
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-4);
    }
}

/*
 * Eine Filterzeile: Auswahl- und Suchfelder nebeneinander, umbrechend erst,
 * wenn der Platz fehlt (admin/benutzer.php, 23.09.2026). Ohne das erben die
 * Felder width: 100% und stehen jedes in einer eigenen Zeile.
 */
.filters-zeile > select,
.filters-zeile > input,
.filters-zeile > .knotenwahl {
    flex: 1 1 12rem;
    width: auto;
    min-width: 0;
}

/* Die Einheitenauswahl bekommt den meisten Platz - lange Namen mit Linien
   davor (Betreiber, 23.09.2026: "Combobox viel breiter"). */
.filters-zeile > .knotenwahl {
    flex: 3 1 24rem;
}

/*
 * Seiten in Fensterhoehe (P6/P7, 04.10.2026) - wie der Chat.
 *
 * Karte und AED hatten feste Hoehen (70dvh) mitten in einer Seite, die
 * selbst rollte: Wer auf der Karte scrollte (zoomen), rollte am Rand die
 * Seite mit. Jetzt hat die Seite genau die Fensterhoehe; Kopf, Leisten und
 * Hinweise sind so hoch wie ihr Inhalt, und den Rest bekommt das Element
 * mit .vollhoehe-rest. Gerollt wird nur noch IN Listen.
 *
 * Seite:  pageStart(['bodyClass' => 'seite-vollhoehe']), pageEnd(['footer' => false])
 * Rahmen: <div class="wrapper vollhoehe"> ... <div class="vollhoehe-rest">
 *
 * Unter 960px nicht: Dort stehen Karte und Liste untereinander, und die
 * Seite darf wieder rollen (die untere Leiste liegt fest darueber).
 */
@media (min-width: 961px) {
    body.seite-vollhoehe {
        display: flex;
        flex-direction: column;
        height: 100vh;
        height: 100dvh;
        min-height: 0;
        overflow: hidden;
    }

    body.seite-vollhoehe > * {
        flex: 0 0 auto;
    }

    /* Ab 961px ist die untere Leiste ausgeblendet; ihr Platz im
       padding-bottom des Wrappers stuende sonst als leerer Streifen unten. */
    body.seite-vollhoehe > .wrapper.vollhoehe {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
        padding-bottom: var(--gutter);
    }

    body.seite-vollhoehe .wrapper.vollhoehe > * {
        flex: 0 0 auto;
    }

    body.seite-vollhoehe .wrapper.vollhoehe > .vollhoehe-rest {
        flex: 1 1 auto;
        min-height: 0;
    }
}

.site-header {
    position: sticky;
    top: 0;
    z-index: var(--z-header);
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    padding-top: var(--safe-top);
}

/*
 * Die Leiste läuft über die ganze Breite, damit das Logo ganz links
 * anliegt - deshalb kein max-width und links keine Polsterung.
 */
.site-header-inner {
    min-height: var(--header-height);
    padding: var(--space-2) var(--gutter);
    padding-left: var(--safe-left);
    padding-right: max(var(--gutter), var(--safe-right));

    display: flex;
    align-items: center;
    gap: var(--space-5);
}

.brand {
    display: flex;
    align-items: center;
    text-decoration: none;
    flex-shrink: 0;
    min-width: 0;
}

.brand-logo {
    display: block;
    height: 30px;
    width: auto;
    flex-shrink: 0;
}

/*
 * Die Rubriken bleiben in EINER Zeile; Platz gibt der Name oben rechts ab
 * (.header-actions, mit „…“). Umgebrochen rutschte die letzte Rubrik unter
 * die anderen - bei 1024 px schon mit sechs Punkten, und eine zweite Zeile
 * im Kopf sieht nach einem Fehler aus.
 */
.nav-desktop {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    flex-wrap: wrap;
    flex-shrink: 0;
    min-width: 0;
}

.nav-desktop > a,
.nav-dropdown-toggle {
    color: var(--text-soft);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--transition);
}

.nav-desktop > a:hover,
.nav-desktop > a[aria-current="page"] {
    color: var(--text);
}

.header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-left: auto;
    flex-shrink: 1;
    min-width: 0;
}

.user-menu,
.user-menu-toggle {
    min-width: 0;
}

.nav-dropdown,
.user-menu {
    position: relative;
}

.nav-dropdown-toggle,
.user-menu-toggle {
    width: auto;
    background: none;
    border: none;
    padding: var(--space-2) 0;
    font-size: inherit;
    font-family: inherit;
    color: var(--text-soft);
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    cursor: pointer;
}

.user-menu-toggle {
    font-size: var(--text-sm);
    max-width: min(260px, 100%);
}

.user-menu-toggle > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nav-dropdown-toggle:hover,
.user-menu-toggle:hover,
.nav-dropdown.open .nav-dropdown-toggle,
.user-menu.open .user-menu-toggle {
    color: var(--text);
}

.caret {
    font-size: 10px;
    transition: transform var(--transition);
}

.nav-dropdown.open .caret,
.user-menu.open .caret {
    transform: rotate(180deg);
}

.nav-dropdown-menu {
    display: none;
    position: absolute;
    top: calc(100% + var(--space-3));
    left: 0;
    min-width: 220px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-2);
    box-shadow: var(--shadow-md);
    z-index: var(--z-dropdown);
}

.user-menu .nav-dropdown-menu {
    left: auto;
    right: 0;
}

.nav-dropdown.open .nav-dropdown-menu,
.user-menu.open .nav-dropdown-menu {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.nav-dropdown-menu a {
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--text-soft);
    text-decoration: none;
    white-space: nowrap;
}

.nav-dropdown-menu a:hover,
.nav-dropdown-menu a[aria-current="page"] {
    background: var(--bg-card-2);
    color: var(--text);
}

/*
 * "Konto wechseln" im Menue oben rechts (includes/header.php): eine
 * Ueberschrift, darunter je verknuepftem Konto Kreis und Name, mit
 * Linien davor und danach abgesetzt.
 *
 * Die Eintraege sind <button> und keine <a>: Hier wird die Anmeldung
 * gewechselt, und ein Link darauf waere vorausladbar und von aussen
 * unterschiebbar. Aussehen sollen sie trotzdem wie die Links daneben.
 */
.nav-dropdown-gruppe {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: var(--space-1) 0;
    padding: var(--space-2) 0;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

.nav-dropdown-titel {
    margin: 0;
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
}

.nav-dropdown-menu .konto-wechseln {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    padding: var(--space-2) var(--space-3);
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    font: inherit;
    color: var(--text-soft);
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}

.nav-dropdown-menu .konto-wechseln:hover,
.nav-dropdown-menu .konto-wechseln:focus-visible {
    background: var(--bg-card-2);
    color: var(--text);
}

.nav-dropdown-menu .konto-wechseln:disabled {
    opacity: .6;
    cursor: progress;
}

.nav-dropdown-menu .konto-wechseln .personkreis {
    width: 24px;
    height: 24px;
    font-size: 10px;
}

.nav-toggle {
    display: none;
    width: var(--tap);
    height: var(--tap);
    padding: 0;
    align-items: center;
    justify-content: center;
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text);
    flex-shrink: 0;
    cursor: pointer;
}

.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
    display: block;
    width: 18px;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
    transition: transform var(--transition), opacity var(--transition);
}

.nav-toggle-bars {
    position: relative;
}

.nav-toggle-bars::before,
.nav-toggle-bars::after {
    content: "";
    position: absolute;
    left: 0;
}

.nav-toggle-bars::before {
    top: -6px;
}

.nav-toggle-bars::after {
    top: 6px;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bars {
    background: transparent;
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bars::before {
    top: 0;
    transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle-bars::after {
    top: 0;
    transform: rotate(-45deg);
}

.nav-scrim {
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-drawer) - 1);
    background: var(--bg-overlay);
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--transition), visibility var(--transition);
}

.nav-scrim.open {
    opacity: 1;
    visibility: visible;
}

.nav-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-drawer);
    width: min(86vw, 340px);
    background: var(--bg-card);
    border-left: 1px solid var(--border);
    box-shadow: var(--shadow-lg);

    display: flex;
    flex-direction: column;

    padding-top: var(--safe-top);
    padding-right: var(--safe-right);
    padding-bottom: var(--safe-bottom);

    transform: translateX(100%);
    visibility: hidden;
    transition: transform 0.22s ease, visibility 0.22s ease;
    overscroll-behavior: contain;
}

.nav-drawer.open {
    transform: translateX(0);
    visibility: visible;
}

.nav-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-height: var(--header-height);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border);
}

.nav-drawer-user {
    min-width: 0;
}

.nav-drawer-user strong {
    display: block;
    font-size: var(--text-base);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nav-drawer-user span {
    display: block;
    font-size: var(--text-sm);
    color: var(--text-soft);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.nav-drawer-close {
    width: var(--tap);
    height: var(--tap);
    flex-shrink: 0;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 26px;
    line-height: 1;
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text-soft);
    cursor: pointer;
}

.nav-drawer-close:hover {
    color: var(--text);
}

.nav-drawer-body {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding: var(--space-3) var(--space-3) var(--space-5);
}

.nav-group-label {
    margin: var(--space-4) var(--space-3) var(--space-1);
    font-size: var(--text-xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.nav-group-label:first-child {
    margin-top: 0;
}

.nav-link {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: var(--tap-lg);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    color: var(--text-soft);
    text-decoration: none;
    font-size: var(--text-md);
}

.nav-link:active {
    background: var(--bg-card-2);
}

/* „Konto wechseln" steht als Knopf in derselben Liste wie die Links
   (header.php) - ohne die Vorgaben des Browsers für Knöpfe. */
button.nav-link {
    width: 100%;
    background: none;
    border: 0;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
}

.nav-link[aria-current="page"] {
    background: var(--accent-soft);
    color: var(--text);
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--accent);
}

.nav-drawer-foot {
    border-top: 1px solid var(--border);
    padding: var(--space-3) var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.nav-drawer-foot .btn {
    width: 100%;
}

.bottom-nav {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--z-header);
    background: var(--bg-card);
    border-top: 1px solid var(--border);
    padding-bottom: var(--safe-bottom);
    box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.25);
}

.bottom-nav-inner {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    align-items: stretch;
    min-height: var(--bottom-nav-height);
}

.bottom-nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: var(--space-1) var(--space-1);
    color: var(--text-muted);
    text-decoration: none;
    font-size: 11px;
    font-weight: 600;
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
}

.bottom-nav-item svg {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
}

.bottom-nav-item[aria-current="page"] {
    color: var(--accent-text);
}

.bottom-nav-item:active {
    background: var(--bg-card-2);
}

.bottom-nav-badge {
    position: absolute;
    transform: translate(14px, -12px);
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius-pill);
    background: var(--danger-fill);
    color: #fff;
    font-size: 10px;
    line-height: 18px;
    text-align: center;
}

@media (max-width: 960px) {

    .site-header-inner {
        gap: var(--space-3);
    }

    .nav-toggle {
        display: flex;
    }

    .bottom-nav {
        display: block;
    }
}

@media (max-width: 380px) {

    /* Das Langlogo ist breit - auf schmalen Geräten etwas kleiner. */
    .brand-logo {
        height: 24px;
    }
}

/* -------------------------------------------------------------------
   Rubriken statt Aufklapplisten

   Die Leiste trägt nur noch wenige Punkte. Der aktive bekommt einen
   Balken darunter - bei einer flachen Leiste ohne Trennung ist sonst
   nicht zu sehen, wo man gerade steht.
   ------------------------------------------------------------------- */

.nav-desktop > a {
    position: relative;
    padding: var(--space-2) 0;
    font-weight: 500;
}

.nav-desktop > a[aria-current="page"]::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 2px;
    border-radius: 2px;
    background: var(--accent-text, var(--accent));
}

/* Im Menü auf dem Telefon führt auch die Überschrift zur Rubrik. */
.nav-group-link {
    display: block;
    text-decoration: none;
    transition: color var(--transition);
}

.nav-group-link:hover,
.nav-group-link:focus-visible {
    color: var(--text);
}

/* Symbol im Menü: feste Spur links, damit die Beschriftungen
   untereinander auf einer Linie stehen. */
.nav-link .icon {
    width: 18px;
    height: 18px;
    opacity: .8;
}

.nav-link[aria-current="page"] .icon {
    opacity: 1;
}

/*
 * Die Zeile, solange der Systemadmin das Portal als eine andere Person
 * ansieht (src/ansicht_als.php). In der Kopfleiste, damit sie beim
 * Blättern mitläuft - und gelb, weil man nicht übersehen darf, wessen
 * Seite das gerade ist.
 */
.ansicht-als-leiste {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-2) var(--gutter);
    background: var(--warning);
    color: #1a1a1a;
    font-size: 0.9rem;
    text-align: center;
}

.ansicht-als-leiste .btn {
    background: #1a1a1a;
    border-color: #1a1a1a;
    color: #ffffff;
}

/*
 * Die Zeile, solange eine Stummschaltung läuft (stummLeisteHtml() in
 * src/stummschaltung.php). Nicht wegklickbar und auf jeder Seite - wie
 * der Hinweis über der Alarmliste in den Apps. Gelb wie die Zeile oben:
 * Beides sind Zustände, die man nicht übersehen darf.
 */
.stumm-leiste {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-2) var(--gutter);
    background: var(--warning);
    color: #1a1a1a;
    font-size: 0.9rem;
    text-align: center;
}

.stumm-leiste .btn {
    background: #1a1a1a;
    border-color: #1a1a1a;
    color: #ffffff;
}

.site-footer {
    border-top: 1px solid var(--border);
    margin-top: var(--space-8);
    padding: var(--space-5) 0 calc(var(--space-5) + var(--safe-bottom));
}

body.has-bottom-nav .site-footer {
    margin-bottom: calc(var(--bottom-nav-height) + var(--safe-bottom));
}

.site-footer-inner {
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 var(--gutter);
    padding-left: max(var(--gutter), var(--safe-left));
    padding-right: max(var(--gutter), var(--safe-right));

    display: flex;
    align-items: center;
    gap: var(--space-2) var(--space-5);
    flex-wrap: wrap;
}

.site-footer-inner a {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
    color: var(--text-soft);
    text-decoration: none;
    font-size: var(--text-sm);
}

.site-footer-inner a:hover {
    color: var(--text);
}

/* Die Themenseiten ueber den Pflichtlinks, fuer Besucher ohne Anmeldung. */
.site-footer-themen {
    padding-bottom: var(--space-3);
    margin-bottom: var(--space-3);
    border-bottom: 1px solid var(--border-soft);
}

.site-footer-copy {
    /* Wie die Links daneben: --text-muted hatte auf --bg-main 4,3:1 (P4-17). */
    color: var(--text-soft);
    font-size: var(--text-sm);
    margin-left: auto;
}

@media (max-width: 600px) {

    .site-footer-inner {
        flex-direction: column;
        align-items: flex-start;
        gap: 0;
    }

    .site-footer-copy {
        margin: var(--space-2) 0 0;
    }
}

.card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow-sm);
}

.card .card {
    background: var(--bg-card-2);
    box-shadow: none;
}

a.card {
    display: block;
    color: inherit;
    text-decoration: none;
    transition: border-color var(--transition), transform var(--transition);
}

a.card:hover {
    border-color: var(--accent);
}

a.card:active {
    transform: scale(0.99);
}

.meta-box {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-4) var(--space-5);
    background: rgba(255, 255, 255, 0.02);
}

.group-block {
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-4);
    margin: 0 0 var(--space-4);
    background: var(--bg-card-2);
}

.group-block legend {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    width: 100%;
    padding: 0 0 var(--space-3);
    font-size: var(--text-base);
    font-weight: 600;
}

.group-block legend .btn {
    min-height: 36px;
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-sm);
}

@media (max-width: 600px) {

    .card {
        padding: var(--space-4);
        border-radius: var(--radius-md);
    }

    .meta-box {
        padding: var(--space-4);
    }

    .group-block legend {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-2);
    }

    .group-block legend .btn {
        width: 100%;
    }
}

/*
 * ======================================================================
 * AUFKLAPPBARE KARTEN (Betreiber, 11.09.2026)
 * ======================================================================
 * "Die Felder Nehme teil, nehmen nicht teil, Gelesen von usw. ein- und
 * ausklappbar machen."
 *
 * Vier Listen untereinander, jede so lang wie die Mannschaft: Wer auf
 * dem Telefon wissen will, wann der Termin anfaengt, scrollt an hundert
 * Namen vorbei.
 *
 * <details> statt eigener Schalter - der Browser kann das Auf und Zu
 * selbst, mit Tastatur und mit Vorlesesoftware. Hier steht nur, wie es
 * aussieht.
 */
.aufklapper > summary {
    /*
     * Der eigene Marker, nicht der des Browsers: list-style-type wirkt in
     * Chrome, ::-webkit-details-marker in aelterem Safari. Beide weg, und
     * das Dreieck kommt aus ::after - sonst steht es je nach Browser an
     * einer anderen Stelle.
     */
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 10px;

    /* Der ganze Kopf ist die Schaltflaeche, nicht nur das Wort. */
    margin: calc(var(--space-md, 16px) * -1);
    padding: var(--space-md, 16px);

    /* Und er ist so hoch wie ein Fingertipp breit ist. */
    min-height: var(--tap, 44px);
}

.aufklapper > summary::-webkit-details-marker {
    display: none;
}

.aufklapper > summary::after {
    content: "▾";
    margin-left: auto;

    /*
     * Als runder Knopf, nicht als blasses Zeichen: Das kleine Dreieck
     * allein wurde uebersehen - "die Abschnitte sollen aufklappbar
     * sein" kam, als sie es laengst waren (26.09.2026).
     */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 30px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: rgba(128, 128, 128, .18);
    font-size: 1.3rem;
    line-height: 1;
    opacity: .85;
    transition: transform .15s ease, background-color .15s ease;
}

.aufklapper[open] > summary::after {
    transform: rotate(180deg);
}

.aufklapper > summary:hover::after,
.aufklapper > summary:focus-visible::after {
    opacity: 1;
    background: rgba(128, 128, 128, .3);
}

/* Die Ueberschrift steht im summary und braucht dort keinen eigenen
   Abstand mehr - sonst sitzt das Dreieck nicht auf ihrer Mittellinie. */
.aufklapper > summary > h2,
.aufklapper > summary > h3 {
    margin: 0;
}

/* Was aufgeklappt erscheint, braucht wieder Luft zum Kopf. */
.aufklapper[open] > summary {
    margin-bottom: 0;
}

.aufklapper[open] > summary + * {
    margin-top: var(--space-md, 16px);
}

button {
    min-height: var(--tap);
    padding: var(--space-3) var(--space-4);
    background: var(--bg-card-2);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: var(--text-base);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.btn,
.btn-danger,
.status-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    width: auto;
    min-height: var(--tap);
    padding: var(--space-3) var(--space-5);
    border: none;
    border-radius: var(--radius-md);
    background: var(--accent);
    color: #ffffff;
    font-family: inherit;
    font-size: var(--text-base);
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background var(--transition), transform var(--transition);
    -webkit-tap-highlight-color: transparent;
}

.btn:hover {
    background: var(--accent-fill-hover);
}

.btn:active,
.btn-danger:active,
.status-btn:active {
    transform: scale(0.98);
}

.btn.secondary {
    background: var(--bg-card-2);
    color: var(--text);
}

.btn.secondary:hover {
    background: var(--bg-elevated);
}

.btn.ghost {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text);
}

.btn.ghost:hover {
    background: var(--bg-card-2);
}

.btn-danger {
    background: var(--danger-fill);
}

.btn-danger:hover {
    background: var(--danger-fill-hover);
}

.btn.small {
    min-height: 36px;
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-sm);
}

.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

.status-btn {
    flex-direction: column;
    min-width: 110px;
    padding: var(--space-3) var(--space-4);
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    color: var(--text);
    font-weight: 600;
}

.status-picker {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
    gap: var(--space-2);
}

.status-picker > .btn,
.status-picker > button,
.status-picker .status-btn {
    width: 100%;
    min-width: 0;
}

.status-btn[aria-pressed="true"] {
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.25);
}

.icon-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--tap);
    height: var(--tap);
    padding: 0;
    background: none;
    border: none;
    color: var(--accent-text);
    font-size: var(--text-lg);
    cursor: pointer;
}

.icon-button:hover {
    color: var(--text);
}

@media (max-width: 600px) {

    .btn,
    .btn-danger {
        width: 100%;
    }

    .btn.small,
    .btn.inline,
    .actions .btn.inline {
        width: auto;
    }

    .status-btn {
        flex: 1 1 calc(50% - var(--space-3));
        min-width: 0;
    }
}

@media (max-width: 420px) {
    .status-picker {
        grid-template-columns: repeat(2, 1fr);
    }
}

/*
 * Die Haupthandlung einer Maske.
 *
 * ======================================================================
 * DIE KLASSE WAR TOT (gefunden 07.09.2026)
 * ======================================================================
 * `btn-primary` steht an zwölf Stellen im Markup - definiert war sie
 * nirgends. Meistens fiel das nicht auf, weil `.btn` ohnehin die
 * Akzentfarbe trägt: Der Knopf sah richtig aus, ohne dass die Klasse
 * etwas tat.
 *
 * Wo es darauf ankommt: admin/baum.php hebt im Verschiebemodus den
 * Knopf "Hierher" hervor - den einen, der dort etwas bewirkt.
 *
 * Jetzt ist sie definiert und meint, was sie sagt. Sie steht bewusst
 * NACH .btn.secondary und .btn.ghost: Wer beides anschreibt, meint die
 * Haupthandlung.
 */
.btn-primary {
    background: var(--accent);
    color: #ffffff;
}

.btn-primary:hover {
    background: var(--accent-fill-hover);
}

input,
select,
textarea {
    width: 100%;
    min-height: var(--tap);
    padding: var(--space-3);
    background: var(--bg-card-2);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: var(--text-base);
    outline: none;
    -webkit-appearance: none;
    appearance: none;
}

select {
    background-image:
        linear-gradient(45deg, transparent 50%, var(--text-soft) 50%),
        linear-gradient(135deg, var(--text-soft) 50%, transparent 50%);
    background-position:
        calc(100% - 18px) calc(50% + 2px),
        calc(100% - 13px) calc(50% + 2px);
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
    padding-right: var(--space-8);
}

input:focus,
select:focus,
textarea:focus {
    border-color: var(--accent);
}

input[readonly],
input:disabled,
select:disabled,
textarea:disabled {
    opacity: 0.7;
    cursor: default;
}

textarea {
    min-height: 110px;
    resize: vertical;
    line-height: 1.5;
}

@media (max-width: 960px) {

    input,
    select,
    textarea {
        font-size: 16px;
    }
}

input[type="checkbox"],
input[type="radio"] {
    width: 20px;
    height: 20px;
    min-height: 0;
    flex-shrink: 0;
    margin: 0;
    padding: 0;
    accent-color: var(--accent);
    -webkit-appearance: auto;
    appearance: auto;
}

input[type="color"] {
    padding: var(--space-1);
    height: var(--tap);
    cursor: pointer;
}

input[type="range"] {
    width: 100%;
    max-width: 320px;
    min-height: 0;
    padding: 0;
    background: none;
    border: none;
    accent-color: var(--accent);
    cursor: pointer;
    -webkit-appearance: auto;
    appearance: auto;
}

input[type="file"] {
    padding: var(--space-2);
    line-height: 1.6;
}

input[type="file"]::file-selector-button {
    margin-right: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--bg-elevated);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-family: inherit;
    font-size: var(--text-sm);
    cursor: pointer;
}

::placeholder {
    color: var(--text-muted);
    opacity: 1;
}

label {
    display: inline-block;
}

.form-card {
    max-width: 900px;
    margin-inline: auto;
}

/*
 * Bearbeitungsseiten mit Reitern brauchen mehr als 900px: bei "Rechte je
 * Einheit" stehen sieben Spalten nebeneinander, und die Reiterleiste selbst
 * war so breit, dass die hinteren Reiter am Kartenrand abgeschnitten waren.
 */
.form-card-wide {
    max-width: none;
}

.form-group {
    display: flex;
    flex-direction: column;
    margin-bottom: var(--space-4);
}

.form-group label {
    margin-bottom: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-soft);
}

.form-group .btn {
    align-self: flex-start;
    margin-top: var(--space-2);
}

@media (max-width: 600px) {
    .form-group .btn {
        align-self: stretch;
    }
}

.checkbox-inline {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-3);
    min-height: var(--tap);
    margin: 0;
    width: 100%;
    cursor: pointer;
}

.checkbox-inline input {
    width: 20px;
}

.filter-box {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    min-width: 260px;
}

.filter-title {
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--text-soft);
}

.select {
    min-width: 220px;
}

.readonly-field {
    min-height: var(--tap);
    padding: var(--space-3);
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    color: var(--text-soft);
}

.readonly-field.multiline {
    min-height: 110px;
    line-height: 1.6;
}

@media (max-width: 600px) {

    .filter-box {
        min-width: 0;
        width: 100%;
    }

    .select {
        min-width: 0;
    }
}

/* Auswahlliste mehrerer Werte (z.B. Gruppen eines Kontakts, Mängelmelder) */
.checkbox-list {
    max-height: 260px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3);
    background: var(--bg-card-2);
}

.checkbox-list .checkbox-inline {
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--border-soft);
}

.checkbox-list .checkbox-inline:last-child {
    border-bottom: none;
}

.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

table {
    width: 100%;
    border-collapse: collapse;
}

th,
td {
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border);
    text-align: left;
    vertical-align: middle;
}

th {
    background: var(--bg-card-2);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-soft);
    white-space: nowrap;
}

tbody tr:last-child td {
    border-bottom: none;
}

tbody tr:hover {
    background: rgba(255, 255, 255, 0.03);
}

th.sortable {
    cursor: pointer;
    user-select: none;
    padding-right: var(--space-6);
    position: relative;
}

th.sortable::after {
    content: "\2195";
    position: absolute;
    right: var(--space-3);
    opacity: 0.35;
    font-size: var(--text-sm);
}

th.sortable[data-sort-dir="asc"]::after {
    content: "\2191";
    opacity: 1;
    color: var(--accent-text);
}

th.sortable[data-sort-dir="desc"]::after {
    content: "\2193";
    opacity: 1;
    color: var(--accent-text);
}

@media (max-width: 768px) {

    table.table-cards,
    table.table-cards thead,
    table.table-cards tbody,
    table.table-cards tr,
    table.table-cards th,
    table.table-cards td {
        display: block;
    }

    table.table-cards thead {
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-2);
        margin-bottom: var(--space-3);
    }

    table.table-cards thead tr {
        display: contents;
    }

    table.table-cards thead th {
        border: 1px solid var(--border);
        border-radius: var(--radius-pill);
        padding: var(--space-2) var(--space-4);
        background: var(--bg-card-2);
        font-size: var(--text-xs);
    }

    table.table-cards thead th:not(.sortable) {
        display: none;
    }

    table.table-cards:not(:has(thead th.sortable)) thead {
        display: none;
    }

    table.table-cards thead th.sortable::after {
        position: static;
        margin-left: var(--space-2);
    }

    table.table-cards tbody tr {
        margin-bottom: var(--space-3);
        padding: var(--space-2) var(--space-4);
        background: var(--bg-card-2);
        border: 1px solid var(--border);
        border-radius: var(--radius-md);
    }

    table.table-cards tbody tr:hover {
        background: var(--bg-card-2);
    }

    table.table-cards tbody td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-4);
        padding: var(--space-2) 0;
        border-bottom: 1px solid var(--border-soft);
        text-align: right;
    }

    table.table-cards tbody td:last-child {
        border-bottom: none;
    }

    table.table-cards tbody td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        max-width: 45%;
        color: var(--text-muted);
        font-size: var(--text-sm);
        font-weight: 600;
        text-align: left;
    }

    table.table-cards tbody td[data-label=""]::before,
    table.table-cards tbody td:not([data-label])::before {
        display: none;
    }

    table.table-cards tbody td.cell-actions {
        display: block;
        padding-top: var(--space-3);
    }

    table.table-cards tbody td.cell-actions::before {
        display: none;
    }

    table.table-cards tbody td.cell-actions .btn,
    table.table-cards tbody td.cell-actions button {
        width: 100%;
    }

    table.table-cards tbody td form {
        margin: 0;
    }
}

/*
 * Zwischenueberschrift einer Rechtegruppe (RIGHT_GROUPS, apRightGroups)
 * in den drei Rechtemasken: als Tabellenzeile auf der Benutzerseite, als
 * Ueberschrift in der Vorlagenmaske und im Gitter der Knotenmaske. Eine
 * Gestalt fuer alle drei, damit "Einsatz", "Kommunikation" usw. ueberall
 * gleich aussehen - dieselbe Form wie die Gruppenzeile der Rueckmeldeliste.
 */
/* tr...:first-child, weil die Benutzerseite die letzte Zelle jeder Zeile
   zentriert (.unit-rights th:last-child) - die einzige Zelle einer
   Gruppenzeile ist beides. */
tr.rechte-gruppe > th:first-child,
.rechte-gruppe-titel {
    background: var(--bg-card-2);
    font-size: var(--text-sm);
    font-weight: 600;
    text-align: left;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.rechte-gruppe-titel {
    margin: var(--space-3) 0 var(--space-1);
    padding: 4px var(--space-2);
    border-radius: var(--radius-sm);
}

/* Im Gitter der Knotenmaske ueber die ganze Breite, nicht als Kachel. */
.knoten-rechtegitter > .rechte-gruppe-titel {
    grid-column: 1 / -1;
    margin: var(--space-2) 0 0;
}

.badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-pill);
    background: var(--accent);
    color: #ffffff;
    font-size: var(--text-sm);
    font-weight: 600;
    white-space: nowrap;
}

.badge.status-new {
    background: rgba(59, 130, 246, 0.15);
    color: #60a5fa;
    border: 1px solid rgba(59, 130, 246, 0.4);
}

.badge.status-progress {
    background: rgba(245, 158, 11, 0.15);
    color: #FFAD1F;
    border: 1px solid rgba(245, 158, 11, 0.4);
}

.badge.status-waiting {
    background: rgba(168, 85, 247, 0.15);
    color: #c084fc;
    border: 1px solid rgba(168, 85, 247, 0.4);
}

.badge.status-solved {
    background: rgba(34, 197, 94, 0.15);
    color: #2FD96E;
    border: 1px solid rgba(34, 197, 94, 0.4);
}

.badge.status-closed {
    background: rgba(107, 114, 128, 0.15);
    color: #9ca3af;
    border: 1px solid rgba(107, 114, 128, 0.4);
}

.badge.online {
    background: rgba(34, 197, 94, 0.15);
    color: #4ade80;
    border: 1px solid rgba(34, 197, 94, 0.35);
}

.badge.offline {
    background: rgba(239, 68, 68, 0.15);
    color: #f87171;
    border: 1px solid rgba(239, 68, 68, 0.35);
}

.badge.role-admin {
    background: rgba(239, 68, 68, 0.15);
    color: #f87171;
    border: 1px solid rgba(239, 68, 68, 0.4);
}

.badge.role-unit-admin {
    background: rgba(245, 158, 11, 0.15);
    color: #FFAD1F;
    border: 1px solid rgba(245, 158, 11, 0.4);
}

.badge.role-group-admin {
    background: rgba(168, 85, 247, 0.15);
    color: #c084fc;
    border: 1px solid rgba(168, 85, 247, 0.4);
}

.role-badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.badge.priority-low {
    background: rgba(107, 114, 128, 0.15);
    color: #9ca3af;
    border: 1px solid rgba(107, 114, 128, 0.4);
}

.badge.priority-normal {
    background: rgba(59, 130, 246, 0.15);
    color: #60a5fa;
    border: 1px solid rgba(59, 130, 246, 0.4);
}

.badge.priority-high {
    background: rgba(245, 158, 11, 0.15);
    color: #FFAD1F;
    border: 1px solid rgba(245, 158, 11, 0.4);
}

.badge.priority-critical {
    background: rgba(239, 68, 68, 0.15);
    color: #f87171;
    border: 1px solid rgba(239, 68, 68, 0.4);
}

/*
 * Persoenlich gewidmeter Alarm: vom Alarmmonitor an eine einzelne Person
 * gerichtet statt an eine Gruppe (siehe person_key in api/ingest.php).
 * Sichtbar nur fuer die adressierte Person - und in den Adminsichten,
 * dort mit Namen.
 */
.badge.alarm-personal {
    background: rgba(236, 72, 153, 0.15);
    color: #f472b6;
    border: 1px solid rgba(236, 72, 153, 0.4);
    margin-left: var(--space-2);
    font-size: var(--text-xs);
}

/* Der Empfaenger mit Passbild (08.10.2026) - der Kreis kleiner als im
   Fliesstext, damit das Abzeichen nicht hoeher wird als die Zeile. */
.badge.alarm-personal .person-im-text {
    margin-left: 4px;
}

.badge.alarm-personal .personkreis.personkreis-text {
    width: 16px;
    height: 16px;
    font-size: 7px;
}

/*
 * Fortgeschriebener Einsatz: nach der Alarmierung kam noch etwas dazu -
 * nachgemeldete Fahrzeuge, ein verlegter Einsatzort, eine zusaetzlich
 * alarmierte Wehr (siehe update=1 in api/ingest.php).
 *
 * Bernstein statt Rot: es ist ein Hinweis, kein Alarm. Wer das Abzeichen
 * sieht, soll den Abschnitt "Fortschreibung" darunter lesen.
 */
.badge.alarm-updated {
    background: rgba(245, 158, 11, 0.15);
    color: #fbbf24;
    border: 1px solid rgba(245, 158, 11, 0.4);
    margin-left: var(--space-2);
    font-size: var(--text-xs);
}

/*
 * Zurueckgenommener Einsatz (R). Grau, nicht rot: Der Alarm ist vorbei,
 * und ein farbiges Abzeichen wuerde in der Liste weiter nach
 * Aufmerksamkeit rufen. Auffallen soll der Vermerk auf der Detailseite.
 */
.badge.alarm-zurueckgenommen {
    background: rgba(148, 163, 184, 0.15);
    color: #cbd5e1;
    border: 1px solid rgba(148, 163, 184, 0.4);
    margin-left: var(--space-2);
    font-size: var(--text-xs);
}

/*
 * Der Farbpunkt einer Einheit - Struktur und Alarmieren.
 *
 * Betreiber, 07.09.2026: "bei Alarm und bei Struktur vorne die
 * definierten Farben der Gruppen anzeigen." Es ist dieselbe Farbe, die
 * der Alarmmonitor zeigt (units.color, gepflegt in einheit_edit).
 *
 * In badges.css und nicht in einer der beiden Seiten-CSS: Beide Seiten
 * brauchen ihn, und eine Kopie in der zweiten Datei liefe irgendwann
 * auseinander - so wie es die Artbezeichnungen getan haben.
 *
 * Dieselben Masse wie .knotenwahl-farbe (css/components/knotenwahl.css):
 * 3 px nach innen, dann sitzt die Mitte des Punkts genau ueber der
 * Senkrechten seiner Kinder, und deren Ast endet 1 px vor ihrem Punkt.
 */
.knoten-farbe {
    flex: 0 0 auto;
    align-self: center;
    width: 10px;
    height: 10px;
    margin: 0 var(--space-2) 0 3px;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
}

/*
 * Ohne eingestellte Farbe bleibt der PLATZ, aber kein Punkt: Sonst
 * ruecken die Namen der Einheiten ohne Farbe nach links, und die
 * Namen derselben Ebene stuenden nicht mehr in einer Flucht.
 */
.knoten-farbe[data-ohne="ja"] {
    background: transparent;
    box-shadow: none;
}

/*
 * Das Bild einer Gruppe (14.10.2026, window.apKnotenBild) - ein kleiner
 * Kreis zwischen Farbpunkt und Name. Ueberall gleich gross, damit die
 * Namen mit und ohne Bild nicht springen, wo es auffiele.
 */
.knoten-bild {
    /* In der Zeile, auch in einer Überschrift - die Grundregel setzt img auf block. */
    display: inline-block;
    flex: 0 0 auto;
    align-self: center;
    width: 22px;
    height: 22px;
    margin-right: var(--space-2);
    border-radius: 50%;
    object-fit: cover;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.2);
    vertical-align: middle;
}

/* Gross im Kopf der Gruppenseite (admin/knoten.php). */
.knoten-bild.gross {
    width: 44px;
    height: 44px;
    margin-right: var(--space-3);
}
.knoten-titel {
    display: flex;
    align-items: center;
}
.knoten-bild-knoepfe {
    display: inline-flex;
    gap: var(--space-2);
}

/* Im Namen einer Baumzeile (Struktur, Alarmieren): Bild und Name
 * nebeneinander - ein langer Name bricht neben dem Bild um, nicht darunter. */
.baum-name:has(> .knoten-bild) {
    display: flex;
    align-items: center;
}

.modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);
    background: var(--bg-overlay);
    padding: var(--space-5);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;

    align-items: center;
    justify-content: center;
}

.modal-content {
    position: relative;
    width: 100%;
    max-width: 640px;
    margin: auto;
    max-height: calc(100vh - 2 * var(--space-5));
    max-height: calc(100dvh - 2 * var(--space-5));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

.modal-content.wide {
    max-width: 900px;
}

.modal-content > h3:first-child,
.modal-content > h2:first-child {
    margin-top: 0;
    padding-right: var(--space-7);
}

.modal .close,
.modal-content .close {
    position: absolute;
    top: var(--space-3);
    right: var(--space-4);
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--tap);
    height: var(--tap);
    float: none;
    font-size: 24px;
    line-height: 1;
    color: var(--text-soft);
    cursor: pointer;
}

.modal .close:hover {
    color: var(--text);
}

@media (max-width: 600px) {

    .modal {
        padding: 0;
        align-items: flex-end;
    }

    .modal-content {
        max-width: 100%;
        max-height: 92vh;
        max-height: 92dvh;
        margin: 0;
        border-radius: var(--radius-xl) var(--radius-xl) 0 0;
        border-bottom: none;
        padding-bottom: calc(var(--space-5) + var(--safe-bottom));
    }

    .modal-content::before {
        content: "";
        position: sticky;
        top: 0;
        display: block;
        width: 40px;
        height: 4px;
        margin: 0 auto var(--space-3);
        border-radius: var(--radius-pill);
        background: var(--border);
    }
}

/*
 * Die Rueckfrage (window.apBestaetigen, siehe includes/layout.php).
 *
 * Schmaler als ein gewoehnliches Modal: Es steht eine Frage darin und
 * zwei Knoepfe. In der vollen Breite von 640px sieht das aus, als fehle
 * der Inhalt.
 */
.ap-frage-kasten {
    max-width: 460px;
    padding: var(--space-5);
}

.ap-frage-kasten > h3 {
    margin-top: 0;
}

.ap-frage-kasten .actions {
    display: flex;
    gap: var(--space-3);
    justify-content: flex-end;
    margin-top: var(--space-5);
}

/* Auf dem Telefon untereinander und in voller Breite - zwei kleine
   Knoepfe nebeneinander trifft man mit dem Daumen nicht sicher, und bei
   einer Rueckfrage ist der Fehlgriff der ganze Punkt. */
@media (max-width: 480px) {
    .ap-frage-kasten .actions {
        flex-direction: column-reverse;
    }

    /* flex zurueck auf die Knopfhoehe: grid.css gibt `.actions > .btn`
       unter 960px `flex: 1 1 180px`, und in der Spalte wird die
       Grundgroesse zur HOEHE - jeder Knopf stand 180px hoch. */
    .ap-frage-kasten .actions .btn {
        flex: 0 0 auto;
        width: 100%;
    }
}

/* Die Vorlagenauswahl in der Rechtemaske: Feld und Knopf nebeneinander. */
.vorlage-zeile {
    display: flex;
    gap: var(--space-3);
    align-items: center;
    min-width: 0;
}

.vorlage-zeile .input {
    min-width: 0;
    flex: 1 1 auto;
}

.vorlage-zeile .btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* -------------------------------------------------------------------
   Bildansicht für Anhänge

   Baut auf .modal auf (gleiche Ein-/Ausblendung, gleiches Escape- und
   Hintergrundverhalten), setzt aber die Innereien neu: Hier soll das
   Bild der Inhalt sein, nicht eine Karte mit einem Bild darin.
   ------------------------------------------------------------------- */

.lightbox {
    padding: var(--space-4);
}

.lightbox-frame {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    max-width: 1200px;
    margin: auto;
}

.lightbox img {
    max-width: 100%;

    /* Die Leiste darüber und etwas Luft abziehen - sonst schiebt ein
       hohes Foto die Bedienelemente aus dem Bild. */
    max-height: calc(100dvh - 8rem);
    object-fit: contain;
    border-radius: var(--radius-md);
    background: var(--bg-card);
}

.lightbox-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    border: 1px solid var(--border);
}

.lightbox-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

.lightbox-count {
    flex: none;
    color: var(--text-soft);
    font-variant-numeric: tabular-nums;
}

.lightbox-action {
    flex: none;
    display: grid;
    place-items: center;
    width: var(--tap);
    height: var(--tap);
    padding: 0;
    border: none;
    border-radius: var(--radius-md);
    background: none;
    color: var(--text-soft);
    cursor: pointer;
}

.lightbox-action:hover,
.lightbox-action:focus-visible {
    background: var(--bg-elevated);
    color: var(--text);
}

/* Die Pfeile liegen über dem Bild und mittig an den Rändern - dort
   sucht man sie, und auf dem Telefon sind sie mit dem Daumen zu
   erreichen, ohne quer über den Bildschirm zu greifen. */
.lightbox-nav {
    position: absolute;
    top: 55%;
    display: grid;
    place-items: center;
    width: var(--tap);
    height: var(--tap);
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--bg-card);
    color: var(--text);
    cursor: pointer;
}

.lightbox-nav:hover,
.lightbox-nav:focus-visible {
    background: var(--bg-elevated);
}

.lightbox-nav.prev {
    left: 0;
}

.lightbox-nav.next {
    right: 0;
}

@media (max-width: 600px) {

    /* Auf dem Telefon nicht als Blatt von unten (so macht es .modal
       sonst), sondern bildschirmfüllend - ein Foto will Platz. */
    .lightbox {
        align-items: center;
        padding: var(--space-2);
    }

    .lightbox img {
        max-height: calc(100dvh - 7rem);
    }
}

/* -------------------------------------------------------------------
   Ein Bild gross: Passbild, Bild im Chat (js/portal-bausteine.js,
   apBildGross). Bewusst schlicht - kein Blaettern, keine Leiste.

   Ueber den Dialogen (--z-modal) und ihren Auswahllisten (+10): Ein
   Passbild steht auch in Dialogen, etwa in den Raumdetails des Chats.
   ------------------------------------------------------------------- */

.bild-gross {
    position: fixed;
    inset: 0;
    z-index: calc(var(--z-modal) + 20);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-4);
    background: rgba(0, 0, 0, 0.85);
    cursor: zoom-out;
}

.bild-gross img {
    display: block;
    max-width: min(94vw, 100%);
    max-height: 94vh;
    max-height: 94dvh;
    object-fit: contain;
    border-radius: 4px;
}

.bild-gross-schliessen {
    position: absolute;
    top: calc(var(--space-3) + var(--safe-top));
    right: calc(var(--space-3) + var(--safe-right));
    display: grid;
    place-items: center;
    width: var(--tap);
    height: var(--tap);
    min-height: 0;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #ffffff;
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
}

.bild-gross-schliessen:hover,
.bild-gross-schliessen:focus-visible {
    background: rgba(255, 255, 255, 0.2);
}

.bild-gross-schliessen:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}

/* Ein Passbild, das gross aufgeht (apPassbildGross). */
.vergroesserbar {
    cursor: zoom-in;
}

.vergroesserbar:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.error,
.success,
.info-box,
.warning-box {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-4);
    font-size: var(--text-base);
}

.error {
    background: rgba(200, 60, 60, 0.15);
    border: 1px solid rgba(200, 60, 60, 0.4);
    color: #ffb3b3;
}

.success {
    background: rgba(34, 197, 94, 0.15);
    border: 1px solid rgba(34, 197, 94, 0.4);
    color: #a7f3c4;
}

.info-box {
    background: rgba(59, 130, 246, 0.12);
    border: 1px solid rgba(59, 130, 246, 0.35);
    color: #bfdbfe;
}

.warning-box {
    background: rgba(245, 158, 11, 0.12);
    border: 1px solid rgba(245, 158, 11, 0.35);
    color: #fde68a;
}

.empty,
.empty-state {
    padding: var(--space-5) var(--space-4);
    color: var(--text-muted);
    text-align: center;
}

.is-loading {
    color: var(--text-muted);
}

/*
 * Kurzer Hinweis oben am Bildschirm.
 *
 * Vorher hiess "gespeichert" auf den Bearbeitungsseiten: die Maske schliesst
 * sich und man landet wieder in der Liste. Wer zwei Kleinigkeiten hintereinander
 * aendern wollte, musste sich jedes Mal neu durchklicken - und wer nur den
 * Reiter wechseln wollte, verlor dabei den Stand. Jetzt bleibt die Seite stehen
 * und sagt oben Bescheid.
 */
.toast-host {
    position: fixed;
    top: calc(var(--header-height) + var(--safe-top) + var(--space-3));
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-modal);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    align-items: center;
    width: max-content;
    max-width: min(92vw, 520px);
    pointer-events: none;
}

.toast {
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-pill);
    font-size: var(--text-base);
    font-weight: 600;
    box-shadow: var(--shadow-md);
    text-align: center;
    opacity: 1;
    transform: translateY(0);
    transition: opacity var(--transition), transform var(--transition);
}

.toast-success {
    background: rgba(34, 197, 94, 0.95);
    border: 1px solid rgba(34, 197, 94, 0.4);
    color: #06240f;
}

.toast-error {
    background: rgba(200, 60, 60, 0.95);
    border: 1px solid rgba(200, 60, 60, 0.4);
    color: #ffffff;
}

.toast-info {
    background: rgba(59, 130, 246, 0.95);
    border: 1px solid rgba(59, 130, 246, 0.4);
    color: #ffffff;
}

.toast-enter {
    opacity: 0;
    transform: translateY(-10px);
}

.toast-out {
    opacity: 0;
    transform: translateY(-10px);
}

@media (prefers-reduced-motion: reduce) {

    .toast {
        transition: none;
    }
}

/*
 * Die Reiter brechen um, statt seitlich wegzulaufen. Mit "overflow-x: auto"
 * und versteckter Scrollleiste sahen die hinteren Reiter schlicht
 * abgeschnitten aus - dass man dort noch scrollen kann, war nicht zu sehen.
 */
.h-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.h-tabs::-webkit-scrollbar {
    display: none;
}

.h-tab {
    flex: 0 0 auto;
    width: auto;
    white-space: nowrap;
}

@media (max-width: 600px) {
    .h-tabs .btn {
        width: auto;
    }
}

.h-tab.active {
    background: var(--accent);
    color: #ffffff;
}

.h-tab-content {
    display: none;
}

.h-tab-content.active {
    display: block;
}

/*
 * Die Personenzeile - EIN Standard fuer jede Liste von Menschen.
 * (Betreiber, 23.09.2026: "bitte einen Standard entwickeln, der dann auch
 * z.B. hier gilt: /admin/benutzer")
 *
 * Gebaut wird sie ueber window.apPersonZeile() (includes/layout.php);
 * wer eine Personenliste schreibt, nimmt diese Funktion und kein eigenes
 * Markup - sonst hat jede Seite wieder ihre eigene Hoehe und ihre eigene
 * Reihenfolge.
 *
 *   [Haken] (Kuerzel)  Name  [Zusatz]              [Marken]  [Aktionen]
 *                      Infozeile 1
 *                      Infozeile 2
 *
 * Hoch genug fuer zwei Infozeilen und einen Finger (min. 72 px). Was
 * fehlt, laesst seine Zeile weg, statt Platz zu halten.
 */
.personliste {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.personzeile {
    display: flex;
    align-items: center;
    gap: var(--space-3) var(--space-4);
    min-height: 72px;
    padding: var(--space-3) var(--space-4);
    background: var(--bg-card-2);
    border: 1px solid var(--border-soft);
    border-radius: var(--radius-md);
    color: inherit;
    text-decoration: none;
}

.personzeile[hidden] {
    display: none;
}

a.personzeile:hover,
a.personzeile:focus-visible,
.personzeile:has(.personzeile-haken:checked) {
    border-color: var(--accent);
    text-decoration: none;
}

.personzeile:has(.personzeile-haken:checked) {
    background: var(--accent-soft);
}

.personzeile-haken {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    min-height: 0;
    margin: 0;
    accent-color: var(--accent);
    cursor: pointer;
}

/* Das Kuerzel: macht die Zeile beim Ueberfliegen wiederfindbar und
   unterscheidet Fahrzeuge und Sirenen auf einen Blick von Menschen. */
.personzeile-bild {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent-text);
    font-weight: 700;
    font-size: var(--text-sm);
    letter-spacing: 0.02em;
    user-select: none;
}

.personzeile-bild[data-art="geraet"] {
    border-radius: var(--radius-md);
    background: var(--bg-elevated);
    color: var(--text-muted);
}

.personzeile-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1 1 14rem;
    min-width: 0;
}

.personzeile-name {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-2);
    font-weight: 600;
    font-size: var(--text-base);
}

.personzeile-info {
    color: var(--text-soft);
    font-size: var(--text-sm);
    overflow-wrap: anywhere;
}

.personzeile-marken {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-2);
    flex: 0 1 auto;
}

.personzeile-marken:empty,
.personzeile-aktionen:empty {
    display: none;
}

.personzeile-aktionen {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 0 0 auto;
}

.personzeile-aktionen .input {
    width: auto;
    min-width: 11rem;
}

/* Auf dem Telefon rutschen Marken und Aktionen unter den Namen - in einer
   Reihe bliebe dem Namen nichts. */
@media (max-width: 640px) {
    .personzeile {
        flex-wrap: wrap;
    }

    .personzeile-marken,
    .personzeile-aktionen {
        flex: 1 1 100%;
        justify-content: flex-start;
        padding-left: calc(44px + var(--space-3));
    }

    /* Die Aktionen nutzen die volle Breite - eingerueckt bliebe einer
       Auswahl kaum Platz fuer den Namen einer Vorlage. */
    .personzeile-aktionen {
        min-width: 0;
        padding-left: 0;
    }

    /* Breite 0 und wachsen: Ein <select> bringt sonst die Breite seines
       laengsten Eintrags mit und schiebt den Knopf daneben aus dem Bild. */
    .personzeile-aktionen .input {
        flex: 1 1 0;
        width: 0;
        min-width: 0;
    }
}

.personzeile-marke {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--space-2);
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.06);
    font-size: var(--text-sm);
    white-space: nowrap;
}

/* Blass: Nebenauskunft ("kein Mitglied", "Einsatzmittel"). */
.personzeile-marke[data-art="leer"] {
    opacity: 0.6;
}

/* Auffaellig: eine Ausnahme, die man sehen muss ("Kein Alarm"). */
.personzeile-marke[data-art="hinweis"] {
    background: color-mix(in srgb, var(--warning) 18%, transparent);
    color: var(--warning);
}

/* Waehlbare Zeilen: die ganze Zeile markiert (apPersonZeile mit haken). */
.personzeile[data-waehlbar="ja"] {
    cursor: pointer;
    user-select: none;
}

.personzeile[data-waehlbar="ja"]:hover {
    border-color: var(--border);
}

/* Die Markierleiste der Benutzerliste - wie auf der Knotenseite. */
.nutzer-auswahlleiste {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin: var(--space-3) 0;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--accent);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
}

.nutzer-auswahlleiste[hidden] {
    display: none;
}

.nutzer-auswahlleiste > span {
    flex: 0 0 auto;
    margin-right: var(--space-2);
    font-weight: 600;
}

.nutzer-auswahlleiste > select {
    flex: 0 1 20rem;
    width: auto;
    min-width: 12rem;
}

/*
 * apPersonenHaken() (js/portal-bausteine.js): Suchfeld und "n ausgewählt"
 * ueber der Liste der Personenzeilen.
 */
.personen-haken-kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    margin-bottom: var(--space-3);
}

.personen-haken-kopf input[type="search"] {
    flex: 1 1 16rem;
    width: auto;
    min-width: 0;
}

.personen-haken-zaehler {
    flex: 0 0 auto;
}

/*
 * Der Kreis mit Bild oder Kuerzel (src/person_bild.php, personKreisHtml).
 *
 * Das Kuerzel liegt immer darunter, das Bild - wenn es eines gibt -
 * darueber. Laedt das Bild nicht, bleibt das Kuerzel stehen.
 *
 * Dieselben Farben wie .personzeile-bild in den Listen: Wer sich oben
 * rechts als "JL" sieht, soll sich in der Liste als "JL" wiederfinden.
 */
.personkreis {
    position: relative;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--accent-soft);
    /* Schrift, also --accent-text: --accent auf --accent-soft hatte 2,6:1,
       WCAG 2.1 AA verlangt 4,5:1 (P4-17, axe). */
    color: var(--accent-text);
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 0.02em;
    line-height: 1;
    user-select: none;
}

.personkreis img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.personkreis-gross {
    width: 96px;
    height: 96px;
    font-size: 28px;
}

/* In den Listen (apPersonZeile): das Bild ueber dem Kuerzel. */
.personzeile-bild {
    position: relative;
    overflow: hidden;
}

.personzeile-bild img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Der Kreis vor einem Namen in einer Tabellen- oder Listenzeile
   (apPersonKreisHtml, personKreisHtml mit 'personkreis-zeile') -
   Rueckmeldungen, Teilnehmer, Auswahllisten. */
.personkreis-zeile {
    margin-right: var(--space-2);
    vertical-align: middle;
}

/*
 * Ein Name mitten in einer Text- oder Metazeile ("angelegt von …",
 * "Besteller", "Von …") - der Kreis klein und auf der Schriftlinie, damit
 * die Zeile nicht hoeher wird (07.10.2026: "ueberall, wo ein Name eines
 * Kontakts steht, das Profilbild"). personNameHtml() / apPersonNameHtml().
 */
.person-im-text {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    vertical-align: middle;
    white-space: nowrap;
}

.personkreis.personkreis-text {
    width: 20px;
    height: 20px;
    font-size: 8px;
}

/* Mehrere Personen nebeneinander (Zugewiesen an, Zuständig). */
.personen-im-text {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px var(--space-3);
    align-items: center;
}

/* Der Bildbereich im Profil und in der Benutzermaske. */
.personbild-feld {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    flex-wrap: wrap;
}

.personbild-feld > div {
    flex: 1 1 16rem;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.personbild-feld .actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0;
}

.personbild-feld input[type="file"] {
    display: none;
}

/* Oben rechts im Kopf: Kreis, dann Name und Organisation. */
.user-menu-toggle .personkreis {
    margin-right: var(--space-1);
}

.user-menu-toggle > .personkreis + span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Im aufklappenden Menue auf dem Telefon. Die Regeln fuer
   ".nav-drawer-user span" (layout/header.css) wuerden den Kreis sonst
   zu einer grauen Textzeile machen. */
.nav-drawer-user:has(.personkreis) {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.nav-drawer-user .personkreis {
    display: inline-flex;
    width: 40px;
    height: 40px;
    font-size: 14px;
    color: var(--accent-text);
}

.nav-drawer-user .personkreis-kuerzel {
    display: inline;
    font-size: inherit;
    color: inherit;
}

.nav-drawer-user-text {
    min-width: 0;
}

/* (G3, 04.10.2026) "Gelesen von" einer Mitteilung - Namen mit Passbild
   nebeneinander statt einer Zeile mit Mittelpunkten. */
.gesehen-liste {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
}

.gesehen-person {
    display: inline-flex;
    align-items: center;
}

/*
 * Im Druck (Bestellschein, Einladungsblatt; 08.10.2026): Der Kreis behaelt
 * seinen Grund, sonst laesst der Browser ihn weg und das Kuerzel steht
 * ohne Kreis da. Das Bild darueber druckt ohnehin.
 */
@media print {
    .personkreis {
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }
}

/*
 * Die Einheitenauswahl als Baum (window.apKnotenAuswahl, includes/layout.php).
 * (Betreiber, 23.09.2026: "optisch noch schoener")
 *
 * Linien wie in der Alarmierung: je Ebene ein senkrechter Strich, solange
 * darunter noch ein Geschwister folgt, und ein Winkel zum Namen. Die
 * Eintraege haben keinen Abstand untereinander - sonst reissen die
 * Striche zwischen den Zeilen ab.
 */
.knotenwahl {
    position: relative;
    display: inline-flex;
    min-width: 16rem;
    max-width: 100%;
}

.knotenwahl[data-breit="ja"] {
    display: flex;
    width: 100%;
}

.knotenwahl-quelle {
    display: none !important;
}

.knotenwahl-knopf {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
    min-height: var(--tap);
    padding: var(--space-2) var(--space-3);
    background: var(--bg-input, var(--bg-card-2));
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color var(--transition);
}

.knotenwahl-knopf:hover,
.knotenwahl-knopf[aria-expanded="true"] {
    border-color: var(--accent);
}

.knotenwahl-wert {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

/* Der Pfeil als gezeichnetes Dreieck - kein Zeichen, das je nach Schrift
   anders aussieht. */
.knotenwahl-pfeil {
    flex: 0 0 auto;
    width: 0;
    height: 0;
    margin-left: var(--space-1);
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 6px solid var(--text-muted);
    transition: transform var(--transition);
}

.knotenwahl-knopf[aria-expanded="true"] .knotenwahl-pfeil {
    transform: rotate(180deg);
}

.knotenwahl-liste {
    position: fixed;
    z-index: calc(var(--z-modal) + 10);
    overflow-y: auto;
    padding: var(--space-1) 0;
    background: var(--bg-elevated);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    overscroll-behavior: contain;
}

.knotenwahl-liste[hidden] {
    display: none;
}

.knotenwahl-eintrag {
    --kw-strich: color-mix(in srgb, var(--text-muted) 55%, transparent);
    display: flex;
    align-items: stretch;
    min-height: 38px;
    padding: 0 var(--space-3);
    cursor: pointer;
    outline: none;
}

.knotenwahl-eintrag:hover,
.knotenwahl-eintrag:focus {
    background: var(--bg-card-2);
}

.knotenwahl-eintrag[aria-selected="true"] {
    background: var(--accent-soft);
}

.knotenwahl-eintrag[aria-selected="true"] .knotenwahl-name {
    color: var(--accent);
    font-weight: 700;
}

/* "Alle Einheiten" und Aehnliches: abgesetzt, ohne Linien. */
.knotenwahl-eintrag[data-leer="ja"] {
    border-bottom: 1px solid var(--border-soft);
    margin-bottom: var(--space-1);
}

.knotenwahl-eintrag[data-leer="ja"] .knotenwahl-name {
    color: var(--text-soft);
    font-style: italic;
}

/* Die Organisation: die Wurzel, kraeftiger. */
.knotenwahl-eintrag[data-tiefe="0"] .knotenwahl-name {
    font-weight: 700;
}

/* Nur Pfad (selectable: false): gezeigt, damit der Baum zusammenhaelt,
   aber nicht waehlbar (Kleidung K5). */
.knotenwahl-eintrag[aria-disabled="true"] {
    cursor: default;
}

.knotenwahl-eintrag[aria-disabled="true"]:hover {
    background: transparent;
}

.knotenwahl-eintrag[aria-disabled="true"] .knotenwahl-name {
    color: var(--text-soft);
    font-weight: 400;
    font-style: italic;
}

/*
 * 18 px je Ebene - als `width` UND als flex-basis. Nur die flex-basis
 * reicht nicht: Steht die Linienspalte in einer Rasterspalte `auto`
 * (Alarmbaum, Struktur), misst der Browser ihre Breite aus dem Inhalt,
 * und manche Browser rechnen leere Kaestchen dabei mit 0 px - flex-basis
 * hin oder her. Dann ist die Spalte 0 px breit, jede Ebene steht
 * untereinander und die Striche laufen durch die Punkte (Betreiber,
 * 24.09.2026, Bildschirmfoto: "es ist nicht eingerueckt").
 */
.knotenwahl-linie,
.knotenwahl-ast {
    position: relative;
    flex: 0 0 18px;
    width: 18px;
}

.knotenwahl-linie[data-weiter="1"]::before,
.knotenwahl-ast::before {
    content: "";
    position: absolute;
    left: 8px;
    top: 0;
    bottom: 0;
    border-left: 1px solid var(--kw-strich);
}

/* Der letzte eines Astes: Strich nur bis zur Mitte - ein Winkel, kein T. */
.knotenwahl-ast[data-letzter="1"]::before {
    bottom: 50%;
}

.knotenwahl-ast::after {
    content: "";
    position: absolute;
    left: 8px;
    top: 50%;
    width: 12px;
    border-top: 1px solid var(--kw-strich);
}

.knotenwahl-name {
    flex: 1 1 auto;
    align-self: center;
    padding: var(--space-2) var(--space-2) var(--space-2) 2px;
    min-width: 0;
    overflow-wrap: anywhere;
}

.knotenwahl-zahl {
    flex: 0 0 auto;
    align-self: center;
    min-width: 1.6em;
    padding: 1px 7px;
    border-radius: var(--radius-pill);
    background: rgba(255, 255, 255, 0.07);
    color: var(--text-soft);
    font-size: var(--text-xs);
    font-weight: 600;
    text-align: center;
}

/* Eine leere Einheit ist gewollt sichtbar - aber blass. */
.knotenwahl-zahl[data-null="ja"] {
    opacity: 0.5;
}

/*
 * Die Linien ausserhalb der Aufklappliste - als eigene Spalte in einer
 * Zeile (der Alarmbaum in alarmieren.php). Dieselben Bausteine, damit
 * beide gleich aussehen; die Spalte fuellt die ganze Zeilenhoehe, sonst
 * reissen die Striche zwischen den Zeilen ab.
 */
.baum-linienspalte {
    --kw-strich: color-mix(in srgb, var(--text-muted) 55%, transparent);
    display: flex;
    align-self: stretch;
}

.baum-linienspalte:empty {
    width: 0;
}

/*
 * Die hinterlegte Farbe der Einheit (units.color), wie im Monitor.
 *
 * 3 px nach innen: Dann sitzt die Mitte des Punkts genau ueber der
 * Senkrechten seiner Kinder (8 px in deren Linienspalte), und der Ast
 * (bis 20 px) laeuft bis an den Punkt heran. Dieselben Masse gelten in
 * den Baeumen von alarmieren.php und admin/baum.php.
 */
.knotenwahl-farbe {
    flex: 0 0 auto;
    align-self: center;
    width: 10px;
    height: 10px;
    margin-left: 3px;
    margin-right: var(--space-2);
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.35);
}

.knotenwahl-farbe[data-ohne="ja"] {
    box-shadow: none;
    background: transparent;
}

/*
 * Die Leiste fuer Arbeit im Hintergrund (window.apHintergrund,
 * includes/layout.php): oben am Bildschirm, mit Kreisel und Balken - man
 * arbeitet weiter und sieht, wie weit es ist.
 */
.ap-fortschritt {
    position: fixed;
    top: calc(var(--header-h, 61px) + var(--space-2));
    left: 50%;
    transform: translateX(-50%);
    z-index: calc(var(--z-modal) - 1);
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: min(32rem, calc(100vw - 2 * var(--space-4)));
    padding: var(--space-2) var(--space-3);
    background: var(--bg-elevated);
    border: 1px solid var(--accent);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    font-size: var(--text-sm);
}

.ap-fortschritt[hidden] {
    display: none;
}

.ap-fortschritt-kreisel {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    border: 2px solid var(--accent-soft);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: ap-kreisel 0.8s linear infinite;
}

@keyframes ap-kreisel {
    to { transform: rotate(360deg); }
}

.ap-fortschritt-text {
    flex: 0 1 auto;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.ap-fortschritt-bahn {
    flex: 1 1 6rem;
    height: 6px;
    border-radius: var(--radius-pill);
    background: var(--bg-card-2);
    overflow: hidden;
}

.ap-fortschritt-bahn > span {
    display: block;
    height: 100%;
    width: 0;
    background: var(--accent);
    transition: width 0.2s ease;
}

/*
 * Der Zurueck-Knopf ueber dem Inhalt (zurueckZiel() in
 * includes/navigation.php, gesetzt von pageEnd()).
 *
 * Ein ruhiger Knopf statt eines nackten Links - er soll als Weg erkennbar
 * sein, ohne sich vor den Inhalt zu draengen.
 */
.ap-zurueck {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 36px;
    margin-bottom: var(--space-3);
    padding: var(--space-1) var(--space-4) var(--space-1) var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    background: var(--bg-card-2);
    color: var(--text);
    font-size: var(--text-sm);
    font-weight: 600;
    text-decoration: none;
    transition: background var(--transition), border-color var(--transition);
}

/* Der Pfeil gezeichnet, nicht als Zeichen: "‹" sitzt je nach Schrift auf
   der Grundlinie und damit unter der Mitte (Betreiber, 23.09.2026). */
.ap-zurueck-pfeil {
    width: 7px;
    height: 7px;
    margin-left: 3px;
    border-left: 2px solid var(--text-muted);
    border-bottom: 2px solid var(--text-muted);
    transform: rotate(45deg);
}

.ap-zurueck:hover {
    border-color: var(--accent);
    background: var(--bg-elevated);
    text-decoration: none;
}

.ap-zurueck:hover .ap-zurueck-pfeil {
    border-color: var(--accent);
}

/*
 * Die Organisationsauswahl des Systemadmins (orgWahlLeiste() in
 * includes/layout.php, gesetzt ueber pageStart(['orgwahl' => ...])).
 *
 * Steht ueber dem Inhalt, unter dem Zurueck-Knopf, auf jeder Seite an
 * derselben Stelle - wer die Organisation wechseln will, sucht nicht erst.
 * Farblich abgesetzt: Sie ist die eine Einstellung, die bestimmt, WESSEN
 * Daten darunter stehen.
 */
.ap-orgwahl {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-3);
    margin-bottom: var(--space-4);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--accent);
    border-radius: var(--radius-md);
    background: var(--bg-card-2);
}

.ap-orgwahl label {
    margin: 0;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-muted);
}

.ap-orgwahl select {
    flex: 1 1 16rem;
    max-width: 28rem;
    min-width: 0;
}

.ap-orgwahl-hinweis {
    flex-basis: 100%;
    margin: 0;
    font-size: var(--text-sm);
    color: var(--warning, #b8860b);
}

/*
 * Die Farbauswahl (js/farbwahl.js) - statt des Farbfensters von Windows.
 *
 * .ap-farbe      das Farbfeld, das an der Stelle des Eingabefelds steht
 * .ap-farbwahl   das aufklappende Fenster: Palette, zuletzt benutzt,
 *                eigene Farbe, Hexwert
 */

/* Das Eingabefeld bleibt im Formular und traegt den Wert - nur sehen
   und anklicken kann man es nicht mehr. Ohne top/left bleibt es an
   seiner Stelle und schiebt nichts aus dem Bild.
   !important, weil Seiten ihre Farbfelder selbst bemassen (etwa
   ".f-row input[type=color] { width: 100% }") - absolut gesetzt hiesse
   das 100 % eines ganz anderen Rahmens, und die Seite liefe seitlich ueber. */
input[type="color"].ap-farbe-nativ {
    position: absolute !important;
    width: 1px !important;
    min-width: 0 !important;
    height: 1px !important;
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    opacity: 0;
    pointer-events: none;
    clip-path: inset(50%);
}

.ap-farbe {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-width: 0;
    min-height: 40px;
    padding: 4px var(--space-3) 4px 4px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-input, var(--bg-card-2));
    color: var(--text);
    font: inherit;
    font-size: var(--text-sm);
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: border-color var(--transition), box-shadow var(--transition);
}

.ap-farbe:hover {
    border-color: var(--accent);
}

.ap-farbe:focus-visible,
.ap-farbe[aria-expanded="true"] {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

.ap-farbe:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

.ap-farbe-flaeche {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: calc(var(--radius-md) - 3px);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25), inset 0 0 0 2px rgba(255, 255, 255, 0.12);
}

.ap-farbe-wert {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-soft);
}

/* In engen Spalten (Funktionen, Qualifikationen) nur die Farbe. */
.f-row .ap-farbe,
.q-row .ap-farbe {
    justify-content: center;
    padding: 4px;
}

.f-row .ap-farbe-flaeche,
.q-row .ap-farbe-flaeche {
    width: 100%;
    min-width: 30px;
}

.f-row .ap-farbe-wert,
.q-row .ap-farbe-wert {
    display: none;
}

/* ------------------------------------------------------------------ */

.ap-farbwahl {
    position: fixed;
    z-index: calc(var(--z-modal) + 10);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: 340px;
    max-width: calc(100vw - 16px);
    max-height: calc(100vh - 16px);
    overflow-y: auto;
    padding: var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--bg-elevated);
    box-shadow: var(--shadow-lg, 0 12px 32px rgba(0, 0, 0, 0.45));
}

.ap-farbwahl[hidden] {
    display: none;
}

.ap-farbwahl-kopf {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.ap-farbwahl-probe {
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25), inset 0 0 0 2px rgba(255, 255, 255, 0.12);
}

.ap-farbwahl-hex {
    flex: 1 1 auto;
    min-width: 0;
    font-family: var(--font-mono, ui-monospace, monospace);
    text-transform: uppercase;
}

.ap-farbwahl-titel {
    margin-top: var(--space-1);
    font-size: var(--text-xs, 0.75rem);
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.ap-farbwahl-titel[hidden],
.ap-farbwahl-palette[hidden] {
    display: none;
}

.ap-farbwahl-palette {
    display: grid;
    grid-template-columns: repeat(8, minmax(0, 1fr));
    gap: 8px;
}

/* min-height/min-width: Die allgemeine Knopfregel (buttons.css) gibt
   jedem <button> die Mindesthoehe fuer Finger - hier machte sie aus
   jedem Farbfeld ein hohes Rechteck, und die Palette passte nicht mehr. */
.ap-farbwahl-feld {
    aspect-ratio: 1;
    width: 100%;
    min-width: 0;
    min-height: 0;
    height: auto;
    padding: 0;
    border: 0;
    border-radius: 6px;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25), inset 0 0 0 2px rgba(255, 255, 255, 0.1);
    cursor: pointer;
    transition: transform 0.1s ease;
}

.ap-farbwahl-feld:hover {
    transform: scale(1.12);
}

.ap-farbwahl-feld:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.ap-farbwahl-feld.ist-gewaehlt {
    outline: 2px solid var(--text);
    outline-offset: 2px;
}

/* Saettigung nach rechts, Helligkeit nach oben - ueber dem Farbton. */
.ap-farbwahl-flaeche {
    position: relative;
    height: 132px;
    border-radius: var(--radius-md);
    background-image:
        linear-gradient(to top, #000, rgba(0, 0, 0, 0)),
        linear-gradient(to right, #fff, rgba(255, 255, 255, 0));
    cursor: crosshair;
    touch-action: none;
}

.ap-farbwahl-ton {
    position: relative;
    height: 14px;
    margin: var(--space-1) 0;
    border-radius: var(--radius-pill);
    background: linear-gradient(to right, #f00 0%, #ff0 16.67%, #0f0 33.33%, #0ff 50%, #00f 66.67%, #f0f 83.33%, #f00 100%);
    cursor: pointer;
    touch-action: none;
}

.ap-farbwahl-punkt {
    position: absolute;
    width: 16px;
    height: 16px;
    border: 2px solid #fff;
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.5), 0 2px 4px rgba(0, 0, 0, 0.4);
    transform: translate(-50%, -50%);
    pointer-events: none;
}

.ap-farbwahl-ton .ap-farbwahl-punkt {
    top: 50%;
    width: 18px;
    height: 18px;
}

.ap-farbwahl-flaeche:focus-visible,
.ap-farbwahl-ton:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.ap-farbwahl-fuss {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-2);
}

/*
 * Das Kontextmenue (window.apKontextmenue, js/portal-bausteine.js) -
 * Rechtsklick, langes Druecken oder die Kontextmenuetaste an einer Zeile.
 * Dasselbe Menue in Chat, Dokumenten und Galerie.
 *
 * .ap-kontextmenue                    die Liste (position: fixed, im Fenster gehalten)
 * .ap-kontextmenue-eintrag            ein Eintrag; .gefaehrlich rot, [disabled] blass
 * .ap-kontextmenue-symbol             ein Symbol vor dem Text (optional)
 * .ap-kontextmenue-trenner            eine Linie zwischen Gruppen
 *
 * Der Chat gibt seinen Menues zusaetzlich .chat-menue (chat.php) - dort
 * stehen nur noch Reaktionsleiste und Schleier.
 */

.ap-kontextmenue {
    position: fixed;
    /* Ueber der unteren Leiste am Telefon (--z-drawer + 1) und ueber einem
       Dialog, aus dem es vielleicht aufgeht. */
    z-index: calc(var(--z-modal, 1600) + 5);
    min-width: 200px;
    max-width: calc(100vw - 16px);
    max-height: calc(100dvh - 16px);
    overflow-y: auto;
    margin: 0;
    padding: 4px 0;
    list-style: none;
    background: var(--bg-elevated, var(--bg-card));
    color: var(--text, inherit);
    border: 1px solid var(--border, rgba(128, 128, 128, 0.35));
    border-radius: var(--radius-md, 8px);
    box-shadow: var(--shadow-md, 0 6px 24px rgba(0, 0, 0, 0.35));
    font-size: 0.95em;
}

.ap-kontextmenue li button.ap-kontextmenue-eintrag {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 36px;
    padding: 6px 14px;
    border: 0;
    border-radius: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.ap-kontextmenue li button.ap-kontextmenue-eintrag:hover {
    background: rgba(128, 128, 128, 0.15);
}

.ap-kontextmenue li button.ap-kontextmenue-eintrag:focus-visible {
    background: rgba(128, 128, 128, 0.22);
    outline: none;
}

.ap-kontextmenue li button.ap-kontextmenue-eintrag.gefaehrlich {
    color: var(--danger-hover, #F05555);
}

.ap-kontextmenue li button.ap-kontextmenue-eintrag:disabled {
    opacity: 0.45;
    cursor: default;
    background: none;
}

.ap-kontextmenue-symbol {
    flex: none;
    display: inline-grid;
    place-items: center;
    width: 18px;
    color: var(--text-soft);
}

.ap-kontextmenue-eintrag.gefaehrlich .ap-kontextmenue-symbol {
    color: inherit;
}

.ap-kontextmenue-trenner {
    height: 1px;
    margin: 4px 0;
    background: var(--border-soft, rgba(128, 128, 128, 0.25));
}

/* Am Telefon groessere Ziele - der Finger, nicht die Maus. */
@media (pointer: coarse) {
    .ap-kontextmenue li button.ap-kontextmenue-eintrag {
        min-height: 44px;
    }
}

/*
 * Die Fehlerseite (src/fehlerseite.php).
 *
 * Eine Karte in der Mitte, oben ein Kreis mit Symbol in der Farbe der
 * Art: gelb fuer "kein Zugriff", blau fuer "nicht gefunden" und
 * "Anfrage", rot nur fuer den Serverfehler - Rot bedeutet im Portal
 * Stoerung, und ein fehlendes Recht ist keine.
 *
 * Im Kern-Bundle und nicht als eigenes: Die eigenstaendige Fassung (ohne
 * Kopfleiste, wenn die Datenbank fehlt) laedt nur "core".
 */

.fehler-seite {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    min-height: calc(100vh - var(--header-height) - 120px);
    min-height: calc(100dvh - var(--header-height) - 120px);
    padding: var(--space-8) var(--gutter) calc(var(--space-8) + var(--safe-bottom, 0px));
    padding-left: max(var(--gutter), var(--safe-left, 0px));
    padding-right: max(var(--gutter), var(--safe-right, 0px));
}

.fehler-karte {
    --fehler-farbe: var(--accent-text);
    --fehler-grund: var(--accent-soft);

    position: relative;
    width: 100%;
    max-width: 520px;
    padding: var(--space-8) var(--space-7) var(--space-7);
    overflow: hidden;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    text-align: center;
}

/* Ein farbiger Streifen oben - dieselbe Farbe wie der Kreis. */
.fehler-karte::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--fehler-farbe);
}

.fehler-karte--zugriff {
    --fehler-farbe: var(--warning);
    --fehler-grund: rgba(255, 173, 31, 0.14);
}

.fehler-karte--server {
    --fehler-farbe: var(--danger-hover);
    --fehler-grund: rgba(220, 63, 63, 0.16);
}

.fehler-symbol {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 84px;
    height: 84px;
    margin-bottom: var(--space-5);
    border-radius: 50%;
    background: var(--fehler-grund);
    color: var(--fehler-farbe);
    box-shadow: 0 0 0 8px color-mix(in srgb, var(--fehler-grund) 45%, transparent);
}

.fehler-symbol-bild {
    width: 40px;
    height: 40px;
}

.fehler-code {
    margin: 0 0 var(--space-2);
    color: var(--fehler-farbe);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.fehler-titel {
    margin: 0 0 var(--space-4);
    font-size: var(--text-h2);
    line-height: 1.25;
}

.fehler-text {
    margin: 0 auto var(--space-3);
    max-width: 42ch;
    color: var(--text-soft);
    font-size: var(--text-md);
    line-height: 1.55;
}

.fehler-hinweis {
    margin: 0 auto;
    max-width: 44ch;
    color: var(--text-muted);
    font-size: var(--text-base);
    line-height: 1.55;
}

.fehler-aktionen {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    margin-top: var(--space-7);
}

.fehler-aktionen .btn {
    min-width: 150px;
}

.fehler-fuss {
    margin: var(--space-6) 0 0;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-soft);
    color: var(--text-muted);
    font-size: var(--text-xs);
}

.fehler-fuss code {
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
    color: var(--text-soft);
}

/* Die eigenstaendige Fassung: statt der Kopfleiste nur das Zeichen. */
.fehlerseite-eigenstaendig .fehler-marke {
    display: flex;
    justify-content: center;
    padding: var(--space-7) var(--gutter) 0;
}

.fehlerseite-eigenstaendig .fehler-marke img {
    width: auto;
    height: 40px;
}

.fehlerseite-eigenstaendig .fehler-seite {
    min-height: 0;
    padding-top: var(--space-6);
}

@media (max-width: 480px) {
    .fehler-seite {
        padding-top: var(--space-6);
    }

    .fehler-karte {
        padding: var(--space-7) var(--space-5) var(--space-6);
    }

    .fehler-aktionen {
        flex-direction: column;
    }

    .fehler-aktionen .btn {
        width: 100%;
    }
}

/* Statusverlauf eines Fahrzeugs (02.10.2026) - js/portal-bausteine.js,
   apFahrzeugVerlauf(). Geöffnet von jedem Knopf mit data-vehicle-history:
   Dashboard ("Fahrzeuge"), Alarmansicht ("Fahrzeugstatus"), Karte (Liste
   und Popup), Einsatzanzeige (Kacheln) und Fahrzeugverwaltung ("Verlauf"). */

/* Die ganze Fahrzeugzeile als Knopf - sieht aus wie vorher, ist aber mit
   Tastatur und Finger bedienbar. Das Seitenlayout setzt die Anordnung. */
.fz-verlauf-knopf {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    border-radius: var(--radius-sm);
}

.fz-verlauf-knopf:hover .fz-verlauf-mehr,
.fz-verlauf-knopf:focus-visible .fz-verlauf-mehr {
    color: var(--text);
}

.fz-verlauf-mehr {
    flex: 0 0 auto;
    color: var(--text-soft);
    font-size: 1.2em;
    line-height: 1;
}

.fz-verlauf-name {
    margin: 0 0 var(--space-1, 4px);
    font-weight: 600;
}

.fz-verlauf-hinweis {
    margin: 0 0 var(--space-3);
}

.fz-verlauf-liste {
    list-style: none;
    margin: 0;
    padding: 0;
}

.fz-verlauf-eintrag {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--border-soft);
}

.fz-verlauf-eintrag:last-child {
    border-bottom: none;
}

.fz-verlauf-ziffer {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.2em;
    height: 2.2em;
    padding: 0 .3em;
    border-radius: var(--radius-sm);
    background: var(--fz-farbe, var(--bg-card-2));
    color: var(--fz-schrift, var(--text));
    font-weight: 700;
}

/* Der Einsatzbeginn (03.10.2026): Glocke statt Statusziffer, in Alarmrot. */
.fz-verlauf-glocke {
    background: var(--danger);
    color: #fff;
}

.fz-verlauf-glocke svg {
    width: 1.2em;
    height: 1.2em;
}

.fz-verlauf-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.fz-verlauf-text > * {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.fz-verlauf-zeit {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    font-variant-numeric: tabular-nums;
    text-align: right;
}

/* Wie lange der Status stand - bis zum naechsten, beim neuesten "seit". */
.fz-verlauf-dauer {
    font-size: var(--text-sm, .88rem);
}

/* Im Monitor ausgeblendet (04.10.2026): eine Meldung ohne Zustandswechsel
   (Sprechwunsch …) - gedaempft, die Ziffer gestrichelt umrandet, ohne Dauer. */
.fz-verlauf-signal .fz-verlauf-ziffer {
    opacity: .6;
    outline: 1px dashed var(--text-soft);
    outline-offset: 1px;
}

.fz-verlauf-signal .fz-verlauf-text strong {
    font-weight: 500;
    color: var(--text-soft);
}

/* Rueckmeldung zum Einsatz (04.10.2026): ebenfalls kein Zustand, also
   gedaempft wie oben - aber durchgezogen in Akzentfarbe umrandet und die
   Beschriftung in Akzentschrift, damit sie sich vom Sprechwunsch abhebt. */
.fz-verlauf-rueckmeldung .fz-verlauf-ziffer {
    outline: 2px solid var(--accent-text);
}

.fz-verlauf-rueckmeldung .fz-verlauf-art {
    color: var(--accent-text);
}

.fz-verlauf-vorher {
    margin-top: var(--space-4, 16px);
    padding-top: var(--space-3);
    border-top: 1px dashed var(--border-soft);
}

.fz-verlauf-unter {
    margin: 0 0 var(--space-2);
    font-size: var(--text-sm, .88rem);
    color: var(--text-soft);
}

@media (max-width: 420px) {

    .fz-verlauf-zeit {
        max-width: 7.5em;
        white-space: normal;
    }
}

/* Fahrzeugstatuslisten sortieren und filtern (04.10.2026) - js/fahrzeugliste.js.
   Dashboard ("Fahrzeuge"), Alarmansicht ("Fahrzeugstatus"), Karte
   ("Fahrzeugstatus") und Fahrzeugverwaltung. */

.fz-liste-werkzeug {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-2);
}

.fz-liste-werkzeug[hidden] {
    display: none;
}

.fz-liste-suche {
    flex: 1 1 10rem;
    min-width: 0;
}

.fz-liste-wahl {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
}

.fz-liste-werkzeug .fz-liste-suche,
.fz-liste-werkzeug .fz-liste-wahl {
    width: auto;
    margin: 0;
    padding: 6px 10px;
    font-size: .9rem;
}

/* Rechts Platz für den Pfeil der Auswahl (forms.css malt ihn als Hintergrund). */
.fz-liste-werkzeug .fz-liste-wahl {
    padding-right: 2rem;
}

.fz-liste-stand {
    margin: 0 0 var(--space-2);
    font-size: .88rem;
}

.fz-liste-stand[hidden] {
    display: none;
}

.fz-liste-zuruecksetzen {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

/* Ausgefilterte Zeilen: Die Listen setzen display:flex an ihre Zeilen, das
   schlüge das hidden-Attribut sonst. */
[data-fz-name][hidden] {
    display: none !important;
}

/* Wann der Status zuletzt wechselte - klein neben dem Namen. */
.fz-liste-seit {
    flex: 0 0 auto;
    color: var(--text-soft);
    font-size: .8rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

@media (max-width: 480px) {
    .fz-liste-suche {
        flex-basis: 100%;
    }

    /* Zwei je Zeile - drei nebeneinander schnitten die Beschriftung ab. */
    .fz-liste-wahl {
        flex: 1 1 calc(50% - var(--space-2));
    }
}

/*
 * Das Vorschaufenster fuer Dokumente (js/dokumentansicht.js) - auf jeder
 * Seite, die es zeigt: Dokumente und Lagekarte (07.10.2026). Bis dahin
 * stand es nur in pages/dokumente.css und galt damit nur dort.
 *
 * Dazu die Kuerzel-Plakette (.dok-symbol), die das Fenster zeigt, wenn es
 * fuer einen Typ keine Vorschau gibt - die Dokumentenliste benutzt sie
 * ebenso.
 */
.dok-symbol {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border-radius: var(--radius-sm);
    background: var(--bg-card-2);
    border: 1px solid var(--border);
    color: var(--text-soft);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}


.dok-symbol-pdf { color: #e53935; border-color: rgba(229, 57, 53, 0.45); }
.dok-symbol-doc, .dok-symbol-docx { color: #1e88e5; border-color: rgba(30, 136, 229, 0.45); }
.dok-symbol-xls, .dok-symbol-xlsx, .dok-symbol-csv { color: #43a047; border-color: rgba(67, 160, 71, 0.45); }
.dok-symbol-ppt, .dok-symbol-pptx { color: #fb8c00; border-color: rgba(251, 140, 0, 0.45); }

/* ---- Die Vorschau ------------------------------------------------- */

.modal.dok-viewer {
    align-items: stretch;
    justify-content: stretch;
    padding: var(--space-3);
}

.dok-viewer-rahmen {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    max-height: calc(100dvh - 2 * var(--space-3));
    max-width: 1400px;
    margin: 0 auto;
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    overflow: hidden;
}

.dok-viewer-kopf {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border);
}

.dok-viewer-titel {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.dok-viewer-titel strong,
.dok-viewer-titel span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dok-viewer-flaeche {
    position: relative;
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-card-2);
    overflow: auto;
}

.dok-viewer-pdf {
    width: 100%;
    height: 100%;
    min-height: 70vh;
    border: 0;
    background: #fff;
}

/* Word und Excel: ein Rahmen ohne Skripte, darueber bei Excel die Blaetter. */
.dok-viewer-office {
    align-self: stretch;
    display: flex;
    flex-direction: column;
    width: 100%;
    min-height: 70vh;
}

.dok-viewer-office iframe {
    flex: 1;
    width: 100%;
    border: 0;
    background: #fff;
}

.dok-viewer-blaetter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1, 4px);
    padding: var(--space-2);
    border-bottom: 1px solid var(--border);
    background: var(--bg-card);
}

.dok-viewer-bild {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.dok-viewer-text {
    align-self: stretch;
    width: 100%;
    margin: 0;
    padding: var(--space-4);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    font-size: var(--text-sm);
}

.dok-viewer-ohne {
    display: grid;
    justify-items: center;
    gap: var(--space-3);
    padding: var(--space-6, 32px);
    text-align: center;
}

.dok-symbol-gross {
    width: 88px;
    height: 88px;
    font-size: 1.1rem;
}

@media (max-width: 719px) {
    .modal.dok-viewer {
        padding: 0;
    }

    .dok-viewer-rahmen {
        border-radius: 0;
    }

    .dok-viewer-kopf {
        flex-wrap: wrap;
    }
}

/* -------------------------------------------------------------------
   Übersichtsseite einer Rubrik

   Eine Karte je Seite, mit einem Satz dazu. Der Satz ist der eigentliche
   Punkt: eine Liste aus dreißig Wörtern wie "Vorlagen" oder "Status"
   sagt niemandem, was dahinter steckt - genau daran ist die alte
   Navigation gescheitert.
   ------------------------------------------------------------------- */

.hub-head {
    margin-bottom: var(--space-6);
}

.hub-head h1 {
    margin: 0 0 var(--space-2);
}

.hub-head p {
    margin: 0;
    max-width: 62ch;
    color: var(--text-soft);
}

.hub-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--space-4);
}

.hub-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--bg-card);
    color: inherit;
    text-decoration: none;
    transition: border-color var(--transition), background var(--transition), transform var(--transition);
}

.hub-card:hover,
.hub-card:focus-visible {
    border-color: var(--accent);
    background: var(--bg-elevated);
}

.hub-card-title {
    font-size: var(--text-lg, 1.05rem);
    font-weight: 600;
    color: var(--text);
}

.hub-card-blurb {
    font-size: var(--text-sm, .9rem);
    line-height: 1.45;
    color: var(--text-soft);
}

/* Auf dem Telefon eine Spalte, aber mit ordentlicher Tapfläche. */
@media (max-width: 560px) {
    .hub-grid {
        grid-template-columns: 1fr;
        gap: var(--space-3);
    }

    .hub-card {
        padding: var(--space-4);
    }
}

@media (prefers-reduced-motion: no-preference) {
    .hub-card:hover {
        transform: translateY(-1px);
    }
}

/* Symbol links, Text rechts - das Symbol ist der Ankerpunkt beim
   Ueberfliegen, der Satz die Erklaerung. */
.hub-card {
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-4);
}

.hub-card-icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    background: var(--bg-card-2);
    color: var(--accent-text, var(--text-soft));
}

.hub-card-icon .icon {
    width: 20px;
    height: 20px;
}

.hub-card-text {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

/* Die Suche der Rubrikseite (includes/hub.php). */
.hub-suche {
    display: block;
    width: 100%;
    max-width: 32rem;
    margin-top: var(--space-4);
}

.hub-card[hidden] {
    display: none;
}

.hub-leer {
    margin: 0 0 var(--space-4);
}

.hub-andere {
    margin-top: var(--space-6);
}

.hub-andere[hidden] {
    display: none;
}

.hub-andere h2 {
    margin: 0 0 var(--space-3);
    font-size: var(--text-base, 1rem);
    color: var(--text-soft);
}

/* Aus welcher Rubrik ein Treffer kommt - klein neben dem Titel. */
.hub-card-rubrik {
    margin-left: var(--space-2);
    padding: 1px var(--space-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-pill);
    font-size: var(--text-xs, 0.75rem);
    font-weight: 500;
    color: var(--text-muted);
    vertical-align: middle;
}

/* -------------------------------------------------------------------
   Themen und gleich hohe Kacheln (Betreiber, 01.10.2026)

   "Kacheln sollen auch alle gleich hoch sein (wenn Text zu lang, eher
   den Text kürzen)": feste Zeilenhöhe, Titel eine Zeile, Satz höchstens
   zwei. Der volle Text steht im title der Kachel (includes/hub.php).
   ------------------------------------------------------------------- */

.hub-abschnitt + .hub-abschnitt {
    margin-top: var(--space-6);
}

.hub-abschnitt[hidden] {
    display: none;
}

.hub-thema {
    margin: 0 0 var(--space-3);
    font-size: var(--text-sm, .9rem);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-soft);
}

@media (min-width: 561px) {
    .hub-grid {
        grid-auto-rows: 7.25rem;
    }

    .hub-card {
        height: 100%;
        overflow: hidden;
    }

    .hub-card-title {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

}

/* Der Satz höchstens zwei Zeilen - auch in der Telefonliste. */
.hub-card-blurb {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
}

/*
 * ======================================================================
 * DAS PORTAL AUF DEM TELEFON - SO NAH AN DEN APPS WIE MÖGLICH
 * ======================================================================
 * Betreiber, 28.09.2026: Wer online aktiv ist, soll sich am Handy so
 * ähnlich wie möglich wie in der App fühlen.
 *
 * Die Masse kommen aus design-tokens.md (Projektstamm), das die iOS-App
 * am Simulator vermessen hat und nach dem Android nachgebaut ist:
 *
 *   Seitengrund                #000000           (0.2, gemessen)
 *   Blöcke / Karten            #1C1C1E, Radius 10, kein Schatten (1.3, 4)
 *   Trennlinie                 #545458 @ 65 %, 0.33 pt (1.3)
 *   gruppierte Liste           Zeile 44, 16 waagerecht, 11 senkrecht,
 *                              Linie ab 52 mit Symbol, Winkel 14 (3.1)
 *   Abschnittsüberschrift      13, Grossbuchstaben, secondaryLabel (2.3)
 *   grosser Titel              34, fett, 20 Einzug (3.2)
 *   Reiterleiste               49 hoch, Symbol 25, Schrift 10 / 500,
 *                              aktiv #2F6FD0, inaktiv #999999 (3.2)
 *
 * Diese Datei steht als LETZTE im Kernbündel (includes/css-bundles.php)
 * und gilt nur für schmale Schirme - am Rechner ändert sie nichts.
 * Seitenbündel kommen danach und dürfen einzelne Stellen weiter
 * überschreiben.
 *
 * Was nicht geht: Blätterübergänge zwischen Seiten, der einklappende
 * grosse Titel und das Wischen zurück - das Portal lädt jede Seite neu.
 */

/* -------------------------------------------------------------------
   Reiterleiste - überall dort, wo sie steht (angemeldet, bis 960 px)
   ------------------------------------------------------------------- */

@media (max-width: 960px) {

    :root {
        --bottom-nav-height: 49px;
        --ios-aktiv: #2F6FD0;
        /* Dieselbe Farbe fuer SCHRIFT, heller: #2F6FD0 hat auf dem Grund der
           Reiterleiste 4,2:1, WCAG 2.1 AA verlangt fuer Text 4,5:1 (P4-17,
           axe). #5596F5 hat dort 6,2:1 und noch 4,6:1, wenn eine helle Karte
           durch die Leiste scheint. Symbole brauchen 3:1 und bleiben bei
           --ios-aktiv. */
        --ios-aktiv-text: #5596F5;
        --ios-inaktiv: #999999;
        --ios-trennlinie: rgba(84, 84, 88, 0.65);
    }

    /*
     * Über dem Menü, nicht darunter: „Mehr" ist ein Reiter wie die
     * anderen, und die Leiste bleibt stehen, während er offen ist.
     */
    .bottom-nav {
        z-index: calc(var(--z-drawer) + 1);
        background: rgba(22, 22, 24, 0.94);
        border-top: 0;
        box-shadow: 0 -0.5px 0 var(--ios-trennlinie);
    }

    @supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
        .bottom-nav {
            /* 0.90 statt 0.78: Unter einer hellen Karte fiel das inaktive
               Grau sonst auf 3,5:1 (P4-17). Bei 0.90 bleiben es 4,8:1. */
            background: rgba(22, 22, 24, 0.9);
            -webkit-backdrop-filter: saturate(180%) blur(20px);
            backdrop-filter: saturate(180%) blur(20px);
        }
    }

    .bottom-nav-item {
        gap: 3px;
        padding: 0;
        color: var(--ios-inaktiv);
        font-size: 10px;
        font-weight: 500;
        letter-spacing: 0.1px;
        -webkit-tap-highlight-color: transparent;
        -webkit-user-select: none;
        user-select: none;
    }

    .bottom-nav-item svg {
        width: 25px;
        height: 25px;
    }

    /* Kein grauer Fleck beim Tippen - die Reiter einer App haben keinen. */
    .bottom-nav-item:active {
        background: none;
    }

    .bottom-nav-item[aria-current="page"],
    .bottom-nav-item[aria-expanded="true"] {
        color: var(--ios-aktiv);
    }

    /* Ist „Mehr" offen, ist nur „Mehr" der aktive Reiter. */
    .bottom-nav:has(.bottom-nav-item[aria-expanded="true"]) .bottom-nav-item[aria-current="page"] {
        color: var(--ios-inaktiv);
    }

    /*
     * Eine Seite, die keinem Reiter gehört (Mängelmelder, Profil ...),
     * liegt in den Apps unter „Mehr" - also leuchtet dort „Mehr".
     */
    .bottom-nav:not(:has(a.bottom-nav-item[aria-current="page"])) #bottomNavMenu {
        color: var(--ios-aktiv);
    }

    /* Die Beschriftung des aktiven Reiters in der Schriftfarbe (s. o.). */
    .bottom-nav-item[aria-current="page"] > span,
    .bottom-nav-item[aria-expanded="true"] > span,
    .bottom-nav:not(:has(a.bottom-nav-item[aria-current="page"])) #bottomNavMenu > span {
        color: var(--ios-aktiv-text);
    }

    .bottom-nav:has(.bottom-nav-item[aria-expanded="true"]) .bottom-nav-item[aria-current="page"] > span {
        color: inherit;
    }

    /* Der Knopf mit den drei Strichen oben wäre ein zweiter Weg zu
       „Mehr" - die Apps haben keinen. Ohne Anmeldung bleibt er. */
    body.has-bottom-nav .nav-toggle {
        display: none;
    }
}

/* -------------------------------------------------------------------
   Telefon
   ------------------------------------------------------------------- */

@media (max-width: 600px) {

    /*
     * Die Flächen der Apps. Die Namen bleiben, nur die Werte wechseln -
     * so zieht jede Seite mit, die mit den Tokens arbeitet.
     *
     * --bg-card-2 wird HELLER als die Karte, nicht dunkler: Auf
     * schwarzem Grund liegt ein Feld in einem Block eine Stufe darüber
     * (systemGray5), wie ein Eingabefeld in einer iOS-Liste.
     */
    :root {
        --bg-main: #000000;
        --bg-card: #1C1C1E;
        --bg-card-2: #2C2C2E;
        --bg-elevated: #2C2C2E;
        --border: #38383A;
        --border-soft: rgba(84, 84, 88, 0.65);
        /* Heller als systemGray #8E8E93: der hatte auf den Feldern
           (#2C2C2E) 4,27:1, #A1A1A6 hat dort 5,4:1. */
        --text-muted: #A1A1A6;
        --radius-lg: 10px;
        --header-height: 44px;
        --shadow-sm: none;
        --ios-zeile-gedrueckt: #3A3A3C;
        --ios-zweit: rgba(235, 235, 245, 0.6);
        --ios-dritt: rgba(235, 235, 245, 0.3);
    }

    html {
        -webkit-tap-highlight-color: transparent;
    }

    /* ---- Kopf: schmal, durchscheinend, Wortmarke in der Mitte ---- */

    .site-header {
        background: rgba(0, 0, 0, 0.82);
        border-bottom: 0;
        box-shadow: 0 0.5px 0 var(--ios-trennlinie);
    }

    @supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
        .site-header {
            background: rgba(0, 0, 0, 0.7);
            -webkit-backdrop-filter: saturate(180%) blur(20px);
            backdrop-filter: saturate(180%) blur(20px);
        }
    }

    .site-header-inner {
        padding-top: 0;
        padding-bottom: 0;
        padding-left: max(var(--gutter), var(--safe-left));
    }

    .brand-logo {
        height: 20px;
    }

    body.has-bottom-nav .site-header-inner {
        justify-content: center;
    }

    body.has-bottom-nav .header-actions {
        display: none;
    }

    /* ---- Grosser Titel ---- */

    .wrapper h1:not(.card *),
    .hub-head h1 {
        font-size: 34px;
        line-height: 41px;
        font-weight: 700;
        letter-spacing: 0.37px;
        text-wrap: pretty;
    }

    .wrapper {
        padding-top: var(--space-4);
    }

    /*
     * Die Listenseiten (Alarme, Termine, Mängel, Mitteilungen, Galerie,
     * Dokumente, Fahrtenbuch ...) legen ihren Titel samt Liste in EINE
     * grosse Karte. In den Apps steht der Titel frei auf dem Grund, und
     * darunter liegen die Einträge als eigene Blöcke.
     *
     * Also löst sich die äussere Karte auf dem Telefon auf - nur sie,
     * erkennbar an der Titelzeile als erstem Kind. Was darin mit
     * --bg-card-2 gezeichnet ist (Zeilen, Felder, Knöpfe), bekommt die
     * Blockfarbe der Apps und steht damit als Block auf Schwarz.
     */
    .wrapper > .card:has(> :is(.headerline, .topbar):first-child > h1) {
        --bg-card-2: #1C1C1E;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: transparent;
    }

    .wrapper > .card > :is(.headerline, .topbar):first-child > h1 {
        font-size: 34px;
        line-height: 41px;
        font-weight: 700;
        letter-spacing: 0.37px;
    }

    /* ---- Zurück ---- */

    /*
     * Die Reiter der Leiste sind in den Apps oberste Ebene - dort gibt es
     * kein Zurück. Auf allen anderen Seiten steht es wie auf dem iPhone:
     * Winkel und Name in der Akzentfarbe, ohne Kapsel.
     */
    body:has(a.bottom-nav-item[aria-current="page"]) .ap-zurueck {
        display: none;
    }

    .ap-zurueck,
    .ap-zurueck:hover {
        min-height: 32px;
        margin-left: -4px;
        padding: 0 var(--space-2) 0 0;
        border: 0;
        background: transparent;
        color: var(--ios-aktiv-text);
        font-size: 17px;
        font-weight: 400;
    }

    .ap-zurueck-pfeil,
    .ap-zurueck:hover .ap-zurueck-pfeil {
        width: 11px;
        height: 11px;
        border-color: var(--ios-aktiv);
        border-width: 0 0 2.5px 2.5px;
    }

    /* ---- Umschalter wie der Segmentknopf der Apps ---- */

    /*
     * Nur bis vier Teile - mehr passen auf dem Telefon nicht in eine
     * Reihe, und ein umbrechender Segmentknopf ist keiner. Die
     * Plattformwahl auf der Startseite hängt an Optionsfeldern und
     * behält ihr eigenes Aussehen.
     */
    .termin-ansicht-wahl,
    .h-tabs:not(.app-plattform-schalter):not(:has(> :nth-child(5))) {
        display: flex;
        flex-wrap: nowrap;
        gap: 2px;
        width: 100%;
        margin-right: 0;
        padding: 2px;
        border-radius: 9px;
        background: rgba(118, 118, 128, 0.24);
    }

    .termin-ansicht-wahl > .btn,
    .h-tabs:not(.app-plattform-schalter):not(:has(> :nth-child(5))) > .h-tab {
        flex: 1 1 0;
        width: auto;
        min-width: 0;
        min-height: 32px;
        padding: 3px 8px;
        border: 0;
        border-radius: 7px;
        background: transparent;
        color: var(--text);
        font-size: 13px;
        font-weight: 500;
    }

    .termin-ansicht-wahl > .btn.active,
    .h-tabs:not(.app-plattform-schalter):not(:has(> :nth-child(5))) > .h-tab.active {
        background: #636366;
        font-weight: 600;
    }

    /* ---- Fusszeile: klein und leise ---- */

    .site-footer {
        margin-top: var(--space-7);
        padding-top: var(--space-4);
        border-top: 0;
    }

    .site-footer-inner {
        flex-direction: row;
        justify-content: center;
        gap: 0 var(--space-4);
    }

    .site-footer-inner a,
    .site-footer-copy {
        min-height: 32px;
        margin: 0;
        font-size: 12px;
        color: var(--text-muted);
    }

    /* ---- Karten: Blöcke ohne Rahmen und Schatten ---- */

    .card,
    .hub-card,
    .meta-box,
    .filter-box {
        border-color: transparent;
        box-shadow: none;
    }

    .card {
        border-radius: 10px;
    }

    a.card:hover {
        border-color: transparent;
    }

    a.card:active {
        transform: none;
        background: var(--ios-zeile-gedrueckt);
    }

    /* ---- Felder und Knöpfe ---- */

    /* 17 px wie die Zeilen der Apps - und nie unter 16, sonst
       vergrössert Safari beim Antippen die ganze Seite. */
    input,
    select,
    textarea {
        font-size: 17px;
        border-radius: 10px;
    }

    .btn,
    .btn-danger {
        min-height: 50px;
        border-radius: 12px;
        font-size: 17px;
    }

    .btn.small {
        min-height: 36px;
        border-radius: 8px;
        font-size: 15px;
    }

    .btn:active,
    .btn-danger:active,
    .status-btn:active {
        transform: none;
        opacity: 0.85;
    }

    /* ---- Rubrikseiten als gruppierte Liste ---- */

    .hub-head {
        margin-bottom: var(--space-5);
    }

    .hub-head p {
        color: var(--ios-zweit);
        font-size: 15px;
    }

    .hub-grid {
        gap: 0;
        background: var(--bg-card);
        border-radius: 10px;
        overflow: hidden;
    }

    .hub-card {
        position: relative;
        align-items: center;
        gap: 15px;
        min-height: 44px;
        padding: 11px 36px 11px 16px;
        border: 0;
        border-radius: 0;
        background: transparent;
        transition: none;
    }

    .hub-card:hover,
    .hub-card:focus-visible {
        background: transparent;
        transform: none;
    }

    .hub-card:active {
        background: var(--ios-zeile-gedrueckt);
    }

    /* Trennlinie ab dem Text, nicht ab dem Rand - wie in den Apps. */
    .hub-card + .hub-card::before {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        left: 52px;
        height: 0.5px;
        background: var(--ios-trennlinie);
    }

    /* Der Winkel rechts */
    .hub-card::after {
        content: "";
        position: absolute;
        top: 50%;
        right: 18px;
        width: 8px;
        height: 8px;
        border-top: 2px solid var(--ios-dritt);
        border-right: 2px solid var(--ios-dritt);
        transform: translateY(-50%) rotate(45deg);
    }

    .hub-card-icon {
        width: 22px;
        height: 22px;
        border-radius: 0;
        background: none;
        color: var(--ios-aktiv);
    }

    .hub-card-icon .icon {
        width: 22px;
        height: 22px;
    }

    .hub-card-text {
        gap: 1px;
    }

    .hub-card-title {
        font-size: 17px;
        font-weight: 400;
    }

    .hub-card-blurb {
        font-size: 13px;
        color: var(--ios-zweit);
    }

    /* ---- „Mehr": das Menü als eigener Bildschirm ---- */

    .nav-scrim {
        display: none;
    }

    .nav-drawer {
        left: 0;
        width: 100%;
        bottom: calc(var(--bottom-nav-height) + var(--safe-bottom));
        padding-bottom: 0;
        border-left: 0;
        box-shadow: none;
        background: var(--bg-main);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;

        /* Ein Reiterwechsel gleitet nicht, er ist einfach da. */
        transform: none;
        opacity: 0;
        transition: opacity 0.12s ease, visibility 0.12s ease;
    }

    .nav-drawer.open {
        opacity: 1;
    }

    /* Das ganze Menü blättert - dann darf kein Teil davon schrumpfen,
       sonst drückt die Liste den Kopfblock auf eine Linie zusammen. */
    .nav-drawer > * {
        flex-shrink: 0;
    }

    /* Ohne Anmeldung gibt es keine Reiterleiste - dann bis unten. */
    body:not(.has-bottom-nav) .nav-drawer {
        bottom: 0;
        padding-bottom: var(--safe-bottom);
    }

    .nav-drawer-titel {
        display: block;
        margin: 0;
        padding: var(--space-4) 20px var(--space-2);
        font-size: 34px;
        line-height: 41px;
        font-weight: 700;
        letter-spacing: 0.37px;
        color: var(--text);
    }

    /* Wer man ist - der oberste Block, wie in den Einstellungen. */
    .nav-drawer-head {
        position: relative;
        min-height: 0;
        margin: var(--space-2) 16px 0;
        padding: 11px 16px;
        border: 0;
        border-radius: 10px;
        background: var(--bg-card);
    }

    .nav-drawer-user {
        display: flex;
        align-items: center;
        gap: var(--space-3);
    }

    .nav-drawer-user .personkreis {
        width: 44px;
        height: 44px;
        font-size: 16px;
    }

    .nav-drawer-user strong {
        font-size: 17px;
        font-weight: 600;
    }

    .nav-drawer-user span {
        font-size: 13px;
        color: var(--ios-zweit);
    }

    .nav-drawer-close {
        width: 30px;
        height: 30px;
        border: 0;
        border-radius: 50%;
        background: var(--bg-elevated);
        font-size: 20px;
        color: var(--ios-zweit);
    }

    /* Die Blätterfläche ist jetzt das ganze Menü, nicht nur die Mitte. */
    .nav-drawer-body {
        flex: none;
        overflow: visible;
        padding: 0 16px;
    }

    .nav-group-label,
    .nav-group-label:first-child {
        margin: 35px 16px 6px;
        font-size: 13px;
        font-weight: 400;
        letter-spacing: 0;
        color: var(--ios-zweit);
    }

    .nav-gruppe {
        background: var(--bg-card);
        border-radius: 10px;
        overflow: hidden;
    }

    .nav-link {
        position: relative;
        gap: 15px;
        min-height: 44px;
        padding: 11px 36px 11px 16px;
        border-radius: 0;
        color: var(--text);
        font-size: 17px;
        -webkit-user-select: none;
        user-select: none;
    }

    .nav-link:active {
        background: var(--ios-zeile-gedrueckt);
    }

    .nav-link + .nav-link::before {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        left: 52px;
        height: 0.5px;
        background: var(--ios-trennlinie);
    }

    .nav-link::after {
        content: "";
        position: absolute;
        top: 50%;
        right: 18px;
        width: 8px;
        height: 8px;
        border-top: 2px solid var(--ios-dritt);
        border-right: 2px solid var(--ios-dritt);
        transform: translateY(-50%) rotate(45deg);
    }

    .nav-link .icon {
        width: 22px;
        height: 22px;
        flex: none;
        opacity: 1;
        color: var(--ios-aktiv);
    }

    .nav-link[aria-current="page"] {
        background: transparent;
        box-shadow: none;
        font-weight: 400;
    }

    .nav-link[aria-current="page"] .nav-link-text {
        color: var(--accent-text);
    }

    /* Konto wechseln und Abmelden - als Zeilen, Abmelden rot wie in
       den Einstellungen der Apps. */
    .nav-drawer-foot {
        margin: 35px 16px var(--space-7);
        padding: 0;
        border-top: 0;
        gap: 0;
        background: var(--bg-card);
        border-radius: 10px;
        overflow: hidden;
    }

    /* „Konto wechseln" als Kopfzeile im Block - ohne sie stünden dort
       nur Namen, und man wüsste nicht, was ein Tippen darauf tut. */
    .nav-drawer-foot .nav-group-label {
        margin: 0;
        padding: 11px 16px 4px;
    }

    .nav-drawer-foot .btn {
        position: relative;
        min-height: 44px;
        justify-content: flex-start;
        padding: 11px 16px;
        border: 0;
        border-radius: 0;
        background: transparent;
        font-size: 17px;
        font-weight: 400;
        color: var(--accent-text);
    }

    .nav-drawer-foot .btn + .btn::before {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        left: 16px;
        height: 0.5px;
        background: var(--ios-trennlinie);
    }

    .nav-drawer-foot .btn:active {
        background: var(--ios-zeile-gedrueckt);
    }

    .nav-drawer-foot a.btn[href="/logout.php"] {
        justify-content: center;
        color: #FF453A;
    }
}

/* Der grosse Titel über dem Menü gehört nur zum Telefon. */
@media (min-width: 601px) {
    .nav-drawer-titel {
        display: none;
    }
}

.landing-hero {
    padding: var(--space-9) var(--space-6) var(--space-8);
    text-align: center;
    background:
        radial-gradient(ellipse 80% 60% at 50% -10%, rgba(47, 111, 208, 0.35), transparent),
        linear-gradient(180deg, var(--bg-card) 0%, var(--bg-main) 100%);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
}

.landing-eyebrow {
    display: inline-block;
    margin-bottom: var(--space-3);
    color: var(--accent-text);
    font-size: var(--text-sm);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.landing-hero h1 {
    font-size: clamp(26px, 6vw, 44px);
    margin-bottom: var(--space-4);
    line-height: 1.15;
}

.landing-hero p {
    max-width: 700px;
    margin: 0 auto var(--space-3);
    color: var(--text-soft);
    font-size: clamp(15px, 2.4vw, 17px);
    line-height: 1.6;
}

.landing-hero .actions {
    justify-content: center;
    margin-top: var(--space-7);
}

.landing-section {
    margin-top: var(--space-9);
}

.landing-section-head {
    max-width: 640px;
    margin: 0 auto var(--space-7);
    text-align: center;
}

.landing-section-head h2 {
    font-size: clamp(20px, 4vw, 30px);
    margin-bottom: var(--space-2);
}

.landing-section-head p {
    color: var(--text-soft);
    margin: 0;
}

.landing-features {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--space-5);
    max-width: 1100px;
    margin: 0 auto;
}

.landing-features .card {
    transition: transform var(--transition), border-color var(--transition);
}

.landing-features .card:hover {
    transform: translateY(-3px);
    border-color: var(--accent);
}

.feature-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-bottom: var(--space-3);
    border-radius: var(--radius-lg);
    background: var(--accent-soft);
    color: var(--accent-text);
}

/* ---------------------------------------------------------------------
   Die Knoepfe zu den App-Laeden
   ---------------------------------------------------------------------
   Ohne Herstellerabzeichen (siehe storeKnoepfe() in includes/marketing.php). Die
   Form lehnt sich an die gewohnten Abzeichen an - kleine Zeile oben,
   grosser Name darunter -, damit man sie als das erkennt, was sie sind.

   --------------------------------------------------------------------- */

.store-buttons {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-3);
    margin-top: var(--space-5);
}

.store-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    min-height: var(--tap-lg);
    padding: var(--space-2) var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--bg-card-2);
    color: var(--text);
    text-decoration: none;
    transition: border-color var(--transition), transform var(--transition);
}

a.store-btn:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
}

.store-text {
    display: flex;
    flex-direction: column;
    line-height: 1.15;
    text-align: left;
}

.store-oben {
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.store-name {
    font-size: var(--text-md);
    font-weight: 700;
}

.landing-hero-note {
    margin-top: var(--space-6);
    font-size: var(--text-sm);
    color: var(--text-muted);
}

/* ---------------------------------------------------------------------
   Die drei Zugaenge
   --------------------------------------------------------------------- */

.zugang-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--space-5);
    max-width: 1100px;
    margin: 0 auto;
}

.zugang-card {
    display: flex;
    flex-direction: column;
    color: inherit;
    text-decoration: none;
    transition: transform var(--transition), border-color var(--transition);
}

.zugang-card:hover {
    transform: translateY(-3px);
    border-color: var(--accent);
}

.zugang-card p {
    flex: 1;
}

.zugang-mehr {
    margin-top: var(--space-4);
    color: var(--accent-text);
    font-weight: 600;
    font-size: var(--text-sm);
}

.zugang-mehr::after {
    content: " \2193";
}

/* ---------------------------------------------------------------------
   Die App: je Geraet die Werbebilder der Stores
   ---------------------------------------------------------------------
   Dieselben Motive wie in App Store und Google Play: iPhone, iPad,
   Android-Telefon und -Tablet je acht, je Uhr vier, der Autobildschirm
   (CarPlay) vier quer. Acht nebeneinander
   passen nicht, ohne dass jedes Bild zu klein zum Lesen wird; vier und
   vier halten die Reihenfolge des Stores von links oben nach rechts
   unten.

   Auf schmalen Bildschirmen wird daraus eine Bahn, durch die man
   seitlich wischt. Acht Bilder untereinander waeren auf dem Telefon
   mehrere Bildschirmlaengen Scrollen - und genau dort steht der
   Leser, der die App sucht.

   Welche Anzeige ein Raster hat (Raster breit, Bahn schmal), steht in
   --app-schau-anzeige. Die Umschaltung unten setzt nur diese Variable
   ein und muss deshalb nicht wissen, wie breit der Bildschirm ist.
   --------------------------------------------------------------------- */

.app-schau {
    --app-schau-anzeige: grid;
    display: var(--app-schau-anzeige);
    grid-template-columns: repeat(4, minmax(0, 220px));
    gap: var(--space-6) var(--space-4);
    justify-content: center;
    max-width: 1100px;
    margin: 0 auto;
    padding-bottom: var(--space-3);
}

.app-bild {
    margin: 0;
}

/* Das iPad ist 3:4 - breiter, sonst ist die Schrift im Bild zu klein. */
.app-schau-ipad {
    grid-template-columns: repeat(4, minmax(0, 260px));
}

/* Der Autobildschirm (CarPlay) ist quer (16:10): zwei und zwei. Vier
   nebeneinander waeren je knapp 270 Punkte breit - die Schrift auf dem
   Autobildschirm im Bild waere nicht mehr zu lesen. */
.app-schau-carplay {
    grid-template-columns: repeat(2, minmax(0, 520px));
}

/*
 * Das Geraet wird umgeschaltet ohne Skript. Die Optionsfelder stehen
 * unsichtbar VOR Schalter und Rastern, damit ":checked ~" beide erreicht.
 * Sie bleiben fokussierbar: Tab springt hinein, die Pfeiltasten wechseln.
 *
 * Alle Raster sind verborgen, gezeigt wird nur das gewaehlte - ein
 * neues Geraet braucht so je eine Zeile in den drei Listen unten, keine
 * Paare "dieses gewaehlt, jenes aus". Verborgen heisst "display: none":
 * js/lightbox.js blaettert nur durch Bilder, die zu sehen sind.
 */
.app-plattform-wahl {
    position: absolute;
    opacity: 0;
    pointer-events: none;
}

.app-plattform-schalter {
    justify-content: center;
    margin-bottom: var(--space-6);
}

.app-plattform-schalter label {
    cursor: pointer;
}

.app-plattformen > .app-schau {
    display: none;
}

#app-plattform-ios:checked ~ .app-schau-ios,
#app-plattform-ipad:checked ~ .app-schau-ipad,
#app-plattform-watch:checked ~ .app-schau-watch,
#app-plattform-carplay:checked ~ .app-schau-carplay,
#app-plattform-android:checked ~ .app-schau-android,
#app-plattform-tablet:checked ~ .app-schau-tablet,
#app-plattform-uhr:checked ~ .app-schau-uhr {
    display: var(--app-schau-anzeige);
}

#app-plattform-ios:checked ~ .app-plattform-schalter label[for="app-plattform-ios"],
#app-plattform-ipad:checked ~ .app-plattform-schalter label[for="app-plattform-ipad"],
#app-plattform-watch:checked ~ .app-plattform-schalter label[for="app-plattform-watch"],
#app-plattform-carplay:checked ~ .app-plattform-schalter label[for="app-plattform-carplay"],
#app-plattform-android:checked ~ .app-plattform-schalter label[for="app-plattform-android"],
#app-plattform-tablet:checked ~ .app-plattform-schalter label[for="app-plattform-tablet"],
#app-plattform-uhr:checked ~ .app-plattform-schalter label[for="app-plattform-uhr"] {
    background: var(--accent);
    color: #ffffff;
}

#app-plattform-ios:focus-visible ~ .app-plattform-schalter label[for="app-plattform-ios"],
#app-plattform-ipad:focus-visible ~ .app-plattform-schalter label[for="app-plattform-ipad"],
#app-plattform-watch:focus-visible ~ .app-plattform-schalter label[for="app-plattform-watch"],
#app-plattform-carplay:focus-visible ~ .app-plattform-schalter label[for="app-plattform-carplay"],
#app-plattform-android:focus-visible ~ .app-plattform-schalter label[for="app-plattform-android"],
#app-plattform-tablet:focus-visible ~ .app-plattform-schalter label[for="app-plattform-tablet"],
#app-plattform-uhr:focus-visible ~ .app-plattform-schalter label[for="app-plattform-uhr"] {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/*
 * Der Zeiger sagt, dass ein Klick etwas tut. Ohne ihn sieht ein
 * Bildschirmfoto aus wie ein Bild und nicht wie eines, das sich
 * vergroessern laesst.
 */
.app-bild a,
.monitor-bild a,
a.screenshot-body {
    cursor: zoom-in;
}

.app-bild a {
    display: block;
}

.app-bild img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--bg-card-2);
    box-shadow: var(--shadow-md);
}

.landing-punkte {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--space-6);
    max-width: 1100px;
    margin: var(--space-8) auto 0;
}

.landing-punkte h3 {
    margin-bottom: var(--space-2);
    font-size: var(--text-h3);
}

.landing-punkte p {
    margin: 0;
}

/* ---------------------------------------------------------------------
   Der Alarmmonitor
   ---------------------------------------------------------------------
   Bild und Text nebeneinander, abwechselnd - die Bilder sind breite
   Streifen, unter denen ein zentrierter Satz verloren wirkte.
   --------------------------------------------------------------------- */

.monitor-schau {
    display: grid;
    gap: var(--space-6);
    max-width: 1100px;
    margin: 0 auto var(--space-7);
}

.monitor-bild {
    margin: 0;
}

.monitor-bild a {
    display: block;
    border-radius: var(--radius-lg);
}

.landing-hinweis {
    max-width: 720px;
    margin: 0 auto;
    color: var(--text-soft);
    font-size: var(--text-base);
    text-align: center;
}

.monitor-bild img {
    display: block;
    width: 100%;
    height: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}

.monitor-bild figcaption {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-3);
    font-size: var(--text-base);
}

.monitor-bild figcaption strong {
    font-size: var(--text-h3);
}

.monitor-bild figcaption span {
    flex: 1 1 320px;
}

/* ---------------------------------------------------------------------
   Der Abschluss
   --------------------------------------------------------------------- */

.landing-schluss .card {
    max-width: 720px;
    margin: 0 auto;
    text-align: center;
}

.landing-schluss h2 {
    margin-bottom: var(--space-3);
}

.landing-schluss .actions {
    justify-content: center;
    margin-top: var(--space-6);
}

/*
 * Zwei Spalten, nicht vier: In einem Bildschirmfoto steht Schrift, und
 * bei vier Spalten auf 1100 Pixeln ist sie 250 Pixel breit - da sieht
 * man, dass etwas da ist, aber nicht mehr, was.
 */
.screenshot-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
    gap: var(--space-6);
    max-width: 1100px;
    margin: 0 auto;
}

.screenshot-frame {
    margin: 0;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
}

.screenshot-chrome {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    background: var(--bg-card-2);
    border-bottom: 1px solid var(--border);
}

.screenshot-chrome span {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--border);
}

.screenshot-body {
    /*
     * Das Seitenverhaeltnis ist das der Aufnahmen (1440x1000, siehe
     * Symbole/werbung/aufbereiten.php). Stuende hier ein anderes,
     * schnitte object-fit oben und unten etwas weg - bei einem
     * Bildschirmfoto gerade die Kopfleiste.
     */
    aspect-ratio: 36 / 25;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, rgba(47, 111, 208, 0.15), rgba(47, 111, 208, 0.02));
    color: var(--text-soft);
    text-align: center;
    font-size: var(--text-sm);
}

.screenshot-body img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.screenshot-caption {
    padding: var(--space-3) var(--space-4);
    border-top: 1px solid var(--border);
    font-size: var(--text-base);
    font-weight: 600;
}

.screenshot-text {
    display: block;
    margin-top: var(--space-1);
    color: var(--text-soft);
    font-size: var(--text-sm);
    font-weight: 400;
}

.video-frame {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    max-width: 900px;
    margin: 0 auto;
    aspect-ratio: 16 / 9;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: linear-gradient(135deg, var(--bg-card-2), var(--bg-card));
}

.video-frame iframe {
    width: 100%;
    height: 100%;
    border: 0;
}

.video-placeholder {
    padding: var(--space-5);
    color: var(--text-soft);
    text-align: center;
}

.video-play {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin: 0 auto var(--space-3);
    border-radius: 50%;
    background: var(--accent);
    color: #ffffff;
    font-size: 24px;
    box-shadow: 0 4px 20px rgba(47, 111, 208, 0.5);
}

.example-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: var(--space-5);
    max-width: 1100px;
    margin: 0 auto;
}

.example-card {
    position: relative;
    padding-top: var(--space-7);
}

.example-number {
    position: absolute;
    top: var(--space-4);
    right: var(--space-4);
    font-size: var(--text-h2);
    font-weight: 800;
    color: var(--accent-text);
    opacity: 0.35;
}

.example-card h3 {
    margin-bottom: var(--space-2);
}

@media (max-width: 600px) {

    .landing-hero {
        padding: var(--space-7) var(--space-4) var(--space-6);
        border-radius: var(--radius-lg);
    }

    .landing-section {
        margin-top: var(--space-8);
    }

    .landing-hero .actions {
        flex-direction: column;
        align-items: stretch;
    }

    .screenshot-gallery,
    .landing-features,
    .example-list,
    .zugang-grid,
    .landing-punkte {
        grid-template-columns: 1fr;
    }

    /*
     * Die Telefonbahn beginnt am linken Rand statt mittig: Bei acht
     * Bildern und einem schmalen Bildschirm stuende sonst eines aus der
     * Mitte vorn, und der Leser faengt nicht beim Alarm an.
     */
    .app-schau {
        --app-schau-anzeige: flex;
        justify-content: flex-start;
        margin-inline: calc(var(--gutter) * -1);
        padding-inline: var(--gutter);
        overflow-x: auto;
        scroll-snap-type: x mandatory;
    }

    .app-bild {
        flex: 0 0 160px;
        scroll-snap-align: center;
    }

    .app-schau-ipad .app-bild {
        flex-basis: 240px;
    }

    /* Quer: so breit, dass vom naechsten Bild ein Rand zu sehen bleibt -
       der Hinweis, dass die Bahn weitergeht. */
    .app-schau-carplay .app-bild {
        flex-basis: 290px;
    }
}

/* ---------------------------------------------------------------------
   Die Themenseiten (includes/marketing.php)
   ---------------------------------------------------------------------
   Dieselben Bausteine wie die Startseite - Einstieg, Abschnitte, Punkte,
   Kacheln, Schluss. Neu sind nur Brotkrumen, Fliesstext, die haeufigen
   Fragen und der Pfeil der Kacheln: Auf der Startseite springen sie nach
   unten, hier auf eine andere Seite.
   --------------------------------------------------------------------- */

.marketing-brotkrumen {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-bottom: var(--space-4);
    color: var(--text-soft);
    font-size: var(--text-sm);
}

.marketing-brotkrumen a {
    color: var(--accent-text);
    text-decoration: none;
}

.marketing-brotkrumen a:hover {
    text-decoration: underline;
}

.marketing-text {
    max-width: 760px;
    margin: 0 auto;
    color: var(--text-soft);
    font-size: var(--text-md);
    line-height: 1.7;
}

.marketing-text p {
    margin: 0 0 var(--space-4);
}

.marketing-text strong {
    color: var(--text);
}

.marketing-text ul {
    margin: 0 0 var(--space-4);
    padding-left: var(--space-6);
}

.marketing-text li {
    margin-bottom: var(--space-2);
}

/* Ein Satz mit Verweisen unter einem Abschnitt. Die Startseite setzt
   .landing-hinweis direkt unter Bilder; hier steht er unter Text. */
.marketing-verweis {
    margin-top: var(--space-7);
}

.marketing-verweis a,
.landing-hinweis a {
    color: var(--accent-text);
}

.marketing-kacheln .zugang-mehr::after {
    content: " \2192";
}

/* Drei Telefonbilder nebeneinander statt vier wie auf der Startseite:
   Hier stehen sie neben einem Abschnitt, nicht als Galerie. */
.marketing-bilder {
    grid-template-columns: repeat(3, minmax(0, 220px));
}

.marketing-faq {
    display: grid;
    gap: var(--space-3);
    max-width: 760px;
    margin: 0 auto;
}

.marketing-faq summary {
    cursor: pointer;
    font-weight: 600;
    min-height: var(--tap);
    display: flex;
    align-items: center;
}

.marketing-faq details p {
    margin: var(--space-3) 0 0;
    line-height: 1.6;
}

/* Bilder unter Textpunkten brauchen Luft nach oben - auf der Startseite
   steht .monitor-schau direkt unter der Abschnittsueberschrift. */
.marketing-monitor {
    max-width: 1100px;
    margin: var(--space-8) auto 0;
}

