/* ============================================================
   Portal — Grundgeruest und Komponenten
   ============================================================

   Enthaelt KEINE Farbe und KEINE Schriftfamilie im Klartext (A10) — alles
   ueber `var(--…)` aus `marke/tokens.css`. Wer hier eine Farbe im Klartext schreibt, macht
   die Zweitinstallation zur Codeaenderung.

   Grundregeln der Oberflaeche:
   - Ohne JavaScript vollstaendig bedienbar.
   - Kein Inline-Style (CSP `style-src 'self'`).
   - WCAG 2.1 AA: sichtbarer Fokus ueberall, Kontrast, Tabellen stapeln.
   ============================================================ */

/* ---- Masse der Oberflaeche ---------------------------------------------

   Das Gestaltungsraster: Abstaende, Schriftgroessen, Breiten, Dauern. Es steht
   im Kern und nicht in der Marken-Datei — eine Marke entscheidet ueber Farbe,
   Schrift und Rundung, nicht ueber den Rhythmus der Seite.

   **Eine Leiter statt freier Zahlen.** Vorher stand in jeder Regel ein eigener
   Wert (.7rem, .75rem, .8rem, .9rem, 1.05rem …). Was dabei entsteht, ist kein
   Rhythmus, sondern Rauschen: Zwei Karten untereinander haben verschiedene
   Innenabstaende, und niemand kann sagen, ob das Absicht war. */
:root {
  --raum-1: .25rem;
  --raum-2: .5rem;
  --raum-3: .75rem;
  --raum-4: 1rem;
  --raum-5: 1.5rem;
  --raum-6: 2rem;
  --raum-7: 3rem;
  --raum-8: 4.5rem;

  /* Schriftgroessen skalieren mit der Fensterbreite (`clamp`), statt fest zu
     stehen: Auf einem breiten Bildschirm war die feste Groesse zu klein, auf
     einem schmalen zu gross. Die Titelgroessen sind bewusst kraeftiger als
     zuvor — Hierarchie entstand vorher fast nur ueber Farbe, und Farbe traegt
     keine Ordnung. */
  --schrift-xs: .78rem;
  --schrift-s: .88rem;
  --schrift-m: 1rem;
  --schrift-l: 1.12rem;
  --titel-3: clamp(1.15rem, 1.05rem + .35vw, 1.35rem);
  --titel-2: clamp(1.45rem, 1.15rem + 1.1vw, 1.95rem);
  --titel-1: clamp(2rem, 1.35rem + 2.6vw, 3.1rem);
  --titel-held: clamp(2.2rem, 1.4rem + 3.4vw, 3.6rem);

  /* Zwei Breiten, und die Unterscheidung ist der halbe Befund dieser Runde:
     Fliesstext wird ab etwa 75 Zeichen je Zeile muehsam — die Startseite hatte
     ueber 120. Tabellen und Boards dagegen brauchen alles, was da ist.

     **Eine Kastenbreite fuer alle erklaerenden Kaesten, eine Lesebreite fuer
     allen Fliesstext.** Vorher stand `--kastenbreite` mit 84ch fuer sich, und
     daneben lagen verstreut eigene Literale — 68ch an drei weiteren Stellen
     (`.fliesstext`, `.klappinhalt > p`, `.zeitleiste p`), 46rem an
     `.feld-schmal`. Ergebnis: Hilfe-Block, Hinweiskasten und Feld-Hilfe endeten
     auf derselben Seite an drei verschiedenen Kanten, ohne dass das eine
     Entscheidung gewesen waere.

     `--kastenbreite` ist jetzt an `--lesebreite` gekoppelt:
     Lesebreite + Kastenpolster. Der Polster entspricht dem waagrechten
     Innenabstand von Meldung, Hinweiskasten und Hilfe-Block (je 1rem, also
     2rem in Summe) — bei `box-sizing: border-box` liegt die TEXTKANTE eines
     Kastens damit exakt auf der Kante von blankem Fliesstext daneben, statt
     16 Zeichen weiter rechts zu enden. */
  --lesebreite: 68ch;
  --kastenpolster: 2rem;
  --kastenbreite: calc(var(--lesebreite) + var(--kastenpolster));
  --seitenbreite: 1180px;

  --dauer-schnell: .14s;
  --dauer-ruhig: .28s;

  /* Die Kopfleiste steht an mehreren Stellen im Weg (klebende Seitenleiste,
     Sprungziele). Ihre Hoehe stand als nackte 57px im Code — wer die Leiste
     hoeher macht, muss daran denken, und wer nicht daran denkt, bekommt eine
     Seitenleiste, die schief haengt. */
  --kopfhoehe: 60px;
}

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

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

body {
  margin: 0;
  font-family: var(--schriftfamilie);
  /* Nie unter 16px: Kleiner loest auf iOS beim Fokus in ein Feld einen Zoom
     aus, der die Seite verschiebt — und trifft genau die, die ohnehin schlecht
     lesen. */
  font-size: 16px;
  line-height: 1.55;
  color: var(--schrift);
  background: var(--grund);
}

/* Ueberschriften.
   **Blau, nicht schwarz** — Ueberschriften tragen im CD die Primaerfarbe; in
   Schwarz wirkt jede Seite schwer und beliebig.

   Aber Farbe allein ordnet nicht: Vorher waren H1 und H2 beide blau, fast
   gleich gross und gleich schwer — „Mein Profil", „Profilbild" und die
   Begruessung wirkten gleich wichtig. Jetzt trennt sie **Groesse, Gewicht und
   Laufweite**, und die dritte Ebene verlaesst das Blau ganz: Eine H3 ist eine
   Zwischenueberschrift im Text, kein Seitentitel. */
h1, h2, h3 {
  font-family: var(--schriftfamilie-titel);
  color: var(--blau);
  margin: .1em 0 .5em;
  text-wrap: balance;
}

h1 { font-size: var(--titel-1); line-height: 1.06; font-weight: 800; letter-spacing: -.018em; }
h2 { font-size: var(--titel-2); line-height: 1.15; font-weight: 700; letter-spacing: -.01em; }
h3 {
  font-size: var(--titel-3); line-height: 1.25; font-weight: 700;
  letter-spacing: 0; color: var(--schrift);
}

/* Fliesstext bleibt lesbar breit.

   Aufgezaehlt statt pauschal ueber `.inhalt p`: In einer Tabellenzelle, einer
   Kachel oder einer Kartenspalte ist ein Absatz kein Fliesstext, sondern eine
   Angabe — dort ist ein Deckel von 68 Zeichen falsch und erzeugt Umbrueche
   mitten in der Zeile. Der Deckel gilt fuer das, was man **liest**: Seitentext,
   Begruessung, Meldungen, Hilfe.

   Kaesten duerfen etwas breiter sein als blanker Text: Sie tragen ihren eigenen
   Rahmen, und der fuehrt das Auge ohnehin zurueck an den Zeilenanfang. */
.inhalt > p, .inhalt > ul, .inhalt > ol,
.fliesstext, .lead, .begruessung p, .anleitung {
  max-width: var(--lesebreite);
}
.meldung, .hinweiskasten, .hilfe-block { max-width: var(--kastenbreite); }

a { color: var(--blau-dunkel); }
a:hover { color: var(--blau); }

/* Sichtbarer Fokus, ueberall und ohne Ausnahme. Ein `outline: none` ohne
   Ersatz macht die Tastaturbedienung unmoeglich — man sieht nicht mehr, wo man
   ist. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--blau);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* ---- Sprungmarke ------------------------------------------------------- */

/* Erster fokussierbarer Punkt der Seite. Wer mit der Tastatur arbeitet, muss
   sich nicht durch die ganze Navigation tasten. */
.sprungmarke {
  position: absolute;
  left: -9999px;
  top: 0;
  padding: .75rem 1rem;
  background: var(--karte);
  border: 2px solid var(--blau);
  border-radius: 0 0 var(--radius-s) 0;
  z-index: 100;
}
.sprungmarke:focus { left: 0; }

/* ---- Grundgeruest ------------------------------------------------------ */

.huelle { display: flex; flex-direction: column; min-height: 100vh; }

.kopf {
  background: var(--karte);
  border-bottom: 1px solid var(--linie);
  padding: .75rem 1rem;
}
.kopf-innen {
  display: flex;
  align-items: center;
  gap: var(--raum-4);
  flex-wrap: wrap;
  max-width: var(--seitenbreite);
  margin: 0 auto;
}

/* Das Logo steht laut CD nur auf weisser Flaeche und wird nie verzerrt. */
.logo { display: block; height: 38px; width: auto; }

.inhalt {
  flex: 1;
  width: 100%;
  max-width: var(--seitenbreite);
  margin: 0 auto;
  padding: var(--raum-5) var(--raum-4) var(--raum-7);
}

.fuss {
  background: var(--karte);
  border-top: 1px solid var(--linie);
  padding: 1.25rem 1rem;
  color: var(--schrift-leise);
  font-size: .9rem;
}
.fuss-innen {
  max-width: 1180px;
  margin: 0 auto;
  display: flex;
  gap: 1rem 1.5rem;
  flex-wrap: wrap;
}
/* Wessen Portal das ist -- steht als Erstes und ist kein Verweis. */
.fuss-marke { font-weight: 600; color: var(--schrift-weich); }
/* Die laufende Fassung am Verweis auf die Aenderungen. Kleiner, aber nicht
   kleiner als 0.75rem: Was niemand lesen kann, braucht auch nicht dazustehen. */
.fuss-fassung { font-size: .78rem; opacity: .85; }

/* ---- Aenderungsprotokoll ------------------------------------------------ */

/* Ein langes Dokument aus Ueberschriften und Listen. Es braucht Luft zwischen
   den Fassungen, sonst laufen sie optisch ineinander -- und dann sucht man die
   Fassungsnummer, statt sie zu sehen. */
.changelog h2 {
  margin-top: 2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--linie);
}
.changelog h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.changelog h3 { margin-top: 1.5rem; }
.changelog ul { margin: .5rem 0 1rem; padding-left: 1.25rem; }
.changelog li { margin-bottom: .5rem; }
.changelog code {
  background: var(--linie-weich);
  padding: .1rem .3rem;
  border-radius: var(--radius-xs);
  font-size: .9em;
}

/* ---- Navigation -------------------------------------------------------- */

.nav { display: flex; gap: .25rem; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
.nav a {
  display: inline-block;
  padding: .5rem .8rem;
  border-radius: var(--radius-xs);
  text-decoration: none;
  color: var(--schrift-weich);
}
.nav a:hover { background: var(--linie-weich); }
.nav a[aria-current="page"] { background: var(--blau-20); color: var(--blau-dunkel); font-weight: 600; }

/* Navigationspfad. Die aktuelle Seite ist KEIN Link — ein Verweis auf sich
   selbst sagt nichts und verspricht eine Bewegung, die nicht stattfindet. */
.krume { font-size: .9rem; color: var(--schrift-leise); margin-bottom: 1rem; }
.krume ol { list-style: none; display: flex; flex-wrap: wrap; gap: .3rem; margin: 0; padding: 0; }
.krume li::after { content: "›"; margin-left: .3rem; color: var(--schrift-leise); }
.krume li:last-child::after { content: ""; }

/* ---- Karten und Kacheln ------------------------------------------------ */

.karte {
  background: var(--karte);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: var(--raum-5);
  margin-bottom: var(--raum-5);
}
/* Der Titel einer Karte sitzt an ihrer Oberkante — der Vorgabewert von `h2`
   setzt darueber noch einmal Luft, und die Karte wirkt dann oben ausgebeult. */
.karte > :first-child { margin-top: 0; }
.karte > :last-child { margin-bottom: 0; }

/* Eine Karte, die ein Verweis ist, hebt sich beim Ueberfahren an. Eine, die
   keiner ist, tut es nicht: Bewegung ist ein Versprechen auf Klickbarkeit.

   Farbe und Unterstreichung des Verweises werden dabei zurueckgenommen: Die
   ganze Flaeche ist der Link, nicht der Text darin — durchgehend unterstrichen
   und blau sah der Inhalt aus wie eine Sammlung einzelner Verweise. Erkennbar
   bleibt sie an Titelfarbe, Anhebung und Zeiger. */
a.karte, a.karte:hover { color: inherit; text-decoration: none; }
a.karte .karte-titel { color: var(--blau); }

/* Symbol vor der Ueberschrift einer einfachen `.karte` (z. B. die drei
   Zweig-Kacheln unter „Anliegen einreichen") — nicht zu verwechseln mit
   `.karte-titel` aus der `<x-portal.karte>`-Komponente, die eine eigene
   Kopfzeile mit Aktionen mitbringt und hier nicht passt. */
.karte-titel-symbol { display: flex; align-items: center; gap: .55rem; }
.karte-titel-symbol .symbol { width: 22px; height: 22px; flex: 0 0 22px; color: var(--blau); }

a.karte, .karte-ziel {
  transition: box-shadow var(--dauer-ruhig) var(--uebergang),
              transform var(--dauer-ruhig) var(--uebergang),
              border-color var(--dauer-ruhig) var(--uebergang);
}
a.karte:hover, .karte-ziel:hover {
  box-shadow: var(--schatten-md);
  transform: translateY(-3px);
  border-color: var(--blau-hell);
}

/* **`auto-fit`, nicht `auto-fill`, und eine Obergrenze je Kachel.** `auto-fill`
   legt so viele Spalten an, wie rechnerisch passen — auch wenn gar nicht so
   viele Kacheln da sind. Auf der Anliegen-Startseite (drei Kacheln) blieben
   auf einem breiten Schirm dadurch mehrere leere Spalten rechts stehen, und
   die drei Kacheln standen klein und linksbuendig davor. `auto-fit` klappt
   ungenutzte Spalten stattdessen ein und laesst die vorhandenen Kacheln den
   Platz unter sich aufteilen — bis zur Obergrenze von `30rem`: Ohne sie waere
   eine einzelne Kachel auf einem 2000-Pixel-Schirm so breit wie die halbe
   Arbeitsflaeche.

   Durchgerechnet (Kacheln je 260–480 px, `raum-5` Abstand):
     1200 px breit: 1 Kachel = 1 Spalte volle Breite; 3 = 3 Spalten (~380 px);
                     5 = 4 Spalten, die fuenfte faellt um; 8 = 4 Spalten in
                     zwei Zeilen.
     2000 px breit: 1 Kachel = 1 Spalte, aber gedeckelt bei 30rem (480 px),
                     der Rest der Zeile bleibt leer (`justify-content: start`
                     haelt ihn links, statt die einzelne Kachel zu spreizen);
                     3 = 3 Spalten (~480 px, am Deckel); 5 = 5 Spalten (~370 px);
                     8 = 6 Spalten in zwei Zeilen (~300 px).
   Fuenf Kacheln nebeneinander (Vorlage Startseite) bleiben damit auf ueblichen
   breiten Schirmen moeglich, ohne dass eine einzelne Kachel ausufert. */
.kacheln {
  display: grid; gap: var(--raum-5);
  grid-template-columns: repeat(auto-fit, minmax(260px, 30rem));
  justify-content: start;
}
.kachel-breit { grid-column: 1 / -1; }

/* ---- Knoepfe ----------------------------------------------------------- */

/* Gefuellt = Aktion, umrandet = Navigation. Diese Unterscheidung ist im
   Original verbindlich geworden, weil sonst auf jeder Seite drei gleich
   aussehende Knoepfe standen und niemand wusste, welcher etwas veraendert. */
.knopf {
  display: inline-flex;
  align-items: center;
  gap: var(--raum-2);
  padding: .65rem 1.15rem;
  border: 1px solid var(--blau);
  border-radius: var(--radius-xs);
  background: var(--blau);
  color: var(--schrift-auf-farbe);
  font: inherit;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dauer-schnell) var(--uebergang),
              border-color var(--dauer-schnell) var(--uebergang),
              box-shadow var(--dauer-schnell) var(--uebergang),
              transform var(--dauer-schnell) var(--uebergang);
}
.knopf:hover {
  background: var(--blau-dunkel); border-color: var(--blau-dunkel);
  color: var(--schrift-auf-farbe);
  box-shadow: var(--schatten); transform: translateY(-1px);
}
/* Beim Druecken zurueck auf die Grundlinie: Ein Knopf, der sich beim Klick
   nicht bewegt, fuehlt sich an, als waere nichts passiert. */
.knopf:active { transform: translateY(0); box-shadow: none; }
.knopf[disabled] { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }

.knopf-rand { background: transparent; color: var(--blau-dunkel); }
.knopf-rand:hover { background: var(--blau-20); color: var(--blau-dunkel); }

/* **Nicht das Signalrot als Flaeche.** `--akzent` ist die CD-Farbe fuer Linien
   und Marken; als gefuellte Flaeche hinter weisser Schrift war die Beschriftung
   in der geometrischen Ersatzschrift kaum zu entziffern — bei „Zugang sperren",
   ausgerechnet. Die Marke bringt dafuer einen abgedunkelten Ton mit. */
.knopf-gefahr { background: var(--gefahr-flaeche); border-color: var(--gefahr-flaeche); }
.knopf-gefahr:hover { background: var(--gefahr-flaeche-tief); border-color: var(--gefahr-flaeche-tief); }

/* Eine gefaehrliche Aktion ist selten und selten dringend. Sie steht deshalb
   nicht gefuellt in der Flaeche, sondern umrandet — bis jemand sie anfasst.
   Vorher war der roteste, groesste Knopf einer Listenseite die Sammelsperre:
   optisch das Wichtigste auf der Seite, tatsaechlich das Seltenste. */
.knopf-gefahr-leise {
  background: transparent; color: var(--fehler); border-color: var(--fehler);
  font-weight: 600;
}
.knopf-gefahr-leise:hover {
  background: var(--gefahr-flaeche); border-color: var(--gefahr-flaeche);
  color: var(--schrift-auf-farbe);
}

.knopf-leise {
  background: transparent;
  border-color: transparent;
  color: var(--schrift-weich);
  font-weight: 400;
  text-decoration: underline;
}

/* ---- Formulare --------------------------------------------------------- */

.feld { margin-bottom: 1.1rem; }

/* Beschriftung VOR der Hilfe: Erst wissen, worum es geht, dann die Erklaerung.
   Umgekehrt liest man eine Erklaerung zu etwas, das man noch nicht kennt. */
.feld label { display: block; font-weight: 600; margin-bottom: .25rem; }
/* Ein Bild statt eines Eingabefeldes -- etwa der QR-Code fuer einen Aushang.
   Kein `label`, weil es nichts zu beschriften gibt; die Auszeichnung muss
   trotzdem gleich aussehen. */
.feld .feld-beschriftung { display: block; font-weight: 600; margin: 0 0 .25rem; }
/* Angaben, die man liest statt aendert -- eine Angabe je Zeile, Bezeichnung
   links in fester Breite, Wert rechts. Angaben sind eine Liste, kein Raster:
   mehrere Spalten aus Werten nebeneinander liest man nicht der Reihe nach,
   sondern sucht sie ab (zwoelf Angaben als Raster ergaben vier, fuenf Spalten
   im Kasten -- genau das Bild, das hier vermieden werden soll). Das Raster
   ist Sache der Kaesten selbst (`.karten-zeile`, `.kacheln`), nicht ihres
   Inhalts. Bei schmalem Fenster stehen Bezeichnung und Wert zusaetzlich
   untereinander: zwei Spalten auf 360 Pixeln sind zwei halbe Woerter je
   Zeile. */
