/* ═══════════════════════════════════════════════════════════════════════════════════
 * verband.css – die Designsprache der Verbands-App.
 *
 * Stand 20.10.2026, Richtung „Werkzeug“.
 *
 * ─────────────────────────────────────────────────────────────────────────────────────
 * WIE ES DAZU KAM – damit niemand den Weg zweimal geht
 * ─────────────────────────────────────────────────────────────────────────────────────
 * Drei Anläufe, und die ersten zwei waren falsch:
 *
 *   1. Bootstrap-Navigationsleiste, dunkel          → benutzte `theme.css` kaum
 *   2. `theme.css` aus `trainer-app` übernommen     → Formensprache eines Vereinsportals
 *   3. Eigene Gestaltung, „sportlich und kräftig“    → Großbuchstaben, dunkle farbige
 *                                                      Seitenleiste; wirkte nach Plakat,
 *                                                      nicht nach Software
 *   4. **Diese Fassung: „nach einem richtigen Tool“** – entschieden am 20.10.2026
 *      anhand von Entwurfsblättern im Browser, nicht anhand von Adjektiven.
 *
 * Die Lehre daraus ist methodisch: Gestaltung lässt sich nicht aus Beschreibungen
 * beurteilen. „Kräftig“ und „sportlich“ hießen für uns beide etwas anderes. Erst ein
 * Blatt mit vier Varianten derselben Teilnehmerliste hat die Entscheidung möglich
 * gemacht. **Beim nächsten Gestaltungswunsch also zuerst ein Blatt, dann Code.**
 *
 * ─────────────────────────────────────────────────────────────────────────────────────
 * DIE GRUNDSÄTZE DIESER FASSUNG
 * ─────────────────────────────────────────────────────────────────────────────────────
 *   · Hierarchie entsteht aus **Größe und Gewicht**, nicht aus Farbflächen.
 *   · Die Akzentfarbe kommt an **drei** Stellen vor: Links, aktiver Menüpunkt,
 *     Hauptknopf. Je weniger Farbe im Raster, desto mehr bedeutet sie dort, wo sie steht.
 *   · **Keine Großbuchstaben-Überschriften**, keine Serifen, keine Schatten.
 *   · **Dicht, aber nicht gedrängt:** Zeilen in Tabellen sind rund 30 px hoch – knapp
 *     doppelt so viele Zeilen je Schirm wie vorher. Der Bezirk arbeitet länger mit der
 *     Anwendung, als er sie vorführt.
 *   · Zahlen in **Tabellenziffern** und rechtsbündig, damit Spalten vergleichbar sind.
 *   · Zustände als **Plakette mit Wort** – nie nur Farbe.
 *
 * ⚠ NACH JEDER ÄNDERUNG die `?v=`-Nummer in `vorlagen/basis.html` erhöhen. Browser
 *   speichern CSS zwischen; sonst zeigt der Browser die alte Fassung. Lehre aus
 *   `trainer-app`, wo die Nummer bei 45 steht.
 * ═══════════════════════════════════════════════════════════════════════════════════ */


/* ═══ 1 · SCHRIFTEN ════════════════════════════════════════════════════════════════
 *
 * Barlow in zwei Schnitten, LOKAL ausgeliefert, SIL Open Font License (`OFL.txt` liegt
 * daneben – die Lizenz verlangt das bei Weitergabe, und ein Test prüft es).
 *
 * ⚠ BARLOW CONDENSED WIRD NICHT MEHR BENUTZT.
 * Die kondensierte Schrift war das Herz der „sportlichen“ Fassung: Überschriften und
 * Tabellenköpfe in schmalen Großbuchstaben. Genau das wirkte nach Plakat statt nach
 * Werkzeug. Die Dateien bleiben vorerst im Projekt – falls doch einmal etwas
 * Plakatives gebraucht wird, etwa eine Urkunde oder ein Aushang.
 *
 * WARUM LOKAL UND NICHT VON GOOGLE FONTS?
 * Beim Laden von Google würde der Browser jedes Besuchers seine IP-Adresse an einen
 * Dritten senden. Bei einer Anwendung mit Klarnamen Minderjähriger ist das nicht
 * abwägbar – unabhängig davon, dass die CSP fremde Quellen verbietet und das WLAN im
 * Vorführtermin fremd sein kann.
 *
 * `font-display: swap`: Der Browser zeigt Text sofort in einer Ersatzschrift und
 * tauscht sie aus. Ohne das bliebe die Seite kurz leer – auf einem Beamer unangenehm.
 */

@font-face {
    font-family: "Barlow";
    src: url("../vendor/schrift/Barlow-Regular.woff2") format("woff2");
    font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
    font-family: "Barlow";
    src: url("../vendor/schrift/Barlow-SemiBold.woff2") format("woff2");
    font-weight: 600; font-style: normal; font-display: swap;
}


