/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ AUF DAS AUSSEHEN DES FRONTENDS UMGESTELLT — 14.08.2026
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Nutzerwunsch: „Backend: Bitte mir Design — gerne so wie im Frontend."
 *
 * Übernommen aus dem Neudinger Projekt, wo der interne Bereich HELL ist:
 * weisse Flächen, blaue Akzente, hellblaue Karten. Auf einer Website, die
 * schwarz mit Orange ist, wäre das ein Bruch — man merkt beim Anmelden, dass
 * man das Haus verlässt.
 *
 * ⚠ GEÄNDERT WURDEN NUR DIE VIER WURZELVARIABLEN UND DIE FLÄCHENFARBEN.
 * Die Geometrie (Abstände, Rasterbreiten, Schriftgrössen) bleibt, wie sie ist:
 * sie ist bei Neudingen an echten Masken erarbeitet und hat dort gehalten. Wer
 * hier mehr ändert, macht den Abgleich mit Neudingen zur Handarbeit.
 *
 * ⚠ RUNDE ECKEN BLEIBEN HIER RUND. Die Regel „alles eckig" gilt im Frontend
 * und ist dort begründet (Logo und Wortmarke sind kantig). Im Backend geht es
 * um Bedienbarkeit, nicht um Auftritt — und ein Formularfeld mit 2 px Radius
 * ist leichter als Feld zu erkennen als ein rechteckiger Kasten neben einem
 * rechteckigen Rahmen.
 */

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * DIE ARBEITSFLÄCHE ZWISCHEN KOPF UND FUSS DER WEBSITE
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * ⚠ HIER STAND EINMAL DAS GEGENTEIL: „Bewusst schlicht und NICHT im Aussehen der
 * öffentlichen Seite: wer hier ist, arbeitet." Der Nutzer hat am 05.08.2026
 * anders entschieden — Kopf und Fuss der Website umschliessen jetzt auch den
 * internen Bereich. Und er hat recht: für acht Menschen, die zwei- bis dreimal im
 * Jahr etwas eintragen, ist eine vertraute Umgebung mehr wert als die Ansage
 * „du bist woanders". Der `noindex`-Vermerk und die Anmeldung sagen das ohnehin.
 *
 * Diese Datei formatiert nur noch DAZWISCHEN: Formulare, Tabellen, Hinweise,
 * Karten. Sie wird NACH dem Stylesheet der Website geladen und gewinnt deshalb bei
 * gleicher Genauigkeit.
 *
 * ⚠ KEINE `font-family` FÜR `body`. Die Schrift der Website steht als `style` am
 * `<html>`-Element und wird vererbt; eine Angabe hier würde sie überschreiben, und
 * der interne Bereich stünde in Systemschrift zwischen zwei Blöcken in
 * Vereinsschrift.
 *
 * Reines CSS ohne Aufbauwerkzeug: der interne Bereich muss auf einem
 * Standard-Webspace laufen und in fünf Jahren noch, ohne Tailwind-Bau. Die
 * Klassen `.kopf`, `.marke`, `.kopfnav` und `.wer` gehören zum schlichten
 * Rückfallrahmen (`seite_kopf_schlicht`) und werden nur gebraucht, wenn
 * `_rahmen.php` fehlt — also unter `npm run dev`.
 */
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ HIER STAND `* { border-radius: 0 !important; }` — ENTFERNT FÜR BaarRock
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Die Regel gehört zu hupbraum. Dort ist „alles eckig" eine begründete
 * Markenentscheidung (Logo und Wortmarke sind kantig), und die Sammelregel
 * ersetzt sechzehn Einzeländerungen.
 *
 * ⚠ BaarRock RUNDET. Knöpfe, Karten und Felder im Frontend haben Radien; eine
 * Sammelregel auf 0 hätte den internen Bereich als einzige eckige Insel der
 * Seite hinterlassen — genau der Bruch, den die Übernahme des Frontend-Designs
 * vermeiden soll.
 *
 * Damit gelten wieder die sechzehn Einzelangaben weiter unten, die aus dem
 * Neudinger Projekt stammen. Sie sind für ein rundendes Design gebaut und
 * passen deshalb hier ohne Zutun.
 */

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * DIE FARBEN KOMMEN AUS DEM FRONTEND — nicht abgeschrieben, sondern verwiesen
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * hupbraum trägt hier sechs feste Hex-Werte, von Hand aus dem Frontend
 * übertragen. Das geht dort, weil beide Paletten von Hand gepflegt sind — und
 * es driftet, sobald jemand nur eine Seite ändert.
 *
 * Hier steht stattdessen `var(--…)`. ⚠ DAS FUNKTIONIERT NUR, WEIL DER RAHMEN
 * DIE STYLESHEETS DER WEBSITE VOR DIESER DATEI LÄDT (`website_stylesheets()` in
 * `_kern.php` liest sie aus `htdocs/index.html`). Damit gelten hier dieselben
 * Variablen wie im Frontend, und eine Farbänderung in `globals.css` kommt ohne
 * Zutun auch im Backend an.
 *
 * ⚠ DIE RÜCKFALLWERTE SIND KEINE ZWEITE PALETTE. Sie sind wörtlich dieselben
 * `oklch()`-Angaben wie in `src/app/globals.css` und greifen nur, wenn es
 * `htdocs/index.html` nicht gibt — also unter `npm run dev`, wo nie gebaut
 * wurde. Ohne sie stünde der interne Bereich dort ohne Farben da.
 *
 * ⚠ DIE NAMEN BLEIBEN `--blau`, `--hell`, `--dunkel`. Sie stammen aus dem
 * Neudinger Projekt, wo die Seite hell und blau ist. Umzubenennen hiesse, 960
 * Zeilen anzufassen, die aus dem Abgleich mit Neudingen leben — für null
 * Gewinn. Der Name lügt, die Farbe stimmt; dieser Kommentar ist der Ausgleich.
 */
:root {
  /* Akzent: BaarRocks Bernstein. Bei Neudingen Blau, daher der Name. */
  --blau: var(--accent, oklch(0.8 0.165 72));
  /* Flächen hinter Inhalten — im Frontend die Kartenfarbe. */
  --hell: var(--card, oklch(0.205 0.006 60));
  /* Text. War bei Neudingen fast schwarz, hier das warme Off-White. */
  --dunkel: var(--foreground, oklch(0.96 0.008 85));
  --rand: var(--border, oklch(1 0 0 / 12%));
  --grund: var(--background, oklch(0.145 0.006 60));
  --gedaempft: var(--muted-foreground, oklch(0.68 0.01 70));
}

/*
 * ⚠ GRUND UND SCHRIFT AUSDRÜCKLICH SETZEN. Bei Neudingen kam Weiss vom Browser;
 * ein dunkler Bereich muss es selbst mitbringen, sonst steht helle Schrift auf
 * weissem Grund — genau der Fehler, der im Frontend am Einwilligungstext des
 * Kontaktformulars aufgefallen ist.
 */
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ DIE SCHRIFTEN MÜSSEN HIER GESETZT WERDEN — hupbraum darf das NICHT
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * In hupbraums Fassung steht an dieser Stelle ausdrücklich „KEINE `font-family`
 * für `body`" — dort schneidet ein Bauskript den echten Kopf der Website mit
 * seinen Klassen heraus, und eine Angabe hier würde ihn überschreiben.
 *
 * BaarRock hat dieses Bauskript nicht. Der Rahmen setzt nur die Klassen des
 * `<html>`-Elements (`website_html_klassen()`), und die tragen die VARIABLEN —
 * `--font-sans` und `--font-display`. Angewandt werden sie im Frontend über
 * Tailwind-Klassen an einzelnen Elementen, und die stehen hier nicht.
 *
 * ⚠ OHNE DIESE ZWEI REGELN STEHT DER INTERNE BEREICH IN TIMES. Genau so sah die
 * erste Aufnahme der Anmeldemaske am 16.08.2026 aus: Farben und Knöpfe richtig,
 * Schrift fremd.
 *
 * Die Rückfallwerte greifen nur ohne gebautes Frontend (`npm run dev`).
 */
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ DAS HORIZONTALE ZUCKEN — und es lag NICHT am Kopf
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Nutzerhinweis 16.08.2026: „Das Logo scheint noch horizontal zu zucken."
 * Gemessen, mit sichtbarem Scrollbalken:
 *
 *                        clientWidth   Logo beginnt bei
 *   Startseite (lang)       1265 px         x = 96.5
 *   Anmeldemaske (kurz)     1280 px         x = 104.0
 *
 * **7.5 px** — und die Kopfmasse waren auf beiden Seiten identisch. Die Ursache
 * ist der Scrollbalken: er belegt nur Platz, wenn gescrollt werden kann. Die
 * lange Startseite hat ihn, die kurze Anmeldemaske nicht, und weil der Inhalt
 * mittig sitzt, verschiebt sich alles um die HÄLFTE der Balkenbreite.
 *
 * ⚠ `scrollbar-gutter: stable` ALLEIN GENÜGT NICHT. Ohne `overflow-y: scroll`
 * ist das Wurzelelement bei kurzen Seiten gar kein Scrollbehälter, und dann
 * reserviert `stable` nichts. Genau diese Lehre steht in hupbraums
 * `globals.css`, wo sie am 06.08.2026 erarbeitet wurde.
 *
 * ⚠ DIESELBE REGEL GEHÖRT INS FRONTEND — und stand dort am 16.08.2026 NICHT.
 * BaarRocks kurze Seiten (Impressum, Datenschutz) zucken deshalb gegen die
 * Startseite, unabhängig vom internen Bereich. Ergänzt in `src/app/globals.css`.
 */
html {
  scrollbar-gutter: stable;
  overflow-y: scroll;
}

body {
  background: var(--grund);
  color: var(--dunkel);
  font-family: var(--font-sans, ui-sans-serif, system-ui, sans-serif);
}

/*
 * Überschriften und Beschriftungen in der schmalen Auszeichnungsschrift, gross
 * geschrieben — dieselbe Behandlung wie im Frontend (`font-display`,
 * `uppercase`, `tracking-tight`). Ohne `text-transform` sähe Barlow Condensed
 * hier deutlich anders aus als auf der Website.
 */