.angaben { display: grid; grid-template-columns: minmax(9rem, 12rem) 1fr; gap: .35rem 1rem; margin: .4rem 0 0; }
/* Manche Seiten fassen `dt`+`dd` zu einem Paar in `.angabe` zusammen (etwa
   `x-portal.datenzeile`, um ein Paar bedingt ganz auszulassen). Ohne
   `display: contents` waere das Paar selbst ein Rasterfeld der Liste und
   wanderte abwechselnd in die linke, dann die rechte Spalte -- Beschriftung
   und Wert stuenden dann nicht mehr nebeneinander. `contents` loest den Div
   aus dem Rasterbaum, `dt`/`dd` werden direkte Rasterfelder von `.angaben`,
   genau wie bei Seiten ohne den Wrapper. */
.angabe { display: contents; }
.angaben dt {
  color: var(--schrift-leise); font-size: .8rem; font-weight: 700;
  letter-spacing: .012em;
}
.angaben dd { margin: .1rem 0 0; overflow-wrap: anywhere; }
@media (max-width: 34rem) {
  .angaben { grid-template-columns: 1fr; gap: 0 0; }
  .angaben dt { margin-top: .6rem; }
}

/* Ein Verlauf: Die Reihenfolge ist die Aussage, deshalb nummeriert. */
.chronik { margin: .4rem 0 0; padding-left: 1.4rem; }
.chronik li { margin: 0 0 .7rem; }
.chronik strong { display: block; }
.chronik-meta { display: block; font-size: .88rem; color: var(--schrift-leise); }
.chronik-text { display: block; margin-top: .25rem; }

.feldbild { display: block; width: 100%; max-width: 280px; height: auto; margin: .5rem 0; border: 1px solid var(--linie); border-radius: var(--radius-s); background: var(--karte); }

.feld-hilfe { display: block; font-size: .9rem; color: var(--schrift-leise); margin-bottom: .35rem; }

/* **Eine Ausschlussliste, keine Aufzählung.**
   Hier standen die Feldarten einzeln: `text`, `email`, `password`, `date`,
   `tel`, `number`, `search`. Was fehlte, blieb ungestaltet — und `url` fehlte.
   Im Anliegen-Formular standen deshalb neben ordentlichen Feldern zwei winzige
   graue Kästchen in Browser-Vorgabe, keine 150 Pixel breit, mitten in einer
   sonst gepflegten Seite.

   Eine Aufzählung ist bei Eingabefeldern die falsche Form: Es kommen laufend
   Arten dazu (`url`, `color`, `time`, `week`), und jede vergessene sieht
   nicht etwa falsch aus, sondern **kaputt**. Ausgenommen sind nur die, die
   gar keine Textfelder sind. */
.feld input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):not([type="range"]),
.feld select, .feld textarea {
  width: 100%;
  /* **Eine Höhe für alles.** Ein Auswahlfeld war sichtbar flacher als das
     Textfeld daneben — der Browser rechnet bei `select` andere Innenabstände,
     und nebeneinander sieht das aus, als sei eines davon kaputt. `min-height`
     statt nur Polsterung: Sie gilt unabhängig davon, was der Browser sonst
     dazurechnet. */
  min-height: 2.75rem;
  padding: .6rem .75rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius-xs);
  background: var(--karte);
  font: inherit;
  color: var(--schrift);
}

/* Das eigene Dreieck statt des Systempfeils: Der ist je nach Betriebssystem
   verschieden gross und sitzt verschieden weit innen — zwei Auswahlfelder
   nebeneinander sahen dadurch ungleich aus. `appearance: none` nimmt ihn weg,
   das Dreieck kommt als Hintergrundbild in der Schriftfarbe.

   Ohne `--pfeil` in der Marke bleibt es bei der Systemdarstellung: Das Bild
   traegt keine Farbe im Klartext (A10). */
.feld select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2.2rem;
  background-image: var(--auswahlpfeil);
  background-repeat: no-repeat;
  background-position: right .75rem center;
  background-size: .7rem;
}

.feld textarea { min-height: 7rem; resize: vertical; }

/* ---- Breite der Felder -------------------------------------------------

   **Ein Feld ist so breit wie das, was hineingehört.** Vorher war jedes Feld
   100 % breit — auf einem 1600-Pixel-Schirm bekam „Vorname" dieselben 1400
   Pixel wie eine mehrzeilige Beschreibung. Das sieht nicht nur verschwenderisch
   aus, es kostet Verständnis: Die Feldbreite ist der stärkste Hinweis darauf,
   wie viel erwartet wird, und ein riesiges Feld für „PLZ" führt in die Irre.

   **Ein Raster, kein Fließen.** Der erste Versuch ließ die Felder über
   `flex-wrap` laufen — sie füllten die Zeile, wie es gerade passte. Das
   Ergebnis war schlechter als vorher: Vier Felder standen nebeneinander, die
   fachlich nichts miteinander zu tun haben; ein Kästchen-Feldsatz rutschte
   neben ein Suchfeld und ließ eine halbe Karte leer; und die Eingaben lagen
   auf verschiedenen Höhen, weil ein Feld mit Hilfetext höher beginnt als eines
   ohne.

   Ein Formular ist keine Bildergalerie. Was nebeneinander steht, gehört
   fachlich zusammen, und das entscheidet die Fläche — nicht der Zufall des
   Umbruchs. Deshalb feste Spalten, ausdrücklich gesetzt.

   **Die Eingabefelder liegen auf einer Linie**, auch wenn über dem einen zwei
   Zeilen Hilfe stehen und über dem anderen keine: `subgrid` gibt allen Feldern
   einer Reihe dieselben Zeilen — Beschriftung, Hilfe, Bedienelement, Fehler.
   Ohne das versetzen sich die Felder um genau die Höhe des Hilfetexts, und das
   ist der Unterschied zwischen „gesetzt" und „hingefallen". */
.feldreihe {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 var(--raum-4);
  align-items: start;
}

/* Zwei und drei Spalten erst, wenn wirklich Platz ist. Unter 48rem bleibt
   alles untereinander — zwei Felder auf 360 Pixeln sind zwei halbe Felder. */
@media (min-width: 48rem) {
  .feldreihe-2 { grid-template-columns: 1fr 1fr; }
  .feldreihe-3 { grid-template-columns: 1fr 1fr 1fr; }
  /* Ein schmales neben einem breiten Feld — PLZ und Ort, Hausnummer und
     Straße. Die Zahl bekommt so viel, wie sie braucht, nicht die Hälfte. */
  .feldreihe-schmal-breit { grid-template-columns: minmax(7rem, 1fr) 3fr; }
  .feldreihe-breit-schmal { grid-template-columns: 3fr minmax(7rem, 1fr); }
}

.feldreihe > .feld { min-width: 0; }

/* Was kein Feld ist, nimmt die ganze Reihe: Ein Hinweis oder eine Aufzählung
   zwischen zwei Eingaben gehört auf eine eigene Zeile — sonst steht der Satz
   als schmale Spalte neben einem Feld und liest sich als dessen Beschriftung.

   Ein `fieldset` steht hier ausdrücklich mit dabei. Genau das ist schiefgegangen:
   Der Kästchensatz „Welche Systeme sind betroffen?" landete als Flex-Nachbar
   rechts neben dem Suchfeld, und die halbe Karte blieb leer. */
.feldreihe > .meldung,
.feldreihe > .hinweisliste,
.feldreihe > fieldset,
.feldreihe > p,
.feldreihe > ol,
.feldreihe > h2,
.feldreihe > h3 {
  grid-column: 1 / -1;
}

/* **Die Ausrichtung über die Reihe hinweg.** Jedes Feld übernimmt die Zeilen
   seiner Reihe, statt eigene aufzumachen — damit stehen Beschriftungen auf
   einer Höhe und Eingabefelder ebenso.

   Vier Zeilen, weil ein Feld aus vier Teilen besteht: Beschriftung, Hilfe,
   Bedienelement, Fehlermeldung. Fehlt einer, bleibt seine Zeile leer statt den
   Rest zu verschieben.

   In `@supports`, weil das ohne `subgrid` nicht bloß anders aussieht, sondern
   die Felder übereinanderschöbe. Ältere Browser bekommen die einfache
   Darstellung: untereinander, aber vollständig. */
@supports (grid-template-rows: subgrid) {
  @media (min-width: 48rem) {
    .feldreihe-2, .feldreihe-3, .feldreihe-schmal-breit, .feldreihe-breit-schmal {
      grid-auto-rows: auto;
    }
    .feldreihe-2 > .feld, .feldreihe-3 > .feld,
    .feldreihe-schmal-breit > .feld, .feldreihe-breit-schmal > .feld {
      display: grid;
      grid-template-rows: subgrid;
      grid-row: span 4;
      /* Das Bedienelement sitzt in Zeile 3 — auch wenn die Hilfe fehlt.
         Sonst rutschte es bei einem Feld ohne Hilfe eine Zeile höher. */
      align-content: start;
    }
    .feldreihe-2 > .feld > label:first-child, .feldreihe-3 > .feld > label:first-child,
    .feldreihe-2 > .feld > .feld-beschriftung, .feldreihe-3 > .feld > .feld-beschriftung,
    .feldreihe-2 > .feld > .feld-gruppentitel, .feldreihe-3 > .feld > .feld-gruppentitel { grid-row: 1; }
    .feldreihe-2 > .feld > .feld-hilfe, .feldreihe-3 > .feld > .feld-hilfe { grid-row: 2; }
    .feldreihe-2 > .feld > input, .feldreihe-2 > .feld > select, .feldreihe-2 > .feld > textarea,
    .feldreihe-3 > .feld > input, .feldreihe-3 > .feld > select, .feldreihe-3 > .feld > textarea { grid-row: 3; }
    .feldreihe-2 > .feld > .feld-fehler, .feldreihe-3 > .feld > .feld-fehler { grid-row: 4; }

    /* Dieselbe Ausrichtung für die beiden ungleichen Aufteilungen. */
    .feldreihe-schmal-breit > .feld > label:first-child,
    .feldreihe-breit-schmal > .feld > label:first-child { grid-row: 1; }
    .feldreihe-schmal-breit > .feld > .feld-hilfe,
    .feldreihe-breit-schmal > .feld > .feld-hilfe { grid-row: 2; }
    .feldreihe-schmal-breit > .feld > input,
    .feldreihe-schmal-breit > .feld > select,
    .feldreihe-breit-schmal > .feld > input,
    .feldreihe-breit-schmal > .feld > select { grid-row: 3; }
    .feldreihe-schmal-breit > .feld > .feld-fehler,
    .feldreihe-breit-schmal > .feld > .feld-fehler { grid-row: 4; }
  }
}

/* Die ausdrückliche Breite gilt weiterhin — sie steuert jetzt, über wie viele
   Spalten ein Feld reicht statt wie breit es fließt. */
.feldreihe > .feld.feld-voll { grid-column: 1 / -1; }
.feldreihe > .feld:has(textarea),
.feldreihe > .feld:has(input[type="file"]) { grid-column: 1 / -1; }

/* Ein Zahlenfeld nimmt sich nie die ganze Breite — auch außerhalb einer
   Reihe. Der Browser stellt bei `number` und `date` ohnehin eigene Bedienteile
   an den Rand, die auf halber Seitenbreite verloren stehen. */
.feld input[type="number"], .feld input[type="date"], .feld input[type="time"] { max-width: 14rem; }

/* Auch außerhalb einer Reihe soll ein Feld nicht über die ganze Karte laufen.
   Die Breitenklassen wirken deshalb überall — in einer Reihe steuern sie die
   Spalte, allein stehend die Höchstbreite. */
.feld-kurz:not(.feldreihe > *) { max-width: 12rem; }
.feld-mittel:not(.feldreihe > *) { max-width: 24rem; }
.feld-lang:not(.feldreihe > *) { max-width: 42rem; }

/* ---- Kästchen- und Auswahllisten ---------------------------------------

   Untereinander gestapelt nahm eine Liste mit zwölf kurzen Möglichkeiten
   („Mo Di Mi Do Fr …") zwölf Zeilen ein und schob alles Folgende aus dem Bild.
   Als umbrechende Spalten passen sie in drei.

   `auto-fill` und nicht `auto-fit`: Bei zwei Einträgen sollen die Spalten ihre
   Breite behalten und nicht auf je eine halbe Bildschirmbreite auseinander
   laufen. */
.kaestchenliste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  gap: var(--raum-2);
  border: 0;
  padding: 0;
  margin: 0 0 var(--raum-2);
}

/* **Ankreuzbare Flächen statt einer Liste nackter Häkchen.**
   Vorher standen sechs winzige Kästchen mit Text daneben in einer Spalte — das
   Ziel war der Punkt selbst, und getroffen werden musste er auch. Jetzt ist die
   ganze Fläche das Ziel (WCAG 2.5.5), und man sieht ohne Hinsehen, was gewählt
   ist: Das Kästchen bleibt sichtbar, aber die Fläche trägt die Auskunft mit.

   Die Auswahl zeigt sich in Rahmen UND Fläche, nie in der Farbe allein
   (WCAG 1.4.1) — und das Kästchen daneben sagt es ohnehin noch einmal. */
.kaestchenliste .feld-kaestchen,
.kaestchenliste > p > label {
  display: flex;
  gap: .6rem;
  align-items: center;
  margin: 0;
  padding: .6rem .8rem;
  min-height: 2.75rem;
  border: 1.5px solid var(--linie);
  border-radius: var(--radius-xs);
  background: var(--karte);
  font-weight: 400;
  cursor: pointer;
  transition: border-color var(--dauer-schnell) var(--uebergang),
              background var(--dauer-schnell) var(--uebergang);
}
.kaestchenliste .feld-kaestchen:hover,
.kaestchenliste > p > label:hover { border-color: var(--blau-hell); background: var(--grund-2); }

.kaestchenliste .feld-kaestchen:has(input:checked),
.kaestchenliste > p > label:has(input:checked) {
  border-color: var(--blau);
  background: var(--blau-20);
  font-weight: 600;
}

/* Der Fokus gehört sichtbar an die Fläche, nicht an das kleine Kästchen darin
   — sonst sieht man beim Durchtasten kaum, wo man ist. */
.kaestchenliste .feld-kaestchen:has(input:focus-visible),
.kaestchenliste > p > label:has(input:focus-visible) {
  outline: 2px solid var(--blau);
  outline-offset: 2px;
}

.kaestchenliste input[type="checkbox"],
.kaestchenliste input[type="radio"] { margin: 0; flex: 0 0 auto; accent-color: var(--blau); }

/* Lange Beschriftungen — etwa die Kandidaten einer mehrdeutigen Zuordnung —
   brauchen die ganze Zeile: In einer schmalen Spalte bräche jede über vier
   Zeilen um, und die unterscheidende Angabe stünde ganz unten. */
.kaestchenliste-lang { grid-template-columns: 1fr; }

/* Auch die Listen, die ihre Einträge als Absätze führen — im Anliegen-Formular
   trägt der Absatz `data-option` für die Suche und darf deshalb nicht
   verschwinden. `hidden` muss weiter wirken: Ein Grid-Kind bleibt sonst
   sichtbar, weil `display:grid` die Vorgabe `display:none` überschreibt. */
.kaestchenliste > p { margin: 0; display: contents; }
.kaestchenliste > p[hidden] { display: none; }

/* Die Beschriftung der Gruppe steht über den Spalten, nicht in einer davon. */
.kaestchenliste > legend { grid-column: 1 / -1; padding: 0; margin-bottom: .2rem; font-weight: 700; }

/* ---- Wiederholte Zeilen (Links) ---------------------------------------

   Eine Zeile je Eintrag statt fünf. Die Felder fließen wie in einer Feldreihe;
   die Pfeilknöpfe sitzen am Ende und richten sich an der Grundlinie der Felder
   aus — nicht an deren Oberkante, sonst schweben sie neben den
   Beschriftungen. */
/* Volle Breite, immer. Als Flex-Nachbar eines Eingabefelds stand die Gruppe
   rechts in einer schmalen Spalte, mit einer halben leeren Karte daneben —
   und jede Linkzeile brach dort wieder untereinander um. */
.linkgruppe {
  grid-column: 1 / -1;
  border: 1px solid var(--linie); border-radius: var(--radius-s);
  padding: var(--raum-4); margin: 0 0 var(--raum-4);
}
.linkgruppe > legend { padding: 0 .4rem; font-weight: 700; }

.linkzeile {
  display: flex; flex-wrap: wrap; gap: 0 var(--raum-3);
  align-items: flex-end; margin-bottom: var(--raum-3);
}
.linkzeile > .feld { flex: 1 1 14rem; min-width: 0; }
.linkzeile > .feld-lang { flex: 2 1 20rem; }
.linkzeile-pfeile { display: flex; gap: .3rem; margin: 0 0 1.1rem; flex: 0 0 auto; }
.linkzeile-pfeile .knopf { min-width: 2.4rem; justify-content: center; }

.feld input[aria-invalid="true"], .feld select[aria-invalid="true"], .feld textarea[aria-invalid="true"] {
  border-color: var(--fehler);
  background: var(--fehler-grund);
}

/* Fehlertext am Feld, nicht nur oben gesammelt: Wer ein langes Formular
   ausfuellt, sucht sonst die Stelle. */
.feld-fehler { color: var(--fehler); font-size: .9rem; margin-top: .25rem; font-weight: 600; }

fieldset { border: 1px solid var(--linie); border-radius: var(--radius-s); padding: 1rem; margin: 0 0 1.25rem; }
legend { font-weight: 600; padding: 0 .4rem; }

/* Honigtopf des Spamschutzes. Weder `display:none` noch `hidden`: Manche
   Ausfuellhilfen fuellen versteckte Felder trotzdem, und dann sperrt der
   Schutz echte Menschen aus. Aus dem Lesefluss nehmen, nicht entfernen. */
.honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---- Meldungen --------------------------------------------------------- */

.meldung {
  border: 1px solid var(--linie);
  border-left-width: 4px;
  border-radius: var(--radius-s);
  padding: .9rem 1rem;
  margin-bottom: 1.25rem;
  background: var(--karte);
}
.meldung-ok { border-left-color: var(--ok); background: var(--ok-grund); }
.meldung-fehler { border-left-color: var(--fehler); background: var(--fehler-grund); }
.meldung-warnung { border-left-color: var(--warnung); background: var(--warnung-grund); }

/* Die Aufzaehlung unter einem Hinweis — etwa die Vorschau eines Imports.
   Sie steht dicht am Hinweis, weil sie ihn ausfuehrt und nicht ergaenzt. */
/* Aufklappbarer Abschnitt in einem Formular -- etwa je Mailvorlage. Natives
   `details`, damit es ohne Skript klappt und die Tastatur es ohnehin kann. */