/* ═══ 2 · TOKENS ═══════════════════════════════════════════════════════════════════
 *
 * Ein Token ist ein benannter Design-Grundwert. Statt `#1f6feb` an achtzig Stellen
 * steht hier `--akzent`, und alle achtzig benutzen `var(--akzent)`.
 */

:root {
    /* ── Akzent ──
     * ⚠ GENAU EINE ZUWEISUNG VON `--akzent` – ein Test prüft das.
     * Nicht weil die Farbe heilig ist, sondern weil der Wechsel eine Zeile bleiben soll:
     * Frage 27 in KONZEPT.md (Hausfarben des Bezirks) ist offen.
     */
    --akzent:      #1f6feb;
    --akzent-tief: #1a5fd0;   /* Hover auf dem Hauptknopf */
    --akzent-hell: #eaf2fe;   /* Chip-Fläche, markierte Zeile */
    --akzent-rand: #b9d4fb;

    /* ── Text in drei Stufen ──
     * Mehr braucht es nicht, und weniger reicht nicht: Inhalt, Nebeninhalt,
     * Beschriftung. Drei Stufen sind die Hierarchie, die sonst die Farbe tragen müsste.
     */
    --t1: #1c2128;
    --t2: #57606a;
    --t3: #8b949e;

    /* ── Linien und Flächen ──
     * `--l1` trennt Zeilen (sehr fein), `--l2` rahmt Bausteine ein (sichtbar).
     * Flächen sind fast weiß – sie sollen Bereiche abgrenzen, nicht auffallen.
     */
    --l1: #e4e8ec;
    --l2: #d0d7de;
    --f1: #f6f8fa;
    --f2: #fbfcfd;

    /* ── Signalfarben ──
     * Bewusst eigenständig und nicht aus dem Akzent abgeleitet: Eine Warnung muss sich
     * von der Hausfarbe unterscheiden, auch wenn die Hausfarbe wechselt.
     */
    --gut:    #1a7f4b;  --gut-f:    #e6f4ec;  --gut-r:    #bfe0cd;
    --warn:   #9a6700;  --warn-f:   #fdf6e3;  --warn-r:   #eedcab;
    --fehler: #b3261e;  --fehler-f: #fdecea;  --fehler-r: #f5c9c5;

    /* ── Portalfarben ──
     * Drei deutlich unterschiedliche Töne; sie müssen sich im Augenwinkel
     * unterscheiden, nicht beim Vergleichen.
     */
    --portal-bezirk:    #1f6feb;
    --portal-trainer:   #0f7a52;
    --portal-anmeldung: #9a6700;

    /* ── Form ── */
    --r:    6px;      /* klein genug für Software, groß genug für ruhig */
    --kopf: 2.75rem;  /* Höhe der Kopfleiste */
    --leiste: 13.5rem;
}


/* ═══ 3 · GRUNDLAGEN ═══════════════════════════════════════════════════════════════
 *
 * Diese Datei wird NACH Bootstrap geladen (Reihenfolge in `vorlagen/basis.html`, mit
 * eigenem Test) – bei gleicher Gewichtung gewinnt in CSS die spätere Regel. Deshalb
 * lassen sich Bootstraps Klassen hier umgestalten, ohne die Vorlagen anzufassen.
 */

body {
    font-family: "Barlow", system-ui, sans-serif;
    font-size: 14px;          /* Werkzeuge sind kleiner gesetzt als Webseiten */
    line-height: 1.5;
    color: var(--t1);
    background: #fff;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-family: inherit;     /* keine zweite Schrift – siehe Abschnitt 1 */
    font-weight: 600;
    letter-spacing: 0;        /* keine Sperrung: das war die Plakat-Anmutung */
    color: var(--t1);
}