h1, h2, h3, legend, .karte h2, .karte h3 {
  font-family: var(--font-display, var(--font-sans, ui-sans-serif, system-ui, sans-serif));
  text-transform: uppercase;
  letter-spacing: -0.01em;
}
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ NUR IM INHALT — ein `*` HAT DEN KOPF DER WEBSITE ZERSTÖRT
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Hier stand `* { box-sizing: border-box; }`. Harmlos, solange dieser Bereich
 * seinen eigenen schlichten Rahmen hatte. Seit Kopf und Fuss der Website
 * mitgeliefert werden, war es ein Fehler mit sichtbarer Folge.
 *
 * WARUM: `globals.css` gibt der Inhaltsschale ausdrücklich `box-sizing:
 * content-box` (`@utility schale`) — nur so sind `<section class="schale px-4">`
 * und `<section class="mx-auto max-w-schale px-4">` gleich breit. Tailwind legt
 * seine Regeln in einen CASCADE LAYER. Und eine Regel OHNE Layer schlägt jede
 * Regel IN einem Layer, ganz gleich wie spezifisch sie ist — ein `*` mit
 * Spezifität 0 gewinnt gegen `.schale`.
 *
 * GEMESSEN am 06.08.2026 bei 1978 px Fensterbreite:
 *
 *              box-sizing    Schale    Logo im Kopf    Logo im Fuss
 *     Website  content-box     1680         182            182
 *     Intern   border-box      1600         222            182
 *
 * Vierzig Pixel, und der Nutzer hat sie im Screenshot sofort gesehen: „Das Logo
 * sitzt intern viel zu weit rechts und ist mit dem Logo aus dem Footer nicht
 * linksbündig." Meine eigenen Messungen hatten es nicht gefunden, weil ich bei
 * 1440 px gemessen habe — dort greift die Maximalbreite von 1600 px gar nicht,
 * und beide Rechenwege kommen zufällig auf dasselbe Ergebnis.
 *
 * MERKSATZ: Wer fremdes Markup übernimmt, darf keine Regel ohne Layer und ohne
 * Geltungsbereich schreiben. Gemessen wird an der Stelle, an der die Grenze
 * wirkt — nicht dort, wo es gerade bequem ist.
 */
.inhalt, .inhalt *, .bereiche, .bereiche *, .krumen, .krumen *,
.kopf, .kopf * { box-sizing: border-box; }
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * DER RAHMEN — Hintergrundbild, feststehender Kopf, feststehender Fuss
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Nutzerwunsch aus der Aufnahme vom 14.08.2026 („Donaueschingen 7"):
 *
 *     „zum Design des Backends, das darf genauso aussehen wie das Frontend, also
 *      auch mit diesem Hintergrundbild der Band, so wie es im Frontend auch ist.
 *      … wenn ich mich eingeloggt habe, dann darf das Design auch hier den
 *      feststehenden Header, den feststehenden Footer haben, wie ich es von der
 *      Musikkapelle Neudingen kenne. Mit dem Button oben rechts abmelden."
 *
 * ───────────────────────────────────────────────────────────────────────────
 * ⚠ WARUM DER RAHMEN HIER STEHT UND NICHT AUS DEM BAU GESCHNITTEN WIRD
 * ───────────────────────────────────────────────────────────────────────────
 *
 * Neudingen schneidet Kopf und Fuss mit `scripts/rahmen-fuer-intern.mjs` aus dem
 * gebauten `index.html`. Dieses Projekt hat das Skript NICHT, und das ist eine
 * Entscheidung, kein Versäumnis:
 *
 * Hupbraums Kopfleiste enthält den Menüvorhang — einen React-Baustein mit
 * Portal, Fokusverwaltung und Zustand. Geschnitten und in PHP eingesetzt wäre er
 * ein Knopf, der nichts tut: ein sichtbar TOTES Bedienelement mitten im Kopf.
 * Neudingens Navigation ist eine Reihe von Verweisen und übersteht den Schnitt;
 * dieser Vorhang nicht.
 *
 * Also: der Rahmen wird hier nachgebaut — dieselben Farben, dieselbe Schrift,
 * dasselbe Hintergrundbild, dieselbe Schale. Der Preis ist, dass eine
 * Umgestaltung des Frontends hier nachgezogen werden muss. Der Gegenwert ist ein
 * Kopf, in dem jedes Element funktioniert.
 *
 * ⚠ `background-attachment: fixed` UND `background-size: cover` — genau wie im
 * Frontend, wo das Bild hinter dem ganzen Einseiter steht. Dazu ein dunkler
 * Schleier, sonst ist auf dem Foto kein Formular zu lesen. Der Schleier ist
 * DICHTER als im Frontend (0.88 gegen 0.72): hier steht Kleingedrucktes in
 * Tabellen, dort stehen Überschriften.
 */
body {
  margin: 0; font-size: 16px; line-height: 1.5;
  color: var(--dunkel);
  /*
   * Reihenfolge: Schleier ZUERST (liegt oben), Foto darunter.
   *
   * ⚠ DIE WERTE SIND NACHGEZOGEN WORDEN, nach dem Blick auf die Maske
   * „Zugänge": mit .88/.94 schlug die helle Bühnenlicht-Zone des Fotos mitten
   * durch die Rechtetabelle, und die um 90° gedrehten Spaltentitel standen
   * gegen orange-grünes Licht. Auf der Anmeldeseite war davon nichts zu sehen —
   * dort liegt alles auf der Karte.
   *
   * ⚠ GEPRÜFT WIRD AN DER LÄNGSTEN TABELLE, NICHT AM KÜRZESTEN FORMULAR. Die
   * Anmeldeseite ist der bequeme Fall: eine Karte in der Mitte, alles andere
   * leer. Wer dort prüft, hält den Schleier für ausreichend.
   */
  background:
    linear-gradient(rgba(10, 10, 10, .94), rgba(10, 10, 10, .97)),
    url("/bilder/hintergrund-2000.jpg") center / cover no-repeat fixed,
    var(--grund);
  /*
   * ⚠ HÄKCHEN UND RADIOKNÖPFE IN DER MARKENFARBE. Ohne das zeichnet der Browser
   * sie in seinem eigenen Blau — im Album-Formular stand ein blauer Punkt
   * zwischen orangen Knöpfen, und Blau ist die Farbe des NEUDINGER Projekts.
   * Eine Zeile, und es ist überall richtig, auch in Masken, die es noch nicht
   * gibt.
   */
  accent-color: var(--blau);
  /* ⚠ Platz für den feststehenden Fuss. Ohne das verdeckt er die letzte Zeile
     der längsten Tabelle — und zwar nur dort, also fällt es beim Prüfen der
     Übersicht nicht auf. */
  padding-bottom: 3.5rem;
}

/*
 * ⚠ DER KOPF BLEIBT STEHEN (`sticky`, nicht `fixed`).
 *
 * `fixed` nimmt ihn aus dem Fluss, und dann muss jemand den Inhalt von Hand um
 * die Kopfhöhe nach unten schieben — eine Zahl, die bei umbrechendem Kopf am
 * Handy falsch wird. `sticky` hält den Platz frei und klebt trotzdem oben.
 * Genau der Unterschied, der im Frontend beim Menüvorhang zum Sprung geführt hat.
 */
/*
 * ⚠ ZWEI ELEMENTE, NICHT EINS — und das ist der Grund für den Umbau am
 * 14.08.2026 (Nutzerwunsch: „Headerbreite prüfen und bitte exakt an Frontend
 * angleichen").
 *
 * Vorher trug `.kopf` beides: den Balken über die ganze Fensterbreite UND die
 * Anordnung des Inhalts. Damit konnte er keine Maximalbreite haben — eine hätte
 * auch die Trennlinie und den Weichzeichner beschnitten, und der Kopf hätte in
 * einem breiten Fenster als schwebender Kasten in der Mitte gestanden.
 *
 * Gemessen im Frontend (`Kopfleiste.tsx`):
 *
 *     <header class="sticky top-0 border-b bg-grund/85 backdrop-blur-md">
 *       <div class="mx-auto max-w-[88rem] px-4 py-3 sm:px-8">
 *
 * Also: der BALKEN ist voll breit, der INHALT ist auf 88rem begrenzt mit 1rem
 * Rand (ab 640px 2rem). Genau diese Aufteilung steht jetzt hier — `.kopf` ist
 * der Balken, `.kopf-innen` der Inhalt.
 *
 * ⚠ DIE ALTEN RÄNDER WAREN ANDERE: 1rem / 1.5rem ab 640px / 2.5rem ab 1536px,
 * übernommen aus Neudingen. Das Frontend kennt die 1536er-Stufe nicht. Drei
 * Stufen gegen zwei — deshalb standen Logo im Backend und Logo im Frontend bei
 * breiten Fenstern nicht auf derselben Kante.
 */
.kopf {
  position: sticky; top: 0; z-index: 50;
  border-bottom: 1px solid var(--rand);
  /* Halbdurchsichtig mit Weichzeichner — wie die Kopfleiste der Website. */
  background: rgba(10, 10, 10, .85);
  backdrop-filter: blur(12px);
}
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ DIE SCHALE — EINE Kante, und sie ist die des Frontends
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Vom Nutzer gemeldet (14.08.2026): „gleiches bitte im internen überprüfen. Menü
 * ist dort breiter als Header und Fußzeile ist auch mit Header nicht bündig —
 * besonders auf der linken Seite."
 *
 * Er hat recht, und es waren DREI verschiedene Kanten in dieser einen Datei.
 * Gemessen bei 1440 px Fensterbreite, vorher:
 *
 *     .kopf-innen        88rem  + 1rem/2rem     → Inhalt ab   48 px
 *     .bereiche-innen   100rem  + 1rem          → Inhalt ab   16 px
 *     .inhalt            88rem  + 1rem/2rem     → Inhalt ab   48 px
 *     .fuss-innen        88rem  + 1rem/2rem     → Inhalt ab   48 px
 *
 * Die Bereichsleiste stand also 32 Pixel weiter aussen als alles andere — das
 * ist das „Menü ist breiter als Header". Und alle vier standen 56 Pixel weiter
 * aussen als der Inhalt des Frontends, weil ich zwei Stunden vorher „exakt an
 * Frontend angleichen" gelesen und dabei die Kopfleiste als Maßstab genommen
 * habe. Die Kopfleiste war aber selbst die Ausnahme.
 *
 * ⚠ JETZT VIER MAL DERSELBE WERT, UND ER STEHT IM FRONTEND. `.schale` in
 * `src/app/globals.css` ist die Quelle; dort ist auch die ganze Vorgeschichte
 * aufgeschrieben. Diese Datei kann sie nicht lesen — sie ist reines CSS ohne
 * Aufbauwerkzeug, damit der interne Bereich auf jedem Webspace läuft. Die Zahlen
 * stehen deshalb hier noch einmal, aber nur EINMAL: über `--schale` und
 * `--schale-rand`.
 *
 * ⚠ WER SIE ÄNDERT, ÄNDERT SIE IN BEIDEN DATEIEN. Zwei Orte sind das Minimum;
 * vier waren es nicht.
 */
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ DIE SCHALE MUSS DIE DES FRONTENDS SEIN — am 16.08.2026 nachgemessen
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Nutzerhinweis beim Blick auf `:4000`: „Prüf bitte Header und Footerbreite des
 * Backends. Stimmt nicht zum Frontend überein." Er hatte recht, und die Zahlen
 * zeigen, um wie viel:
 *
 *              max-width   padding    Inhalt beginnt bei
 *   Frontend    1152 px     40 px          x = 104
 *   Backend     1280 px     24 px          x = 24
 *
 * Achtzig Pixel Versatz — der Kopf des Backends stand sichtbar weiter aussen als
 * der der Website, und beim Wechsel sprang das Logo.
 *
 * Die Werte stammen aus hupbraum (80rem/1rem) und passen dort. Hier gilt, was
 * BaarRocks Schale vorgibt: `max-w-6xl` (72rem) mit `px-6 sm:px-10`.
 *
 * ⚠ WER DIE SCHALE IM FRONTEND ÄNDERT, ÄNDERT SIE HIER MIT. Es sind zwei
 * Stylesheets; ein `var()` hilft nicht, weil Tailwind die Breite nicht als
 * Variable ablegt, sondern als Klasse auf dem Element.
 */
:root {
  --schale: 72rem;
  --schale-rand: 1.5rem;
}
@media (min-width: 640px) {
  :root { --schale-rand: 2.5rem; }
}

.kopf-innen {
  max-width: var(--schale); margin: 0 auto;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: .75rem 2rem;
  padding: .75rem var(--schale-rand);
}

/* Marke: Logo, Wortmarke, Zusatz — dieselbe Anordnung wie im Frontend. */
.marke { display: flex; align-items: center; gap: .75rem;
  font-weight: 700; text-decoration: none; color: var(--dunkel); }
.marke img.zeichen { width: 44px; height: 44px; display: block; }
/*
 * ⚠ ÜBER DIE HÖHE BEMESSEN, NICHT ÜBER DIE BREITE. Im Frontend steht am Logo
 * `h-8 w-auto sm:h-9` — also 32 px hoch, ab 640 px 36 px, Breite ergibt sich.
 * Hier stand `width: 136px`, und daraus wurden 36.3 px Höhe: 0.3 px zu hoch und
 * 1 px zu breit. Unsichtbar für sich, sichtbar im Wechsel zwischen den Seiten.
 */
.marke img.schriftzug { height: 32px; width: auto; display: block; }
@media (min-width: 640px) { .marke img.schriftzug { height: 36px; } }
/* ⚠ Am Handy fällt der Schriftzug weg, nicht das Zeichen: das Zeichen ist
   quadratisch und bleibt erkennbar, der Schriftzug wird unlesbar schmal. */
@media (max-width: 639px) { .marke img.schriftzug { display: none; } }
/*
 * Das Wort neben der Wortmarke. Es stand schon in Grossbuchstaben, aber in
 * Barlow statt Barlow Condensed — im Kopf der Website gibt es keine Schrift
 * ausser Condensed.
 */
.marke span.bereich {
  font-family: var(--font-display, inherit);
  display: block; font-weight: 600; font-size: .7rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--blau);
}

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * ⚠ DAS SCHRIFTBILD DES KOPFES KOMMT AUS DEM FRONTEND — nachgemessen 16.08.2026
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Nutzerwunsch: „übernimm auch die Schriftart und Design / Größe / Schreibweise
 * des Headers in den internen Header."
 *
 * Gemessen an der Kopfleiste der Website (ANLÄSSE · REPERTOIRE · BAND · …):
 *
 *   Navigation   Barlow Condensed · 16 px · Gewicht 600 · Laufweite 1.92 px · UPPERCASE
 *   Knopf        Barlow Condensed · 14 px · Gewicht 600 · Laufweite 1.4 px  · UPPERCASE
 *
 * Im Backend stand vorher: Barlow (nicht Condensed), 14.4 px, gemischte
 * Schreibung, keine Laufweite. Also dieselbe Familie, aber der andere Schnitt —
 * der Unterschied, den man nicht benennen kann und trotzdem sieht.
 *
 * ⚠ LAUFWEITE IN `em`, NICHT IN `px`. 1.92 px bei 16 px sind 0.12 em; als feste
 * Pixelzahl liefe sie bei jeder anderen Schriftgrösse aus dem Verhältnis.
 */