.klappblock { border: 1px solid var(--linie); border-radius: var(--radius-s); margin: 0 0 .75rem; padding: 0 1rem; }
.klappblock > summary { cursor: pointer; font-weight: 600; padding: .75rem 0; margin: 0 -1rem; padding-left: 1rem; padding-right: 1rem; }
.klappblock > summary:focus-visible { outline: 2px solid var(--blau); outline-offset: 2px; }
.klappblock[open] > summary { border-bottom: 1px solid var(--linie); margin-bottom: .75rem; }
.klappblock > .feld:last-child { margin-bottom: 1rem; }

.hinweisliste { margin: -.4rem 0 1rem 1.6rem; padding: 0; }
.hinweisliste li { margin: .15rem 0; font-size: .92rem; line-height: 1.45; }
.meldung-info { border-left-color: var(--blau); background: var(--blau-20); }

/* ---- Marken ------------------------------------------------------------ */

.marke {
  display: inline-block;
  padding: .15rem .55rem;
  border-radius: 999px;
  font-size: .8rem;
  font-weight: 600;
  background: var(--linie-weich);
  color: var(--schrift-weich);
}
.marke-ok { background: var(--ok-grund); color: var(--ok); }
.marke-warnung { background: var(--warnung-grund); color: var(--warnung); }
.marke-fehler { background: var(--fehler-grund); color: var(--fehler); }

/* Vorschau-Kennzeichen: freischwebend am oberen Rand, damit es keine eigene
   Zeile im Inhalt beansprucht. */
.vorschau-marke {
  position: fixed;
  top: .5rem;
  right: .5rem;
  z-index: 50;
  padding: .3rem .7rem;
  border-radius: 999px;
  background: var(--warnung);
  color: var(--schrift-auf-farbe);
  font-size: .8rem;
  font-weight: 700;
  box-shadow: var(--schatten-md);
}

/* ---- Modulkopf --------------------------------------------------------- */

/* Jede Modulseite beginnt mit Bild und Ueberschrift. Konvention statt
   Sonderfall: So sieht auch ein frisch gebautes Modul ordentlich aus, statt
   als leere Karte. */
.modulkopf { align-items: center; gap: 1rem; margin-bottom: 1.25rem; }

.modulbild {
  width: 160px;
  height: 90px;
  object-fit: cover;
  border-radius: var(--radius-s);
  border: 1px solid var(--linie);
  background: var(--grund-2);
}

/* Ersatz, wenn ein Modul kein Bild mitbringt: Initialen auf farbiger Flaeche. */
.modul-emblem {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 90px;
  height: 90px;
  flex: 0 0 auto;
  border-radius: var(--radius-s);
  font-family: var(--schriftfamilie-titel);
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--schrift-auf-farbe);
  background: var(--blau);
}

/* Sechs Abstufungen, damit benachbarte Module unterscheidbar bleiben. Bewusst
   nur Helligkeitsstufen EINER Markenfarbe statt sechs bunter Toene: Die Farbe
   traegt hier keine Bedeutung, sie unterscheidet nur — und wer Farben schlecht
   trennt, erkennt die Module weiterhin an den Initialen. */
.emblem-1 { background: var(--blau); }
.emblem-2 { background: var(--blau-dunkel); }
.emblem-3 { background: var(--blau-hell); }
.emblem-4 { background: var(--schrift-weich); }
.emblem-5 { background: var(--akzent); }
.emblem-6 { background: var(--schrift-leise); }

/* ---- Linkliste --------------------------------------------------------- */

/* Aufzaehlung von Verweisen ohne Aufzaehlungszeichen — die Nummerierung oder
   der Punkt davor traegt nichts bei, wenn jede Zeile ein Link ist. */
.linkliste { list-style: none; margin: 0; padding: 0; }
.linkliste li { padding: .35rem 0; border-bottom: 1px solid var(--linie-weich); }
.linkliste li:last-child { border-bottom: 0; }

/* ---- Etappen ----------------------------------------------------------- */

.etappen { display: flex; gap: .5rem; flex-wrap: wrap; list-style: none; margin: 0 0 1.5rem; padding: 0; font-size: .9rem; }
.etappe { padding: .35rem .75rem; border-radius: 999px; background: var(--linie-weich); color: var(--schrift-leise); }
.etappe-aktiv { background: var(--blau); color: var(--schrift-auf-farbe); font-weight: 600; }
.etappe-fertig { background: var(--ok-grund); color: var(--ok); }

/* ---- Tabellen ---------------------------------------------------------- */

.tabellen-huelle { overflow-x: auto; }

table.liste { width: 100%; border-collapse: collapse; background: var(--karte); }
table.liste th, table.liste td { padding: .6rem .7rem; text-align: left; border-bottom: 1px solid var(--linie); vertical-align: top; }
table.liste th { font-weight: 600; background: var(--grund-2); }
table.liste tbody tr:hover { background: var(--grund-2); }

/* Das Stapeln auf schmalen Geraeten steht **einmal** weiter unten, bei den
   Arbeitslisten — fuer jede Tabelle gemeinsam. Hier stand frueher eine zweite
   Fassung nur fuer `table.liste`: eigene Grenze (720px statt 48rem), eigenes
   Attribut (`data-spalte` statt `data-titel`), eigene Anordnung. Zwei
   Regelwerke fuer dieselbe Frage heisst, dass es ein Fenster gibt, in dem die
   eine Tabelle gestapelt ist und die daneben nicht. */

/* ---- Klappbereiche ----------------------------------------------------- */

/* `details`/`summary` statt eigener Schalter: klappt ohne JavaScript und ist
   von Haus aus tastaturbedienbar. */
details.klappfeld { border: 1px solid var(--linie); border-radius: var(--radius-s); background: var(--karte); margin-bottom: 1rem; }
details.klappfeld > summary { padding: .75rem 1rem; cursor: pointer; font-weight: 600; list-style-position: inside; }
details.klappfeld > .klappinhalt { padding: 0 1rem 1rem; }

/* ---- Hilfe ------------------------------------------------------------- */

.hilfe-block {
  border-left: 3px solid var(--blau-hell);
  background: var(--grund-2);
  padding: .75rem 1rem;
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  margin-bottom: 1rem;
  font-size: .95rem;
}

/* ---- Hilfsklassen ------------------------------------------------------ */

.leise { color: var(--schrift-leise); }
.klein { font-size: .9rem; }
.reihe { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.abstand-oben { margin-top: 1.25rem; }

/* Nur fuer Screenreader — sichtbar fuer die Vorlesehilfe, unsichtbar am
   Bildschirm. Nicht `display:none`: Das nimmt es auch der Vorlesehilfe. */
.nur-vorlesen {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Wer weniger Bewegung eingestellt hat, bekommt weniger Bewegung. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ============================================================
   Arbeitsflaeche der angemeldeten Oberflaeche (Konzept 4.7)
   ============================================================

   Kopfleiste + Seitenleiste + Inhalt. Alle Klappbereiche sind `<details>`;
   nichts hier braucht JavaScript (A3).

   Die Regeln fuer schmale Geraete stehen weiter unten und tragen die
   Begruendungen, aus denen sie entstanden sind — sie sind allesamt aus
   gemessenen Ueberlaeufen der Vorgaengerfassung hervorgegangen und nicht aus
   Geschmack.
   ============================================================ */

/* Der Hintergrund der Arbeitsflaeche (Farbe und Bild) steht gebuendelt im
   Abschnitt „Hintergrundbild" weiter unten — er gilt dort fuer `.huelle`
   allgemein, nicht mehr eigens fuer die Arbeitsflaeche. */

/* ---- Kopfleiste -------------------------------------------------------- */

.kopfleiste {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 1rem;
  padding: .7rem 1.5rem;
  background: var(--karte);
  color: var(--schrift);
  border-bottom: 1px solid var(--linie);
  box-shadow: var(--schatten-kopf);
}

/* **Die Akzentlinie unter der Kopfleiste.** Sie ist im CD der markanteste
   Wiedererkennungspunkt der Seite — zwei Pixel, die vom Blau ins Rot laufen.
   Sie fehlte, und ohne sie sieht der Kopf aus wie der jeder beliebigen
   Anwendung. */
.kopfleiste::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
  background: linear-gradient(90deg, var(--blau), var(--blau-hell) 58%, var(--akzent));
}

.portalmarke { display: inline-flex; align-items: center; gap: .6rem; flex: 0 0 auto; text-decoration: none; }
.portalmarke-logo { display: block; height: 40px; width: auto; }
.portalmarke-titel {
  font-family: var(--schriftfamilie-titel);
  font-weight: 700; color: var(--blau); font-size: 1.06rem;
  letter-spacing: .012em;
  /* Der Trennstrich zum Logo: Er macht aus Bildmarke und Wortmarke zwei
     Dinge, die zusammengehoeren, statt einer gedraengten Zeile. */
  padding-left: .8rem; border-left: 1px solid var(--linie);
}

/* `flex: 0 0 auto` hiesse: niemals schrumpfen. Die Gruppe naehme damit immer
   ihre volle Inhaltsbreite — auf einem 390 px breiten Display lief die
   Vorgaengerfassung damit auf JEDER angemeldeten Seite waagrecht ueber, und das
   `flex-wrap` der Mobil-Regel lief ins Leere: Umbrechen kann nur, was vorher
   schmaler werden darf. */
.kopf-rechts {
  display: flex; align-items: center; justify-content: flex-end;
  gap: .7rem; flex: 1 1 auto; min-width: 0; flex-wrap: wrap;
}

/* Der Klapp-Knopf der Kopfleiste ist auf breiten Schirmen unsichtbar: Dort ist
   die Gruppe ohnehin offen, und ein Knopf, der nichts bewirkt, ist ein Knopf,
   den jemand sucht. */
.kopf-klapp { flex: 1 1 auto; min-width: 0; }
.kopf-klapp > summary { display: none; }
.kopf-klapp > summary::-webkit-details-marker { display: none; }

.symbolgruppe { display: flex; align-items: center; gap: var(--raum-1); }
.symbolziel {
  position: relative;
  display: inline-flex; align-items: center; gap: .4rem;
  color: var(--schrift-leise); padding: .35rem .5rem;
  border-radius: var(--radius-xs); text-decoration: none;
  font-size: var(--schrift-s); font-weight: 600;
  transition: background var(--dauer-schnell) var(--uebergang),
              color var(--dauer-schnell) var(--uebergang);
}
.symbolziel:hover { color: var(--blau); background: var(--blau-20); }
.symbolziel[aria-current="page"] { color: var(--blau-dunkel); background: var(--blau-20); }
.symbol { width: 22px; height: 22px; }

/* Das Wort am Symbol. Es weicht in zwei Stufen: erst in der Kopfleiste, wo vier
   beschriftete Ziele mit Name, Rolle und Sichtwahl um dieselbe Zeile streiten —
   dann bleibt das Zeichen. Entfernt wird es nie: Es steht weiter im Quelltext
   und wird der Vorlesehilfe angesagt.

   Warum nicht `display: none`? Weil das den Text auch der Vorlesehilfe nimmt.
   Die Regeln fuer `.nur-vorlesen` stehen weiter oben und tun genau das
   Richtige — sie werden hier nur wiederverwendet. */
.symbolziel-text { white-space: nowrap; }

/* Ist der Erklaerungen-Schalter aus, stehen nur noch die Symbole mit ihren
   Zaehler-Blasen da — kein `display: none`, sonst verliert die Vorlesehilfe
   das Wort mit. Dieselben Eigenschaften wie `.nur-vorlesen` weiter oben,
   hier eigens notiert, weil sie nur unter dieser Klasse gelten sollen und
   nicht grundsaetzlich. `kopf-rechts.blade.php` setzt sie einmal, `title` am
   Link traegt dort den Namen fuer den Bildschirm nach. */
.symbolgruppe-knapp .symbolziel-text {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 1400px) {
  .symbolziel-text {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .symbolziel { padding: .35rem; }
}

/* Was ohne Skript nichts tun kann, steht ohne Skript auch nicht da. */
.nur-mit-js { display: none; }
:root.js-an .nur-mit-js { display: flex; }

/* Der Zaehler sitzt am Symbol und nicht daneben: Er gehoert zu ihm, und
   daneben wandert er beim Umbrechen in eine andere Zeile. */
.zaehler {
  position: absolute; top: -.1rem; right: -.25rem;
  background: var(--akzent); color: var(--schrift-auf-farbe);
  font-size: .68rem; font-weight: 800; line-height: 1;
  border-radius: 999px; padding: .18rem .34rem;
}

/* ---- Rollenumschalter --------------------------------------------------- */

.sichtwahl { display: inline-flex; align-items: center; gap: .4rem; margin: 0; }
.sichtwahl-beschriftung { display: inline-flex; align-items: center; color: var(--schrift-leise); }
.sichtwahl-beschriftung .symbol { width: 18px; height: 18px; }
.sichtwahl select {
  font: inherit; font-size: .85rem; padding: .32rem .5rem;
  border: 1.5px solid var(--linie); border-radius: var(--radius-xs);
  background: var(--karte); color: var(--schrift-weich);
}

.sicht-banner {
  display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
  background: var(--akzent-20); color: var(--akzent);
  padding: .55rem 1.4rem; font-weight: 600; font-size: .9rem; margin: 0;
}
.sicht-banner form { margin: 0; }
.sicht-banner .knopf { border-color: var(--akzent); color: var(--akzent); background: transparent; }
.sicht-banner .knopf:hover { background: var(--karte); color: var(--akzent); }
.sicht-banner .symbol { width: 18px; height: 18px; flex: 0 0 18px; }

/* ---- Nutzermenue -------------------------------------------------------- */

.nutzermenue { position: relative; }
.nutzermenue > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: .55rem;
  padding: .25rem .4rem; border-radius: 999px;
}
.nutzermenue > summary::-webkit-details-marker { display: none; }
.nutzermenue > summary:hover { background: var(--grund); }
.nutzermenue > summary .symbol { width: 16px; height: 16px; color: var(--schrift-leise); }
.nutzer-angabe { display: flex; flex-direction: column; line-height: 1.15; }
.nutzer-angabe strong { color: var(--schrift); font-size: .88rem; }
.nutzer-angabe small { color: var(--schrift-leise); font-size: .74rem; }

.nutzermenue-klapp {
  position: absolute; right: 0; top: calc(100% + .4rem);
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); box-shadow: var(--schatten-md);
  min-width: 250px; padding: .4rem; z-index: 40;
}
.nutzermenue-klapp a, .nutzermenue-klapp button {
  display: flex; align-items: center; gap: .55rem; width: 100%;
  padding: .55rem .6rem; border-radius: var(--radius-xs);
  color: var(--schrift-weich); text-decoration: none;
  font: inherit; font-weight: 600; font-size: .9rem;
  background: none; border: 0; cursor: pointer; text-align: left;
}
.nutzermenue-klapp a:hover, .nutzermenue-klapp button:hover { background: var(--blau-20); color: var(--blau-dunkel); }
.nutzermenue-klapp .symbol { width: 18px; height: 18px; }
.nutzermenue-klapp form { margin: 0; border-top: 1px solid var(--linie-weich); margin-top: .3rem; padding-top: .3rem; }

/* ---- Avatar ------------------------------------------------------------- */

.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; overflow: hidden; flex: 0 0 auto;
  background: var(--blau-20); color: var(--blau-dunkel);
  font-weight: 800; font-family: var(--schriftfamilie-titel);
}
.avatar-klein { width: 36px; height: 36px; font-size: .85rem; }

/* ---- Rumpf: Seitenleiste + Inhalt --------------------------------------- */

.rumpf { display: block; flex: 1; }
/* **Zwei Spalten nur mit Leiste.** Ohne Fachbereiche gibt es keine
   Seitenleiste — stand das Raster trotzdem auf `250px 1fr`, rutschte der
   Inhalt als erstes Kind in die schmale Spalte, und die Seite war 250 Pixel
   breit neben einer riesigen leeren Fläche. Die Vorlage setzt
   `rumpf-mit-leiste`, wenn es etwas zu zeigen gibt. */
/* `minmax(0, 1fr)` statt `1fr`: Eine Rasterspalte ist mindestens so breit wie
   ihr breitester Inhalt (`min-content`), und eine breite Tabelle weitete damit
   die ganze Seite auf — die Seite rollte waagrecht statt der Tabellenhuelle.
   Mit der Null als Untergrenze bleibt die Spalte am Fenster, und
   `.tabellen-huelle { overflow-x: auto }` rollt wieder nur die Tabelle. */
.huelle-arbeitsflaeche .rumpf { display: grid; grid-template-columns: minmax(0, 1fr); }
.huelle-arbeitsflaeche .rumpf-mit-leiste { grid-template-columns: 250px minmax(0, 1fr); }
.huelle-arbeitsflaeche .inhalt { min-width: 0; }

.seitenleiste {
  position: sticky; top: var(--kopfhoehe); align-self: start;
  height: calc(100vh - var(--kopfhoehe)); overflow-y: auto;
  background: var(--karte); border-right: 1px solid var(--linie);
  padding: 1rem .7rem;
}
.leiste-klapp > summary { display: none; }
.leiste-klapp > summary::-webkit-details-marker { display: none; }

.seitennav { display: flex; flex-direction: column; gap: .12rem; }
.navzeile {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .65rem; border-radius: var(--radius-xs);
  color: var(--schrift-weich); text-decoration: none;
  font-weight: 600; font-size: .92rem;
  background: none; border: 0; width: 100%;
  cursor: pointer; font-family: inherit; text-align: left;
}
.navzeile:hover { background: var(--blau-20); color: var(--blau-dunkel); }
.navzeile.aktiv { background: linear-gradient(120deg, var(--blau), var(--blau-hell)); color: var(--schrift-auf-farbe); }
.navzeile .symbol { width: 19px; height: 19px; flex: 0 0 19px; }

/* In der Bereichsliste steht die Zahl am Zeilenende, nicht als Blase am Symbol:
   Die Zeile ist breit, und eine Blase mittendrin laese sich als Teil des
   Namens. Ohne diese Zeile flöge sie als `position:absolute` aus der Leiste. */
.navzeile .zaehler { position: static; margin-left: auto; flex: 0 0 auto; }

.navgruppe > summary { list-style: none; }
.navgruppe > summary::-webkit-details-marker { display: none; }
.navgruppe-pfeil { margin-left: auto; transition: transform .2s var(--uebergang); }
.navgruppe[open] > summary .navgruppe-pfeil { transform: rotate(180deg); }
.navgruppe-link { color: inherit; text-decoration: none; font: inherit; flex: 1 1 auto; }
.navgruppe-link:hover { text-decoration: underline; }
.navunter { padding: .1rem 0 .2rem .9rem; display: flex; flex-direction: column; gap: .1rem; }
.navzeile-unter { font-weight: 500; font-size: .88rem; padding: .4rem .6rem; }