a { color: var(--akzent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Hilfsklassen, die in mehreren Vorlagen vorkommen. */
.leise { color: var(--t3); }
.schluessel {
    /* Technische Bezeichner – Rechte-Namen, Aktionen im Protokoll. Feste Zeichenbreite
       macht sie als „Wert aus der Datenbank“ erkennbar und nicht als Fließtext. */
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: .8rem;
    color: var(--t2);
}


/* ═══ 4 · DIE APP-SCHALE ═══════════════════════════════════════════════════════════
 *
 *      header.app-topbar        weiß, schmal; Marke, Pfad, Suche, Konto
 *      div.app-shell
 *        aside.app-sidebar      HELL – trägt nicht mehr die Farbe
 *        div.app-main           Arbeitsfläche
 *      footer
 *
 * ⚠ DIE SEITENLEISTE IST HELL, UND DAS IST DER KERN DIESER FASSUNG.
 * In der vorigen war sie dunkelblau und damit das auffälligste Element der ganzen
 * Anwendung. Ein Werkzeug stellt den Inhalt nach vorn, nicht die Navigation.
 */

.app-shell { min-height: 100vh; }

.app-topbar {
    position: sticky; top: 0; z-index: 1030;
    height: var(--kopf);
    display: flex; align-items: center; gap: .6rem;
    padding: 0 .85rem;
    background: #fff;
    border-bottom: 1px solid var(--l1);
}

.app-brand {
    display: inline-flex; align-items: center; gap: .5rem;
    font-weight: 600; font-size: .95rem;
    color: var(--t1); text-decoration: none; white-space: nowrap;
}
.app-brand:hover { color: var(--t1); text-decoration: none; }

/* ── Der Logoplatz – und der neue Träger der Portalfarbe ──
 *
 * ⚠ WARUM TRÄGT ER DIE PORTALFARBE?
 * Die Portalkennung ist nach Entscheidung E40 eine Vorkehrung und keine Zierde: Ein
 * Bezirkstrainer, der auch Heimtrainer ist, hat ZWEI getrennte Konten, und er muss ohne
 * Hinsehen merken, in welchem er steckt.
 *
 * Bisher trug die dunkle Seitenleiste das. Die ist jetzt hell – also braucht es einen
 * neuen Träger. Zwei kleine Flächen statt einer großen: dieses Quadrat und die
 * Haarlinie am oberen Rand (siehe `.portalkante`). Zusammen sind sie unübersehbar,
 * ohne die Arbeitsfläche einzufärben.
 *
 * Kommt ein Logo (Frage 27), ersetzt ein `<img>` das Symbol – die Größe ist reserviert,
 * die Leiste springt nicht.
 */
.app-brand .logoplatz {
    width: 1.5rem; height: 1.5rem; flex: 0 0 auto;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 4px; font-size: .85rem;
    background: var(--portalfarbe, var(--akzent));
    color: #fff;
}
.app-brand .logoplatz img { max-width: 100%; max-height: 100%; display: block; }

/* Die Haarlinie am oberen Rand in der Portalfarbe. 3 px, über die volle Breite, immer
   sichtbar – der ruhigste mögliche Weg, ein Portal zu kennzeichnen. */
/* ───────────────────────────────────────────────────────────────────────────────────
 * Das Staging-Band
 * ───────────────────────────────────────────────────────────────────────────────────
 *
 * ⚠ ES MUSS UNÜBERSEHBAR SEIN, OHNE DIE SEITE UNBENUTZBAR ZU MACHEN.
 *
 * Deshalb ein kräftiges Gelb über die volle Breite, aber **nicht** fest am Bildschirm
 * (`position: fixed`): Ein festes Band verdeckt auf dem Telefon ein Fünftel der
 * Arbeitsfläche, und man gewöhnt sich daran, es zu übersehen. Es scrollt mit weg und
 * ist beim Öffnen jeder Seite wieder da – das genügt.
 *
 * ⚠ `--warn-f` UND NICHT ROT. Rot heißt „Fehler" und wird nach dem dritten Mal
 * ignoriert. Dies ist kein Fehler, sondern eine Lage, die man wissen muss.
 *
 * `role="status"` steht im HTML, damit ein Screenreader es vorliest, ohne die
 * Bedienung zu unterbrechen – es ist eine Mitteilung, kein Alarm.
 */
.stagingband {
    background: var(--warn-f);
    border-bottom: 2px solid var(--warn);
    color: #6b4800;
    padding: .55rem 1rem;
    font-size: .88rem;
    line-height: 1.35;
    text-align: center;
}

.portalkante {
    height: 3px;
    background: var(--portalfarbe, var(--akzent));
}

/* ── Der Pfad in der Kopfleiste ──
 * Sagt, wo man steht, und erlaubt den Rückweg – ohne eine eigene Zeile dafür. Auf
 * kleinen Schirmen tritt er zurück (siehe unten), weil dort der Platz fehlt.
 */
.pfad {
    display: flex; align-items: center; gap: .35rem;
    font-size: .88rem; color: var(--t3); min-width: 0;
}
.pfad a { color: var(--t2); }
.pfad a:hover { color: var(--akzent); }
.pfad .jetzt {
    color: var(--t1); font-weight: 600;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pfad .bi { font-size: .7rem; }

.kopf-rechts { margin-left: auto; display: flex; align-items: center; gap: .5rem; }

/* ── Die Seitenleiste ── */
.app-sidebar {
    background: var(--f1);
    border-right: 1px solid var(--l1);
}
@media (min-width: 992px) {
    .app-sidebar { flex: 0 0 var(--leiste); width: var(--leiste); }
    /* Die Navigation klebt beim Scrollen – aber UNTER der Kopfleiste. */
    .app-sidebar > .offcanvas-body {
        position: sticky; top: var(--kopf);
        max-height: calc(100vh - var(--kopf));
        overflow-y: auto;
    }
}

.app-sidebar .portalname {
    font-size: .7rem; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--portalfarbe, var(--t3));
    padding: .8rem .85rem .25rem;
}

.app-main { min-width: 0; background: #fff; }


/* ═══ 5 · NAVIGATION ═══════════════════════════════════════════════════════════════
 *
 * Auf hellem Grund. Der aktive Punkt ist eine **weiße Fläche mit Rahmen** – wie eine
 * herausgehobene Karte, nicht wie ein farbiger Balken. Das ist das Muster, das
 * Werkzeuge benutzen, weil es auch dann noch funktioniert, wenn zehn Punkte in der
 * Leiste stehen.
 *
 * ⚠ DER AKTIVE PUNKT TRÄGT `aktiv`, NICHT BOOTSTRAPS `active`.
 * Der Name stammt aus `theme.css` und ist über drei Gestaltungswechsel hinweg
 * beibehalten worden – dadurch mussten die Vorlagen nie angefasst werden. Wer `active`
 * schreibt, bekommt keinen Fehler, sondern eine Navigation, in der nie etwas markiert
 * ist. Eigener Test.
 */

.app-nav { display: flex; flex-direction: column; padding: .2rem .4rem .8rem; }

.app-nav .nav-link {
    display: flex; align-items: center; gap: .5rem;
    padding: .35rem .5rem;
    border-radius: var(--r);
    color: var(--t1); font-size: .9rem; font-weight: 400;
}
.app-nav .nav-link .bi:first-child {
    width: 1.1rem; text-align: center; color: var(--t3);
}
.app-nav .nav-link:hover { background: #eceff2; text-decoration: none; }
.app-nav .nav-link.aktiv {
    background: #fff;
    box-shadow: inset 0 0 0 1px var(--l2);
    font-weight: 600;
}
.app-nav .nav-link.aktiv .bi:first-child { color: var(--akzent); }

/* Zählerstand rechts im Menüpunkt („Teilnehmer 300“). Tabellenziffern, damit die
   Zahlen untereinander stehen. */
.app-nav .nav-link .zahl {
    margin-left: auto; font-size: .78rem; color: var(--t3);
    font-variant-numeric: tabular-nums;
}

.app-nav .sidebar-heading {
    font-size: .68rem; font-weight: 600;
    letter-spacing: .06em; text-transform: uppercase;
    color: var(--t3);
    padding: .8rem .5rem .2rem;
}

/* Noch nicht gebaute Bereiche: sichtbar, aber erkennbar kein Link. */
.app-nav .nav-link.disabled { color: var(--t3); cursor: default; }
.app-nav .nav-link.disabled:hover { background: none; }


/* ═══ 6 · PORTALFARBE ══════════════════════════════════════════════════════════════
 *
 * Eine Klasse am `<body>` setzt **eine** Variable; Logoplatz, Portalkante,
 * Portalname und das Kopfband lesen sie. Je Portal also genau eine Stelle mit einer
 * Farbe – ein viertes Portal wären drei Zeilen. Ein Test prüft das.
 */

.portal-bezirk    { --portalfarbe: var(--portal-bezirk); }
.portal-trainer   { --portalfarbe: var(--portal-trainer); }
.portal-anmeldung { --portalfarbe: var(--portal-anmeldung); }

/* Das Kopfband – für Seiten OHNE Schale: öffentliche Seite, Anmeldemaske,
 * Fehlerseiten. Dort gibt es keine Seitenleiste und keinen Logoplatz, also übernimmt
 * es die Kennzeichnung.
 *
 * ⚠ Besonders wichtig auf der Anmeldemaske: Die beiden Masken sehen einander zum
 *   Verwechseln ähnlich, und wer nach E40 zwei Konten hat, muss vor dem Tippen wissen,
 *   welches Passwort gefragt ist.
 */
.portalband {
    background: var(--portalfarbe, var(--akzent));
    color: #fff;
    font-size: .78rem; font-weight: 600;
    letter-spacing: .08em; text-transform: uppercase;
    padding: .45rem 1rem;
    text-align: center;
}


/* ═══ 7 · SEITENKOPF UND WERKZEUGLEISTE ════════════════════════════════════════════
 *
 * Titel, Anzahl und Aktionen in EINER Zeile, darunter eine Unterzeile, darunter die
 * Filter. Keine Großbuchstaben, keine Akzentlinie – die Hierarchie entsteht aus
 * Größe und Gewicht. Das ist der sichtbarste Unterschied zur vorigen Fassung.
 */

/* Der Innenbereich unter dem Kopfbereich. Bewusst knapp: Ein Werkzeug darf nicht die
   halbe Fläche an Rand verlieren – aber auch nicht randlos sein, sonst kleben Tabellen
   am Fensterrahmen. */
.inhalt { padding: 1rem; }

.seitenkopf { padding: .9rem 1rem .6rem; border-bottom: 1px solid var(--l1); }
.titelzeile { display: flex; align-items: center; gap: .6rem; margin-bottom: .15rem;
              flex-wrap: wrap; }
.titelzeile h1, .titelzeile h2 { font-size: 1.1rem; font-weight: 600; margin: 0; }
.titelzeile .anzahl {
    font-size: .85rem; color: var(--t3); font-variant-numeric: tabular-nums;
}
.titelzeile .aktionen { margin-left: auto; display: flex; gap: .4rem; }
.unterzeile { font-size: .85rem; color: var(--t2); }

/* Die Filterleiste. Eigene Fläche, damit sie sich vom Inhalt abhebt, ohne einen
   Rahmen zu brauchen. */
.werkzeugleiste {
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
    padding: .55rem 1rem;
    border-bottom: 1px solid var(--l1);
    background: var(--f2);
}

/* Eingabefelder in der Werkzeugleiste: klein, mit Symbol, in einer Zeile. */
.feld {
    display: flex; align-items: center; gap: .35rem;
    background: #fff; border: 1px solid var(--l2); border-radius: var(--r);
    padding: .22rem .45rem; font-size: .86rem; color: var(--t3);
}
.feld .form-control, .feld .form-select, .feld input, .feld select {
    border: 0; background: none; outline: none; box-shadow: none;
    font: inherit; color: var(--t1); padding: 0; height: auto; min-width: 0;
}
.feld:focus-within { border-color: var(--akzent); }

/* Gesetzte Filter als Chip. Zum Entfernen gehört ein Link, der genau diesen Parameter
   weglässt – das kommt mit dem Sortier-/Filterschritt. */
.chip {
    display: inline-flex; align-items: center; gap: .3rem;
    font-size: .8rem; font-weight: 600;
    background: var(--akzent-hell); border: 1px solid var(--akzent-rand);
    color: #0f4c9e; border-radius: 999px;
    padding: .1rem .3rem .1rem .55rem;
}
.chip a { color: #0f4c9e; line-height: 1; padding: 0 .15rem; }
.chip a:hover { text-decoration: none; opacity: .7; }

/* ⚠ `chip leise` – EIN GEDÄMPFTER CHIP, UND VORHER WIRKUNGSLOS.
 *
 * In mehreren Vorlagen steht `class="chip leise"` für Marken wie „unveröffentlicht“ –
 * etwas, das dasteht, aber nicht ruft. `.leise` (weiter oben) und `.chip` haben
 * dieselbe Spezifität, und `.chip` steht später: Die Marke erschien im Akzentblau,
 * also **auffälliger** als der normale Text, obwohl sie leiser sein sollte.
 *
 * Gefunden bei der Bedienbarkeitsdurchsicht am 21.10.2026. Eine eigene Regel mit
 * höherer Spezifität ist die saubere Lösung – `!important` wäre die bequeme. */
.chip.leise {
    background: var(--f1);
    border-color: var(--l2);
    color: var(--t2);
    font-weight: 500;
}

/* ⚠ `chip aktiv` – DER AUSGEWÄHLTE FILTER, UND VORHER UNSICHTBAR.
 *
 * Mehrere Listen benutzen Chips als Filter („offen · übernommen · abgelehnt“) und
 * markieren den aktiven mit `aktiv`. Die Klasse gab es nur als `.app-nav .nav-link.aktiv`
 * – hier griff sie nicht, und alle Chips sahen gleich aus. Wer filtert, wusste nicht,
 * welche Liste er gerade sieht. Gefunden bei der Bedienbarkeitsdurchsicht am
 * 21.10.2026. */
.chip.aktiv {
    background: var(--akzent);
    border-color: var(--akzent);
    color: #fff;
}
.chip.aktiv a { color: #fff; }


/* ═══ Die öffentliche Seite liest sich anders ═══════════════════════════════════════
 *
 * ⚠ AUF `anmeldung.` SIND DIE „LEISEN“ TEXTE DIE WICHTIGSTEN.
 *
 * Im Bezirksportal ist `.leise` eine Nebenbemerkung für Leute, die das Werkzeug täglich
 * benutzen. Auf der Anmeldeseite stehen in derselben Klasse die Sätze, die ein
 * Elternteil **lesen muss**: woher der Vorab-Code kommt, dass noch kein Platz sicher
 * ist, und der Wortlaut der Einwilligung.
 *
 * `--t3` auf Weiß ergibt einen Kontrast von etwa 3,1:1 – unter den 4,5:1, die für Text
 * dieser Größe gefordert sind. Auf dieser Domain gilt deshalb die kräftigere Farbe.
 * Gefunden bei der Bedienbarkeitsdurchsicht am 21.10.2026. */
.portal-anmeldung .leise {
    color: var(--t2);
}

/* Eingabefelder auf Handys: **mindestens 16 px**.
 *
 * iOS-Safari zoomt beim Antippen jedes Feldes, das kleiner gesetzt ist – danach ist das
 * Formular verschoben und muss von Hand zurückgezoomt werden. Bei acht Feldern achtmal.
 * Das ist kein Geschmacksthema, sondern der Unterschied zwischen „geht“ und „nervt so
 * sehr, dass man abbricht“. */
@media (max-width: 575.98px) {
    .form-control, .form-select { font-size: 16px; }

    /* Der Hauptknopf über die volle Breite – mit nassen Fingern am Beckenrand oder
       einhändig im Bus ist eine 28 px hohe Fläche zu klein. */
    .portal-anmeldung .btn-primary,
    .portal-trainer .btn-primary { width: 100%; padding: .6rem; }

    /* Das Eigenschaftsraster bricht um, statt die Werte auf 144 px zu quetschen. */
    .eigenschaften { grid-template-columns: 1fr; }
    .eigenschaften dt { margin-top: .4rem; }
}

/* Der Tastenhinweis an der Suche. Noch Zierde: `Strg K` braucht eigenes JavaScript in
   einer eigenen Datei, weil die CSP kein eingebettetes Skript erlaubt. */
.taste {
    font-family: ui-monospace, monospace; font-size: .72rem; color: var(--t3);
    background: #fff; border: 1px solid var(--l2); border-bottom-width: 2px;
    border-radius: 4px; padding: 0 .3rem;
}


/* ═══ 8 · KNÖPFE ═══════════════════════════════════════════════════════════════════
 *
 * Gestaltet werden Bootstraps Klassen, damit die Vorlagen unverändert bleiben.
 * Klein, kantig-rund, kein Schatten – und nur EINER je Seite ist farbig.
 */

.btn {
    font-size: .86rem; font-weight: 600;
    padding: .3rem .65rem;
    border-radius: var(--r);
    box-shadow: none !important;
}
.btn-sm { font-size: .8rem; padding: .22rem .5rem; }

.btn-primary { background: var(--akzent); border-color: var(--akzent); }
.btn-primary:hover, .btn-primary:focus {
    background: var(--akzent-tief); border-color: var(--akzent-tief);
}

.btn-outline-secondary, .btn-secondary {
    background: #fff; border-color: var(--l2); color: var(--t1);
}
.btn-outline-secondary:hover, .btn-secondary:hover {
    background: var(--f1); border-color: var(--l2); color: var(--t1);
}

/* Der leise Knopf – für Dinge, die man selten braucht (Abmelden, Spalten). */
.btn-link, .btn-leise {
    background: none; border-color: transparent; color: var(--t2);
    text-decoration: none;
}
.btn-link:hover, .btn-leise:hover { background: var(--f1); color: var(--t1); }


/* ═══ 9 · FORMULARE ════════════════════════════════════════════════════════════════ */

.form-control, .form-select {
    font-size: .88rem;
    border-radius: var(--r);
    border-color: var(--l2);
}
.form-control:focus, .form-select:focus {
    border-color: var(--akzent);
    /* `color-mix` leitet den Ring aus der Variablen ab – beim Farbwechsel zieht er
       automatisch mit. In `theme.css` stand hier ein fest eingetragener rgba-Wert, der
       beim Überschreiben der Farbe rötlich blieb; diese Stelle gibt es nicht mehr. */
    box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--akzent) 20%, transparent);
}
.form-label {
    font-size: .78rem; font-weight: 600;
    color: var(--t2);
    margin-bottom: .2rem;
    letter-spacing: 0;
    text-transform: none;
}


/* ═══ 10 · TABELLEN – das Herzstück ════════════════════════════════════════════════
 *
 * Dicht, aber nicht gedrängt: rund 30 px Zeilenhöhe. Die Kopfzeile **klebt** beim
 * Scrollen; Zahlen stehen rechts und in Tabellenziffern, damit Spalten vergleichbar
 * sind.
 */

.card { border: 1px solid var(--l1); border-radius: var(--r); box-shadow: none; }
.card-body { padding: .85rem 1rem; }

.table { --bs-table-bg: transparent; margin-bottom: 0; font-size: .88rem; }

.table > thead th {
    position: sticky; top: 0; z-index: 1;
    background: var(--f1);
    font-size: .75rem; font-weight: 600; letter-spacing: .03em;
    text-transform: uppercase;
    color: var(--t2);
    padding: .4rem .7rem;
    border-bottom: 1px solid var(--l2);
    white-space: nowrap;
}
.table > tbody td {
    padding: .3rem .7rem;
    border-bottom: 1px solid var(--l1);
    vertical-align: middle;
    font-variant-numeric: tabular-nums;
}
.table-hover > tbody > tr:hover > * { background: var(--f2); }

/* ───────────────────────────────────────────────────────────────────────────────────
 * Eine Zeile mit einer offenen Aufgabe
 * ───────────────────────────────────────────────────────────────────────────────────
 *
 * ⚠ WOFÜR: Über der Anmeldeliste steht „Noch zu informieren: 7". Ohne Markierung
 * heißt das für den Benutzer: sieben Zeilen mit dem Auge suchen – am Handy in einer
 * waagerecht scrollenden Tabelle. Die Zahl sagte, DASS etwas zu tun ist, aber nicht,
 * WO.
 *
 * ⚠ WARUM EIN RAND LINKS UND KEINE FLÄCHENFARBE: Eine eingefärbte Zeile konkurriert
 * mit `.table-hover` und mit der Lesbarkeit des Textes darin. Ein Rand von drei
 * Pixeln ist am Rand des Blickfelds erkennbar und stört beim Lesen nicht.
 *
 * ⚠ UND WARUM NICHT ROT: Eine offene Aufgabe ist kein Fehler. `--warn-r` ist die
 * gedeckte Warnfarbe des Hauses (dasselbe Gelb wie `.alert-warning`); Rot wäre eine
 * Aussage über Dringlichkeit, die hier niemand treffen kann.
 *
 * `box-shadow: inset` und nicht `border-left`: Ein Rahmen würde die Zelle um drei
 * Pixel verschieben und die Spalten der Tabelle gegeneinander verrücken.
 */
.table > tbody > tr.aufgabe-offen > td:first-child {
    box-shadow: inset 3px 0 0 var(--warn-r);
}

/* Zahlenspalten rechts. Die Klasse steht in der Vorlage an `th` und `td`. */
.table .zahl, .table th.zahl, .table td.zahl { text-align: right; }

/* Namen in Listen sind Links, aber in Textfarbe – blau wäre bei 25 Zeilen zu laut.
   Erst beim Überfahren zeigt sich, dass es ein Link ist. */
.table tbody a.name { color: var(--t1); font-weight: 600; }
.table tbody a.name:hover { color: var(--akzent); }

/* Der Tabellenfuß: „1–25 von 300“ sagt mehr als „Seite 1 von 12“ – man weiß, wo man
   ist UND wie viel es insgesamt ist. */
.tabellenfuss {
    display: flex; align-items: center; gap: .6rem;
    padding: .5rem 1rem;
    border-top: 1px solid var(--l1);
    background: var(--f2);
    font-size: .85rem; color: var(--t2);
}
.tabellenfuss .rechts { margin-left: auto; display: flex; align-items: center; gap: .3rem; }


/* ═══ 11 · PLAKETTEN UND MELDUNGEN ═════════════════════════════════════════════════
 *
 * Eine Plakette trägt **immer ein Wort**, nie nur Farbe. Wer Farben schlecht
 * unterscheidet, liest sonst nichts – und auf einem schlechten Beamer sieht Grün wie
 * Grau aus.
 */

.badge {
    font-size: .75rem; font-weight: 600;
    padding: .1rem .4rem;
    border-radius: 999px;
    border: 1px solid transparent;
}
.badge.text-bg-success { background: var(--gut-f) !important; color: var(--gut) !important;
                         border-color: var(--gut-r); }
.badge.text-bg-warning { background: var(--warn-f) !important; color: var(--warn) !important;
                         border-color: var(--warn-r); }
.badge.text-bg-danger  { background: var(--fehler-f) !important; color: var(--fehler) !important;
                         border-color: var(--fehler-r); }
.badge.text-bg-light, .badge.text-bg-secondary {
    background: var(--f1) !important; color: var(--t2) !important;
    border-color: var(--l2);
}

.alert {
    font-size: .88rem;
    border: 1px solid var(--l2);
    border-radius: var(--r);
    padding: .6rem .75rem;
}
.alert-success   { background: var(--gut-f);    border-color: var(--gut-r);    color: #0f5c35; }
.alert-warning   { background: var(--warn-f);   border-color: var(--warn-r);   color: #6b4800; }
.alert-danger    { background: var(--fehler-f); border-color: var(--fehler-r); color: #8c1d18; }
.alert-secondary { background: var(--f1);       border-color: var(--l2);       color: var(--t2); }


/* ═══ 12 · ABSCHNITTE AUF DETAILSEITEN ═════════════════════════════════════════════
 *
 * Ein Kasten mit grauem Kopf. Der Kopf trägt den Titel, eine Nebenangabe und rechts
 * die Aktionen, die zu diesem Abschnitt gehören – nicht zur ganzen Seite. Das ist das
 * Muster, mit dem Werkzeuge Detailseiten ordnen.
 */

.abschnitt {
    border: 1px solid var(--l1); border-radius: var(--r);
    margin-bottom: .9rem; overflow: hidden;
}
.abschnitt > .kopf {
    display: flex; align-items: center; gap: .5rem;
    font-size: .85rem; font-weight: 600; color: var(--t2);
    padding: .5rem .75rem;
    background: var(--f1);
    border-bottom: 1px solid var(--l1);
}
.abschnitt > .kopf .rechts { margin-left: auto; display: flex; gap: .35rem; }
.abschnitt > .kopf .nebenangabe { font-weight: 400; color: var(--t3); }
.abschnitt > .koerper { padding: .75rem; }

/* Eigenschaftsliste: zweispaltiges Raster, Beschriftung links. Lesbarer als eine
   Tabelle, weil die Werte nicht alle gleich lang sind. */
.eigenschaften {
    display: grid; grid-template-columns: 9.5rem 1fr;
    gap: .35rem .75rem; font-size: .9rem; margin: 0;
}
.eigenschaften dt { color: var(--t3); font-weight: 400; }
.eigenschaften dd { margin: 0; }


/* ═══ 13 · BRotKRUMEN, BLÄTTERN, FUSSZEILE ═════════════════════════════════════════ */

.breadcrumb { font-size: .85rem; margin-bottom: .6rem; }
.breadcrumb-item + .breadcrumb-item::before { color: var(--t3); }

.page-link {
    color: var(--t1); border-color: var(--l2); font-size: .85rem;
    padding: .2rem .5rem;
}
.page-item.active .page-link { background: var(--akzent); border-color: var(--akzent); }
.page-item.disabled .page-link { color: var(--t3); }

footer {
    background: var(--f1);
    border-top: 1px solid var(--l1);
    color: var(--t3);
    padding: 1rem 0;
    margin-top: 2rem;
    font-size: .82rem;
}
footer a { color: var(--t2); }


/* ═══ 14 · ANMELDEMASKE UND FEHLERSEITEN ═══════════════════════════════════════════ */

.anmeldekarte { max-width: 22rem; margin: 3.5rem auto; }
.fehlerseite  { max-width: 34rem; margin: 3rem auto; }


/* ═══ 15 · KLEINE SCHIRME ══════════════════════════════════════════════════════════
 *
 * Unter 992 px klappt die Seitenleiste als Offcanvas weg (Bootstrap, über
 * `data-bs-*` – also ohne eigenes JavaScript, das die CSP blockieren würde). Was dann
 * noch weicht:
 */

@media (max-width: 575.98px) {
    /* Der Pfad braucht Platz, den es auf dem Handy nicht gibt – die Kopfleiste behält
       Marke, Suche und Konto. */
    .pfad { display: none; }
    .seitenkopf, .werkzeugleiste, .tabellenfuss { padding-left: .75rem; padding-right: .75rem; }
}


/* ═══ 16 · DRUCKANSICHT ════════════════════════════════════════════════════════════
 *
 * Ein Bezirk druckt Listen – Anwesenheit am Beckenrand, Teilnehmerlisten für die
 * Fahrt. Ohne eigene Regeln kommt die Navigation mit aufs Papier, Farbflächen fressen
 * Toner, und die Tabelle verliert ab Seite zwei ihre Kopfzeile.
 *
 * ⚠ NICHT ZU VERWECHSELN mit den PDF-Belegen aus Schritt 12. Die entstehen mit
 *   weasyprint aus eigenen Vorlagen – ein Beleg ist ein Dokument mit Nummer und
 *   Snapshot (Regel D21), keine gedruckte Bildschirmseite.
 */

@media print {
    .app-topbar, .app-sidebar, .portalband, .portalkante,
    footer, .pagination, .tabellenfuss .rechts,
    .werkzeugleiste, .btn, .breadcrumb {
        display: none !important;
    }

    body { background: #fff; color: #000; font-size: 10pt; }
    .app-main, .card, .abschnitt { border: 0 !important; background: #fff !important; }
    .seitenkopf { border-bottom: 1pt solid #000; padding-left: 0; }
    .titelzeile h1, .titelzeile h2 { font-size: 14pt; }

    .table > thead th {
        position: static;                      /* „sticky“ ist auf Papier sinnlos */
        background: #fff !important; color: #000 !important;
        border-bottom: 1pt solid #000 !important;
    }
    .table > tbody td { border-bottom: .5pt solid #999 !important; }

    /* ⚠ DER WICHTIGSTE TEIL: Kopfzeile auf JEDER Seite, keine zerrissenen Zeilen.
       Eine zwölfseitige Teilnehmerliste, bei der nur Seite 1 eine Kopfzeile hat, ist am
       Beckenrand unbrauchbar. */
    thead { display: table-header-group; }
    tr, td, th { page-break-inside: avoid; }

    /* Auf Papier nützt ein Link nichts – die Adresse dahinter manchmal doch. */
    a[href^="http"]::after {
        content: " (" attr(href) ")"; font-size: 8pt; color: #444;
    }
}