.kopfnav { display: flex; gap: 1.4rem; align-items: center; }
.kopfnav a {
  color: var(--dunkel); text-decoration: none;
  font-family: var(--font-display, inherit);
  font-size: 1rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
}
.kopfnav a:hover { color: var(--blau); text-decoration: none; }
/*
 * Die Kennung bleibt gemischt geschrieben: „Benedikt Hauger" in Grossbuchstaben
 * wäre kein Name mehr, sondern eine Beschriftung. Die Rolle darunter nimmt das
 * Schriftbild der Navigation auf, weil sie genau das ist — eine Beschriftung.
 */
.wer { color: var(--gedaempft); font-size: .8rem; line-height: 1.3; text-align: right; }
.wer strong {
  display: block; color: var(--dunkel); font-weight: 600;
  font-family: var(--font-display, inherit); font-size: .95rem; letter-spacing: .02em;
}

/*
 * ⚠ DER ABMELDEKNOPF SIEHT AUS WIE EIN KNOPF DER WEBSITE — oranger Grund,
 * dunkle Schrift, eckig. Nutzerwunsch: „Mit dem Button oben rechts abmelden."
 *
 * ⚠ DIE SCHRIFTFARBE IST DUNKEL UND MUSS DUNKEL SEIN. Am 14.08.2026 ist im
 * Frontend genau hier ein Fehler passiert: ich habe bei einem Knopf die Fläche
 * getauscht und die Schrift stehen gelassen — schwarz auf schwarz, vom Nutzer
 * gemeldet. Farbe ist ein PAAR, nie ein einzelner Wert.
 */
/*
 * ⚠ RUND, NICHT ECKIG — Nutzerhinweis 16.08.2026: „bei BaarRock haben wir runde,
 * bzw. oval rundliche" Knöpfe. Nachgemessen im Frontend: jeder Knopf dort trägt
 * `border-radius: 3.35e7px` (Tailwinds `rounded-full`), die Karten 14 px.
 * Gemessen im Backend vor der Änderung: dieser Knopf 0 px.
 *
 * Der Wert kommt aus hupbraum, wo „alles eckig" Programm ist. Hier war er der
 * einzige eckige Knopf zwischen lauter runden — der „Anmelden"-Knopf darunter
 * trug schon 999 px aus dem Neudinger Bestand.
 */
/*
 * ⚠ ZWEI WÄHLER, UND DER ZWEITE IST DER GRUND. Gemessen nach der ersten
 * Fassung: der Knopf trug 16 px statt 14 — `.kopfnav a` (Klasse + Element) ist
 * spezifischer als `.knopf-kopf` (nur Klasse) und gewann, sobald der Knopf in
 * der Kopfnavigation steht. Auf der Anmeldemaske steht er daneben, dort stimmte
 * es; im angemeldeten Zustand nicht. Ein Unterschied, der nur auf einer von zwei
 * Seiten sichtbar ist, ist der, den man beim Prüfen übersieht.
 */