/* Der Inhalt fuellt die Arbeitsflaeche neben der Leiste bis zum Rand-Padding
   aus — auf keiner angemeldeten Seite mehr zentriert oder gedeckelt.

   **Kein Deckel mehr, auf Wunsch des Auftraggebers.** Erst galt hier der
   Deckel von 1180 px, dann die groessere Arbeitsbreite von 1560 px — auf
   einem 2000 px breiten Fenster blieben trotzdem links und rechts breite
   Leerstreifen stehen, auf einem Bildschirmfoto markiert. Jetzt nutzt der
   Container immer die volle verfuegbare Breite; die Lesbarkeit einzelner
   Textabschnitte begrenzen `--lesebreite` und `.fliesstext` weiterhin (siehe
   unten), nur eben am Absatz und nicht mehr am ganzen Container. */
.huelle-arbeitsflaeche .inhalt {
  width: 100%;
  /* `max-width: none` steht hier ausdruecklich: Die Grundregel `.inhalt`
     weiter oben traegt den Deckel `--seitenbreite` fuer Gastseiten, und ein
     `width: 100%` allein hebt ihn nicht auf — die Startseite stand deshalb
     zentriert zwischen zwei Leerstreifen, waehrend jede Tabellenseite
     randvoll war. */
  max-width: none;
  padding: var(--raum-6) var(--raum-5) var(--raum-7);
}

/* `inhalt-breit` und `.inhalt:has(table)` setzten frueher `max-width: none`
   gegen den Deckel der Zeile darueber. Seit der Container keinen Deckel mehr
   hat, sind beide Regeln wirkungslos — sie bleiben trotzdem bewusst stehen:
   Die Vorlagen setzen die Klasse weiterhin (siehe `Modulseite::render`,
   `layout.blade.php`), Tests halten ihr Vorhandensein fest, und sollte die
   Breitenbegrenzung fuer einzelne Seitenarten je zurueckkommen, ist die
   Ausnahme fuer Tabellen- und `breit`-Seiten schon vorbereitet, statt neu
   erfunden werden zu muessen. */
.inhalt-breit { max-width: none; }
.inhalt:has(table) { max-width: none; }

.gast-nav { display: flex; align-items: center; gap: 1rem; margin-left: auto; }
.gast-nav a { color: var(--schrift-weich); text-decoration: none; font-weight: 600; }
.gast-nav a:hover { color: var(--blau-dunkel); }

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

@media (max-width: 900px) {
  .kopfleiste { flex-wrap: wrap; padding: .5rem .9rem; gap: .4rem; }
  .portalmarke { margin-right: auto; }

  /* Nicht klebend auf schmalen Geraeten: Umgebrochen ist die Kopfleiste rund
     140 px hoch — als Dauergast waere das ein Sechstel des Bildschirms, auf
     jeder Seite, fuer immer. Oben steht sie vollstaendig da, beim Lesen macht
     sie Platz. Erreichbar bleibt sie ueberall, nur eben nach oben gewischt. */
  .kopfleiste { position: static; }

  /* Der Knopf ist ein Knopf: Flaeche, Rand, Fingerbreite. Vorher war er ein
     blasses Zeichen ohne Rahmen und sah aus wie Zierrat — man sucht ihn nicht,
     wenn man ihn nicht als bedienbar erkennt. Mindestens 44 Pixel hoch, das ist
     die Zielgroesse aus WCAG 2.5.5. */
  .kopf-klapp { flex: 0 0 auto; }
  .kopf-klapp > summary {
    display: inline-flex; align-items: center; justify-content: center;
    gap: .4rem; list-style: none; cursor: pointer;
    min-width: 44px; min-height: 44px;
    border: 1px solid var(--linie); border-radius: var(--radius-xs);
    color: var(--schrift-weich); background: var(--karte);
  }
  .kopf-klapp[open] > summary { background: var(--blau-20); color: var(--blau-dunkel); border-color: var(--blau-hell); }
  .kopf-klapp:not([open]) > .kopf-rechts { display: none; }
  .kopf-rechts { flex-wrap: wrap; gap: var(--raum-2); justify-content: flex-start; width: 100%; padding-top: var(--raum-2); }

  /* Aufgeklappt ist die Liste der Portalfunktionen keine Symbolreihe mehr,
     sondern eine Liste mit Worten: Auf dem Telefon ist Platz in der Hoehe, aber
     keiner in der Breite — und geraten wird hier ohnehin nicht mehr.

     Das gilt unabhaengig vom Erklaerungen-Schalter: `.symbolgruppe-knapp
     .symbolziel-text` hat zwei Klassen und damit hoehere Spezifitaet als
     dieses `.symbolziel-text` allein — ohne die Regel hier zu wiederholen,
     bliebe der Text auf dem Telefon versteckt, selbst wenn Platz dafuer da
     ist. */
  .symbolgruppe { flex-direction: column; align-items: stretch; width: 100%; gap: 0; }
  .symbolziel { padding: .7rem .6rem; font-size: var(--schrift-m); }
  .symbolziel-text,
  .symbolgruppe-knapp .symbolziel-text {
    position: static; width: auto; height: auto;
    margin: 0; overflow: visible; clip-path: none;
  }
  .symbolziel .zaehler { position: static; margin-left: auto; }

  /* Das Wort am Erklaerungs-Schalter kehrt zurueck. Es weicht weiter oben, wo
     die Kopfleiste eng ist — in der aufgeklappten Liste auf dem Telefon ist
     Platz in der Hoehe, und dort steht neben jedem anderen Eintrag auch eins. */
  .hilfe-schalter-text { display: inline; }
  .hilfe-schalter { padding: .55rem .8rem; }

  /* Der Rollenumschalter ist mit Abstand der breiteste Teil der Kopfleiste und
     betrifft nur die Verwaltung. Auf schmalen Geraeten bekommt er eine eigene
     Zeile — und zwar die LETZTE, sonst zerreisst er die Symbolgruppe und die
     Kopfleiste braucht eine Zeile mehr. */
  .sichtwahl { order: 9; width: 100%; }

  /* Auf schmalen Geraeten immer einspaltig — auch mit Leiste. */
  .huelle-arbeitsflaeche .rumpf,
  .huelle-arbeitsflaeche .rumpf-mit-leiste { grid-template-columns: 1fr; }
  .seitenleiste {
    position: static; height: auto; overflow: visible;
    border-right: 0; border-bottom: 1px solid var(--linie);
    padding: .6rem .9rem;
  }
  .leiste-klapp > summary {
    display: flex; align-items: center; gap: var(--raum-2);
    list-style: none; cursor: pointer;
    min-height: 44px; padding: .55rem .8rem;
    border: 1px solid var(--linie); border-radius: var(--radius-xs);
    background: var(--karte); font-weight: 700; color: var(--schrift-weich);
  }
  .leiste-klapp[open] > summary {
    background: var(--blau-20); color: var(--blau-dunkel); border-color: var(--blau-hell);
    margin-bottom: var(--raum-2);
  }
  /* Auf dem Telefon zugeklappt: Eine 250 px breite Liste ueber dem Inhalt
     waere dort die halbe Seite, jedes Mal. */
  .leiste-klapp:not([open]) > .seitennav { display: none; }

  /* Aufgeklappt darf die Liste nicht die ganze Seite fuellen: Ein Bereich mit
     acht Unterpunkten schob den Inhalt sonst aus dem Bild, und das Zuklappen
     lag hinter dem, was man gerade lesen wollte. */
  .leiste-klapp[open] > .seitennav {
    max-height: 60vh; overflow-y: auto;
    border: 1px solid var(--linie); border-radius: var(--radius-s);
    background: var(--karte); padding: var(--raum-2);
    box-shadow: var(--schatten);
  }

  .huelle-arbeitsflaeche .inhalt { padding: 1.2rem .9rem 2rem; }
}

/* Kleiner Knopf fuer Nebenaktionen in dichten Leisten (Wechseln, Zurueck). */
.knopf-klein { font-size: .8rem; padding: .28rem .6rem; }

/* Eine Zaehlerkachel ohne Inhalt bleibt sichtbar, aber matt: Dass ein Stapel
   leer ist, ist selbst eine Auskunft — wer „Rueckfrage offen (0)" sieht, weiss,
   dass nichts haengt; wer die Kachel gar nicht sieht, weiss nur, dass er sie
   nicht sieht.

   Gedaempft, nicht ausgegraut: Sie bleibt ein Verweis und muss anklickbar
   aussehen. Der Kontrast bleibt deshalb ueber dem Mindestwert, und die Auskunft
   steht ohnehin als Zahl in der Beschriftung — sie haengt nicht an der Farbe
   allein (WCAG 1.4.1). */
.zaehler-leer { opacity: .62; }
.zaehler-leer:hover,
.zaehler-leer:focus-visible { opacity: 1; }

/* Vorschau-Kennzeichen in der Navigation — dasselbe Wort wie am Seitenkopf,
   damit niemand raten muss, ob es dasselbe meint. */
.marke-vorschau { background: var(--warnung-grund); color: var(--warnung); font-size: .7rem; }

/* ---- Startseiten-Kacheln ------------------------------------------------ */

/* Farbfeld oben, Text darunter — wie in der Vorlage. Der Sinn des Farbfelds
   ist Wiedererkennung: Wer taeglich dieselben drei Bereiche benutzt, findet sie
   nach der Farbe schneller als nach dem Wort. */

.kachel {
  display: flex; flex-direction: column;
  background: var(--karte);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  overflow: hidden;
  color: inherit; text-decoration: none;
  transition: box-shadow .2s var(--uebergang), transform .2s var(--uebergang);
}
a.kachel:hover { box-shadow: var(--schatten-md); transform: translateY(-2px); }

.kachel-kopf {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  min-height: 128px;
  background: var(--kachel-grau);
  color: var(--schrift-auf-farbe);
}
.kachel-blau { background: var(--kachel-blau); }
.kachel-gruen { background: var(--kachel-gruen); }
.kachel-violett { background: var(--kachel-violett); }
.kachel-rot { background: var(--kachel-rot); }
.kachel-grau { background: var(--kachel-grau); }

.kachel-symbol { width: 44px; height: 44px; stroke-width: 1.5; }
/* Das Modulbild auf der Kachel: dieselbe Groesse wie im Held, auf der
   Farbflaeche freigestellt. */
.kachel-bild { width: 160px; height: 90px; object-fit: contain; }
.kachel-kuerzel {
  font-family: var(--schriftfamilie-titel);
  font-size: 2.1rem; font-weight: 800; letter-spacing: .04em;
}

.kachel-fahne {
  position: absolute; top: .6rem; right: .6rem;
  background: var(--karte); color: var(--blau-dunkel);
  font-size: .7rem; font-weight: 700;
  padding: .15rem .5rem; border-radius: 999px;
}

.kachel-text { display: block; padding: 1.05rem 1.25rem 1.3rem; }
.kachel-text h2 { margin: 0 0 .3rem; font-size: 1.06rem; color: var(--blau-dunkel); }
.kachel-text p { margin: 0; color: var(--schrift-weich); font-size: .93rem; line-height: 1.45; }

/* Eine Kachel ohne Ziel ist ein Ausblick, kein Angebot: sichtbar, aber
   erkennbar nicht anklickbar — und ohne die Bewegung beim Ueberfahren, die
   sonst Klickbarkeit verspricht. */
.kachel-ruhend { opacity: .75; }
.kachel-ruhend:hover { transform: none; box-shadow: var(--schatten); }

/* ---- Hintergrundbild ---------------------------------------------------- */

/* Der Kern nennt keine Datei — nur die Variable. Wer kein Bild hat, setzt in
   der Marken-Datei `--hintergrundbild: none` und bekommt eine ruhige Flaeche.

   **Auf jeder Seite, wie im Vorgaengerportal.** Zwischenzeitlich lief das
   Bild nur noch auf den Gastseiten, weil es auf der Arbeitsflaeche unter
   Karten durchlief und Ueberschriften anschnitt. Der Auftraggeber will es
   zurueck, exakt wie in v1 — es ist dort das Wiedererkennungszeichen des
   Portals. Karten, Tabellen, Seitenleiste und Kopfleiste tragen alle einen
   eigenen deckenden Hintergrund (`var(--karte)`), das Bild bleibt also nur
   im Rand sichtbar und laeuft nirgends unter Text durch, den es schwerer
   lesbar machen wuerde. */
body { background: var(--grund); }

.huelle {
  background-color: var(--hintergrundfarbe, var(--grund));
  background-image: var(--hintergrundbild, none);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: cover;
  background-attachment: fixed;
}

/* Mit eingeblendeter Seitenleiste verdeckt deren 250 Pixel Breite sonst den
   linken Teil des Bildes. Dann faengt es rechts daneben an und wird in
   voller Breite gezeigt — wie im Original (dort per `body:has(.with-sidebar)`,
   hier an derselben Stelle auf `.huelle-arbeitsflaeche`). Browser ohne
   `:has()`-Unterstuetzung behalten schlicht die Darstellung ohne den Versatz. */
@media (min-width: 900px) {
  .huelle-arbeitsflaeche:has(.rumpf-mit-leiste) {
    background-position: 250px bottom;
    background-size: calc(100% - 250px) auto;
  }
}

/* Wer Bewegtes meidet, bekommt kein mitlaufendes Bild. */
@media (prefers-reduced-motion: reduce) {
  .huelle { background-attachment: scroll; }
}

/* ---- Anmeldeseite ------------------------------------------------------- */

/* Zwei Spalten: Vorstellung und Anmeldung. Im Quelltext steht die Anmeldung
   ZUERST — auf schmalen Geraeten bricht sie damit nach oben, und wer sein Ziel
   kennt, scrollt nicht an der Vorstellung vorbei. Auf breiten Schirmen tauscht
   `order` die Spalten zurueck in die gewohnte Leserichtung. */
.anmeldung { display: grid; gap: 2rem; align-items: start; }

@media (min-width: 940px) {
  .anmeldung { grid-template-columns: 1fr 1fr; gap: 3rem; }
  .anmeldung-vorstellung { order: 1; }
  .anmeldung-formular { order: 2; }
}

.anmeldung-vorstellung h1 { margin-top: 0; }
.anmeldung-untertitel {
  display: flex; align-items: center; gap: .4rem;
  color: var(--blau-dunkel); font-weight: 600; margin: -.4rem 0 1rem;
}
.anmeldung-untertitel .symbol { width: 18px; height: 18px; flex: 0 0 18px; }

.nutzen {
  display: flex; gap: .9rem; align-items: flex-start;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); padding: .9rem 1rem; margin-bottom: .8rem;
}
.nutzen-symbol {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: 0 0 40px;
  border-radius: var(--radius-xs);
  background: var(--blau-20); color: var(--blau-dunkel);
}
.nutzen-symbol .symbol { width: 20px; height: 20px; }
.nutzen-text { display: block; }
.nutzen-text strong { display: block; color: var(--blau-dunkel); margin-bottom: .15rem; }
.nutzen-text span { color: var(--schrift-weich); font-size: .93rem; line-height: 1.45; }

.anmeldung-fuss {
  display: flex; gap: .5rem; align-items: flex-start;
  color: var(--schrift-leise); font-size: .85rem; line-height: 1.5;
}
.anmeldung-fuss .symbol { width: 16px; height: 16px; flex: 0 0 16px; margin-top: .15rem; }

/* Reiter — echte Verweise auf zwei echte Seiten.

   **Linksbündig, nur so breit wie nötig — wie im Vorgängerportal.** Vorher
   stand hier `flex: 1 1 0; text-align: center`: Zwei Reiter „Anmelden" und
   „Registrieren" wurden dadurch auf die ganze Zeile gestreckt, und drei
   Board-Reiter nebeneinander waren auf einem breiten Schirm ebenso breit
   auseinandergezogen wie beim Kachel-Container in Aufgabe 3 — genau das
   wollte der Auftraggeber wieder los sein. Vorbild ist v1 (`.tabs`/`.tab`):
   flexibel, aber ohne Wachstum, umbrechend statt zusammengequetscht. */
.reiter { display: flex; flex-wrap: wrap; gap: .3rem; border-bottom: 1px solid var(--linie); margin-bottom: 1.4rem; }
.reiter-blatt {
  padding: .6rem 1rem; text-decoration: none;
  color: var(--schrift-leise); font-weight: 600;
  border-bottom: 3px solid transparent; margin-bottom: -1px;
}
.reiter-blatt:hover { color: var(--blau-dunkel); }
.reiter-blatt.aktiv { color: var(--blau-dunkel); border-bottom-color: var(--blau); }

/* Ausnahme, keine Regel: Nur wo eine Vorlage die gestreckte, zentrierte Form
   ausdrücklich will, setzt sie zusätzlich `reiter-voll`. Aktuell nutzt sie
   niemand — auch die Anmeldeseite ist in v1 linksbündig (`.auth-tabs`). */
.reiter-voll .reiter-blatt { flex: 1 1 0; text-align: center; }

.anmeldung-abschnitt { font-size: .95rem; margin: 0 0 .6rem; }

/* Der SSO-Knopf ist bewusst der groesste Knopf der Seite: Fuer Mitarbeitende
   ist er der richtige Weg, und wer ihn uebersieht, legt sich unnoetig ein
   zweites Passwort an. */
.sso-knopf {
  display: flex; align-items: center; gap: .8rem; width: 100%;
  text-align: left; padding: .85rem 1rem;
  background: var(--blau-20); color: var(--blau-dunkel);
  border: 1.5px solid var(--blau-hell);
}
.sso-knopf:hover { background: var(--blau); color: var(--schrift-auf-farbe); border-color: var(--blau); }
.sso-text { display: flex; flex-direction: column; flex: 1 1 auto; line-height: 1.25; }
.sso-text small { font-weight: 400; font-size: .82rem; opacity: .85; }
.sso-pfeil { transform: rotate(-90deg); flex: 0 0 auto; }

/* Trennlinie mit Wort in der Mitte. */
.trenner {
  display: flex; align-items: center; gap: .8rem;
  color: var(--schrift-leise); font-size: .85rem; margin: 1.3rem 0;
}
.trenner::before, .trenner::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--linie);
}

.knopf-breit { width: 100%; justify-content: center; }

.feld-nebenweg { margin: .35rem 0 0; text-align: right; font-size: .88rem; }

.hinweiskasten {
  border-left: 4px solid var(--blau);
  background: var(--blau-20);
  border-radius: var(--radius-xs);
  padding: .8rem 1rem; margin-bottom: 1.2rem;
  font-size: .9rem;
}
.hinweiskasten p { margin: 0 0 .4rem; }
.hinweiskasten p:last-child { margin-bottom: 0; }
.hinweiskasten .symbol { width: 16px; height: 16px; vertical-align: -2px; }

.anmeldung-rechtliches { text-align: center; margin: 1rem 0 0; }

.anmeldung-hilfe {
  display: flex; align-items: center; gap: .6rem;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); padding: .8rem 1rem; margin-top: 1rem;
  font-size: .9rem; color: var(--schrift-weich);
}
.anmeldung-hilfe .symbol { width: 20px; height: 20px; flex: 0 0 20px; color: var(--blau); }

/* Kaestchen mit Beschriftung dahinter — die einzige Stelle, an der die
   Beschriftung NACH dem Bedienelement steht. Bei einem Kaestchen ist das
   richtig: Man liest „[x] Diesem Browser vertrauen", nicht umgekehrt. */
.feld-kaestchen label { display: flex; gap: .5rem; align-items: flex-start; font-weight: 600; }
.feld-kaestchen input[type="checkbox"] { margin-top: .2rem; flex: 0 0 auto; }
.feld-kaestchen .feld-hilfe { margin-top: .3rem; }

/* ---- Anleitung ---------------------------------------------------------- */

.anleitung { padding-left: 1.3rem; }
.anleitung li { margin-bottom: .9rem; line-height: 1.55; }

.anleitungsbild {
  display: block; max-width: 100%; height: auto;
  margin: .6rem 0; border: 1px solid var(--linie);
  border-radius: var(--radius-s); box-shadow: var(--schatten);
}

/* Sichtbarer Platzhalter statt eines zerbrochenen Bildsymbols: Er sagt, WAS
   dort stehen wird, und macht die Luecke sichtbar, statt sie zu verstecken. */
.anleitungsbild-fehlt {
  margin: .6rem 0; padding: .7rem .9rem;
  border: 1px dashed var(--linie); border-radius: var(--radius-s);
  background: var(--grund-2); color: var(--schrift-leise); font-size: .9rem;
}

/* ---- Begruessung -------------------------------------------------------- */

/* Frei auf der Flaeche, nicht in einer Karte (Vorlage: Altportal). Eine Karte
   ist ein Behaelter fuer etwas, mit dem man arbeitet; die Begruessung ist
   keins — als Karte drueckt sie die Kacheln nach unten und nimmt ihnen die
   erste Bildschirmhoehe. */
.begruessung { margin-bottom: 1.6rem; }
.begruessung h1 { margin: 0 0 .3rem; }
.begruessung .lead { color: var(--schrift-weich); font-size: 1.06rem; margin: 0; }
.begruessung .leise { margin: .4rem 0 0; }

/* Die eigene, engere Kachelbreite der Startseite ist entfallen: `.kacheln`
   deckt jetzt einheitlich alle Kachelraster ab (Startseite, Profil, die drei
   Zweig-Kacheln unter „Anliegen einreichen") — Begruendung und Rechnung
   stehen bei der Regel weiter oben. */

/* ---- Erklaerungs-Schalter ----------------------------------------------- */

/* Als Pille mit Zustand und nicht als Satz (Vorlage: Altportal). „Erklaerungen
   einblenden" sagt, was passiert, aber nicht, was gerade gilt — und genau das
   will man wissen, bevor man drueckt. */
.hilfe-schalter {
  display: inline-flex; align-items: center; gap: .4rem;
  font: inherit; font-size: .85rem; font-weight: 600;
  padding: .32rem .6rem; cursor: pointer;
  border: 1.5px solid var(--linie); border-radius: 999px;
  background: var(--karte); color: var(--schrift-weich);
}
.hilfe-schalter:hover { border-color: var(--blau); color: var(--blau); }
.hilfe-schalter .symbol { width: 17px; height: 17px; }
.hilfe-schalter-zustand {
  font-size: .72rem; padding: .05rem .4rem; border-radius: 999px;
  background: var(--linie-weich); color: var(--schrift-leise);
}
.hilfe-schalter.aktiv {
  border-color: var(--blau); color: var(--blau-dunkel); background: var(--blau-20);
}
.hilfe-schalter.aktiv .hilfe-schalter-zustand {
  background: var(--blau); color: var(--schrift-auf-farbe);
}

/* Auf schmalen Schirmen bleibt das Symbol und der Zustand — das Wort weicht.
   Ein Schalter, der die halbe Kopfleiste einnimmt, ist auf dem Telefon
   teurer als die Beschriftung wert ist. */
@media (max-width: 1100px) {
  .hilfe-schalter-text { display: none; }
}

/* ---- Ausweispruefung am Einlass ---------------------------------------- */

/* Ein grosses Wort auf farbiger Flaeche: Die Seite wird im Stehen, bei Sonne
   und in Eile gelesen. Wer hier suchen muss, winkt durch.

   Die Farbe ist nie die einzige Auskunft (WCAG 1.4.1) — Wort und Symbol stehen
   daneben. Rot und Gruen sind ausgerechnet die beiden Farben, die am
   haeufigsten nicht unterschieden werden. */
.pruefung { max-width: 34rem; margin: 0 auto; }

.pruefung-ergebnis {
  display: flex; align-items: center; justify-content: center; gap: .8rem;
  padding: 2rem 1rem; margin: 0 0 1.2rem;
  border-radius: var(--radius);
  font-family: var(--schriftfamilie-titel);
  font-size: 2rem; text-align: center;
}
.pruefung-symbol { width: 44px; height: 44px; flex: 0 0 44px; }
.pruefung-gueltig { background: var(--ok-grund); color: var(--ok); border: 2px solid var(--ok); }
.pruefung-ungueltig { background: var(--fehler-grund); color: var(--fehler); border: 2px solid var(--fehler); }

/* ---- Einlassliste ------------------------------------------------------- */

.wl-gruppe { margin-bottom: 1.8rem; }
.wl-gruppe h2 { display: flex; align-items: center; gap: .6rem; font-size: 1.15rem; }

.wl-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .5rem; }

/* Grosse Zeilen: Die Liste wird im Stehen gelesen, oft bei Sonne, und
   angetippt wird mit dem Daumen. */
.wl-zeile {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  background: var(--karte); border: 1px solid var(--linie);
  border-left: 5px solid var(--linie);
  border-radius: var(--radius-s); padding: .8rem 1rem;
}
.wl-zutritt .wl-zeile { border-left-color: var(--ok); }
.wl-widerrufen .wl-zeile, .wl-abgelehnt .wl-zeile { border-left-color: var(--fehler); }
.wl-offen .wl-zeile { border-left-color: var(--warnung); }

.wl-person { display: flex; flex-direction: column; gap: .15rem; min-width: 14rem; }
.wl-person strong { font-size: 1.05rem; }

.wl-aktionen { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.wl-aktionen form { display: flex; align-items: center; gap: .4rem; margin: 0; }
.wl-aktionen input[type="text"] {
  font: inherit; font-size: .9rem; padding: .4rem .6rem; min-width: 9rem;
  border: 1.5px solid var(--linie); border-radius: var(--radius-xs);
}

/* Hinweis, wenn sich der Bestand geaendert hat. Die Zeilen selbst baut das
   Skript nicht nach — das waere eine zweite Fassung der Vorlage, und eine
   davon veraltet. */
[data-wl-veraendert]::before {
  content: "Es hat sich etwas geändert — bitte die Seite neu laden.";
  display: block; margin-bottom: 1rem;
  padding: .7rem 1rem; border-radius: var(--radius-xs);
  background: var(--warnung-grund); color: var(--warnung); font-weight: 600;
}

/* ---- Profilbild --------------------------------------------------------- */

.avatar-gross { width: 96px; height: 96px; font-size: 2rem; }
.avatar-bild { object-fit: cover; }

.bildzeile { display: flex; gap: 1.5rem; align-items: flex-start; flex-wrap: wrap; }
.bildzeile-formulare { display: flex; gap: 1rem; align-items: flex-end; flex-wrap: wrap; flex: 1 1 18rem; }
.bildzeile-formulare form { margin: 0; }

/* ---- Passwort-Umschalter und Längen-Rückmeldung (O035/O036) ---------------
   Der Umschalter sitzt unter dem Feld statt darin: Ein Knopf im Eingabefeld
   überdeckt auf schmalen Geräten den Text, den man gerade lesen will — und
   genau dafür schaltet man ihn ja ein. */

.feld-umschalter {
    align-self: flex-start;
    margin-top: 0.35rem;
    padding: 0.2rem 0.6rem;
    min-height: 2.75rem;              /* Touch-Ziel (O044) */
    background: none;
    border: 1px solid var(--linie);
    border-radius: var(--radius-xs);
    color: var(--schrift-leise);
    font-size: 0.875rem;
    cursor: pointer;
}

.feld-umschalter:hover,
.feld-umschalter:focus-visible { color: var(--schrift); border-color: var(--blau); }

.feld-hilfe.genug { color: var(--ok); }
.feld-hilfe.zuwenig { color: var(--schrift-leise); }

/* ---- Sprungmarke je Frage (O050) -----------------------------------------
   Unauffällig, bis man mit der Maus darauf zeigt oder mit der Tastatur
   hinkommt: Ein dauerhaft sichtbares Rautenzeichen neben jeder Überschrift ist
   Zeichensalat für alle, die es nie brauchen. */

.ankerverweis {
    margin-left: 0.4rem;
    opacity: 0;
    color: var(--schrift-leise);
    text-decoration: none;
}

summary:hover .ankerverweis,
.ankerverweis:focus-visible { opacity: 1; }

/* ============================================================
   Arbeitslisten (Konzept 18.9)
   ============================================================ */

.arbeitsliste-kopf {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-bottom: .7rem;
}

.arbeitsliste-kopf .zaehlung { color: var(--schrift-leise); font-size: .9rem; margin-right: auto; }

/* Waagrecht rollen statt beschneiden. Eine Aktion, die man nicht erreicht,
   gibt es nicht. */
.arbeitsliste-rolle { overflow-x: auto; }

.arbeitsliste {
  width: 100%; border-collapse: collapse; background: var(--karte);
  border: 1px solid var(--linie); border-radius: var(--radius-s);
  overflow: hidden;
}

.arbeitsliste th, .arbeitsliste td {
  padding: .6rem .7rem; text-align: left; vertical-align: top;
  border-bottom: 1px solid var(--linie-weich);
}

.arbeitsliste thead th {
  background: var(--grund-2); color: var(--schrift-leise);
  font-size: .82rem; font-weight: 700; letter-spacing: .012em;
  white-space: nowrap;
}

.arbeitsliste tbody tr:last-child td { border-bottom: 0; }
.arbeitsliste tbody tr:hover { background: var(--grund-2); }

/* Sortierbare Kopfzelle.
   Das Doppelpfeilchen steht dauerhaft da, nur blass: Vorher erschien es erst
   *nach* dem Sortieren -- und eine sortierbare Spalte, von der niemand weiss,
   dass sie es ist, gibt es nicht. Blass genug, um die Kopfzeile nicht in
   Zeichensalat zu verwandeln; beim Zeigen wird es deutlich. */
.arbeitsliste th.sortierbar { cursor: pointer; user-select: none; }
.arbeitsliste th.sortierbar:hover { color: var(--blau); }
.arbeitsliste th.sortierbar::after {
  content: " ⇅"; font-size: .78em; opacity: .35; font-weight: 400;
}
.arbeitsliste th.sortierbar:hover::after { opacity: .8; }
.arbeitsliste th[aria-sort]::after { content: " ▲"; font-size: .7em; opacity: 1; }
.arbeitsliste th[aria-sort="descending"]::after { content: " ▼"; }

.arbeitsliste .zeilenaktionen { display: flex; gap: .4rem; flex-wrap: wrap; white-space: nowrap; }

/* ---- Spaltenwahl ---------------------------------------------------------
   Verschieben ueber Knoepfe, nicht per Ziehen (WCAG 2.1.1). */

.spaltenwahl > summary { cursor: pointer; }
/* **Nach links aufklappen, nicht nach rechts.**

   Der Knopf „Spalten" sitzt am rechten Ende der Kopfzeile. Ohne Verankerung
   oeffnete das Klappfeld nach rechts und wurde am Fensterrand abgeschnitten —
   die letzten Spalten und der Knopf „Standard wiederherstellen" waren nicht
   mehr erreichbar. `right: 0` haengt es an dieselbe Kante wie den Knopf.

   `max-width` und `max-height` fangen den Rest ab: auf schmalen Geraeten die
   Breite, bei vielen Spalten die Hoehe. Ein Klappfeld, das laenger ist als das
   Fenster, hat dasselbe Problem nur in der anderen Richtung. */
.arbeitsliste-kopf { position: relative; }
.spaltenwahl-klapp {
  position: absolute; right: 0; z-index: 20; margin-top: .3rem; padding: .6rem;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); box-shadow: var(--schatten-md);
  min-width: 15rem;
  max-width: min(22rem, calc(100vw - 2rem));
  max-height: min(70vh, 32rem); overflow-y: auto;
}

.spaltenzeile { display: flex; align-items: center; gap: .3rem; padding: .15rem 0; }
.spaltenzeile label { flex: 1 1 auto; font-size: .9rem; }
.spaltenknopf {
  border: 1px solid var(--linie); background: none; border-radius: var(--radius-xs);
  width: 1.9rem; height: 1.9rem; cursor: pointer; color: var(--schrift-leise);
}
.spaltenknopf:disabled { opacity: .35; cursor: default; }
.spaltenknopf:hover:not(:disabled) { border-color: var(--blau); color: var(--blau); }

/* ---- Gestapelt auf schmalen Geraeten --------------------------------------

   Unter 48rem wird aus jeder Zeile eine Karte: Eine Tabelle mit acht Spalten
   ist auf einem Telefon nicht zu lesen, und waagrechtes Rollen ueber acht
   Spalten ist keine Bedienung, sondern eine Suche.

   Es gilt fuer **jede** Tabelle, nicht nur fuer die Arbeitsliste:
   `table.stapelbar` setzt `liste.js` auf alles mit einer Kopfzeile, und die
   Beschriftung jeder Zelle kommt aus derselben Quelle. Vorher stapelten genau
   zwei Tabellensorten, alle uebrigen rollten waagrecht -- und welche wovon
   war, sah man erst auf dem Telefon.

   Die Grenze ist eine gemeinsame: Vorher stapelte die eine Sorte bei 40rem und
   die andere bei 720px. Zwei Grenzen fuer dieselbe Frage heisst, dass es
   dazwischen ein Fenster gibt, in dem die eine Tabelle gestapelt ist und die
   daneben nicht. */

@media (max-width: 48rem) {
  .arbeitsliste thead, table.liste thead, table.stapelbar thead { display: none; }

  .arbeitsliste, .arbeitsliste tbody, .arbeitsliste tr, .arbeitsliste td,
  table.liste, table.liste tbody, table.liste tr, table.liste td,
  table.stapelbar, table.stapelbar tbody, table.stapelbar tr, table.stapelbar td {
    display: block; width: 100%;
  }

  .arbeitsliste tr, table.liste tr, table.stapelbar tr {
    border: 1px solid var(--linie); border-radius: var(--radius-s);
    margin-bottom: .6rem; padding: .3rem 0;
  }

  .arbeitsliste td, table.liste td, table.stapelbar td {
    border-bottom: 0; padding: .35rem .7rem;
  }

  .arbeitsliste td[data-titel]::before,
  table.liste td[data-titel]::before,
  table.stapelbar td[data-titel]::before {
    content: attr(data-titel) ": ";
    font-weight: 700; color: var(--schrift-leise); font-size: .82rem;
  }

  /* Eine leere Zelle bekommt keine Beschriftung: „Verantwortlich: " ohne Wert
     ist eine Zeile, die nur Platz kostet. */
  .arbeitsliste td:empty, table.liste td:empty, table.stapelbar td:empty { display: none; }

  /* Waagrechtes Rollen ist damit gegenstandslos — und ein Rollbereich, der
     nichts mehr zu rollen hat, faengt trotzdem Wischgesten ab. */
  .arbeitsliste-rolle, .tabellen-huelle { overflow-x: visible; }
}

/* ============================================================
   Filterleiste einer Arbeitsliste (Konzept 18.9)
   ============================================================

   Zugeklappt bleiben genau zwei Zeilen stehen: Ueberschrift und Reiter.
   Darunter beginnt sofort die Liste -- sie ist das, wofuer man hergekommen
   ist. Alles, was die Ansicht steuert, liegt im Klappbereich. */

/* Der Klapp-Schalter sitzt oben rechts **neben** den Reitern, die Leiste
   darunter geht ueber die **ganze** Breite.

   Vorher war die Leiste ein Kind des Schalters und damit so breit wie er:
   sieben Filter draengten sich in einer 20rem-Spalte, waehrend rechts daneben
   der halbe Bildschirm leer blieb. Deshalb ist `.board-kopf` ein gewoehnlicher
   Block -- Reiter, dann Leiste, beide voll breit -- und nur der Schalter wird
   in die freie Ecke der Reiterzeile gesetzt. */
/* **Der Schalter liegt im Fluss, nicht darueber.**

   Vorher war er absolut positioniert (`top:0; right:0`) und die Reiterreihe
   liess ihm mit `padding-right: 11rem` Platz. Auf einer Flaeche **ohne
   Reiter** — der Priorisierung etwa — gab es diesen Platz nicht: Der Schalter
   lag auf dem geoeffneten Filterbereich, ueber Suchfeld und Knopf.

   Jetzt tragen beide dieselbe Reihe: Reiter links, Schalter rechtsbuendig auf
   eigener Zeile, der Filterbereich darunter ueber die volle Breite. Das kann
   sich nicht mehr ueberlagern, egal ob es Reiter gibt oder nicht. */
.board-kopf {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: .5rem; margin-bottom: 1.2rem;
}
.board-kopf .reiter { flex: 1 1 auto; margin-bottom: 0; padding-right: 0; }

.filter-klapp { flex: 1 1 100%; }
.filter-klapp > summary {
  margin-left: auto; width: max-content;
  display: inline-flex; align-items: center; gap: .4rem;
  list-style: none; cursor: pointer;
  padding: .45rem .8rem; border: 1px solid var(--linie);
  border-radius: var(--radius-xs); background: var(--karte);
  color: var(--schrift-weich); font-weight: 600; font-size: .9rem;
  white-space: nowrap;
}
.filter-klapp > summary::-webkit-details-marker { display: none; }
.filter-klapp > summary:hover { border-color: var(--blau); color: var(--blau-dunkel); }
.filter-klapp > summary::after { content: "▾"; font-size: .8em; }
.filter-klapp[open] > summary::after { content: "▴"; }

.filter-panel {
  margin-top: .6rem; padding: .9rem;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); box-shadow: var(--schatten);
}

.board-leiste {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-bottom: .8rem;
}

/* Aktiv und Archiv sind zwei Ansichten, keine Filter -- deshalb ein
   zusammenhaengendes Schaltpaar und nicht zwei einzelne Knoepfe. */
.ansicht-schalter {
  display: inline-flex; border: 1px solid var(--linie);
  border-radius: var(--radius-xs); overflow: hidden;
}
/* Zwei Bauformen, ein Aussehen: Im Board sind es Verweise (jede Ansicht hat
   ihre eigene Adresse), in „Meine Anliegen" Auswahlknoepfe in einem
   Filterformular. Getrennt gestaltet waere dieselbe Bedienung an zwei Stellen
   verschieden — die Konvention verlangt das Gegenteil. */
.ansicht-schalter a,
.ansicht-schalter label {
  padding: .35rem .7rem; font-size: .88rem; font-weight: 600;
  color: var(--schrift-weich); text-decoration: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: .35rem;
}
.ansicht-schalter a + a,
.ansicht-schalter label + label { border-left: 1px solid var(--linie); }
.ansicht-schalter a:hover,
.ansicht-schalter label:hover { background: var(--grund-2); }
.ansicht-schalter a.aktiv,
.ansicht-schalter label.aktiv { background: var(--blau); color: var(--schrift-auf-farbe); }
/* Der Tastaturfokus liegt auf dem verborgenen Auswahlknopf — ohne diese Zeile
   sieht man beim Durchtabben nicht, wo man ist. */