.knopf-kopf,
.kopfnav a.knopf-kopf {
  /*
   * ⚠ `.5rem 1rem` SIND DIE 8px/16px DES FRONTEND-KNOPFES. Vorher `.45rem`:
   * 37.4 px Knopfhöhe statt 40 — und weil der Knopf das höchste Element im Kopf
   * ist, war damit der ganze Kopf 62.4 px hoch statt 65. Beim Wechsel sprang
   * die Leiste um 2.6 px.
   */
  display: inline-block; padding: .5rem 1rem;
  /*
   * ⚠ `line-height` FEST AUF 22px — nicht aus Geschmack, sondern aus Arithmetik.
   * Der Kopf ist so hoch wie sein höchstes Kind, und das ist dieser Knopf. Der
   * Frontend-Kopf misst 65.0 px; hier waren es 64.0. Die Rechnung:
   * 8 px Polsterung oben + 8 unten + 1 px Rahmen oben + 1 unten = 18, bleiben
   * 22 für die Zeile. Mit den vorherigen 21 fehlte genau ein Pixel, und der
   * bewegte beim Wechsel die ganze Leiste.
   *
   * Warum nicht einfach die Klasse des Frontend-Knopfes übernehmen: die kommt
   * aus Tailwind und existiert nur, wo Tailwind gebaut hat. Diese Datei ist
   * reines CSS und muss ohne Aufbauwerkzeug auskommen.
   */
  line-height: 22px;
  background: var(--blau); color: #0a0a0a !important;
  font-size: .88rem; font-weight: 700; text-decoration: none;
  border: 1px solid var(--blau);
  border-radius: 999px;
  /* Schriftbild des „Anfragen"-Knopfes der Website — siehe Messung oben. */
  font-family: var(--font-display, inherit);
  font-size: .875rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
}
.knopf-kopf:hover { background: #ffa566; border-color: #ffa566; text-decoration: none; }

/*
 * ⚠ DER FUSS STEHT FEST AM UNTEREN RAND (`fixed`), anders als der Kopf.
 *
 * Hier ist `fixed` richtig und `sticky` wäre falsch: ein `sticky` Fuss klebt
 * erst, wenn man weit genug gescrollt hat — auf einer kurzen Maske (Anmelden,
 * Passwort) sässe er mitten im Bild. Der Platz für ihn kommt aus dem
 * `padding-bottom` des `body`, siehe oben.
 */
/* Wie der Kopf: der Balken voll breit, der Inhalt auf 88rem. So stehen Marke
   oben links und Fusstext unten links auf derselben Kante — genau der Fehler,
   den der Nutzer bei Neudingen am 06.08.2026 im Screenshot gesehen hat. */
.fuss {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 40;
  font-size: .78rem; color: var(--gedaempft);
  border-top: 1px solid var(--rand);
  background: rgba(10, 10, 10, .9);
  backdrop-filter: blur(12px);
}
.fuss-innen {
  max-width: var(--schale); margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: .4rem 1.25rem; align-items: center;
  justify-content: space-between;
  padding: .6rem var(--schale-rand);
}
.fuss a { color: var(--gedaempft); }
.fuss a:hover { color: var(--dunkel); }

/*
 * ⚠ HIER STANDEN EIGENE REGELN `.mitte`/`.kasten` FÜRS MITTIGSTELLEN — von mir,
 * eine Stunde alt, und schon wieder weg. Die Anmeldeseite bringt ihr
 * Mittigstellen selbst mit (`.anmeldekarte--hintergrund`, weiter unten); ich
 * hatte es nur nicht gesehen, weil ihr Block hinter 900 Zeilen steht.
 *
 * Zwei Mechanismen für dieselbe Sache heißt, dass beim nächsten Umbau der
 * falsche geändert wird — und der andere still weiterwirkt.
 */
/*
 * ⚠ DIESELBE SCHALE WIE DIE WEBSITE (100rem) UND DIESELBEN SEITENRÄNDER.
 *
 * Sonst begänne der Inhalt an einer anderen Kante als Wappen und Fusszeile — und
 * genau darauf hat der Nutzer bei der Startseite schon zweimal hingewiesen
 * („Text zu Text"). Die Werte stammen aus `globals.css` (`--container-schale`)
 * und den Polstern der Kopfleiste (`px-4 sm:px-6 2xl:px-10`).
 *
 * Damit Formulare nicht über die ganze Breite laufen, sind Karten und
 * Formularelemente einzeln begrenzt — Tabellen dürfen breit sein, sie brauchen
 * den Platz.
 */
/*
 * ⚠ DIESELBE KANTE WIE ALLES ANDERE — über `--schale`, siehe oben.
 *
 * Vorher 100rem, dann 88rem — begründet damit, dass Tabellen Platz brauchen. Das
 * stimmt, und es war trotzdem falsch: eine Tabelle, die WEITER reicht als der
 * Kopf darüber, sieht nicht geräumig aus, sondern verrutscht.
 *
 * ⚠ TABELLEN DÜRFEN WEITER DIE GANZE SCHALE NUTZEN (`.inhalt > table`), nur ist
 * die Schale jetzt 80rem. Bei der breitesten Maske („Wer darf was", fünf Spalten)
 * reicht das; wird eine Maske einmal breiter, gehört `--schale` geändert — und
 * dann im Frontend genauso, sonst beginnt der Zwiespalt neu.
 */
.inhalt {
  max-width: var(--schale); margin: 0 auto;
  padding: 2rem var(--schale-rand) 4rem;
}
.inhalt > p, .inhalt > .hinweis, .karte, .inhalt form { max-width: 52rem; }
/* Tabellen dürfen die ganze Schale nutzen — eine Meldungsliste mit sechs Spalten
   auf 52 rem zu quetschen macht sie unlesbar. */
.inhalt > table { max-width: none; }
/* `font-weight` mitgeben: die Website setzt für Überschriften eigene Gewichte,
   und ohne Angabe erbte hier ein zufälliger Wert aus deren Stylesheet. */
h1 { font-size: 1.9rem; font-weight: 800; margin: .25rem 0 1.5rem; letter-spacing: -0.02em; }
h2 { font-size: 1.15rem; font-weight: 700; margin: 2rem 0 .75rem; }
label { display: block; margin: .9rem 0 .25rem; font-weight: 600; font-size: .92rem; }
/*
 * ⚠ `input[type=number]` HAT HIER GEFEHLT — gemeldet vom Nutzer am 08.08.2026:
 * „ich sehe erst bei mouse hover dass man da was eintragen könnte, weil Pfeile
 * erscheinen."
 *
 * Diese Aufzählung nennt Feldarten einzeln. Solange es nur Text-, Passwort-,
 * Mail- und Datumsfelder gab, fiel die Lücke nicht auf; mit dem ersten
 * Zahlenfeld (Maske „Kennzahlen") stand dort ein Eingabefeld ganz OHNE
 * Gestaltung — kein Rahmen, kein Polster, kein weisser Grund. Sichtbar wurde es
 * erst beim Überfahren, weil der Browser dann die Pfeilchen einblendet.
 *
 * ⚠ EINE AUFZÄHLUNG EINZELNER TYPEN IST GENAU DAFÜR ANFÄLLIG. Die naheliegende
 * Alternative wäre `input:not([type=file]):not([type=checkbox])` gewesen — dann
 * bekäme jede künftige Feldart die Gestaltung von selbst. Dagegen sprach, dass
 * `input[type=file]` in dieser Maske eigene Regeln hat (Zeile 286 ff.) und eine
 * Ausschlussliste beim nächsten Sonderfall genauso lückenhaft wäre, nur
 * schwerer zu lesen. Also weiter aufzählen — aber mit dem Wissen, dass jede
 * neue Feldart hier eingetragen werden muss.
 */
/*
 * ⚠ `input[type=url]` AM 16.08.2026 ERGÄNZT — dieselbe Lücke wie `number` am
 * 08.08.2026, damals vom Nutzer gemeldet. Ein Feldtyp, der hier fehlt, sieht
 * nicht kaputt aus, sondern nur anders: heller Grund, andere Höhe, kein Rahmen.
 * Man sucht den Fehler dann in der Maske und nicht in dieser Liste.
 * Gebraucht von der Terminmaske (Link zum Veranstalter).
 */
input[type=text], input[type=password], input[type=email], input[type=date],
input[type=number], input[type=url], select, textarea {
  width: 100%; padding: .55rem .7rem; border: 1px solid var(--rand);
  border-radius: .4rem; font: inherit; background: var(--hell); }

/*
 * Zahlenfelder etwas schmaler und mit sichtbaren Pfeilen.
 *
 * ⚠ DIE PFEILE WERDEN AUSDRÜCKLICH DAUERHAFT GEZEIGT (`appearance: auto` +
 * Firefox' `-moz-appearance: number-input`). Chrome blendet sie normalerweise
 * erst beim Überfahren ein — genau das hat den Nutzer in die Irre geführt, nur
 * andersherum: er sah das FELD nicht und die Pfeile als einzigen Hinweis.
 * Mit Rahmen ist das Feld erkennbar, und die dauerhaften Pfeile sagen zusätzlich
 * „hier steht eine Zahl".
 *
 * ⚠ NICHT ÜBER DIE VOLLE BREITE. Ein 52 rem breites Feld für eine zweistellige
 * Zahl sieht aus, als erwarte es einen Satz. 9 rem tragen vier Ziffern plus
 * Pfeile bequem.
 */
input[type=number] {
  /* ⚠ `display: block` — aufgefallen beim Nachsehen am 08.08.2026, nicht beim
     Schreiben. Alle anderen Felder sind `width: 100%` und stehen dadurch von
     selbst unter ihrer Beschriftung. Ein schmaleres Feld bleibt dagegen in der
     Zeile der Beschriftung hängen: im selben Formular sassen die Zahlenfelder
     rechts NEBEN dem Text, das Textfeld darunter. Zwei Anordnungen in einer
     Maske lesen sich als Versehen. */
  display: block;
  margin-top: .25rem;
  max-width: 9rem;
  appearance: auto;
  -moz-appearance: number-input;
}
input[type=number]::-webkit-inner-spin-button {
  opacity: 1;
}
textarea { min-height: 8rem; }
button, .knopf { display: inline-block; margin-top: 1.1rem; padding: .6rem 1.1rem;
  border: 0; border-radius: 999px; background: var(--blau); color: var(--hell);
  font: inherit; font-weight: 600; cursor: pointer; text-decoration: none; }
/*
 * ⚠ `a.leise` MUSS MITGENANNT WERDEN — hier stand nur `button.leise`, und das war
 * ein Fehler mit unsichtbarer Folge im Wortsinn.
 *
 * `.knopf` setzt `color: var(--hell)` (weisse Schrift auf blauem Grund). Für ein `<a
 * class="leise knopf">` griff `button.leise` nicht — es blieb also weisse Schrift.
 * Auf dem Rechner fiel das nicht auf, weil der Grund blau blieb. Am Handy setzt
 * `.inhalt td.aktionen a` den Grund auf `var(--hell)`, und damit stand weisse Schrift auf
 * weissem Grund: der Knopf „Herunterladen" war eine leere weisse Fläche.
 *
 * Gemeldet vom Nutzer am 06.08.2026 („der download button auf mobil ist nur weiß
 * ohne text ersichtlich"). Meine eigene Prüfung hatte nur das Markup gelesen —
 * dass der Verweis DA ist, sagt nichts darüber, ob man ihn SIEHT.
 *
 * ⚠ NEBENWIRKUNG, ausdrücklich gewollt: die Verweise „Zurück zur Übersicht" tragen
 * dieselbe Klasse und waren dadurch bisher gefüllte blaue Knöpfe — also so laut wie
 * „Speichern". Ab jetzt sind sie umrandet und leise, wie der Klassenname sagt.
 */
button.leise, a.leise { background: var(--hell); color: var(--blau); border: 1px solid var(--rand); }
.hinweis { padding: .8rem 1rem; border-radius: .5rem; border-left: 3px solid var(--blau);
  background: var(--hell); margin: 1rem 0; }
.hinweis.warnung { border-left-color: #ff6b60; background: rgba(179,38,30,0.16); }
.hinweis.gut { border-left-color: #4fd07a; background: rgba(29,122,61,0.16); }
/*
 * ⚠ DIE KACHELN NUTZEN DIE GANZE BREITE — und das war eine Kehrtwende.
 *
 * Ich hatte sie auf 52 rem begrenzt, nachdem der Nutzer sagte, es sähe „auf
 * Desktop komisch aus". Seine Antwort auf die schmale Fassung: „du darfst intern
 * aber die ganze Breite verwenden. Die 5 Menüpunkte waren vorhin alle mal
 * nebeneinander, fand ich nicht schlecht."
 *
 * Also breit. Bei fünf Bereichen (Rolle `verwaltung`) stehen sie damit in einer
 * Reihe, und das ist die Übersicht, die eine Übersicht sein soll.
 *
 * ⚠ WAS TROTZDEM SCHMAL BLEIBT: laufender Text und Formulare. Nicht aus
 * Geschmack — eine Textzeile über 1400 px ist schwer zu lesen (das Auge findet
 * den Zeilenanfang nicht wieder), und ein Eingabefeld über die ganze Breite für
 * einen 20 Zeichen langen Titel sieht aus wie ein Fehler. Tabellen dürfen breit
 * sein, sie brauchen es.
 */
.karten { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  margin-top: 1.25rem; }

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * HÖCHSTENS VIER SPALTEN IN DER ÜBERSICHT — damit die Zeilen dort umbrechen,
 * wo der Nutzer sie beschrieben hat
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Er hat die Kacheln am 06.08.2026 in drei Zeilen vorgegeben („neue ZEILE …"),
 * sah aber zwei. Der Grund lag nicht in der Reihenfolge, sondern hier: `auto-fit`
 * füllt, was hineinpasst, und `.inhalt` ist 100rem breit — das sind bis zu sechs
 * Spalten. Bei zehn Kacheln wurden daraus 5 + 5.
 *
 * ⚠ VIER, WEIL SEINE MITTLERE ZEILE VIER KACHELN HAT. Die Zahl ist nicht geraten:
 * PopUp, Ankündigung, Rückschau, Presse stehen bei ihm zusammen, und das geht nur
 * bei genau vier Spalten auf. Damit ergibt sich 4 + 4 + 2 — seine drei Zeilen.
 *
 * ⚠ `repeat(4, 1fr)` UND NICHT `auto-fit` MIT OBERGRENZE. Eine Obergrenze für
 * `auto-fit` gibt es in CSS nicht; der übliche Ersatz (`minmax` mit berechneter
 * Mindestbreite) rechnet Spaltenabstände in einer Formel mit und bricht, sobald
 * `gap` sich ändert. Vier feste Spuren sind hier ehrlicher: es sind zehn Kacheln,
 * keine Liste, die wächst.
 *
 * ⚠ NUR DIE ÜBERSICHT, deshalb die zweite Klasse. Die Ordnerkacheln in „Dateien"
 * benutzen dasselbe `.karten` und SOLLEN die Breite ausnutzen — dort sind es
 * beliebig viele, und vier Spalten wären bei zwanzig Ordnern eine unnötig lange
 * Seite.
 *
 * Unterhalb von 62rem bleibt `auto-fit` zuständig und macht daraus von selbst
 * drei, zwei oder eine Spalte. Vier Spalten × 14rem plus drei Abstände sind
 * 58.7rem — die Grenze liegt bewusst knapp darüber.
 */
@media (min-width: 62rem) {
  .karten.bereichskacheln { grid-template-columns: repeat(4, 1fr); }
}

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * DER ERZWUNGENE ZEILENUMBRUCH ZWISCHEN DEN GRUPPEN
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * `grid-column: 1 / -1` heisst „von der ersten bis zur letzten Spalte". Ein
 * Element, das die ganze Breite belegt, drängt alles Folgende in eine neue Zeile —
 * das ist der einzige Weg, in einem Raster einen Umbruch zu erzwingen, ohne für
 * jede Gruppe ein eigenes Raster aufzumachen.
 *
 * ⚠ WARUM NICHT DREI GETRENNTE RASTER, was die naheliegende Lösung wäre: dann
 * bestimmt jede Gruppe ihre Spaltenbreite selbst. Eine Zeile mit zwei Kacheln
 * hätte doppelt so breite Kacheln wie eine mit vier. Ein Raster mit Umbrüchen hält
 * ALLE Kacheln gleich breit — und genau das macht es als Raster erkennbar.
 *
 * `height: 0` und kein Rand: der Abstand zwischen den Zeilen kommt schon von
 * `gap`. Eine Höhe hier käme dazu und die Gruppen fielen auseinander.
 *
 * ⚠ ER GILT AUCH AM HANDY, wo ohnehin jede Kachel allein steht — dort ist er
 * unsichtbar und schadet nicht. Ihn nur oberhalb einer Breite zu setzen wäre eine
 * zweite Regel, die dasselbe entscheidet.
 */
.zeilenbruch { grid-column: 1 / -1; height: 0; }
.karte { display: block; padding: 1.1rem; border: 1px solid var(--rand); border-radius: .75rem;
  text-decoration: none; color: inherit; background: var(--hell); }
.karte:hover { background: var(--hell); }
/*
 * ⚠ NUR IN DEN KACHELN DER ÜBERSICHT, nicht in jeder `.karte`.
 *
 * Diese beiden Regeln machen aus `<strong>` die Kachelüberschrift und aus
 * `<span>` die Beschreibung darunter. Als `.karte strong` geschrieben trafen sie
 * ab dem Moment, in dem auch Formulare in `.karte` stehen, JEDES hervorgehobene
 * Wort in einem Formular — im Hinweis „Absätze durch eine **Leerzeile** trennen"
 * stand „Leerzeile" plötzlich blau in einer eigenen Zeile (gesehen im Bild am
 * 06.08.2026, gemeldet durch Hinsehen).
 *
 * `.karten .karte` trifft nur die Kacheln im Raster der Übersicht.
 */
.karten .karte strong { display: block; color: var(--blau); }
.karten .karte span { font-size: .88rem; color: var(--gedaempft); }
/*
 * Der Abspieler für Hörproben. Eigene Breite, weil er in einer Tabellenspalte
 * steht: ohne Angabe nimmt er die Breite, die der Browser für richtig hält, und
 * das sind in Chrome 300 px und in Safari die ganze Spalte.
 *
 * `display: block` und ein kleiner Abstand nach oben: er steht UNTER dem
 * Dateinamen, nicht daneben. Nebeneinander wird die Zeile in der Handyansicht
 * (Karten) zu einer Zeile mit zwei halben Dingen.
 */
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * DIE FILTERLEISTE — Terminarten im internen Kalender
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Flach gebaut: keine kräftige Farbe, kein Rahmen um das Ganze. Sie steht mitten im
 * Inhalt, und eine zweite laute Leiste unter der Navigation würde mit ihr um
 * Aufmerksamkeit streiten.
 *
 * ⚠ 44 px MINDESTHÖHE, auch am Rechner. Diese Verweise werden am Handy angetippt,
 * womöglich mit einem Instrument in der anderen Hand.
 *
 * `flex-wrap`: bei vier Filtern und 360 px Handybreite passen sie in zwei Zeilen.
 * Waagerechtes Schieben wäre die Alternative und ist schlechter — man sieht dann
 * nicht, dass es einen vierten Filter gibt.
 */
.filter { display: flex; flex-wrap: wrap; gap: .4rem; margin: 1rem 0 1.25rem; }
.filter a { display: inline-flex; align-items: center; gap: .4rem; min-height: 2.75rem;
  padding: .35rem .9rem; border: 1px solid var(--rand); border-radius: 999px;
  background: var(--hell); color: var(--blau); text-decoration: none; font-size: .92rem; }
.filter a span { color: var(--gedaempft); font-size: .82rem; }
.filter a.hier { background: var(--blau); color: var(--hell); border-color: var(--blau); font-weight: 600; }
/* Auf blauem Grund braucht die Zahl eine eigene Farbe — grau ist dort kaum lesbar. */
.filter a.hier span { color: rgba(255,255,255,.78); }

/*
 * Die ZWEITE Filterzeile (Kategorien). Sie steht direkt unter der ersten und ist
 * bewusst leiser: kleiner, weniger Polster, weniger Abstand nach oben.
 *
 * ⚠ WARUM SIE SICH UNTERSCHEIDEN MUSS. Zwei gleich aussehende Leisten übereinander
 * lesen sich als eine, die umgebrochen ist — dann wirkt „Auftritte" und „Kirche" wie
 * dieselbe Art von Wahl. Es sind aber zwei Dimensionen: die obere sagt WAS für ein
 * Termin, die untere WELCHE Kategorie. Die Rangfolge im Aussehen sagt das mit.
 *
 * 40 px statt 44 px Mindesthöhe: knapp unter der Fingerregel, und das ist hier
 * vertretbar — die Kategorien sind eine Verfeinerung, keine Hauptbedienung, und sie
 * stehen mit `gap` weit genug auseinander, dass man nicht danebentrifft.
 */
.filter.filter-zweite { margin: -0.5rem 0 1.25rem; gap: .35rem; }
.filter.filter-zweite a { min-height: 2.5rem; padding: .25rem .75rem; font-size: .86rem; }

.hoerprobe { display: block; width: 100%; max-width: 20rem; margin-top: .4rem; height: 2.25rem; }

/*
 * ⚠ EIN FORMULAR IN DER AKTIONSSPALTE BLEIBT IN DER ZEILE. „Entfernen" ist ein
 * Formular und kein Verweis (sonst löste es jeder Vorschau-Abruf aus, und der
 * Formularschlüssel liesse sich nicht prüfen). Ein `<form>` ist aber ein
 * Blockelement und schöbe den Knopf sonst unter „Ändern".
 * ⚠ Der Knopf darin braucht `margin-top: 0` — die allgemeine Knopfregel setzt
 * 1.1rem Abstand nach oben, gedacht für Knöpfe unter einem Formular.
 */
.aktionen form.daneben { display: inline; }
.aktionen form.daneben button { margin-top: 0; }

table { width: 100%; border-collapse: collapse; margin-top: 1rem; font-size: .93rem; }
th, td { text-align: left; padding: .5rem .4rem; border-bottom: 1px solid var(--rand); }
th { font-size: .8rem; text-transform: uppercase; letter-spacing: .08em; color: var(--gedaempft); }
code { background: var(--hell); padding: .1rem .35rem; border-radius: .25rem; font-size: .9em; }


/* ═══════════════════════════════════════════════════════════════════════════
 * ABLAGEFLÄCHE FÜRS HOCHLADEN — Dateien hineinziehen
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Frage des Nutzers (06.08.2026): „Ist das Upload-Feld ein Drag-and-drop-Feld?
 * Können hier mehrere Dateien ausgewählt werden?"
 *
 * Mehrere: ja, das konnte das Feld schon (`multiple`). Hineinziehen: die Browser
 * nehmen Dateien auch auf einem nackten `<input type="file">` an — aber das ist
 * ein Knopf von 90 px Breite, und darauf zielt niemand. Eine Fläche, die man
 * trifft, ist der Unterschied zwischen „geht theoretisch" und „wird benutzt".
 *
 * ⚠ DAS FELD BLEIBT DARIN UND SICHTBAR. Es wäre verlockend, es zu verstecken und
 * die Fläche als Knopf zu nehmen — dann hinge das Hochladen aber an JavaScript.
 * So funktioniert ohne Skript alles wie bisher, und mit Skript kommt das
 * Hineinziehen dazu.
 */
.ablage { border: 2px dashed var(--rand); border-radius: .75rem; padding: 1.25rem;
  background: var(--hell); transition: border-color .15s, background .15s; }
.ablage.drueber { border-color: var(--blau); background: rgba(255,145,77,0.10); }
.ablage p { margin: 0 0 .75rem; color: var(--gedaempft); font-size: .92rem; }
.ablage .zaehler { margin: .75rem 0 0; font-weight: 600; color: var(--blau); }
.ablage .zaehler:empty { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
 * BEREICHSLEISTE UND BROTKRUMEN
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Die Leiste sitzt direkt unter dem Kopf der Website und trennt sich von ihm
 * durch einen hellen Grund — sie gehört zum internen Bereich, nicht zur Website.
 *
 * ⚠ SIE IST NICHT KLEBRIG (`sticky`). Der Kopf der Website ist es schon; zwei
 * übereinander klebende Leisten nehmen am Handy die halbe Höhe. Die Seiten hier
 * sind kurz genug, dass man oben ist, bevor man sie vermisst.
 */
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * DIE BEREICHSLEISTE BLEIBT BEIM SCROLLEN STEHEN
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Nutzerwunsch (06.08.2026): „schau dass du das Menü oben fixierst und es beim
 * scrollen erhalten bleibt."
 *
 * ⚠ SIE HÄNGT UNTER DEM KOPF DER WEBSITE, nicht bei `top: 0`. Der Kopf ist selbst
 * `sticky top-0 z-40` (er kommt aus dem gebauten HTML, siehe `_rahmen.php`) — eine
 * Leiste bei `top: 0` würde also unter ihm verschwinden. `var(--kopfhoehe)` kommt
 * aus `globals.css` und ist damit dieselbe Zahl, die auch die Sprungziele benutzen
 * (`scrollMarginTop` bei den Ankern). Eine eigene 5rem hier wäre eine zweite
 * Wahrheit über die Höhe des Kopfes.
 *
 * ⚠ `z-index: 30`, ALSO UNTER DEM KOPF (40). Wer sie höher legt, schiebt sie beim
 * Scrollen ÜBER den Kopf — und das Klappmenü der Website, das aus dem Kopf
 * herunterfährt, läge dann dahinter.
 *
 * ⚠ DER HINTERGRUND IST JETZT PFLICHT, nicht Zierde. Solange die Leiste mitscrollte,
 * war `--hell` Gestaltung; als feststehende Leiste liegt sie über dem Inhalt, und
 * ohne deckende Fläche liest man Tabellenzeilen durch die Verweise hindurch.
 * Deshalb steht hier ein VOLL deckender Wert und kein `rgba`.
 *
 * ⚠ WAS ES KOSTET: bei 390 px Fensterbreite bricht die Leiste auf drei Zeilen um und
 * nimmt dann rund 150 px feste Höhe. Zusammen mit dem Kopf bleiben von 844 px etwa
 * 610 px für den Inhalt. Vertretbar, weil die Masken kurze Formulare sind — beim
 * Blättern durch eine lange Tabelle ist der schnelle Wechsel mehr wert als die
 * Zeilen. Sollte es störn, wäre der Weg: unter 640 px NICHT feststellen.
 */
.bereiche { position: sticky; top: calc(var(--kopfhoehe, 5rem) - 4px); z-index: 30;
  border-bottom: 1px solid var(--rand); background: var(--hell); }

/*
 * ⚠ `- 4px` IST KEINE FEINJUSTIERUNG, SONDERN DECKT EINE LÜCKE.
 *
 * `--kopfhoehe` ist 5 rem, also 80 px. Der Kopf ist aber gemessen **77 px** hoch —
 * er richtet sich nach seinem Inhalt, die Variable ist der Wert, mit dem die
 * Sprungziele rechnen. Bei `top: 80px` blieben also 3 px zwischen Kopfunterkante und
 * Leiste, und durch diesen Spalt scrollte der Inhalt sichtbar hindurch: ein
 * wandernder Streifen, den man für einen Darstellungsfehler hält.
 *
 * Mit 76 px liegt die Leiste 1 px UNTER der Kopfkante und deckt die Naht. Eine
 * Überlappung ist hier richtiger als eine Lücke: sie kann nichts verdecken, was man
 * lesen müsste (beide Flächen sind deckend), eine Lücke zeigt immer etwas.
 *
 * ⚠ NICHT `--kopfhoehe` ÄNDERN. Die Zahl gehört den Sprungzielen (`scrollMarginTop`
 * bei den Ankern in `geschichte/page.tsx` und `Meldungen.tsx`); dort ist sie richtig,
 * weil sie ETWAS LUFT über dem Ziel lassen soll. Wer sie auf 77 setzt, schiebt
 * jedes Sprungziel um 3 px unter den Kopf.
 */

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * AM HANDY: EINE ZEILE ZUM WISCHEN STATT VIER FESTE
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Gemessen bei 390 × 844 px: die Leiste brach auf **197 px** um. Mit dem Kopf (77)
 * wären 274 von 844 px dauerhaft belegt — ein Drittel des Bildschirms für die
 * Navigation, während man eine Terminliste durchblättert. Das ist nicht das, was
 * „Menü bleibt beim Scrollen erhalten" bedeuten soll.
 *
 * Also eine Zeile, waagerecht wischbar: 47 px statt 197.
 *
 * ⚠ ICH HABE WAAGERECHTES SCHIEBEN BEI DER FILTERLEISTE ABGELEHNT, mit dem Argument
 * „man sieht dann nicht, dass es einen vierten Filter gibt". Das gilt dort und hier
 * nicht, und der Unterschied ist der Zweck: eine Filterleiste muss man ÜBERBLICKEN,
 * um zu wählen. Eine Navigationsleiste kennt man — man sucht einen bestimmten Punkt,
 * und dass links und rechts mehr ist, verrät die abgeschnittene Kachel am Rand.
 *
 * ⚠ `scrollbar-width: none` NUR, WEIL DIE LEISTE SCHMAL IST. Eine sichtbare
 * Bildlaufleiste unter 47 px Höhe frisst ein Drittel davon. Das Wischen bleibt, die
 * Anzeige geht — und `ablage.js` schiebt beim Laden den aktiven Punkt ins Bild,
 * damit niemand suchen muss, wo er gerade ist.
 */

/* ⚠ WAR 100rem — 32px weiter aussen als Kopf und Fuss. Genau das hat der Nutzer
   als „Menü ist breiter als Header" gesehen. */
.bereiche-innen { max-width: var(--schale); margin: 0 auto; padding: 0 var(--schale-rand);
  display: flex; flex-wrap: wrap; gap: .25rem; }
@media (min-width: 640px) { .bereiche-innen { padding: 0 1.5rem; } }
@media (min-width: 1536px) { .bereiche-innen { padding: 0 2.5rem; } }

/*
 * ⚠ AUCH DIE BEREICHSLEISTE. Sie sitzt unmittelbar unter dem Kopf und liest sich
 * als dessen zweite Zeile; in gemischter Schreibung wäre sie das einzige
 * Navigationselement der Seite, das aus der Reihe fällt.
 */
.bereiche a { display: inline-block; padding: .7rem .95rem;
  font-family: var(--font-display, inherit);
  font-size: .95rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 600; color: var(--gedaempft); text-decoration: none;
  border-bottom: 2px solid transparent; }
.bereiche a:hover { color: var(--blau); }
/* Die laufende Stelle mit Linie UND Farbe: nur Farbe ist bei Blau auf Hellblau
   zu wenig Unterschied, nur Linie übersieht man beim Überfliegen. */
.bereiche a.hier { color: var(--blau); border-bottom-color: var(--blau); }

/*
 * ⚠ DIESER BLOCK MUSS NACH `.bereiche-innen` STEHEN. Erst stand er darüber, und die
 * spätere Regel `.bereiche-innen { flex-wrap: wrap }` gewann bei gleicher
 * Spezifität — gemessen blieb die Leiste am Handy bei 197 px. Reihenfolge ist bei
 * CSS ein Argument, nicht eine Formalie.
 */
@media (max-width: 639px) {
  .bereiche-innen {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .bereiche-innen::-webkit-scrollbar { display: none; }
  .bereiche a { white-space: nowrap; }
}

.krumen { margin: 0 0 1.25rem; font-size: .9rem; color: var(--gedaempft); }
.krumen a { color: var(--blau); }
.krumen .pfeil { margin: 0 .5rem; color: var(--gedaempft); }

/* ═══════════════════════════════════════════════════════════════════════════
 * JAHRGÄNGE ZUM AUFKLAPPEN — in der Galerie-Übersicht
 * ═══════════════════════════════════════════════════════════════════════════ */
.jahrgang { border-top: 1px solid var(--rand); }
.jahrgang:last-of-type { border-bottom: 1px solid var(--rand); }
.jahrgang > summary { cursor: pointer; padding: .85rem .25rem; list-style: none;
  display: flex; align-items: baseline; gap: .75rem; }
.jahrgang > summary::-webkit-details-marker { display: none; }
/* Eigenes Dreieck, damit es links steht und sich dreht — das eingebaute sitzt je
   nach Browser woanders und lässt sich nicht zuverlässig formatieren. */
.jahrgang > summary::before { content: "›"; display: inline-block; width: .8rem;
  color: var(--blau); font-weight: 700; transition: transform .15s; }
.jahrgang[open] > summary::before { transform: rotate(90deg); }
.jahrgang > summary strong { font-size: 1.15rem; }
.jahrgang > summary:hover { background: var(--hell); }
.jahrgang table { margin-top: 0; margin-bottom: 1rem; }

/* ═══════════════════════════════════════════════════════════════════════════
 * ⚠ FESTE SPALTENBREITEN — jede Jahresgruppe ist eine EIGENE Tabelle
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Und genau das ist die Falle: eine Tabelle rechnet ihre Spaltenbreiten aus IHREM
 * Inhalt. Acht Jahrgänge sind acht Tabellen, also acht verschiedene Ergebnisse.
 *
 * GEMESSEN am 06.08.2026 bei 1600 px, linke Kante der Titelspalte:
 *
 *     2026  229      2025  198      2024  274      2023  278
 *     2022  291      2021  266      2020  319      2019  243
 *
 * Über 120 px Unterschied. Beim Aufklappen eines Jahrgangs sprangen die Spalten,
 * und untereinander stand nichts in einer Flucht — vom Nutzer gemeldet.
 *
 * `table-layout: fixed` löst das: die Breiten stehen fest, der Inhalt richtet sich
 * danach. Nur die Titelspalte bleibt frei und nimmt den Rest — sie ist die
 * einzige, deren Länge nicht vorhersehbar ist.
 *
 * ⚠ MIT `overflow-wrap`, sonst schiebt ein langer Titel ohne Leerzeichen die
 * feste Breite doch wieder auf.
 */
.jahrestabelle { table-layout: fixed; width: 100%; }
.jahrestabelle th, .jahrestabelle td { overflow-wrap: anywhere; }
.jahrestabelle th:nth-child(1), .jahrestabelle td:nth-child(1) { width: 10rem; }
.jahrestabelle th:nth-child(2), .jahrestabelle td:nth-child(2) { width: auto; }
.jahrestabelle th:nth-child(3), .jahrestabelle td:nth-child(3) { width: 9rem; }
.jahrestabelle th:nth-child(4), .jahrestabelle td:nth-child(4) { width: 7.5rem; }
.jahrestabelle th:nth-child(5), .jahrestabelle td:nth-child(5) { width: 13rem; }
.jahrestabelle th:nth-child(6), .jahrestabelle td:nth-child(6) { width: 11rem; }

/*
 * Die Galerie-Jahrestabelle hat drei Spalten: Vorschaubild, Angaben, Aktion.
 *
 * ⚠ DIE DRITTE BRAUCHT EINE BREITE, weil die Tabelle auf `fixed` steht. Ohne
 * Angabe teilen sich Spalte 2 und 3 den Rest zu gleichen Teilen — der Albumtitel
 * stünde dann in der halben Breite, obwohl die Aktion nur einen Knopf enthält.
 *
 * ⚠ UND DER KNOPF DARF UMBRECHEN. „Originale in den Papierkorb" ist bei .85 rem
 * rund 190 px breit; als eine Zeile erzwungen müsste die Spalte 13 rem nehmen.
 * Zwei Zeilen kosten Höhe, die in der Zeile sowieso durch das 80-px-Vorschaubild
 * vorgegeben ist — also kosten sie nichts.
 */
.jahrgang table:not(.jahrestabelle) { table-layout: fixed; width: 100%; }
.jahrgang table:not(.jahrestabelle) td:first-child { width: 6rem; }
.jahrgang table:not(.jahrestabelle) td:nth-child(3) { width: 9.5rem; }
.jahrgang table:not(.jahrestabelle) td:nth-child(3) button {
  white-space: normal;
  line-height: 1.25;
  text-align: left;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * AM HANDY — ZEILEN WERDEN KARTEN
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Anlass: der Nutzer hat die Masken am 06.08.2026 auf einem iPhone geprüft.
 * Befund wörtlich: „Es zerhagelt die Tabellen und sieht unbedienbar aus." Am
 * Rechner war alles gut — und soll es bleiben. Denn die Pflege wird nach seiner
 * Einschätzung überwiegend am Telefon stattfinden.
 *
 * WARUM ES ZERHAGELT — gerechnet, nicht geraten:
 * `.jahrestabelle` steht auf `table-layout: fixed` mit festen Spaltenbreiten
 * (10 + auto + 9 + 7,5 + 13 + 11 rem, siehe oben). Das sind rund 808 px
 * Mindestbreite OHNE die Titelspalte. Ein iPhone hat 390 px. Die restlichen
 * Tabellen haben fünf bis sechs Spalten mit `white-space: nowrap` an den Zellen
 * — sie brechen nicht, sie schieben.
 *
 * WARUM KEIN WAAGERECHTES SCROLLEN. Das wäre die kurze Antwort: `overflow-x:
 * auto` um jede Tabelle, fertig. Nur ist der Zweck dieser Tabellen nicht Lesen
 * sondern BEDIENEN — jede Zeile endet in „Bearbeiten" und „Entfernen". In einem
 * Scrollkasten liegen diese Knöpfe genau dort, wo man sie nicht sieht, und man
 * trifft sie beim Wischen versehentlich. Eine Tabelle, durch die man schiebt,
 * ist lesbar; bedienbar ist sie nicht.
 *
 * DESHALB: unter 768 px wird jede Zeile eine Karte, jede Zelle eine Zeile
 * darin, mit ihrer Spaltenüberschrift darüber. Die Kopfzeile entfällt, weil
 * sie dann nichts mehr überschreibt.
 *
 * ⚠ DIE BESCHRIFTUNG KOMMT AUS DER ZELLE (`data-spalte`), NICHT AUS DIESER
 * DATEI. Man könnte sie hier je Spaltennummer hinschreiben
 * (`td:nth-child(3)::before { content: "Kategorie" }`) und käme ohne Änderung
 * am PHP aus. Dann stünde die Überschrift aber zweimal im Projekt — einmal im
 * `<th>` und einmal hier — und beim Umbenennen einer Spalte driftet sie
 * auseinander. Genau diese Art Dublette ist in diesem Projekt schon viermal
 * schiefgegangen. Die Zelle trägt ihre Überschrift selbst.
 *
 * ⚠ `!important` IST HIER NICHT ZU VERMEIDEN, und das ist der einzige Ort in
 * dieser Datei. `white-space: nowrap`, Polster und Schriftgrössen stehen als
 * INLINE-`style` an den Zellen und Knöpfen (`neuigkeiten.php:565` und weitere).
 * Ein Inline-Attribut schlägt jede Regel aus einem Stylesheet, Layer hin oder
 * her — dagegen hilft nur `!important`. Die Alternative wäre, in fünf Masken
 * jedes `style`-Attribut in eine Klasse zu überführen; das ist richtig, aber ein
 * eigener Umbau, und er würde den Handy-Fehler nicht schneller beheben.
 * 768 px = Tailwinds `md`. Darüber greift keine dieser Regeln.
 */
@media (max-width: 767px) {
  .inhalt table { margin-top: .75rem; font-size: 1rem; }

  /* Die Kopfzeile überschreibt nichts mehr, sobald die Zellen untereinander
     stehen — jede Zelle sagt selbst, was sie ist.
     `th` ZUSÄTZLICH zu `thead`: alle fünf Masken benutzen inzwischen `<thead>`,
     aber `zugaenge.php` tat es bis zum 06.08.2026 nicht, und der Fehler wäre
     stumm gewesen — die Überschriften hätten als erste Karte dagestanden. Im
     internen Bereich ist jedes `th` eine Spaltenüberschrift, keine Zeilen-
     überschrift; es auszublenden ist hier immer richtig. */
  .inhalt thead, .inhalt th { display: none; }
  .inhalt tbody, .inhalt tr, .inhalt td { display: block; }

  .inhalt tr {
    margin-bottom: .7rem;
    padding: .85rem .9rem;
    border: 1px solid var(--rand);
    border-radius: .75rem;
  }
  /* Die letzte Karte braucht unten keinen Abstand — darunter kommt schon der
     Abstand der Tabelle. */
  .inhalt tr:last-child { margin-bottom: 0; }

  .inhalt td {
    padding: .3rem 0;
    border-bottom: none;
    /* Bricht das Inline-`white-space:nowrap` der Masken. Ohne das steht ein
       langes Zitat in der Pressetabelle als einzige 900 px breite Zeile. */
    white-space: normal !important;
    overflow-wrap: anywhere;
  }
  /* Leere Zellen (etwa eine Aktionsspalte ohne Rechte) würden als leere Zeile
     mit Polster stehen bleiben. */
  .inhalt td:empty { display: none; }

  /* Die Spaltenüberschrift ÜBER dem Wert, nicht davor: nebeneinander müsste man
     eine Breite für die Beschriftung festlegen, und bei „Überschrift" gegen
     „Wann" wäre jede Wahl für eine von beiden falsch. */
  .inhalt td[data-spalte]::before {
    content: attr(data-spalte);
    display: block;
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--gedaempft);
  }

  /* Die Zelle, an der man die Zeile erkennt (Titel, Überschrift, Name). Sie
     steht als Überschrift der Karte da und braucht keine Beschriftung — was
     „Bäckerei Bräzzele" ist, sagt die Karte durch ihre Stellung. */
  .inhalt td.haupt { padding-bottom: .45rem; font-size: 1.05rem; }
  .inhalt td.haupt::before { display: none; }

  /*
   * Die Aktionsspalte — der Grund für den ganzen Umbau.
   *
   * ⚠ 2,75 rem = 44 px MINDESTHÖHE. Das ist keine Zierde: „Bearbeiten" und
   * „Entfernen" stehen direkt nebeneinander, und die eine Aktion ist nicht
   * zurücknehmbar. Bei den ursprünglichen `.25rem` Polster sind das
   * Trefferflächen von rund 26 px — auf einem Telefon liegt „Entfernen" damit
   * innerhalb der Fingerkuppe, die auf „Bearbeiten" zielt.
   */
  .inhalt td.aktionen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
    margin-top: .55rem;
    padding-top: .7rem;
    border-top: 1px solid var(--rand);
  }
  .inhalt td.aktionen::before { display: none; }
  /* Die Masken setzen `style="display:inline"` an die Formulare — als
     Flex-Kind muss es ein Kasten sein, sonst sitzt der Knopf daneben statt
     darin. */
  .inhalt td.aktionen form { display: inline-flex !important; margin: 0; }
  .inhalt td.aktionen a,
  .inhalt td.aktionen button {
    display: inline-flex;
    align-items: center;
    min-height: 2.75rem;
    margin: 0 !important;
    padding: .4rem 1rem !important;
    font-size: .95rem !important;
    border: 1px solid var(--rand);
    border-radius: .5rem;
    background: var(--hell);
    /* ⚠ FARBE MITGEBEN. Dieser Block setzt den Grund auf weiss; ohne eigene
       Schriftfarbe hängt die Lesbarkeit davon ab, was der Verweis sonst erbt — und
       erbt er `.knopf`, ist sie weiss. Genau so war „Herunterladen" unsichtbar. */
    color: var(--blau);
    text-decoration: none;
  }

  /*
   * Die festen Spaltenbreiten aufheben. Sie sind oben mit `.jahrestabelle
   * td:nth-child(n)` gesetzt (Spezifität 0,2,1) — eine Regel mit `.inhalt td`
   * (0,1,1) käme dagegen nicht an. Deshalb hier mit demselben Gewicht und
   * später in der Datei, nicht mit `!important`.
   */
  .inhalt .jahrestabelle { table-layout: auto; }
  .inhalt .jahrestabelle td:nth-child(1),
  .inhalt .jahrestabelle td:nth-child(2),
  .inhalt .jahrestabelle td:nth-child(3),
  .inhalt .jahrestabelle td:nth-child(4),
  .inhalt .jahrestabelle td:nth-child(5),
  .inhalt .jahrestabelle td:nth-child(6) { width: auto; }
  .inhalt .jahrgang table:not(.jahrestabelle) { table-layout: auto; }
  .inhalt .jahrgang table:not(.jahrestabelle) td:first-child { width: auto; }
  .inhalt .jahrgang table:not(.jahrestabelle) td:nth-child(3) { width: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
 * AM HANDY — DIE FUSSZEILE DER WEBSITE WIRD SCHMAL
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Wunsch des Nutzers (06.08.2026): „Im Internen Bereich Footer auf Mobilversion
 * schmälern, heißt Logo noch anzeigen, die Texte bis zum Copyright entfernen
 * (sind intern auf Mobil auch nicht notwendig)."
 *
 * Der Grund ist nachvollziehbar: unter 640 px stellt Tailwind das Raster
 * einspaltig, und dann stehen vier Spalten UNTEREINANDER — Wappen, Probezeiten,
 * drei Bereichsverweise, drei Rechtsverweise. Auf einer Maske, die selbst kurz
 * ist, ist der Fuss dann länger als der Inhalt.
 *
 * ⚠ EINE ABWEICHUNG VON DER VORGABE, BEWUSST: Kontakt · Impressum ·
 * Datenschutz BLEIBEN. `anmelden.php` ist ohne Anmeldung erreichbar, also eine
 * öffentliche Seite, und § 5 DDG verlangt ein „ständig verfügbares" Impressum.
 * Eine Fusszeile, die es am Telefon weglässt, wäre auf genau der einen Seite
 * dieses Bereichs zu wenig, die jeder sehen kann. Statt einer Spalte sind es
 * jetzt drei Wörter in EINER Zeile — der Platzgewinn bleibt fast derselbe.
 *
 * ⚠ WARUM DIE REGELN AUF `footer` OHNE KLASSE ZIELEN. Der Fuss ist fremdes
 * Markup, aus dem gebauten HTML geschnitten (`scripts/rahmen-fuer-intern.mjs`),
 * und trägt nur Tailwind-Klassen, die sich beim nächsten Bau ändern können.
 * Der Kopfkommentar dieser Datei warnt zu Recht vor Regeln ohne
 * Geltungsbereich — hier ist der Geltungsbereich das Stylesheet selbst:
 * `stil.css` wird ausschliesslich von `intern/_kern.php` eingebunden und von
 * keiner Seite der Website. Es gibt in diesem Bereich genau einen `<footer>`.
 *
 * ⚠ KEIN `!important` NÖTIG. Tailwind legt seine Regeln in einen Cascade Layer,
 * und eine Regel ohne Layer schlägt jede Regel darin — dieselbe Eigenschaft,
 * die weiter oben mit dem `*` einmal Schaden angerichtet hat, hier mit
 * Geltungsbereich nutzbar gemacht.
 *
 * 639 px, nicht 767: das ist Tailwinds `sm`-Grenze und damit der Punkt, an dem
 * der Fuss auf eine Spalte fällt. Zwischen 640 und 768 steht er zweispaltig und
 * ist kompakt genug.
 */
@media (max-width: 639px) {
  /* Alles zwischen Wappen und Rechtsverweisen weg: Probezeiten, die drei
     Bereichsverweise und der `<noscript>`-Rückfall. `:not(:first-child)
     :not(:last-child)` statt Nummern, damit die Regel eine zusätzliche Spalte
     im Fuss überlebt. */
  footer > div:first-child > *:not(:first-child):not(:last-child) { display: none; }

  /* Aus der Spalte eine Zeile machen. `space-y-2` von Tailwind setzt den
     Abstand über `> * + *` als `margin-top` — das muss mit weg, sonst stehen
     die drei Wörter versetzt. */
  footer > div:first-child > ul:last-child {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.25rem;
  }
  footer > div:first-child > ul:last-child > li { margin-top: 0; }

  /* Das Raster braucht keinen Spaltenabstand mehr, wenn nur zwei Dinge
     übrig sind. */
  footer > div:first-child { gap: 1rem; }

  /* 40 px Polster oben und unten waren für vier Spalten gedacht. */
  footer { padding-top: 1.75rem; padding-bottom: 1.75rem; }
  footer > div:last-child { margin-top: 1.1rem; padding-top: 1.1rem; }
}

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * DATEIFELDER — sichtbar als Feld, nicht als nackter Knopf
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Gemeldet vom Nutzer am 08.08.2026: „check noch bitte die Datei auswählen
 * Felder im Backend — die sind genauso unklar wie die Zahlenfelder vorhin …
 * nicht nur auf der Seite sondern auch bei Bildern und sonst überall wo man was
 * hochladen könnte."
 *
 * ⚠ DERSELBE FEHLER ZWEIMAL AM SELBEN TAG. Vormittags fehlte `input[type=number]`
 * in der Aufzählung der gestalteten Feldarten; hier ist es `input[type=file]`.
 * Beide Male stand ein Bedienelement ohne Rahmen, ohne Polster, ohne Grund —
 * ein Browser zeichnet dann nur seinen nackten Knopf, und daneben ist Weiss.
 *
 * ⚠ WARUM ES HIER NICHT EINFACH IN DIE OBIGE AUFZÄHLUNG KONNTE: `width: 100%`
 * und `padding` an einem Dateifeld sehen falsch aus — der Browser zeichnet den
 * Knopf und den Dateinamen selbst, und beide sitzen dann verloren in einer
 * breiten weissen Fläche. Deshalb eine eigene Regel: gestrichelter Rahmen wie
 * bei der Ablagefläche, damit „hier gehört etwas hinein" auch ohne Text
 * verstanden wird, und ein heller Grund, der es vom Papier abhebt.
 *
 * ⚠ DIE ABLAGEFLÄCHE BLEIBT UNANGETASTET. Wo `.ablage` schon eine Fläche zum
 * Hineinziehen aufspannt (Galerie, Dateien, Konzert), soll das Feld darin NICHT
 * ein zweites Mal gerahmt werden — sonst steht ein Kasten im Kasten.
 */
input[type=file] {
  display: block;
  width: 100%;
  max-width: 32rem;
  margin-top: .25rem;
  padding: .7rem;
  border: 2px dashed var(--rand);
  border-radius: .5rem;
  background: var(--hell);
  font: inherit;
  font-size: .92rem;
  cursor: pointer;
}
input[type=file]:hover { border-color: var(--blau); background: rgba(255,145,77,0.10); }
.ablage input[type=file] { border: 0; background: transparent; padding: 0; max-width: none; }

/* Der Knopf IM Dateifeld — der Browser zeichnet ihn, aber wir dürfen ihn kleiden. */
input[type=file]::file-selector-button {
  margin-right: .8rem; padding: .4rem .9rem; border: 0; border-radius: 999px;
  background: var(--blau); color: var(--hell); font: inherit; font-weight: 600;
  font-size: .88rem; cursor: pointer;
}

/* ── Anmeldeseite ────────────────────────────────────────────────
   Nutzerwunsch aus der Aufnahme vom 14.08.2026 (Donaueschingen 7):

     „nur eben mit dem Login-Feld, Zentral in der Mitte, bitte auch hier eckig
      designte Felder und Buttons, dass Hubraum ein wenig kantiger erscheint“

   ─────────────────────────────────────────────────────────────────────────
   ⚠ HIER STAND NEUDINGENS ANMELDESEITE, UND SIE WAR IN ZWEI PUNKTEN KAPUTT

   Der Block ist am 14.08.2026 mit dem internen Bereich mitgekommen — samt zwei
   Voraussetzungen, die in diesem Projekt nicht gelten:

     1. Ein Hintergrundbild `/bilder/anmelden-hintergrund-1600.jpg`, ein Aquarell
        mit Flügel. Die Datei gibt es in hupbraum NICHT. Der Verweis ging ins
        Leere — sichtbar wurde nur, dass kein Bild kam.
     2. Ein WEISSER Schleier (`rgba(255, 255, 255, .58)`) über der ganzen
        Inhaltsfläche. Auf Neudingens heller Seite ist er richtig. Hier hätte er
        zwei Drittel der dunklen Seite aufgehellt und die helle Schrift des
        Rahmens gegen fast-Weiss gestellt.

   Dasselbe Muster wie bei den sechs Frontend-Bausteinen und bei der
   Insta-Lightbox: übernommene Gestaltung trägt die Voraussetzungen ihrer
   Herkunft mit. Wer aus einem hellen Projekt kopiert, muss JEDE Farbangabe
   ansehen — und jeden Bildverweis.

   ⚠ DAS HINTERGRUNDBILD KOMMT JETZT VON `body` und ist das Bandfoto, wie im
   Frontend. Diese Seite braucht deshalb GAR KEIN eigenes Bild mehr — nur noch
   die Mitte. Eine Regel weniger ist eine Regel weniger, die falsch sein kann. */

/* ⚠ `min-height: 100dvh` und Flex am Rumpf: nur so kann `main` den Platz
   zwischen Kopf und Fuss nehmen und die Karte darin mittig stellen. `dvh` und
   nicht `vh`, weil `vh` am Handy die Adressleiste mitrechnet — die Seite liesse
   sich dann um genau deren Höhe scrollen, also um nichts. */
body:has(.anmeldekarte--hintergrund) {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  /* ⚠ Der feststehende Fuss braucht hier KEINEN Platz per `padding`: dieses
     Flex-Layout rechnet ihn selbst ein. Das `padding-bottom` von `body` würde
     unten eine leere Zone erzeugen und die Karte aus der Mitte schieben. */
  padding-bottom: 0;
}

main.inhalt:has(.anmeldekarte--hintergrund) {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  max-width: none;
  /*
   * ⚠ `margin: 0` MUSS HIER STEHEN, und der Grund ist unscheinbar: `.inhalt`
   * bringt `margin: 0 auto` mit. Bei einem FLEX-ELEMENT schluckt ein
   * `auto`-Rand auf der Querachse den freien Platz und verhindert das Dehnen —
   * bei Neudingen am 08.08.2026 gemessen: 432 px statt 1425.
   */
  margin: 0;
  /* Unten mehr Polster: der feststehende Fuss liegt über dem Inhalt. */
  padding: 1.5rem 1rem 4rem;
}
main.inhalt:has(.anmeldekarte--hintergrund) > h1 { margin: 0 0 1rem; text-align: center; }

/* ⚠ EINE FLÄCHE UNTER DER KARTE, kein Schleier über der Seite. Das Bandfoto ist
   dunkel und kontrastreich; ein Formular direkt darauf wäre je nach Ausschnitt
   lesbar oder nicht. Die fast deckende Fläche macht die Frage unabhängig davon,
   welcher Teil des Fotos gerade dahinter liegt. */
.anmeldekarte {
  display: grid;
  overflow: hidden;
  background: rgba(23, 23, 26, .92);
  border: 1px solid var(--rand);
}
.anmeldekarte--hintergrund {
  grid-template-columns: 1fr;
  width: 100%;
  max-width: 26rem;
  margin: 0 auto;
  /* Kein Schatten: auf dunklem Grund ist ein dunkler Schatten unsichtbar. Die
     Kante macht der Rahmen — sichtbar und eckig. */
}
.anmeldekarte-form { padding: 1.75rem 1.75rem 1.5rem; }
.anmeldekarte-form form { max-width: none; margin: 0; }
.anmeldekarte-form .hinweis { max-width: none; margin-top: 1.1rem; font-size: .88rem; }

/* Auf sehr flachen Fenstern darf sie doch scrollen — lieber erreichbar als
   abgeschnitten. */
@media (max-height: 520px) {
  body:has(.anmeldekarte--hintergrund) { min-height: 0; }
  main.inhalt:has(.anmeldekarte--hintergrund) { justify-content: flex-start; }
}

/*
 * ═══════════════════════════════════════════════════════════════════════════
 * INTERNE GALERIE — Knöpfe, die keine sein sollen
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * ⚠ ENTSTANDEN AUS EINEM GEMELDETEN FEHLER (Nutzer, 09.08.2026): „Die Bilder in
 * den Alben werden quadratisch UND rund dargestellt — es sieht sehr komisch aus."
 *
 * Ursache: die Regel `button, .knopf { … border-radius: 999px; background:
 * var(--blau); padding: .6rem 1.1rem; margin-top: 1.1rem; }` weiter oben gilt für
 * JEDEN Knopf im internen Bereich. Die Bildkacheln der Galerie sind Knöpfe (sie
 * öffnen die Lightbox) — also sass ein quadratisches Foto in einer runden blauen
 * Pille, mit Polster ringsum.
 *
 * ⚠ WARUM NICHT MIT TAILWIND-KLASSEN GEGENGESTEUERT: `stil.css` wird ABSICHTLICH
 * nach dem Stylesheet der Website geladen (siehe `seite_kopf`), damit es
 * Formularelemente überschreiben kann. Ein `rounded-none` von Tailwind verlöre
 * also gegen die Regel oben, sobald beide dieselbe Spezifität haben. Die Antwort
 * gehört deshalb hierher, nicht in die PHP-Datei.
 *
 * Öffentlich stellt sich die Frage nicht: dort setzt Tailwinds Preflight alle
 * Knöpfe zurück, und ein Knopf sieht nur so aus, wie man ihn beschreibt.
 */

/* Die Bildkachel: ein Knopf ohne jedes Knopf-Aussehen. */
.bildknopf {
  display: block; width: 100%;
  margin: 0; padding: 0; border: 0; border-radius: 0;
  background: none; color: inherit; font: inherit;
  cursor: zoom-in;
}

/*
 * Die Knöpfe IN der Lightbox. Werte aus `src/bausteine/Lightbox.tsx` übernommen,
 * damit die Bedienung drinnen und draussen gleich aussieht:
 * `rounded-full px-6 py-3 text-[0.85rem] font-semibold`, Rand `white/30`.
 */
.lb-knopf {
  margin: 0; padding: .75rem 1.5rem;
  border: 1px solid rgba(255, 255, 255, .3); border-radius: 999px;
  background: none; color: var(--hell);
  font-size: .85rem; font-weight: 600; cursor: pointer;
}
.lb-knopf:hover { border-color: var(--hell); }
/* „Weiter" ist die Hauptaktion und steht deshalb auf Weiss — wie draussen. */
.lb-knopf--hell { background: var(--hell); color: #00304f; border-color: var(--hell); }
.lb-knopf--hell:hover { opacity: .9; }

.lb-schliessen {
  display: flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; margin: 0; padding: 0;
  border: 1px solid rgba(255, 255, 255, .3); border-radius: 999px;
  background: none; color: var(--hell);
  font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.lb-schliessen:hover { border-color: var(--hell); }