.ansicht-schalter label:has(input:focus-visible) { outline: 2px solid var(--blau); outline-offset: -2px; }
.ansicht-schalter .zahl {
  font-size: .8rem; padding: 0 .35rem; border-radius: var(--radius-xs);
  background: var(--grund-2); color: var(--schrift-leise);
}
.ansicht-schalter a.aktiv .zahl { background: var(--blau-dunkel); color: var(--schrift-auf-farbe); }

.filterreihe { display: flex; gap: .5rem; flex-wrap: wrap; align-items: flex-start; }

/* Die Filterleiste erbt keine Feldstile: Die liegen unter `.feld` und gelten
   fuer Formularzeilen mit Beschriftung darueber. Hier stehen die Felder
   nebeneinander in einer Leiste, also bekommen sie ihre eigenen -- sonst
   stehen dort die nackten Browservorgaben, und ein Suchfeld im Werksdesign
   neben sechs gestalteten Klappfeldern sieht aus wie ein Fehler. */
.filter-panel input[type="search"],
.filter-panel input[type="text"],
.filter-panel select {
  padding: .5rem .7rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius-xs);
  background: var(--karte);
  font: inherit;
  color: var(--schrift);
  -webkit-appearance: none; appearance: none;
}
.filter-panel input[type="search"]::-webkit-search-decoration,
.filter-panel input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }
.filter-panel input:focus-visible,
.filter-panel select:focus-visible { outline: var(--fokusring); outline-offset: 1px; }
.filter-panel input[type="search"]:hover { border-color: var(--blau); }

/* Das Suchfeld nimmt den uebrigen Platz: Es ist das Feld, das am meisten
   benutzt wird, und ein 12 Zeichen breites Suchfeld neben sechs Klappfeldern
   sagt das Gegenteil. */
.board-suche { position: relative; flex: 1 1 22rem; min-width: 14rem; }
/* **Der Innenabstand muss die Spezifitaet der Filterleiste schlagen.**

   `.filter-panel input[type="search"]` (Klasse + Attribut) gewinnt gegen
   `.board-suche input` — und setzt `padding: .5rem .7rem`. Der linke Abstand
   von 2.1rem war damit wirkungslos, und die Lupe lag ueber dem
   Platzhaltertext. Genau der gemeldete Befund; das Symbol allein hat ihn nicht
   behoben. */
.filter-panel .board-suche input[type="search"] { padding-left: 2.5rem; }

.board-suche input {
  width: 100%;
  /* Platz fuer die Lupe. Sie ist ein Zeichen im Vordergrund und kein
     Hintergrundbild: So erbt sie die Textfarbe und bleibt in jedem Kontrast
     sichtbar. */
  padding-left: 2.1rem;
}
/* Die Lupe ist ein SVG und kein Schriftzeichen mehr.

   Vorher stand hier `content: "⌕"`. Das Zeichen fehlt in den geometrischen
   Ersatzschriften, die ohne die lizenzpflichtigen Hausschriften einspringen —
   was stattdessen kam, war breiter als die eingeplanten 2.1rem und lag damit
   über der Eingabe. Ein Symbol mit fester Groesse kann das nicht. */
.board-suche-lupe {
  position: absolute; left: .65rem; top: 50%; transform: translateY(-50%);
  width: 1.05rem; height: 1.05rem; color: var(--schrift-leise);
  pointer-events: none;
}

.vorschlagsliste {
  position: absolute; z-index: 30; left: 0; right: 0; top: 100%;
  margin: .2rem 0 0; padding: .2rem; list-style: none;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); box-shadow: var(--schatten-md);
  max-height: 18rem; overflow-y: auto;
}
.vorschlag-board {
  margin-left: auto; padding-left: .5rem;
  color: var(--schrift-leise); font-size: .8rem; white-space: nowrap;
}
.vorschlagsliste li {
  display: flex; gap: .5rem; align-items: baseline;
  padding: .4rem .5rem; border-radius: var(--radius-xs); cursor: pointer;
  font-size: .9rem;
}
.vorschlagsliste li:hover,
.vorschlagsliste li.gewaehlt { background: var(--blau-20); }
.vorschlag-nr { color: var(--schrift-leise); font-variant-numeric: tabular-nums; }

/* ---- Ein Filterfeld ------------------------------------------------------ */

.filterfeld { position: relative; }
.filterfeld > summary {
  display: inline-flex; align-items: center; gap: .35rem;
  list-style: none; cursor: pointer; white-space: nowrap;
  padding: .45rem .7rem; border: 1px solid var(--linie);
  border-radius: var(--radius-xs); background: var(--karte);
  color: var(--schrift-weich); font-size: .88rem; font-weight: 600;
}
.filterfeld > summary::-webkit-details-marker { display: none; }
.filterfeld > summary::after { content: "▾"; font-size: .8em; color: var(--schrift-leise); }
.filterfeld[open] > summary { border-color: var(--blau); color: var(--blau-dunkel); }
.filterfeld > summary:hover { border-color: var(--blau); }

.filterfeld-zahl {
  font-size: .75rem; font-weight: 700; padding: .05rem .35rem;
  border-radius: var(--radius-xs);
  background: var(--blau); color: var(--schrift-auf-farbe);
}
.filterfeld-zahl.ohne { background: var(--warnung); }

.filterfeld-klapp {
  position: absolute; z-index: 25; margin-top: .3rem; padding: .6rem;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); box-shadow: var(--schatten-md);
  min-width: 16rem; max-width: 22rem;
}
.filterfeld-modus { display: block; font-size: .82rem; color: var(--schrift-leise); margin-bottom: .4rem; }
.filterfeld-modus select { width: 100%; margin-top: .15rem; }
.filterfeld-suche { display: block; margin-bottom: .4rem; }
.filterfeld-suche input { width: 100%; }
.filterfeld-werte { max-height: 16rem; overflow-y: auto; margin-bottom: .5rem; }
.filterfeld-wert {
  display: flex; align-items: center; gap: .4rem;
  padding: .2rem .1rem; font-size: .9rem; cursor: pointer;
}
.filterfeld-wert:hover { background: var(--grund-2); }
.filterfeld-text { flex: 1 1 auto; }
.filterfeld-anzahl {
  font-size: .78rem; color: var(--schrift-leise);
  font-variant-numeric: tabular-nums;
}
.filterfeld-leer { font-size: .85rem; margin: .2rem 0 .5rem; }

/* ============================================================
   Prozessschritt als Punktkette
   ============================================================

   Beantwortet „wie weit ist das?" beim Ueberfliegen, ohne dass man „3/4"
   erst lesen und ins Verhaeltnis setzen muss. */

.stufen { display: inline-block; min-width: 6.5rem; }
.punkte { display: flex; gap: .18rem; margin-bottom: .18rem; }
.punkt {
  width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--linie); flex: 0 0 auto;
}
.punkt.erledigt { background: var(--blau); }
.punkt.jetzt { background: var(--blau); box-shadow: 0 0 0 .13rem var(--blau-20); }
.stufen.fertig .punkt.erledigt,
.stufen.fertig .punkt.jetzt { background: var(--ok); }
.stufen.fertig .punkt.jetzt { box-shadow: 0 0 0 .13rem var(--ok-grund); }
.stufen-text {
  display: block; font-size: .78rem; color: var(--schrift-leise);
  line-height: 1.25;
}
/* Die Schrittzahl ist die Auskunft der Spalte, der Statusname die Einzelheit
   dazu. Vorher standen beide im selben blassen Grau — beim Ueberfliegen einer
   langen Liste verschwand damit genau das, wofuer die Spalte da ist. */
.stufen-zahl { color: var(--schrift); font-weight: 600; }

/* Immer sichtbare Spalte: ein Punkt statt eines abgeschalteten Kaestchens --
   ein Kaestchen, das man nicht bedienen kann, laedt zum Klicken ein. */
.spalte-fest { width: 1rem; text-align: center; color: var(--schrift-leise); }
.spalten-fuss { margin: .5rem 0 0; padding-top: .5rem; border-top: 1px solid var(--linie-weich); }

/* Die Tabellenkarte traegt den Rahmen; die Tabelle darin braucht keinen
   zweiten. */
.board-tabelle-karte .arbeitsliste { border: 0; border-radius: 0; }
.board-tabelle-karte .arbeitsliste-kopf h2 { margin: 0 auto 0 0; font-size: 1.15rem; }

@media (max-width: 48rem) {
  /* Der Schalter kommt aus der Ecke zurueck in den Fluss: Neben umgebrochenen
     Reitern gibt es keine freie Ecke mehr, in die er passt. */
  .board-kopf { min-height: 0; }
  .board-kopf .reiter { padding-right: 0; }
  .filter-klapp > summary { position: static; margin-top: .6rem; width: 100%; justify-content: space-between; }

  /* Klappfelder als Blocklagen statt als schwebende Kaesten: Ein 22rem breiter
     Kasten passt auf ein Telefon nicht, und die Haelfte stuende ausserhalb. */
  .filterfeld-klapp, .spaltenwahl-klapp { position: static; max-width: none; min-width: 0; }
  .filterreihe { flex-direction: column; }
  .filterreihe > * { width: 100%; }
  .filterfeld > summary { width: 100%; justify-content: space-between; }
  .board-leiste { flex-direction: column; align-items: stretch; }
  .ansicht-schalter a { flex: 1 1 auto; justify-content: center; }
}

/* ============================================================
   Detailseiten
   ============================================================

   Zwei Spalten: links, was man liest, rechts, was man nachschlaegt.

   Der Anlass war ein Bildschirmfoto. Auf einem breiten Schirm stand alles
   untereinander: zwoelf Angaben als Begriffsliste in einem Streifen von 15 %
   der Breite, daneben nichts -- und der Beschreibungstext ueber die vollen
   2000 px. Volle Breite hat das Layoutproblem nicht verursacht, sie hat es
   sichtbar gemacht. */

.detail-raster {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 1.2rem;
  align-items: start;
}
.detail-haupt, .detail-neben { min-width: 0; display: flex; flex-direction: column; gap: 1.2rem; }
.detail-haupt > .karte, .detail-neben > .karte, .detail-neben > .klappfeld { margin: 0; }

/* Unter 64rem eine Spalte -- und der Hauptteil zuerst: Zuerst will man
   wissen, worum es geht, und nicht die Kategorie nachschlagen. */
@media (max-width: 64rem) {
  .detail-raster { grid-template-columns: 1fr; }
}

/* **Lesbare Zeilenlaenge.** Eine Zeile ueber die ganze Breite verliert das
   Auge beim Ruecksprung an den Zeilenanfang; man liest sie nicht mehr,
   sondern sucht sie ab. Die Grenze steht in `ch` und nicht in Pixeln — das
   gilt fuer `--lesebreite` selbst (siehe Definition oben): Sie soll an der
   Schrift haengen, nicht am Bildschirm. Das eigene Literal ist entfallen,
   damit diese Grenze ueberall im Kern dieselbe ist. */
.fliesstext { max-width: var(--lesebreite); }

/* Das Nachrichtenfeld ist eine Eingabe, kein Textkoerper -- es darf breiter
   sein als der Fliesstext, aber nicht die ganze Spalte: dieselbe Breite wie
   ein erklaerender Kasten, nicht eine dritte eigene Zahl. */
.feld-schmal { max-width: var(--kastenbreite); }

.stand-zeile { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; }

/* ---- Zeitleiste ------------------------------------------------------------
   Verlauf und Nachrichten sind Ereignisfolgen und keine Aufzaehlung. Die
   Nummern der `<ol>` zaehlten mit, was niemand zaehlen will; die Reihenfolge
   traegt trotzdem Bedeutung, deshalb bleibt es eine `<ol>` und verliert nur
   die Nummern. */

.zeitleiste { list-style: none; margin: 0 0 1rem; padding: 0 0 0 1rem; }
.zeitleiste > li {
  position: relative; padding: 0 0 .9rem .9rem;
  border-left: 2px solid var(--linie-weich);
}
.zeitleiste > li:last-child { border-left-color: transparent; padding-bottom: 0; }
.zeitleiste > li::before {
  content: ""; position: absolute; left: -.31rem; top: .45rem;
  width: .55rem; height: .55rem; border-radius: 50%;
  background: var(--blau);
}
.zeitleiste-kopf { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; }
.zeitleiste p { margin: .25rem 0 0; }

/* **Wer spricht, sieht man ohne zu lesen.** In einer Unterhaltung standen
   eigene Beitraege und die des Portal-Teams in derselben Farbe — man musste die
   Zeile darueber lesen, um zu wissen, wer antwortet. Der Punkt der Zeitleiste
   traegt die Auskunft jetzt mit; das Wort daneben bleibt stehen, denn Farbe
   allein ist keine Auskunft (WCAG 1.4.1). */
.zeitleiste > li.von-mir::before { background: var(--schrift-leise); }
.zeitleiste > li.von-mir { border-left-style: dashed; }

/* ---- Lesbare Zeilenlaenge, portalweit -------------------------------------

   `.fliesstext` einzeln zu setzen half nur dort, wo jemand daran dachte. Text
   in einer Karte ist praktisch immer Fliesstext, also gilt die Grenze dort
   von selbst -- auch auf den Textseiten (Hilfe, FAQ, Rechtstexte, Merkblatt),
   die bei 1180 px rund 140 Zeichen pro Zeile hatten.

   Ausgenommen sind Zeilen, die keine Saetze tragen: Knopfreihen (`.reihe`),
   Meldungen, die ihre Flaeche brauchen, und alles, was ausdruecklich breit
   sein soll (`.voll`). Tabellen und Formulare sind ohnehin nicht betroffen --
   die Regel greift nur an direkten Text-Kindern einer Karte. */
.karte > p:not(.reihe):not(.voll),
.karte > ul:not(.voll),
.karte > ol:not(.voll),
.klappinhalt > p:not(.reihe):not(.voll) { max-width: var(--lesebreite); }

/* Die Zeitleiste ist eine Ereignisfolge und traegt ihre Saetze selbst --
   ihre Grenze steht an den Absaetzen darin, nicht an der Liste. */
.karte > ol.zeitleiste { max-width: none; }
.zeitleiste p { max-width: var(--lesebreite); }

/* ---- Blaettern und Sortieren in einer Arbeitsliste ------------------------ */

.blaettern {
  display: flex; align-items: center; justify-content: center;
  gap: .8rem; margin-top: 1rem; flex-wrap: wrap;
}
.blaettern [aria-disabled="true"] { opacity: .45; cursor: default; }

/* Die Kopfzelle wird zum Verweis, sieht aber aus wie eine Kopfzelle: Ein blau
   unterstrichener Spaltenname laese sich wie ein Datenlink. */
.sortierlink { color: inherit; text-decoration: none; }
.sortierlink:hover { color: var(--blau); text-decoration: underline; }

/* Eine Aktion in einer Zeile ist ein winziges Formular (POST), kein Verweis —
   sie soll trotzdem in der Reihe stehen wie ein Knopf. */
.zeilenaktion { display: inline; margin: 0; }

/* Eine Gruppe zusammengehoeriger Kaestchen: `fieldset` traegt die gemeinsame
   Frage, damit die Vorlesehilfe nicht fuenf lose Kaestchen vorliest. */
.kaestchenliste { border: 0; padding: 0; margin: 0; display: grid; gap: .2rem; }
.feld-gruppentitel { display: block; font-weight: 600; margin-bottom: .25rem; }

/* ---- Felder in einer Tabellenzelle ---------------------------------------
   Fuer Flaechen, auf denen man in der Zeile entscheidet statt in einem
   zweiten Fenster. Schmal gehalten: Die Zeile bleibt lesbar, und die Tabelle
   soll nicht doppelt so hoch werden wie vorher. */
.zellenfeld {
  width: 100%; max-width: 11rem; padding: .25rem .4rem;
  border: 1px solid var(--linie); border-radius: var(--radius-xs);
  background: var(--karte); color: var(--schrift); font: inherit; font-size: .88rem;
}
.zellenfeld:focus-visible { outline: var(--fokusring); outline-offset: 1px; }

/* ---- Spaltenboard --------------------------------------------------------

   Fuer Flaechen, deren Aussage die Verteilung ist: wo steht was, und wie voll
   ist welche Spalte. Alle Spalten nebeneinander — das Altsystem hatte das, und
   die zwischenzeitliche Loesung mit Reitern zeigte immer nur eine.

   Waagrecht rollend statt umbrechend: Ein Board, dessen Spalten untereinander
   rutschen, ist kein Board mehr. Auf schmalen Geraeten rollt man. */
.spaltenboard {
  display: flex; gap: .8rem; align-items: flex-start;
  overflow-x: auto; padding-bottom: .6rem;
}
.boardspalte {
  flex: 0 0 17rem; display: flex; flex-direction: column;
  background: var(--grund-2); border: 1px solid var(--linie);
  border-radius: var(--radius-s); padding: .6rem;
}
.boardspalte-kopf {
  margin: 0 0 .2rem; font-size: 1rem; display: flex; align-items: center; gap: .4rem;
}
.boardspalte-kopf .zahl {
  font-size: .8rem; padding: 0 .35rem; border-radius: var(--radius-xs);
  background: var(--karte); color: var(--schrift-leise); font-weight: 400;
}
.boardspalte-zusatz { margin: 0 0 .4rem; font-size: .8rem; color: var(--schrift-leise); }
.boardspalte-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; min-height: 3rem; }
.boardspalte-leer { color: var(--schrift-leise); text-align: center; padding: .8rem 0; }

.boardkarte {
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-xs); padding: .5rem .6rem; font-size: .88rem;
}
.boardkarte-kopf { display: flex; gap: .3rem; align-items: center; flex-wrap: wrap; margin-bottom: .2rem; }
.boardkarte-titel { display: block; font-weight: 600; margin-bottom: .15rem; }
.boardkarte-zusatz { display: block; color: var(--schrift-leise); font-size: .8rem; margin-bottom: .35rem; }
.boardkarte-setzen { display: flex; gap: .3rem; align-items: center; }
.boardkarte-setzen .zellenfeld { max-width: 8.5rem; font-size: .8rem; }

/* Ziehen ist Zugabe: Der Griff erscheint nur, wo das Skript ihn anhaengt. */
.boardkarte[data-ziehbar] { cursor: grab; }
.boardkarte.wird-gezogen { opacity: .5; }
.boardspalte-liste.ziel-aktiv { outline: 2px dashed var(--blau); outline-offset: 2px; border-radius: var(--radius-xs); }

/* Die erste Spalte fuehrt zum Datensatz. Sie sieht aus wie ein Verweis, weil
   sie einer ist — eine Zelle, die auf Klick etwas tut, ohne es zu zeigen, ist
   eine Falle fuer alle, die sie nicht zufaellig entdecken. */
.arbeitsliste .zeilenziel { color: var(--blau); text-decoration: none; font-weight: 600; }
.arbeitsliste .zeilenziel:hover { text-decoration: underline; }

/* ============================================================
   Bausteine des Baukastens
   ============================================================

   Was hier steht, gehoert zu je einer Blade-Komponente unter
   `components/portal/`. Wer eine dieser Klassen von Hand ins Markup schreibt,
   baut die Komponente nach — und dann gibt es sie zweimal, mit dem naechsten
   Unterschied schon eingebaut. Die Musterseite (`/admin/muster`) zeigt jede in
   jedem Zustand.
   ============================================================ */

/* ---- Karte mit Kopf ----------------------------------------------------- */

.karte-kopf {
  display: flex; align-items: flex-start; gap: var(--raum-4);
  flex-wrap: wrap; margin-bottom: var(--raum-4);
}
/* Der Kartentitel ist eine Ebene kleiner als der Abschnittstitel der Seite:
   Als `h2` traegt er die richtige Bedeutung fuer die Vorlesehilfe, aber in
   Seitentitel-Groesse erschlaegt er den Inhalt der Karte. Bedeutung und
   Groesse sind zwei Fragen. */
.karte-titel { margin: 0; flex: 1 1 12rem; font-size: var(--titel-3); }
.karte-aktionen { display: flex; gap: var(--raum-2); flex-wrap: wrap; margin-left: auto; }
.karte-fuss {
  margin-top: var(--raum-4); padding-top: var(--raum-3);
  border-top: 1px solid var(--linie-weich);
  color: var(--schrift-leise); font-size: var(--schrift-s);
}

/* ---- Kennzahl ----------------------------------------------------------- */

/* `auto-fill`, nicht `auto-fit`: Bei `auto-fit` ziehen sich zwei Kennzahlen auf
   je die halbe Bildschirmbreite auseinander — eine Zahl mit einem Wort darunter
   in einem 700 Pixel breiten Feld sieht aus wie ein Fehler. Sie behalten ihre
   Groesse und lassen rechts Platz, bis eine dritte dazukommt. */
.kennzahlen {
  display: grid; gap: var(--raum-4); margin-bottom: var(--raum-5);
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

.kennzahl {
  display: flex; flex-direction: column; gap: var(--raum-2);
  padding: var(--raum-4) var(--raum-5);
  background: var(--karte);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  color: inherit; text-decoration: none;
  transition: box-shadow var(--dauer-ruhig) var(--uebergang),
              transform var(--dauer-ruhig) var(--uebergang),
              border-color var(--dauer-ruhig) var(--uebergang);
}
a.kennzahl:hover {
  box-shadow: var(--schatten-md); transform: translateY(-3px);
  border-color: var(--blau-hell);
}

.kennzahl-kopf { display: flex; align-items: center; gap: var(--raum-2); }
.kennzahl-symbol {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: var(--radius-xs);
  background: var(--blau-20); color: var(--blau-dunkel);
}
.kennzahl-symbol .symbol { width: 18px; height: 18px; }
.kennzahl-beschriftung {
  font-weight: 700; color: var(--schrift-weich); font-size: var(--schrift-s);
  line-height: 1.25;
}

/* Die Zahl ist das Element, das man aus drei Metern Entfernung liest — sie
   traegt die Titelschrift und nicht die Fliesstextschrift. */
.kennzahl-wert {
  font-family: var(--schriftfamilie-titel);
  font-size: clamp(2rem, 1.4rem + 1.8vw, 2.9rem);
  font-weight: 800; line-height: 1; letter-spacing: -.02em;
  color: var(--schrift);
}
.kennzahl-hinweis { color: var(--schrift-leise); font-size: var(--schrift-s); line-height: 1.4; }

.kennzahl-weg {
  display: inline-flex; align-items: center; gap: .35rem;
  margin-top: auto; padding-top: var(--raum-2);
  color: var(--blau); font-weight: 700; font-size: var(--schrift-s);
}
.kennzahl-weg .symbol { width: 16px; height: 16px; transition: transform var(--dauer-schnell) var(--uebergang); }
a.kennzahl:hover .kennzahl-weg .symbol { transform: translateX(3px); }

/* Der Ton faerbt Symbolfeld und Zahl — das Wort daneben sagt dasselbe noch
   einmal in Sprache (WCAG 1.4.1). */
.kennzahl-ok .kennzahl-symbol { background: var(--ok-grund); color: var(--ok); }
.kennzahl-ok .kennzahl-wert { color: var(--ok); }
.kennzahl-warnung .kennzahl-symbol { background: var(--warnung-grund); color: var(--warnung); }
.kennzahl-warnung .kennzahl-wert { color: var(--warnung); }
.kennzahl-fehler .kennzahl-symbol { background: var(--fehler-grund); color: var(--fehler); }
.kennzahl-fehler .kennzahl-wert { color: var(--fehler); }

/* Leer heisst matt, nicht weg — und nicht ausgegraut: Die Kachel bleibt ein
   Verweis und muss anklickbar aussehen. */
.kennzahl-leer { opacity: .66; }
.kennzahl-leer:hover, .kennzahl-leer:focus-visible { opacity: 1; }

/* ---- Verlauf ------------------------------------------------------------ */

.verlauf { display: flex; align-items: center; gap: var(--raum-2); flex-wrap: wrap; }

/* `progress` sieht in jedem Browser anders aus; die drei Regelsaetze sind
   deshalb kein Uebereifer, sondern der Preis dafuer, das native Element zu
   behalten statt es durch zwei `div` zu ersetzen. */
.verlauf-bahn {
  appearance: none; -webkit-appearance: none;
  /* Der Balken waechst nicht ins Unendliche: Ueber eine Bildschirmbreite
     gezogen steht sein Text am anderen Ende der Seite, und man liest beides
     nicht mehr zusammen. */
  flex: 0 1 16rem; min-width: 5rem; height: .5rem;
  border: 0; border-radius: 999px;
  background: var(--linie);
  overflow: hidden;
}
.verlauf-bahn::-webkit-progress-bar { background: var(--linie); border-radius: 999px; }
.verlauf-bahn::-webkit-progress-value {
  background: linear-gradient(90deg, var(--blau), var(--blau-hell));
  border-radius: 999px;
  transition: width var(--dauer-ruhig) var(--uebergang);
}
.verlauf-bahn::-moz-progress-bar {
  background: linear-gradient(90deg, var(--blau), var(--blau-hell));
  border-radius: 999px;
}
.verlauf-ok .verlauf-bahn::-webkit-progress-value { background: var(--ok); }
.verlauf-ok .verlauf-bahn::-moz-progress-bar { background: var(--ok); }
.verlauf-warnung .verlauf-bahn::-webkit-progress-value { background: var(--warnung); }
.verlauf-warnung .verlauf-bahn::-moz-progress-bar { background: var(--warnung); }

.verlauf-text { color: var(--schrift-leise); font-size: var(--schrift-s); }

/* ---- Held --------------------------------------------------------------- */

/* Der Held bricht seitlich aus dem Inhaltsfeld aus — eine Farbflaeche, die vor
   dem Rand aufhoert, sieht aus wie ein grosser Knopf.

   Nach OBEN bricht er nur aus, wenn er das erste Element der Seite ist. Steht
   ein Navigationspfad davor, verschluckt der negative Rand ihn sonst
   vollstaendig: Der Weg zurueck war unter der Farbflaeche und niemand sah ihn. */
.held {
  position: relative; overflow: hidden;
  margin: 0 calc(var(--raum-5) * -1) var(--raum-6);
  padding: var(--raum-7) var(--raum-5) var(--raum-6);
  background: var(--held);
  color: var(--held-schrift);
  isolation: isolate;
}

/* Die Illustration liegt IM Held und laeuft rechts aus. Als eigenes Element
   und nicht als `background` des Helds: So kann sie eine eigene Deckkraft
   tragen, ohne die Farbflaeche mit aufzuhellen. */
.held::after {
  content: "";
  position: absolute; inset: 0 0 0 auto;
  width: min(58%, 640px);
  background-image: var(--held-bild);
  background-repeat: no-repeat;
  background-position: right bottom;
  background-size: cover;
  opacity: .3;
  /* `currentColor` und nicht Schwarz: Eine Maske wertet nur den Alphakanal aus,
     die Farbe ist dabei gleichgueltig — und der Kern traegt keine (A10). */
  mask-image: linear-gradient(90deg, transparent, currentColor 45%);
  z-index: -1;
}
.held-ohne-bild::after { display: none; }

/* Der Held einer Modulseite: Bild links, Text daneben. Das Bild stand frueher
   in einer eigenen Kopfzeile ueber der Seite — zwei Muster fuer denselben
   Anfang. Es ist dasselbe Bild in derselben Groesse, nur an einer Stelle. */
.held-mit-modulbild {
  display: flex;
  align-items: center;
  gap: var(--raum-5);
  flex-wrap: wrap;
}
.held-mit-modulbild .modulbild,
.held-mit-modulbild .modul-emblem { flex: 0 0 auto; }

/* Als erstes Element schliesst der Held oben buendig an die Kopfleiste an. */
.inhalt > .held:first-child { margin-top: calc(var(--raum-6) * -1); }
.krume + .held { margin-top: var(--raum-2); }

/* Der Titel darf die ganze Breite nehmen — die Lesebreite deckelt nur den
   Fliesstext (`.held-lead`, `.held-zusatz` tragen ihre eigene Grenze). Mit
   dem Deckel am ganzen Inhalt brach ein langer Seitentitel schon nach 68
   Zeichen um und wirkte abgeschnitten, obwohl rechts die halbe Seite frei
   war (Befund des Auftraggebers, 10.09.2026). */
.held-inhalt { max-width: none; position: relative; z-index: 1; }
.held-titel {
  color: var(--held-schrift); font-size: var(--titel-held);
  margin: 0 0 var(--raum-2); line-height: 1.02;
}
.held-lead { color: var(--held-leise); font-size: var(--schrift-l); margin: 0; max-width: 52ch; }
.held-aktionen { display: flex; gap: var(--raum-3); flex-wrap: wrap; margin-top: var(--raum-5); }
.held-zusatz { color: var(--held-leise); font-size: var(--schrift-s); margin: var(--raum-3) 0 0; max-width: 58ch; }

/* Ein blauer Knopf auf blauer Flaeche ist keiner. Im Held gilt weiss gefuellt
   fuer die Aktion und weiss umrandet fuer die Navigation — dieselbe
   Unterscheidung wie ueberall, nur in der Gegenfarbe. */
.held .knopf {
  background: var(--held-schrift); color: var(--blau-dunkel); border-color: var(--held-schrift);
}
.held .knopf:hover { background: var(--blau-20); border-color: var(--blau-20); color: var(--blau-dunkel); }
.held .knopf-rand { background: transparent; color: var(--held-schrift); border-color: var(--held-leise); }
.held .knopf-rand:hover { background: var(--schleier); color: var(--held-schrift); border-color: var(--held-schrift); }

.held-klein { padding: var(--raum-6) var(--raum-5) var(--raum-5); }
.held-klein .held-titel { font-size: var(--titel-1); }

@media (max-width: 900px) {
  .held {
    margin: calc(var(--raum-5) * -1) calc(var(--raum-4) * -1) var(--raum-5);
    padding: var(--raum-6) var(--raum-4) var(--raum-5);
  }
  /* Auf dem Telefon steht das Bild hinter dem Text statt neben ihm — dort ist
     keine Breite uebrig, in der es auslaufen koennte. Blasser, weil weisse
     Schrift sonst darauf verschwindet. */
  .held::after { width: 100%; opacity: .16; mask-image: none; }
}

/* ---- Schnellaktionen ---------------------------------------------------- */

.schnellaktionen {
  display: grid; gap: var(--raum-3); margin-bottom: var(--raum-5);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.schnellaktion {
  display: flex; align-items: center; gap: var(--raum-3);
  padding: var(--raum-4);
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius-s); box-shadow: var(--schatten);
  color: var(--schrift); text-decoration: none; font-weight: 700;
  transition: box-shadow var(--dauer-ruhig) var(--uebergang),
              transform var(--dauer-ruhig) var(--uebergang),
              border-color var(--dauer-ruhig) var(--uebergang);
}
.schnellaktion:hover {
  box-shadow: var(--schatten-md); transform: translateY(-3px);
  border-color: var(--blau-hell); color: var(--schrift);
}
.schnellaktion-symbol {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: 0 0 40px;
  border-radius: var(--radius-xs);
  background: var(--blau-20); color: var(--blau-dunkel);
}
.schnellaktion-text { flex: 1 1 auto; line-height: 1.3; }
.schnellaktion-pfeil {
  width: 18px; height: 18px; flex: 0 0 18px; color: var(--schrift-leise);
  transition: transform var(--dauer-schnell) var(--uebergang);
}
.schnellaktion:hover .schnellaktion-pfeil { transform: translateX(3px); color: var(--blau); }

/* Genau eine hervorgehoben — wo alles betont ist, ist nichts betont. */
.schnellaktion-haupt {
  background: var(--blau); border-color: var(--blau); color: var(--schrift-auf-farbe);
}
.schnellaktion-haupt:hover { background: var(--blau-dunkel); border-color: var(--blau-dunkel); color: var(--schrift-auf-farbe); }
.schnellaktion-haupt .schnellaktion-symbol { background: var(--schleier-stark); color: var(--schrift-auf-farbe); }
.schnellaktion-haupt .schnellaktion-pfeil { color: var(--schrift-auf-farbe); }

/* ---- Leerer Zustand ----------------------------------------------------- */

.leerstelle {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--raum-3); padding: var(--raum-7) var(--raum-4);
  background: var(--grund-2); border: 1px dashed var(--linie);
  border-radius: var(--radius);
}
.leerstelle-symbol {
  display: inline-flex; align-items: center; justify-content: center;
  width: 60px; height: 60px; border-radius: 50%;
  background: var(--karte); color: var(--blau-hell);
  border: 1px solid var(--linie);
}
.leerstelle-symbol .symbol { width: 28px; height: 28px; }
.leerstelle-titel { margin: 0; font-size: var(--titel-3); color: var(--schrift); }
.leerstelle-text { margin: 0; max-width: 46ch; color: var(--schrift-leise); }

/* ---- Auswahl als Karten ------------------------------------------------- */

.wahlkarten { display: grid; gap: var(--raum-3); margin-bottom: var(--raum-4); }
@media (min-width: 40rem) {
  .wahlkarten-zwei { grid-template-columns: 1fr 1fr; }
}

.wahlkarte {
  display: block; cursor: pointer;
  border: 1.5px solid var(--linie); border-radius: var(--radius-s);
  background: var(--karte); padding: var(--raum-4);
  transition: border-color var(--dauer-schnell) var(--uebergang),
              background var(--dauer-schnell) var(--uebergang),
              box-shadow var(--dauer-schnell) var(--uebergang);
}
.wahlkarte:hover { border-color: var(--blau-hell); }

/* Die gewaehlte Karte traegt Farbe UND Rand — die Farbe allein waere fuer
   einen Teil der Leserschaft kein Unterschied, und der Knopf darin ist bei
   einem grossen Bildschirm weit weg vom Blick. */
.wahlkarte:has(input:checked) {
  border-color: var(--blau); background: var(--blau-20);
  box-shadow: var(--fokusring);
}
.wahlkarte:has(input:focus-visible) { outline: 2px solid var(--blau); outline-offset: 2px; }

.wahlkarte input { margin: 0 0 var(--raum-2); }
.wahlkarte-inhalt { display: flex; gap: var(--raum-3); align-items: flex-start; }
.wahlkarte-symbol {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; flex: 0 0 40px; border-radius: var(--radius-xs);
  background: var(--blau-20); color: var(--blau-dunkel);
}
.wahlkarte-text { display: block; }
.wahlkarte-text strong { display: block; color: var(--schrift); margin-bottom: .15rem; }
.wahlkarte-text span { color: var(--schrift-weich); font-size: var(--schrift-s); line-height: 1.45; }

/* ---- Dateiauswahl ------------------------------------------------------- */

/* Der rohe Systemknopf („Datei auswählen — Keine ausgewählt") stand mitten im
   Markendesign und war die Stelle, an der eine sorgfaeltig gebaute Seite billig
   wirkte.

   **Das native Element bleibt, nur sein Knopf wird angezogen.** Der uebliche
   Weg — Feld verstecken, `label` als Knopf — kostet den Dateinamen: Ohne Skript
   sieht dann niemand mehr, was ausgewaehlt ist. `::file-selector-button` macht
   dasselbe ohne diesen Preis. */
input[type="file"] {
  font: inherit; color: var(--schrift-weich); font-size: var(--schrift-s);
  max-width: 100%;
}
input[type="file"]::file-selector-button {
  font: inherit; font-weight: 700; font-size: var(--schrift-s);
  margin-right: var(--raum-3); padding: .5rem .9rem;
  border: 1px solid var(--blau); border-radius: var(--radius-xs);
  background: transparent; color: var(--blau-dunkel);
  cursor: pointer;
  transition: background var(--dauer-schnell) var(--uebergang);
}
input[type="file"]::file-selector-button:hover { background: var(--blau-20); }

/* ---- Kopf der Profilseite ----------------------------------------------- */

.profilkopf {
  display: flex; gap: var(--raum-5); flex-wrap: wrap;
  align-items: flex-start; justify-content: space-between;
}
.profilkopf-person { display: flex; gap: var(--raum-4); align-items: center; }
.profilkopf-person h1 { margin: 0 0 .1rem; font-size: var(--titel-2); }
.profilkopf-name { margin: 0; font-size: var(--schrift-l); color: var(--schrift-weich); font-weight: 600; }
.profilkopf-stand { display: flex; flex-direction: column; gap: var(--raum-3); align-items: flex-start; }

.avatar-gross { width: 76px; height: 76px; font-size: 1.7rem; flex: 0 0 76px; }
.avatar-bild { object-fit: cover; }

/* ---- Kopf einer Flaeche zu genau einem Datensatz -------------------------
   Die schlanke Schwester des Helden: Initialen, Name, Kennung, Zustandsmarken
   — und rechts die eine Hauptaktion.

   **Warum keine Farbflaeche.** Der grosse Held sagt „Du bist angekommen" und
   bringt eigene Knopf- und Schriftfarben mit; die Zustandsmarken waeren darin
   nicht lesbar. Hier zaehlt nicht der Ort, sondern die Person. */
.held-datensatz {
  display: flex; gap: var(--raum-4); flex-wrap: wrap;
  align-items: flex-start; justify-content: space-between;
  padding: var(--raum-5) 0 var(--raum-4);
  border-bottom: 1px solid var(--linie);
  margin-bottom: var(--raum-5);
}
.held-datensatz > .avatar { order: -1; }
/* Text und Bild bilden eine Einheit; die Aktion darf nach rechts abwandern. */
.held-datensatz-text { flex: 1 1 22rem; min-width: 0; }
.held-datensatz-titel { margin: 0 0 .15rem; font-size: var(--titel-2); }
.held-datensatz-kennung { margin: 0; }
.held-datensatz-lead { margin: .35rem 0 0; color: var(--schrift-weich); }
.held-datensatz-marken { margin: var(--raum-3) 0 0; }
.held-datensatz-aktion { display: flex; gap: var(--raum-3); flex-wrap: wrap; }

/* Auf schmalem Schirm rutscht die Aktion unter den Namen statt daneben — ein
   Knopf, der halb aus der Zeile ragt, ist schlechter als einer darunter. */
@media (max-width: 40rem) {
  .held-datensatz { gap: var(--raum-3); }
  .held-datensatz-aktion { width: 100%; }
}

/* ---- Gefahrenzone ------------------------------------------------------- */

/* Der Bereich für das, was sich nicht zurücknehmen lässt: Konto löschen,
   Zugang sperren, Daten endgültig entfernen.

   **Abgesetzt statt versteckt.** Vorher stand der Weg zur Kontolöschung als
   gewöhnliche Karte zwischen Profilbild und Nachrichten — optisch gleichrangig
   mit „E-Mail-Adresse ändern". Beides ist falsch: Wegsperren macht es zur
   Schnitzeljagd, gleichrangig zeigen lädt zum Verklicken ein.

   Der rote Rand steht links und nicht rundherum: Ein rot umrahmter Kasten liest
   sich wie ein Fehler, und hier ist nichts kaputt. */
.gefahrenzone {
  border-left: 4px solid var(--fehler);
  background: var(--grund-2);
  margin-top: var(--raum-7);
}
.gefahrenzone h2 { color: var(--fehler); font-size: var(--titel-3); }

/* ---- Musterseite -------------------------------------------------------- */

.muster-abschnitt { margin-bottom: var(--raum-7); }
.muster-abschnitt > h2 {
  padding-bottom: var(--raum-2); margin-bottom: var(--raum-4);
  border-bottom: 2px solid var(--linie);
}
.muster-reihe { display: flex; gap: var(--raum-3); flex-wrap: wrap; align-items: center; margin-bottom: var(--raum-4); }
.muster-notiz {
  color: var(--schrift-leise); font-size: var(--schrift-s);
  max-width: var(--lesebreite); margin: 0 0 var(--raum-4);
}
.muster-felder { display: grid; gap: var(--raum-4); grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.muster-farbe { display: flex; align-items: center; gap: var(--raum-2); font-size: var(--schrift-xs); }
.muster-farbe-feld {
  width: 46px; height: 46px; flex: 0 0 46px;
  border-radius: var(--radius-xs); border: 1px solid var(--linie);
}
.muster-farbe-wort { color: var(--schrift-leise); line-height: 1.35; }

.probe-blau { background: var(--blau); }
.probe-blau-dunkel { background: var(--blau-dunkel); }
.probe-blau-hell { background: var(--blau-hell); }
.probe-blau-20 { background: var(--blau-20); }
.probe-akzent { background: var(--akzent); }
.probe-gefahr-flaeche { background: var(--gefahr-flaeche); }
.probe-ok { background: var(--ok); }
.probe-warnung { background: var(--warnung); }
.probe-fehler { background: var(--fehler); }

.muster-symbol {
  display: inline-flex; flex-direction: column; align-items: center; gap: .3rem;
  width: 5.5rem; color: var(--schrift-weich); font-size: var(--schrift-xs);
}
.muster-symbol .symbol { width: 24px; height: 24px; }
.muster-symbol code { font-size: .68rem; color: var(--schrift-leise); }

/* ============================================================
   Aufgeräumte Arbeitsflächen (2.21.0)
   ============================================================

   Vorbild ist die Kontenliste des Vorgängerportals: Suchzeile direkt über
   der Tabelle, keine Zwischenüberschrift, enge Zeilen, Kennung und Name
   als Verweis, Rollen farbig nach Familie. Die Regeln liegen hier am Ende,
   damit sie gegen die allgemeinen Vorgaben oben gewinnen — ohne sie
   umzuschreiben. Sie gelten für JEDE Fläche, die das Listengerüst benutzt,
   Module eingeschlossen: Genau das ist der Grund für ein gemeinsames Gerüst. */

/* Weniger Luft über und um den Inhalt. Der Titel steht nah an der Krume,
   die Karte nah am Titel. */
.inhalt { padding-top: var(--raum-3); }
.krume { margin-bottom: .45rem; }
.inhalt > h1:first-of-type { margin-top: 0; margin-bottom: .55rem; }
h1 { font-size: clamp(1.7rem, 1.3rem + 1.4vw, 2.3rem); }
/* Waagrecht 1rem, wie Hinweiskasten und Hilfe-Block — sonst passt der
   Kastenpolster von `--kastenbreite` nicht mehr zu allen dreien gleich. */
.meldung { padding: .6rem 1rem; margin-bottom: .8rem; }

/* Die Filterzeile: eine Leiste, kein Kasten im Kasten. */
.board-kopf { margin-bottom: .6rem; gap: .4rem; }
.filter-offen {
  flex: 1 1 100%;
  margin-top: 0; padding: 0;
  background: transparent; border: 0; box-shadow: none;
}
.filter-offen .filterreihe { align-items: center; gap: .45rem; }
.filter-offen .board-suche { flex: 1 1 18rem; min-width: 12rem; max-width: 26rem; }
.filter-offen .filter-export { margin-left: auto; }

/* Karte und Tabelle: enger, ohne doppelten Rahmen. */
.inhalt:has(table.arbeitsliste) .karte { padding: var(--raum-4) var(--raum-4) .6rem; }
.arbeitsliste-kopf { margin-bottom: .45rem; min-height: 1.6rem; }
.arbeitsliste { border: 0; border-radius: 0; background: transparent; }
.arbeitsliste th, .arbeitsliste td { padding: .5rem .6rem; vertical-align: middle; }
.arbeitsliste thead th {
  background: transparent; border-bottom: 1px solid var(--linie);
  text-transform: uppercase; letter-spacing: .06em; font-size: .74rem;
}

/* Was einen Datensatz benennt, bricht nicht um: „BTV-" in der einen und die
   Nummer in der nächsten Zeile ist keine Kennung mehr, sondern ein Rätsel. */
.arbeitsliste td:has(> a.zeilenziel),
.arbeitsliste td[data-spalte="kennung"],
.arbeitsliste td[data-spalte="nummer"] { white-space: nowrap; }
.arbeitsliste td:has(> .marke:only-child) { white-space: nowrap; }
.arbeitsliste .zeilenziel:hover { text-decoration: underline; }

/* Die Ankreuzspalte ist schmal — sie trägt ein Kästchen, keinen Text. */
.arbeitsliste th[data-spalte="auswahl"],
.arbeitsliste td[data-spalte="auswahl"] { width: 1.6rem; padding-right: 0; }

.arbeitsliste .zeilenaktionen { gap: .3rem; }

/* Marken etwas leichter, damit acht davon in einer Zeile nicht schreien. */
.arbeitsliste .marke { font-size: .76rem; padding: .12rem .5rem; }

/* ---- Rollenfarben ------------------------------------------------------
   Je Rollenfamilie eine Farbe, an jeder Stelle dieselbe (App\Support\
   Rollenfarbe). Die Farbe ist ein Zusatz: Der Name steht immer daneben. */
.marke-rolle { border: 1px solid transparent; }
.marke-rolle-system { background: var(--rolle-system-grund); color: var(--rolle-system); border-color: var(--rolle-system-rand); }
.marke-rolle-admin { background: var(--rolle-admin-grund); color: var(--rolle-admin); border-color: var(--rolle-admin-rand); }
.marke-rolle-intern { background: var(--blau-20); color: var(--blau-dunkel); border-color: var(--rolle-intern-rand); }
.marke-rolle-referent { background: var(--rolle-referent-grund); color: var(--rolle-referent); border-color: var(--rolle-referent-rand); }
.marke-rolle-ehrenamt { background: var(--ok-grund); color: var(--ok); border-color: var(--rolle-ehrenamt-rand); }
.marke-rolle-digi { background: var(--rolle-digi-grund); color: var(--rolle-digi); border-color: var(--rolle-digi-rand); }
.marke-rolle-akkreditierung { background: var(--rolle-akkreditierung-grund); color: var(--rolle-akkreditierung); border-color: var(--rolle-akkreditierung-rand); }
.marke-rolle-newsletter { background: var(--rolle-newsletter-grund); color: var(--rolle-newsletter); border-color: var(--rolle-newsletter-rand); }
.marke-rolle-sonstige { background: var(--linie-weich); color: var(--schrift-weich); }
/* Angefragt, nicht bestätigt: dieselbe Familie, aber nur umrandet — die
   Rolle wirkt noch nicht, und die Marke sagt es auch ohne das Fragezeichen.
   Das Dunkelschema kommt aus den Tokens, nicht von hier. */
.marke-rolle.marke-offen { background: transparent; border-style: dashed; }

/* ---- Systemvermerk im Nachrichtenfaden ------------------------------------
   Ein Vermerk des Portals selbst (z. B. „nur per E-Mail hinaus — kein
   Portalkonto") ist keine Wortmeldung im Faden. Ungezeichnet sah er aus wie
   eine Nachricht ohne Autorenname — leise, aber ununterscheidbar von einem
   echten Beitrag. Die Farbe bleibt zurueckhaltend (Tokens, kein eigener Ton):
   ein Hinweis, keine Warnung. */
.zeitleiste > li.nachricht-system { border-left-style: dotted; }
.zeitleiste > li.nachricht-system::before { background: var(--linie-weich); }
.zeitleiste > li.nachricht-system .zeitleiste-kopf { color: var(--schrift-leise); }
.zeitleiste > li.nachricht-system strong { color: var(--schrift-weich); font-weight: 600; }
.zeitleiste > li.nachricht-system .fliesstext { color: var(--schrift-leise); }
.nachricht-system-symbol { width: 1rem; height: 1rem; color: var(--schrift-leise); }

/* ---- Kästen nebeneinander ---------------------------------------------------
   Ein Abschnitt einer Formularfläche kann über `abschnitt_spalte` sagen, dass
   er links oder rechts steht (`App\Verwaltung\Formularflaeche::felder()`).
   Der Anlass: Angaben und Nachweis gehören zusammen gelesen, standen
   untereinander aber zwei Bildschirmhöhen auseinander — wer über einen Antrag
   entschied, sah nie beides gleichzeitig.

   Die Einordnung macht das Raster und nicht die Vorlage: Mehrere Kästen
   derselben Spalte stapeln sich dadurch von selbst untereinander (Nachweis,
   darunter Zustimmungen), und auf einem schmalen Schirm fällt alles in eine
   Spalte zurück, ohne dass irgendwo eine zweite Reihenfolge gepflegt wird. */
.karten-zeile {
    display: grid;
    /* `minmax(0, 1fr)`: sonst weitet eine breite Tabelle im Kasten die Spalte
       und damit die Seite (siehe `.rumpf`). */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
    margin: 0 0 1rem;
}

.karte-block {
    border: 1px solid var(--linie);
    border-radius: var(--radius-s);
    padding: .9rem 1rem;
    /* Ohne diese Zeile sprengt ein langer Dateiname die Rasterspalte. */
    min-width: 0;
}

.karte-block-links { grid-column: 1; }
.karte-block-rechts { grid-column: 2; }
.karte-block > h2 { margin-top: 0; }
.karte-block > :last-child { margin-bottom: 0; }

@media (max-width: 60rem) {
    .karten-zeile { grid-template-columns: 1fr; }
    .karte-block-links,
    .karte-block-rechts { grid-column: 1; }
}

/* ---- Nachweise mit Vorschau -------------------------------------------------
   Dateiname als Verweis, darunter Typ und Grösse — und die Vorschau in einem
   Klappbereich. Zugeklappt, weil ein Ausweisscan nicht schon dann offen
   dastehen soll, wenn jemand die Fläche nur aufruft. */
.nachweisliste { list-style: none; margin: .5rem 0 0; padding: 0; }
.nachweisliste > li { margin: 0 0 .9rem; }
.nachweisliste > li:last-child { margin-bottom: 0; }
.nachweis-meta { display: block; font-size: .88rem; color: var(--schrift-leise); margin: .3rem 0; }

.nachweisbild {
    display: block;
    max-width: 100%;
    height: auto;
    margin: .5rem 0 1rem;
    border: 1px solid var(--linie);
    border-radius: var(--radius-s);
    background: var(--karte);
}

/* Feste Höhe, weil ein PDF-Rahmen von sich aus keine hat und sonst auf ein
   paar Pixel zusammenfällt. Scrollen tut der Betrachter darin selbst. */
.nachweisrahmen {
    display: block;
    width: 100%;
    height: 28rem;
    margin: .5rem 0 1rem;
    border: 1px solid var(--linie);
    border-radius: var(--radius-s);
    background: var(--karte);
}

/* Der Klappteil eines Chronikeintrags (z. B. der Betreff einer Mail): leise,
   damit die Liste ihre Aussage behält — was wann geschah. */
.chronik-klapp > summary {
    cursor: pointer;
    font-size: .88rem;
    color: var(--schrift-leise);
}

.chronik-klapp > summary:focus-visible { outline: 2px solid var(--blau); outline-offset: 2px; }

/* ---- Textverweis mit Pfeil (vierte Knopfsorte) -------------------------- */

/* Die vierte Sorte neben gefuellt (Aktion), rot gefuellt (Gefahr) und umrandet
   (Navigation zu einer anderen Flaeche): der Verweis **innerhalb** desselben
   Datensatzes — ein anderer Ausschnitt derselben Person, derselben Akte.
   Grund: Auf dem Konto-Datenblatt standen vierzehn optisch identische Knoepfe
   nebeneinander. Wo alles gleich aussieht, sieht man nichts; ein Ausschnitt
   derselben Akte ist aber kein Bedienelement, sondern ein Verweis, und der
   traegt keine Flaeche und keinen Rahmen, sondern einen Pfeil. */
.verweis-pfeil {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  /* Derselbe senkrechte Innenabstand wie `.knopf-klein`, damit ein Verweis in
     einer Reihe mit Knoepfen auf derselben Grundlinie sitzt. */
  padding: .28rem 0;
  color: var(--blau-dunkel);
  font-size: .8rem;
  font-weight: 600;
  text-decoration: none;
  background: none;
  border: 0;
  cursor: pointer;
}

.verweis-pfeil:hover { text-decoration: underline; }
.verweis-pfeil:focus-visible { outline: 2px solid var(--blau); outline-offset: 2px; }

/* Der Pfeil laeuft mit der Schrift mit (1em) statt auf den 22px der
   Symbolleiste zu bestehen — sonst ueberragt er den Text, dem er folgt. */
.verweis-pfeil .symbol {
  width: 1em;
  height: 1em;
  flex: 0 0 1em;
}

/* Beim Zeigen ruecken Pfeil und Text auseinander: die Bewegung sagt „geht
   weiter", ohne dass eine zweite Farbe dafuer noetig waere. */
.verweis-pfeil:hover .symbol { transform: translateX(2px); }
.verweis-pfeil .symbol { transition: transform var(--dauer-schnell) var(--uebergang); }

@media (prefers-reduced-motion: reduce) {
  .verweis-pfeil .symbol { transition: none; }
  .verweis-pfeil:hover .symbol { transform: none; }
}

/* Eine Probe auf der Musterseite: das Element und darunter, was es bedeutet.
   Steht am Dateiende bei der vierten Knopfsorte, weil es dafuer gebaut wurde —
   vier Sorten nebeneinander ohne Beschriftung waeren nur vier Knoepfe. */
.muster-probe {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--raum-1);
}

.muster-probe > .muster-notiz { margin: 0; }

/* ===================================================================
   Fussnoten und Legende (AP-4)
   ===================================================================

   Die Herkunft eines Wertes stand frueher als Klammertext hinter dem Wert.
   Bei zwoelf Angaben wuchs jede Zeile um vier Woerter, und die Erklaerung war
   praesenter als das Erklaerte. Jetzt: eine Ziffer am Wert, die Erklaerung
   einmal am Seitenende.

   Die Ziffer ist bewusst **klein und blass, aber nicht winzig**: Sie muss
   anklickbar bleiben. Ein 8-Pixel-Ziel trifft niemand mit zittriger Hand —
   deshalb steht Innenabstand um die Ziffer, nicht nur Schriftgroesse. */
.fussnote {
  font-size: var(--schrift-xs);
  line-height: 1;
  margin-left: 1px;
}

.fussnote a {
  color: var(--schrift-leise);
  text-decoration: none;
  padding: 0 var(--raum-1);
  border-radius: var(--radius-xs);
}

/* Unterstrichen erst bei Zeigerkontakt: Eine dauerhaft unterstrichene Ziffer
   sieht wie ein Tippfehler im Wert aus. Farbe allein traegt die Auskunft
   trotzdem nicht — die Ziffer selbst ist das Merkmal. */
.fussnote a:hover,
.fussnote a:focus-visible {
  color: var(--blau);
  text-decoration: underline;
}

/* Die angesprungene Erklaerung hebt sich kurz hervor. Ohne das landet man
   irgendwo in einer Liste und sucht die Zeile, wegen der man gesprungen ist. */
.fussnoten-liste li:target {
  background: var(--blau-20);
  border-radius: var(--radius-xs);
}

.fussnoten {
  margin-top: var(--raum-6);
  padding-top: var(--raum-4);
  border-top: 1px solid var(--linie);
}

.fussnoten-titel {
  font-size: var(--schrift-xs);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--schrift-leise);
  margin: 0 0 var(--raum-2);
}

/* Kein Aufzaehlungszeichen: Die Ziffer IST die Marke der Zeile. Ein Punkt
   davor waere ein zweites Zeichen fuer dieselbe Aufgabe. */
.fussnoten-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--raum-2);
  font-size: .9rem;
  color: var(--schrift-weich);
}

.fussnoten-liste li {
  display: grid;
  grid-template-columns: 1.4rem 1fr;
  align-items: baseline;
  padding: var(--raum-1) var(--raum-2) var(--raum-1) 0;
}

.fussnote-ziffer {
  font-size: var(--schrift-xs);
  color: var(--schrift-leise);
  font-variant-numeric: tabular-nums;
}

.fussnote-zurueck {
  margin-left: var(--raum-2);
  font-size: var(--schrift-xs);
  color: var(--schrift-leise);
  white-space: nowrap;
}

/* ---- Nachrichtentext ---------------------------------------------------
   Aufzählungen und Verweise in einer Nachricht (`TextFormat::nachricht()`).
   Eine lange Adresse bricht innerhalb des Verweises um statt die Karte zu
   sprengen; Listenpunkte stehen als Liste, nicht als Zeilenumbrüche. */
.nachricht-text p { margin: 0 0 .7rem; }
.nachricht-text p:last-child, .nachricht-text ul:last-child { margin-bottom: 0; }
.nachricht-text a, .chronik-text a { overflow-wrap: anywhere; }
.nachricht-liste { margin: 0 0 .7rem; padding-left: 1.3rem; }
.nachricht-liste li { margin: 0 0 .3rem; }
.chronik-text p { margin: 0; display: inline; }
.chronik-text .nachricht-liste { margin: .3rem 0 0; }
