/* ============================================================
   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;
  /* Die oberen Stufen sind seit 0.37.0 ein Viertel enger (Layoutrunde
     29.09.2026: „alles wirkt zu voluminös"). Sie tragen Karten, Kacheln und
     Seitenkopf — hier liegt der Platz, nicht in den kleinen Stufen. */
  --raum-5: 1.125rem;
  --raum-6: 1.5rem;
  --raum-7: 2rem;
  --raum-8: 3rem;

  /* 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;
  /* Titelstufen seit 0.37.0 auf Arbeitsoberflächen-Maß (vorher bis 3,6rem):
     Die Hierarchie trägt jetzt Gewicht und Abstand mehr als Größe — ein
     58-Pixel-Titel über einer Tabelle kostet eine Zeile Daten. */
  --titel-3: clamp(1rem, .96rem + .2vw, 1.1rem);
  --titel-2: clamp(1.18rem, 1.06rem + .45vw, 1.38rem);
  --titel-1: clamp(1.45rem, 1.2rem + 1vw, 1.9rem);
  --titel-held: clamp(1.55rem, 1.25rem + 1.2vw, 2.05rem);

  /* **Höhe aller Bedienelemente** — Felder, Knöpfe, Klappfelder, Pillen.
     44 Pixel sind die Tippfläche für den Finger (WCAG 2.5.5); mit der Maus
     reichen 36. Die Umschaltung steht unten bei `pointer: fine`, damit
     Telefon und Tablet ihre Tippfläche behalten. */
  --tipphoehe: 2.75rem;

  /* 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.

     [layout] **Seit der Testrunde 02.10. deckelt `--kastenbreite` keinen
     Kasten mehr** — fuenfmal kam die Rueckmeldung „Container zu schmal", und
     ein gruener und ein blauer Kasten auf derselben Seite endeten an zwei
     Kanten. Kaesten, Karten und Hinweisbloecke laufen jetzt so breit wie ihre
     Flaeche. Gedeckelt bleibt nur der blanke Absatz, und der grosszuegiger:
     90 statt 68 Zeichen. Das Token bleibt fuer das Nachrichtenfeld
     (`.feld-schmal`), das eine Eingabe ist und kein Kasten. */
  --lesebreite: 90ch;
  --kastenpolster: 2rem;
  --kastenbreite: calc(var(--lesebreite) + var(--kastenpolster));
  --seitenbreite: 1180px;

  /* **Die dritte Breite, und nur fuer Eingabeformulare.** Ein Eingabefeld
     ueber 1600 Pixel zwingt das Auge, zwischen Beschriftung und Feldende
     hin- und herzuspringen. Listen, Boards, Tabellen und die Startseite
     bleiben randvoll — sie bekommen diese Breite nie (`docs/KONVENTIONEN.md`,
     Abschnitt Breiten).

     [layout] **Genau die Inhaltsbreite einer Gastseite** (Seitenbreite minus
     Randabstand). Vorher 60rem: Registrierung (Karte) lief auf 1148 Pixeln,
     Newsletter und Akkreditierungsantrag (Formularflaeche) auf 960 — drei
     oeffentliche Formulare, zwei Breiten. Jetzt ist ein Formular auf einer
     Gastseite so breit wie die Seite, und hinter der Anmeldung genauso breit
     wie davor. Einzelne Felder begrenzen ihre Breitenklassen. */
  --formularbreite: calc(var(--seitenbreite) - 2 * var(--raum-4));

  --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;
}

/* **Dichte am Rechner.** Mit Maus und breitem Fenster wird das Grundmaß
   15 statt 16 Pixel — in Prozent, damit eine im Browser eingestellte
   größere Schrift weiter wirkt. Alles in `rem` zieht mit, ohne dass eine
   Regel einzeln angefasst wird. Telefon und Tablet (grober Zeiger) bleiben
   bei 16 Pixeln: darunter zoomt iOS beim Fokus in ein Feld. */
@media (pointer: fine) and (min-width: 1024px) {
  html { font-size: 93.75%; }
  :root { --tipphoehe: 2.25rem; }
}

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

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

body {
  margin: 0;
  font-family: var(--schriftfamilie);
  /* Nie unter 16px auf Touch-Geräten: Kleiner loest auf iOS beim Fokus in ein
     Feld einen Zoom aus, der die Seite verschiebt — und trifft genau die, die
     ohnehin schlecht lesen. `1rem` folgt dem Grundmaß: 16px auf Touch, 15px
     am Rechner (siehe „Dichte am Rechner"). */
  font-size: 1rem;
  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.

   [layout] Kaesten sind **so breit wie ihre Flaeche** — gruen, blau und der
   Hilfe-Block auf einer Seite enden an derselben Kante (Testrunde 02.10.,
   „alle voll"). 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 { max-width: none; }
/* Eine Karte, die als Ganzes Fliesstext ist (Merkblatt, Einstiegsseiten),
   bleibt trotzdem so breit wie ihre Nachbarn; gedeckelt werden ihre Absaetze
   (`.karte > p` weiter unten). Sonst stand die Textkarte als schmale Spalte
   neben einer randvollen Formularkarte. */
.karte.fliesstext { max-width: none; }

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: var(--seitenbreite);
  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; }
/* Der Datenschutz in Alltagssprache als zweite, leise Zeile — auf jeder
   Seite an derselben Stelle statt einmal auf der Startseite. */
.fuss-zusatz {
  max-width: var(--seitenbreite); margin: .5rem auto 0;
  font-size: var(--schrift-xs); color: var(--schrift-leise);
}

/* ---- 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. */
/* Knapper Abstand nach unten: Die Krume ist eine Ortsangabe, kein Absatz —
   jeder Pixel davor schiebt die Arbeitsflaeche nach unten. */
.krume { font-size: var(--schrift-s); color: var(--schrift-leise); margin-bottom: var(--raum-1); }
.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-4);
  margin-bottom: var(--raum-4);
}
/* 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. */
/* Kompakter seit der Runde vom 28.09.: Mindestbreite 220 statt 260 Pixel und
   der kleinere Rasterabstand, damit ohne Rollen mehr Kacheln im Blick sind.
   Farbe und Zeichen bleiben — nur das Mass ist dezenter. */
.kacheln {
  display: grid; gap: var(--raum-4);
  grid-template-columns: repeat(auto-fit, minmax(220px, 26rem));
  justify-content: start;
}
.kachel-breit { grid-column: 1 / -1; }

/* **Mein Profil wie die Kontoseite** (0.43.0): zwei gleich breite Spalten
   statt einer breiten Karte über drei schmalen — dieselbe Ordnung wie
   „Person & Kontakt" neben „Zugang & Sicherheit" unter Konten. */
.kacheln-profil { grid-template-columns: repeat(2, minmax(0, 1fr)); justify-content: stretch; align-items: start; }
.kacheln-profil > .kachel-breit { grid-column: auto; }
@media (max-width: 900px) {
  .kacheln-profil { grid-template-columns: minmax(0, 1fr); }
}

/* ---- 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: .45rem .95rem;
  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, .zeilenform select, .board-sammelaktionen 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: var(--tipphoehe);
  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, .zeilenform select, .board-sammelaktionen 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; }

/* ---- Formularflaeche ------------------------------------------------------

   Eingabeformulare laufen auf `--formularbreite`, alles andere randvoll.
   Die Klasse setzt die Vorlage des Formulargeruests (`verwaltung/formular`)
   und jedes Mitglieder-Formular um Erklaerkasten und Formular; der Held
   darueber bleibt draussen und behaelt die volle Breite.

   Die Abschnittsueberschriften eine Stufe kleiner: Im Formular sind sie
   Zwischentitel ueber vier Feldern, keine Seitentitel — in `--titel-2`
   ueberragten sie den Seitentitel des Helds, sobald der `klein` war. */
.formularflaeche { max-width: var(--formularbreite); }
.formularflaeche h2 { font-size: var(--titel-3); }

/* ---- 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: minmax(0, 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: minmax(0, 1fr) minmax(0, 1fr); }
  .feldreihe-3 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 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: var(--tipphoehe);
  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: minmax(0, 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; }
/* Paket digi (Linkzeilen): Die Knöpfe stehen nur mit Skript da
   (`data-nur-mit-js hidden`); `display: flex` oben schlüge sonst `hidden`.
   Oben ausgerichtet statt unten: Mit einer Fehlermeldung unter der Adresse
   rutschten bei `flex-end` Beschriftung und Knöpfe nach unten weg. Der
   Abstand der Knöpfe entspricht Beschriftungszeile plus halbem
   Höhenunterschied zum Eingabefeld. */
.linkzeile { align-items: flex-start; }
.linkzeile-pfeile { margin: 2.3rem 0 1.1rem; }
/* Schmal bricht die Zeile um, die Knöpfe stehen unter der Adresse. */
@media (max-width: 40rem) { .linkzeile-pfeile { margin-top: 0; } }
.linkzeile-pfeile[hidden] { display: none; }

.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);
  /* Dieselbe leise Toenung wie die zweite Reiterebene (Punkt 6.3): Der
     Erklaerkasten ist eine Flaeche des Portals, nicht eine des Moduls. */
  background: var(--kachel-blau);
  padding: .75rem 1rem;
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  margin-bottom: 1rem;
  font-size: .95rem;
  /* **So breit wie seine Flaeche.** Vorher auf `--kastenbreite` gedeckelt:
     Ueber einer randvollen Liste endete der Erklaerkasten nach 70 Zeichen,
     und rechts daneben blieb die halbe Zeile leer — er sah aus wie ein
     Fremdkoerper. In einem schmalen Formular ist er jetzt so breit wie das
     Formular, ueber einer Liste so breit wie die Liste. Die Zeilenlaenge
     begrenzen die Absaetze darin (unten). */
  max-width: none;
}
/* Der Erklaerungstext laeuft so breit wie der Block — Entscheidung 28.09.:
   volle Breite kostet weniger Hoehe als eine halbe Spalte neben Leere. */
.hilfe-block > p { max-width: none; }

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

.leise { color: var(--schrift-leise); }
.klein { font-size: .9rem; }
.reihe { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
/* [layout] Eine Auswahl neben ihrem Knopf („Übernehmen") bekommt Platz: Die
   durchsuchbare Fassung (`.suchauswahl`) schrumpfte in der Reihe auf die Breite
   ihres Eingabefelds, und der Name einer Veranstaltung (QR-Code der
   Akkreditierung) war abgeschnitten. Jetzt wächst sie mit der Zeile, der Knopf
   bricht auf schmalen Geräten darunter. */
.reihe > .suchauswahl, .reihe > select { flex: 1 1 24rem; min-width: 0; max-width: 60rem; }
.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; }
/* Die Bildmarke bekommt ihre Flaeche aus der Marke: auf der hellen Leiste
   keine, auf der dunklen eine weisse — das Logo steht laut CD nur auf Weiss,
   und auf Dunkel war es nicht zu lesen. */
.portalmarke-logo {
  display: block; height: 40px; width: auto;
  background: var(--logo-flaeche); padding: var(--logo-polster);
  border-radius: var(--radius-xs); box-sizing: content-box;
}
.portalmarke-titel {
  font-family: var(--schriftfamilie-titel);
  font-weight: 700; color: var(--wortmarke); 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: 260px 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;
  /* Leise blaue Flaeche statt Weiss (Punkt 6.3 des Aenderungskatalogs
     28.09.): Die Leiste ist die groesste ruhige Flaeche neben dem Inhalt —
     traegt sie den Grundton, wirkt die Seite blau-weiss, ohne dass ein
     einziger Knopf lauter wird. Wert in der Marke (`--leiste`). */
  background: var(--leiste); border-right: 1px solid var(--linie);
  padding: 1rem .7rem;
}
.leiste-klapp > summary { display: none; }
.leiste-klapp > summary::-webkit-details-marker { display: none; }

/* **Die Leiste laesst sich am Rechner einklappen.** Ausgeklappt ist der
   Standard; eingeklappt (`data-leiste="zu"` am `<html>`, gesetzt vor dem
   ersten Anstrich) bleibt ein schmaler Streifen mit dem Knopf, der Inhalt
   bekommt die Breite. Der Knopf erscheint nur mit Skript (`.js-an`) — ohne
   waere er tot — und nur oberhalb von 900 Pixeln: Auf dem Telefon klappt
   die Liste ueber „Bereiche". */
.leiste-schalter { display: none; }
@media (min-width: 901px) {
  .js-an .leiste-schalter {
    display: flex; align-items: center; gap: .6rem;
    width: 100%; min-height: var(--tipphoehe);
    /* Unten in der Leiste, und dort bleibt er: Ist die Bereichsliste
       laenger als das Fenster, rollt sie hinter dem Knopf durch. */
    padding: .3rem .6rem; margin-top: auto;
    position: sticky; bottom: 0;
    border: 0; border-radius: var(--radius-xs); background: var(--leiste);
    color: var(--schrift-weich); font: inherit; font-size: .8rem; font-weight: 600;
    cursor: pointer; text-align: left;
  }
  .js-an .leiste-schalter:hover { background: var(--blau-20); color: var(--blau-dunkel); }
  .js-an .seitenleiste { display: flex; flex-direction: column; }
  .leiste-schalter .symbol { width: 19px; height: 19px; flex: 0 0 19px; transform: rotate(90deg); }

  [data-leiste="zu"] .huelle-arbeitsflaeche .rumpf-mit-leiste { grid-template-columns: 3.25rem minmax(0, 1fr); }
  [data-leiste="zu"] .seitenleiste { padding: 1rem .35rem; overflow: hidden; }
  [data-leiste="zu"] .leiste-klapp,
  [data-leiste="zu"] .leiste-schalter > span { display: none; }
  [data-leiste="zu"] .leiste-schalter { justify-content: center; padding: .3rem 0; }
  [data-leiste="zu"] .leiste-schalter .symbol { transform: rotate(-90deg); }
}

.seitennav { display: flex; flex-direction: column; gap: .12rem; }
.navzeile {
  display: flex; align-items: center; gap: .6rem;
  padding: .38rem .6rem; border-radius: var(--radius-xs);
  color: var(--schrift-weich); text-decoration: none;
  font-weight: 600; font-size: .88rem;
  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: .84rem; padding: .28rem .55rem; }

/* Die dritte Ebene: ein Knoten („Sprints") als `<details>` unter einer
   Gruppe. Der Kopf sieht aus wie ein Unterpunkt und traegt den Pfeil; die
   Blaetter darunter ruecken eine Stufe weiter ein und werden eine Spur
   leiser — drei Ebenen muessen sich ohne Linien unterscheiden lassen. */
.navknoten > summary { list-style: none; }
.navknoten > summary::-webkit-details-marker { display: none; }
.navknoten[open] > summary .navgruppe-pfeil { transform: rotate(180deg); }
.navunter-tief { padding-left: .8rem; }
.navzeile-tief { font-size: .85rem; padding: .35rem .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; }

/* [layout] `flex-wrap` und `min-width: 0`: Mit zwei öffentlichen Modulen
   („Medienakkreditierung", „Newsletter") war die Leiste breiter als ein
   Telefon, und „Anmelden" ragte bei 400 Pixeln über den rechten Rand — die
   ganze Seite ließ sich waagrecht verschieben. Jetzt bricht die Leiste um,
   „Anmelden" bleibt rechts. */
.gast-nav {
  display: flex; align-items: center; gap: .5rem 1rem; margin-left: auto;
  flex-wrap: wrap; justify-content: flex-end; min-width: 0; max-width: 100%;
}
.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; }

  /* **Der Knopf bleibt, wo er ist** (0.40.0). Aufgeklappt nahm das
     Klappelement die ganze Breite und brach unter das Logo um — der Knopf
     sprang von rechts nach links unten. Jetzt hat er einen festen Platz oben
     rechts in der Kopfleiste, offen wie zu, und die Liste klappt darunter
     über die volle Breite auf. */
  .kopfleiste { position: relative; min-height: calc(44px + 1rem); }
  .kopf-klapp > summary { position: absolute; top: .5rem; right: .9rem; }
  .kopf-klapp[open] { flex: 1 1 100%; padding-top: calc(44px + .5rem); margin-top: calc(-44px - .5rem); }
  .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: minmax(0, 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);
  }

  /* [layout] Waagrecht `--raum-4`, nicht .9rem: Der Seitenkopf (`.held`,
     `.held-datensatz`) zieht sich auf schmalen Geräten um genau `--raum-4`
     an den Rand. Mit .9rem Innenabstand ragte er auf jeder angemeldeten
     Seite 1,6 Pixel über den rechten Rand, und die Seite ließ sich waagrecht
     verschieben. */
  .huelle-arbeitsflaeche .inhalt { padding: 1.2rem var(--raum-4) 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); }

/* Leise Flaeche, farbiges Zeichen: Die Farbe sitzt im Symbol und im Kuerzel,
   nicht in einem gesaettigten Block. Fuenf Bloecke nebeneinander schrien um
   die Wette; fuer die Wiedererkennung reicht ein getoentes Feld. */
.kachel-kopf {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  min-height: 84px;
  background: var(--kachel-grau);
  color: var(--kachel-grau-zeichen);
  border-bottom: 1px solid var(--linie-weich);
}
.kachel-blau { background: var(--kachel-blau); color: var(--kachel-blau-zeichen); }
.kachel-gruen { background: var(--kachel-gruen); color: var(--kachel-gruen-zeichen); }
.kachel-violett { background: var(--kachel-violett); color: var(--kachel-violett-zeichen); }
.kachel-rot { background: var(--kachel-rot); color: var(--kachel-rot-zeichen); }
.kachel-grau { background: var(--kachel-grau); color: var(--kachel-grau-zeichen); }

.kachel-symbol { width: 34px; height: 34px; 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: 1.7rem; font-weight: 800; letter-spacing: .04em;
}

/* ---- Startseite: Steht an + Bereiche (0.38.0) ---------------------------

   Zwei Stufen. Oben nur, was Handlungsbedarf meldet (Ton warnung/fehler),
   als Zeilen mit Wert, Name und Weg. Darunter je Modul eine gleich hohe
   Kachel im Raster — gleiche Kanten, gleiche Zeilen, die Wege unten
   bündig. Die erste Fassung stapelte ungleich hohe Karten in Spalten, und
   der Blick sprang zwischen ihnen. */
.uebersicht-titel {
  font-family: inherit; font-size: var(--schrift-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--schrift-leise); margin: 0 0 var(--raum-3);
}

/* [layout] **Jede Stufe beginnt mit einer Linie** (Testrunde 02.10.): „Steht
   an" und „Bereiche" liefen ohne Grenze ineinander. Die Überschrift zieht
   eine Linie in Markenblau bis zum rechten Rand, und zwischen den Stufen
   steht mehr Luft — getrennt durch Linie **und** Abstand, nicht durch
   Farbe allein. Reines CSS: Die Linie ist Zier und kein Inhalt. */
.uebersicht-titel { display: flex; align-items: center; gap: var(--raum-3); }
.uebersicht-titel::after {
  content: ""; flex: 1 1 auto; height: 2px;
  background: var(--blau-20); border-radius: 1px;
}

.anstehend { margin-bottom: var(--raum-7); }
.anstehend-leer {
  margin: 0; padding: var(--raum-3) var(--raum-4);
  background: var(--karte); border: 1px solid var(--linie); border-radius: var(--radius);
  color: var(--schrift-weich);
}
.anstehend-liste {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--raum-2);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr));
}
.anstehend-eintrag {
  display: flex; align-items: center; gap: var(--raum-3); height: 100%;
  padding: var(--raum-2) var(--raum-3);
  background: var(--karte); border: 1px solid var(--linie); border-radius: var(--radius-s);
  /* Der Ton als Kante links — zusätzlich zur Farbe des Werts, damit er
     nicht an der Farbe allein hängt (WCAG 1.4.1: der Name sagt es ohnehin). */
  border-left: 4px solid var(--warnung);
  color: inherit; text-decoration: none;
}
.anstehend-fehler { border-left-color: var(--fehler); }
a.anstehend-eintrag:hover { background: var(--grund-2); }
.anstehend-wert {
  flex: 0 0 auto; min-width: 2.5rem; text-align: center;
  font-family: var(--schriftfamilie-titel); font-weight: 800; font-size: 1.25rem;
  font-variant-numeric: tabular-nums; color: var(--warnung); white-space: nowrap;
}
.anstehend-fehler .anstehend-wert { color: var(--fehler); }
/* Ein Datum ist eine Auskunft, keine Menge — kleiner, damit es die Zeile
   nicht breiter macht als eine Zahl. */
.anstehend-wert-lang { font-family: inherit; font-size: var(--schrift-s); font-weight: 700; }
.anstehend-text { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.anstehend-name { font-weight: 700; font-size: var(--schrift-s); }
.anstehend-hinweis { color: var(--schrift-leise); font-size: var(--schrift-xs); }
.anstehend-weg { flex: 0 0 auto; color: var(--blau-dunkel); font-weight: 700; font-size: var(--schrift-xs); white-space: nowrap; }

.modulraster {
  display: grid; gap: var(--raum-3); margin-bottom: var(--raum-4);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
}
.modulkachel {
  display: flex; flex-direction: column;
  background: var(--karte); border: 1px solid var(--linie);
  border-radius: var(--radius); box-shadow: var(--schatten);
  overflow: hidden;
}
.modulkachel-kopf {
  display: flex; align-items: center; gap: var(--raum-3);
  padding: var(--raum-3) var(--raum-4) var(--raum-2);
}
.modulkachel-zeichen {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto; width: 2.25rem; height: 2.25rem; border-radius: var(--radius-xs);
}
.modulkachel-zeichen .kachel-symbol { width: 19px; height: 19px; }
.modulkachel-zeichen .kachel-bild { width: 2.05rem; height: 2.05rem; }
.modulkachel-zeichen .kachel-kuerzel { font-size: .8rem; }
.modulkachel-name { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; }
.modulkachel-kategorie {
  font-size: .68rem; font-weight: 700; line-height: 1.25;
  text-transform: uppercase; letter-spacing: .06em; color: var(--schrift-leise);
}
.modulkachel-titel { margin: 0; font-size: var(--titel-3); line-height: 1.2; }
.modulkachel-titel a { color: inherit; text-decoration: none; }
.modulkachel-titel a::after { content: " →"; font-weight: 400; color: var(--blau-dunkel); }
.modulkachel-titel a:hover { text-decoration: underline; }
.modulkachel-text { margin: 0; padding: 0 var(--raum-4) var(--raum-2); color: var(--schrift-leise); font-size: var(--schrift-s); }

.modulzahlen, .modulwege { list-style: none; margin: 0; padding: 0; }
.modulzahlen { border-top: 1px solid var(--linie-weich); }
.modulzahlen li + li { border-top: 1px solid var(--linie-weich); }
/* Name links, Wert rechtsbündig in Tabellenziffern: Die Werte stehen in
   jeder Kachel an derselben Kante, auch Datumsangaben. */
.modulzahl {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--raum-3);
  padding: .4rem var(--raum-4);
  color: inherit; text-decoration: none; font-size: var(--schrift-s);
}
a.modulzahl:hover { background: var(--grund-2); }
.modulzahl-name { min-width: 0; }
.modulzahl-wert {
  flex: 0 0 auto; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Nur Handlungsbedarf bekommt Farbe; „in Ordnung" tritt zurück statt grün
   zu leuchten — elf grüne Nullen sind Rauschen, keine Auskunft. */
.modulzahl-warnung .modulzahl-wert { color: var(--warnung); }
.modulzahl-fehler .modulzahl-wert { color: var(--fehler); }
.modulzahl-ok { color: var(--schrift-leise); }
.modulzahl-ok .modulzahl-wert { font-weight: 400; }

/* Die Wege sitzen unten bündig — gleich hohe Kacheln, gleiche Unterkante. */
.modulwege { margin-top: auto; border-top: 1px solid var(--linie-weich); padding: var(--raum-2) 0; }
.modulweg { display: block; padding: .3rem var(--raum-4); color: inherit; text-decoration: none; }
a.modulweg:hover { background: var(--grund-2); }
.modulweg-titel { font-weight: 700; color: var(--blau-dunkel); font-size: var(--schrift-s); }
a.modulweg .modulweg-titel::after { content: " →"; font-weight: 400; }
.modulweg-text { display: block; color: var(--schrift-leise); font-size: var(--schrift-xs); line-height: 1.4; }
.modulweg-ruhend .modulweg-titel { color: var(--schrift-weich); }

.kachel-fahne {
  position: absolute; top: .6rem; right: .6rem;
  background: var(--karte); color: var(--schrift-weich);
  border: 1px solid var(--linie);
  font-size: .7rem; font-weight: 600;
  padding: .15rem .5rem; border-radius: 999px;
}

.kachel-text { display: block; padding: var(--raum-3) var(--raum-4) var(--raum-4); }
/* Der Titel in der Schriftfarbe, nicht in Blau: Auf der Startseite stehen
   sonst fuenf blaue Ueberschriften ueber fuenf farbigen Feldern — die eine
   Farbe im Zeichen genuegt. */
.kachel-text h2 { margin: 0 0 .2rem; font-size: var(--schrift-m); color: var(--schrift); }
.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.

   Auf Breite eingepasst und unten verankert reicht das Bild in einem hohen
   Fenster nicht bis oben; darueber steht die Hintergrundfarbe. Im dunklen
   Schema stand die Bildoberkante deshalb als harte Stufe quer ueber der
   Seite. Ein Verlauf davor deckt bis zur Oberkante voll und laeuft ueber
   knapp die halbe Bildhoehe aus. Er ist so hoch wie die Flaeche (`auto` hat
   fuer einen Verlauf keine eigene Hoehe), die Bildhoehe ergibt sich aus der
   Breite und dem Verhaeltnis der Datei. */
@media (min-width: 900px) {
  .huelle-arbeitsflaeche:has(.rumpf-mit-leiste) {
    --hintergrund-hoehe: calc((100vw - 250px) * var(--hintergrund-verhaeltnis, .5625));
    background-image:
      linear-gradient(
        to bottom,
        var(--hintergrundfarbe, var(--grund)) calc(100% - var(--hintergrund-hoehe)),
        transparent calc(100% - var(--hintergrund-hoehe) * .55)
      ),
      var(--hintergrundbild, none);
    background-position: 250px bottom;
    background-size: calc(100% - 250px) auto;
  }
  /* Eingeklappte Leiste: Das Bild beginnt neben dem schmalen Streifen. */
  [data-leiste="zu"] .huelle-arbeitsflaeche:has(.rumpf-mit-leiste) {
    --hintergrund-hoehe: calc((100vw - 3.25rem) * var(--hintergrund-verhaeltnis, .5625));
    background-position: 3.25rem bottom;
    background-size: calc(100% - 3.25rem) auto;
  }
}

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

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

/* Zwei Spalten: Willkommensbereich und Anmeldung. Der Willkommensbereich
   steht im Quelltext vorn (Findings 02.10.) — auf schmalen Geräten kommen
   damit zuerst die Wege ohne Konto, dann die Anmeldung; ein Sprungverweis
   führt Wiederkehrende direkt hinunter. Der Willkommensbereich ist etwas
   breiter: Er ist die erste Wahl, die Anmeldung der Nebenweg. */
.anmeldung { display: grid; gap: 2rem; align-items: start; }

@media (min-width: 940px) {
  .anmeldung { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 3rem; }
}

.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; }

/* Die Nutzenpunkte sind eine Aufzaehlung, keine Knoepfe. Vorher trugen sie
   Karte, Rahmen und Innenabstand — und sahen damit aus wie vier grosse
   Schaltflaechen, auf die man klicken sollte. Ohne Rahmen bleibt das Symbol
   als Anker der Zeile, der Rest ist Text. */
.nutzen-liste { list-style: none; margin: 0 0 1.4rem; padding: 0; }
.nutzen {
  display: flex; gap: .9rem; align-items: flex-start;
  padding: .45rem 0; margin: 0;
}
.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: var(--raum-3); }
.reiter-blatt {
  padding: .4rem .85rem; 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); }

/* Die Zahl an einem Reiter (Aufgabenseite): im Fluss der Beschriftung, nicht
   als Blase am Rand — `.zaehler` ist sonst absolut gesetzt. */
.reiter-zaehler { position: static; margin-left: .35rem; vertical-align: middle; }

/* **Zwei Ebenen, zwei Formen** (0.38.0). Die erste Ebene („Seite wählen")
   bleibt der Reiter mit Unterstrich. Die zweite („Bereich wählen",
   `?bereich=`) sind Pillen: leise Beschriftung, beim Überfahren eine Fläche,
   der aktive Bereich hellblau gefüllt und fett. Vorher lag die zweite Ebene
   als blauer Kasten unter einer Karteikarten-Lasche der ersten — schwer und
   altmodisch, und bei vielen Bereichen (Texte & Inhalte: 16) ein
   zweizeiliger Block. Der Unterschied der Ebenen liegt jetzt in der Form,
   nicht in einer Fläche.

   [layout] **Und die ganze Pillenleiste liegt auf einer leisen blauen
   Fläche** (Testrunde 02.10.): Allein über die Form unterschieden, sahen
   beide Ebenen auf einen Blick gleich aus — man wusste nicht, welche man
   gerade bedient. Die Fläche sagt „das gehört zum Reiter darüber"; die
   aktive Pille hebt sich davon mit Füllung, Ring und Schriftstärke ab. Die
   Leiste ist nur so breit wie ihre Pillen, damit sie wie ein Teil des
   Reiters wirkt und nicht wie ein Hinweisband. */
.reiter-bereich {
  gap: .35rem;
  border-bottom: 0;
  padding: .3rem;
  width: fit-content; max-width: 100%;
  background: var(--kachel-blau);
  border-radius: var(--radius-s);
}
.reiter-bereich .reiter-blatt {
  margin-bottom: 0;
  padding: .28rem .8rem;
  border: 0; border-radius: 999px;
  font-size: var(--schrift-s); font-weight: 600;
  color: var(--schrift-weich);
  transition: background var(--dauer-schnell) var(--uebergang), color var(--dauer-schnell) var(--uebergang);
}
.reiter-bereich .reiter-blatt:hover { background: var(--karte); color: var(--blau-dunkel); }
/* Aktiv: Fläche, Ring **und** Schriftstärke, nie die Farbe allein (WCAG 1.4.1). */
.reiter-bereich .reiter-blatt.aktiv {
  background: var(--karte); color: var(--blau-dunkel); font-weight: 700;
  box-shadow: inset 0 0 0 1px var(--blau);
}
.reiter-bereich .reiter-blatt:focus-visible { outline-offset: 1px; }
/* Folgt die zweite Ebene direkt auf die erste, rückt sie etwas heran. */
.reiter:has(+ .reiter-bereich) { margin-bottom: var(--raum-2); }

/* 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); }

/* Der geschuetzte Bereich hat eine Ueberschrift ueber der Anmeldemaske, damit
   die beiden Wege der Seite — hinein oder daran vorbei — denselben Rang haben. */
.anmeldung-bereich { margin: 0 0 .2rem; font-size: var(--titel-3); }
.anmeldung-bereich-text { margin: 0 0 1rem; color: var(--schrift-weich); font-size: .93rem; }

/* Die Wege ohne Anmeldung. Seit den Findings vom 02.10. Kacheln im
   Willkommensbereich (`.oeffentlich-kachel`, Block „Paket auth" am Ende) —
   der Gegenpol zu den Nutzenpunkten, die ausdrücklich NICHT wie Knöpfe
   aussehen sollen. */
.oeffentlich { margin-top: 1.6rem; padding-top: 1.2rem; border-top: 1px solid var(--linie); }
.oeffentlich h2 { margin: 0 0 .3rem; font-size: var(--titel-3); }
.oeffentlich-text { margin: 0 0 1rem; color: var(--schrift-weich); font-size: .93rem; }

/* Oeffentliche Listen (Einstieg Akkreditierung, Newsletter-Uebersicht):
   Name und Zeile darunter links, der umrandete Knopf rechts. Auf schmalen
   Geraeten stapelt sich alles. */
.einstieg-punkte { padding-left: 1.2rem; }
.einstieg-punkte li { margin-bottom: .4rem; }
.oeffentliche-liste { list-style: none; margin: 0 0 1rem; padding: 0; }
.oeffentliche-liste li {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: .2rem .9rem;
  align-items: center; padding: .75rem 0; border-top: 1px solid var(--linie-weich);
}
.oeffentliche-liste li:first-child { border-top: 0; padding-top: 0; }
.oeffentliche-liste-name { font-weight: 600; }
.oeffentliche-liste-text { grid-column: 1; font-size: .9rem; line-height: 1.45; }
.oeffentliche-liste .knopf { grid-column: 2; grid-row: 1 / span 2; white-space: nowrap; }
@media (max-width: 600px) {
  .oeffentliche-liste li { grid-template-columns: minmax(0, 1fr); }
  .oeffentliche-liste .knopf { grid-column: 1; grid-row: auto; justify-self: start; margin-top: .3rem; }
}

/* 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; flex-direction: column; gap: 1.25rem; align-items: flex-start; flex: 1 1 18rem; }
.bildzeile-formulare form { margin: 0; }
.bild-gruppe { display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-start; }

/* ---- 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: var(--tipphoehe);              /* 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: var(--raum-3);
}
.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;
}
/* **Der Schalter in die Zeile davor** (0.37.0, wie im Vorgängerportal): Steht
   im Kopf schon etwas — Reiter oder Seitenaktionen —, sitzt „Filter &
   Ansicht" rechts in dieser Zeile statt in einer eigenen darunter. Das
   geöffnete Feld bleibt darunter über die volle Breite. Auf schmalen
   Geräten gilt weiter die Blocklage (siehe `max-width: 48rem`). */
/* Nur neben einer Zeile **mit Inhalt** (`:has(> *)`): Eine leere Aktionszeile
   hat keine Höhe, und der Schalter läge dann über dem geöffneten Filterfeld —
   genau der Fehler, an dem die erste absolute Lösung gescheitert war
   (TabellenbreiteTest). Die Zeile hält deshalb auch mindestens seine Höhe
   frei. */
.board-kopf { position: relative; }
.board-kopf > .reihe { margin-top: 0; margin-bottom: 0; }
.board-kopf > :first-child:not(.filter-klapp):has(> *) {
  padding-right: 13rem; min-height: var(--tipphoehe);
}
.board-kopf > :first-child:not(.filter-klapp):has(> *) ~ .filter-klapp > summary {
  position: absolute; top: 0; right: 0;
}
.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);
  /* Eine Pille mit zwei Zustaenden, kein Paar Knoepfe: Die runde Form
     sagt „eines von beiden gilt", die eckige sah aus wie zwei Aktionen. */
  border-radius: 999px; overflow: hidden;
  background: var(--grund-2);
  min-height: var(--tipphoehe);
}
/* 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; }
/* Schnellfilter nach Stand (`Arbeitsliste::stapelschalter()`): dieselbe Pille,
   nur mit mehr Blättern — bei vielen Ständen darf sie umbrechen und wird
   dafür eckiger, eine umgebrochene Pille sähe aus wie zwei. */
.stapelschalter { flex-wrap: wrap; border-radius: var(--radius-s); }
.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; }

/* **Eine Hoehe, eine Mindestbreite** (Aenderungskatalog 28.09., Punkt 7.2):
   „Suchen", „Zuruecksetzen" und „Excel-Export" waren so breit wie ihr Wort
   und einen Hauch niedriger als die Felder daneben — drei verschieden lange
   Knoepfe in einer Reihe sahen aus wie drei Sorten. Jetzt teilen sich Knoepfe,
   Klappfelder und die Ansichts-Pille die Feldhoehe (2.75rem), und jeder Knopf
   hat dieselbe Mindestbreite; laengere Beschriftungen duerfen darueber
   hinauswachsen, kuerzere werden mittig gesetzt. Auf dem Telefon nimmt jedes
   Element ohnehin die ganze Zeile (siehe unten). */
.filterreihe .knopf,
.filterreihe .filterfeld > summary,
.filterreihe .ansicht-schalter { min-height: var(--tipphoehe); }
.filterreihe .knopf { min-width: 7.5rem; justify-content: center; padding-top: .3rem; padding-bottom: .3rem; }
.filterreihe .filterfeld > summary { box-sizing: border-box; }

/* 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;
  /* Dieselbe Hoehe wie die Felder eines Formulars (`.feld select`): Ein
     Suchfeld und ein Auswahlfeld in einer Zeile sahen sonst verschieden
     hoch aus. */
  min-height: var(--tipphoehe);
  border: 1px solid var(--linie);
  border-radius: var(--radius-xs);
  background: var(--karte);
  font: inherit;
  color: var(--schrift);
  -webkit-appearance: none; appearance: none;
}
/* `appearance: none` nimmt dem Auswahlfeld den Systempfeil — ohne Ersatz
   sah es aus wie ein Textfeld, in das man nichts tippen kann. Derselbe
   Pfeil aus der Marke wie bei `.feld select`. */
.filter-panel select {
  padding-right: 2.2rem;
  background-image: var(--auswahlpfeil);
  background-repeat: no-repeat;
  background-position: right .75rem center;
  background-size: .7rem;
}
.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[hidden] { display: none; }
.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; }

/* ---- Listen und Filter (Findings 02.10.) ----------------------------------
   Eine ruhige Filterreihe und dieselben Plätze für dieselben Knöpfe in Board
   und Verwaltungslisten. */

/* **Eine Mindestbreite für jedes Filterfeld.** „Typ" und „Prozessschritt"
   waren so breit wie ihr Wort — sieben verschieden lange Kästen in einer
   Reihe sahen unruhig aus. Längere Beschriftungen wachsen darüber hinaus;
   Zahl und Pfeil stehen rechts, damit der Titel immer an derselben Stelle
   beginnt. */
.filterreihe .filterfeld > summary { min-width: 10rem; }
.filterfeld-titel { margin-right: auto; }

/* **Die Ankreuzzeilen sind gleich breit**: Das Klappfeld hat eine feste
   Breite statt „so breit wie der längste Wert", und das Kästchen darin wird
   nie schmaler gedrückt — vorher schrumpfte es neben langen Werten. */
.filterfeld-klapp { width: 18rem; }
.filterfeld-wert input[type="checkbox"] { flex: 0 0 auto; margin: 0; }

/* „Alles zurücksetzen" oben rechts im Filterbereich, nur wenn etwas gesetzt ist. */
.board-leiste .filter-zuruecksetzen { margin-left: auto; }

/* Die Sammelaktionen unter der Tabelle: Knöpfe und Auswahlfeld eine Höhe. */
.board-sammelaktionen { align-items: center; flex-wrap: wrap; }
.board-sammelaktionen .knopf,
.board-sammelaktionen select { min-height: var(--tipphoehe); }
.board-sammelaktionen select { width: auto; max-width: 18rem; padding-top: .3rem; padding-bottom: .3rem; }
.sammelaktionen .knopf[disabled], .board-sammelaktionen [disabled] { cursor: not-allowed; }

@media (max-width: 48rem) {
  .filterfeld-klapp { width: auto; }
  .filterreihe .filterfeld > summary { min-width: 0; }
  .board-leiste .filter-zuruecksetzen { margin-left: 0; justify-content: center; }
  .board-sammelaktionen > * { flex: 1 1 100%; justify-content: center; }
  .board-sammelaktionen select { max-width: 100%; min-width: 0; box-sizing: border-box; }
}

/* ============================================================
   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; }
  .board-kopf > :first-child:not(.filter-klapp):has(> *) { padding-right: 0; min-height: 0; }
  .board-kopf > :first-child:not(.filter-klapp):has(> *) ~ .filter-klapp > summary { position: static; }

  /* 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: minmax(0, 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; }
/* Das Schritt-Auswahlfeld je Zeile hat eine feste Breite: Sonst macht ein
   langer Schrittname („In Entwicklungsplanner übernommen") die eine Zeile
   breiter als die andere, der Pfeil verschwindet hinter dem Zellenrand und der
   Knopf „Setzen" rutscht aus dem Bild — Befund 28.09. */
.zeilenform { display: inline-flex; align-items: center; gap: .3rem; flex-wrap: nowrap; }
.zeilenform select.feld-klein { width: 11rem; max-width: 11rem; text-overflow: ellipsis; }

/* 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-3); margin-bottom: var(--raum-4);
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}

.kennzahl {
  display: flex; flex-direction: column; gap: var(--raum-1);
  padding: var(--raum-3) var(--raum-4);
  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(1.45rem, 1.2rem + .8vw, 1.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. */
/* Weniger Polster oben und unten als frueher (raum-7/raum-6): Der Kopf soll
   sagen, wo man ist, nicht die erste Bildschirmhoehe belegen. */
/* Seit 0.37.0 noch einmal gut halb so hoch: Das Band sagt, wo man ist, in
   einer Zeile Titel und einer Zeile Satz — nicht mehr. */
.held {
  position: relative; overflow: hidden;
  margin: 0 calc(var(--raum-5) * -1) var(--raum-4);
  padding: var(--raum-3) var(--raum-5);
  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-4);
  flex-wrap: wrap;
}
.held-mit-modulbild .modulbild,
.held-mit-modulbild .modul-emblem { flex: 0 0 auto; }
/* Im Band ein Zeichen, kein Plakat: halbe Größe, gleiches Seitenverhältnis. */
.held-mit-modulbild .modulbild { width: 80px; height: 45px; border-radius: var(--radius-xs); }
.held-mit-modulbild .modul-emblem { width: 45px; height: 45px; font-size: 1rem; border-radius: var(--radius-xs); }

/* Als erstes Element schliesst der Held oben buendig an die Kopfleiste an. */
/* Nur in der Arbeitsflaeche: Dort sitzt der Held buendig unter der Kopfleiste.
   Auf Gastseiten zog derselbe Zug den Held in den Gastkopf hinein. */
.huelle-arbeitsflaeche .inhalt > .held:first-child { margin-top: calc(var(--raum-6) * -1); }
.krume + .held { margin-top: var(--raum-1); }

/* 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; line-height: 1.12;
}
.held-lead { color: var(--held-leise); font-size: var(--schrift-s); margin: .15rem 0 0; max-width: none; }
.held-aktionen { display: flex; gap: var(--raum-3); flex-wrap: wrap; margin-top: var(--raum-3); }
.held-zusatz { color: var(--held-leise); font-size: var(--schrift-s); margin: var(--raum-3) 0 0; max-width: none; }

/* 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(--blau); color: var(--schrift-auf-farbe); border-color: var(--blau);
}
.held .knopf:hover { background: var(--blau-dunkel); border-color: var(--blau-dunkel); color: var(--schrift-auf-farbe); }
.held .knopf-rand { background: transparent; color: var(--held-schrift); border-color: var(--held-leise); }
.held .knopf-rand:hover { background: var(--kachel-blau); color: var(--held-schrift); border-color: var(--held-schrift); }

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

/* Der Held als eine Zeile in Krumen-Groesse — die Startseite ab dem zweiten
   Aufruf einer Sitzung. Keine Flaeche, kein Bild, kein Satz: Der Empfang ist
   vorbei, der Ort bleibt genannt. Es ist derselbe Baustein mit demselben
   `h1`, deshalb hier nur das Mass und nicht ein zweites Markup. */
.held-zeile {
  margin: 0 0 var(--raum-3);
  /* Innen- statt Aussenabstand: Ein oberer Aussenabstand des ersten Kindes
     kollabiert durch die Arbeitsflaeche hindurch und ist dann nicht zu sehen. */
  padding: var(--raum-4) 0 0;
  background: none;
  color: var(--schrift-leise);
}
.inhalt > .held-zeile:first-child { margin-top: 0; }
.held-zeile .held-titel {
  font-family: inherit; font-size: .9rem; font-weight: 600;
  color: var(--schrift-leise); margin: 0; line-height: 1.4;
}

@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: minmax(0, 1fr) minmax(0, 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); }
.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; }
/* In der Spalte zaehlt `flex-basis` als Hoehe: Das Suchfeld mit `flex-basis`
   18rem bzw. 22rem wurde auf dem Telefon so hoch, und zwischen ihm und den
   Klappfeldern klaffte eine leere Flaeche (Sichtpruefung 29.09.). Die Regel
   steht **hinter** der Zeile darueber — davor verloere sie bei gleicher
   Spezifitaet. */
@media (max-width: 48rem) {
  .filterreihe .board-suche, .filter-offen .board-suche { flex-basis: auto; min-width: 0; max-width: none; }
}
.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: .35rem .5rem; vertical-align: middle; }

/* **Bedienelemente in einer Zeile sind so hoch wie die Zeile, nicht wie ein
   Formularfeld** (0.37.0). Das Schritt-Auswahlfeld mit „Setzen" machte jede
   Board-Zeile 60 Pixel hoch. Am Rechner 2rem; auf Touch-Geräten greift die
   gestapelte Tabelle mit voller Tippfläche. */
@media (pointer: fine) and (min-width: 1024px) {
  .arbeitsliste td select,
  .arbeitsliste td .zellenfeld { min-height: 2rem; padding-top: .15rem; padding-bottom: .15rem; }
  .arbeitsliste td .knopf { min-height: 2rem; padding: .15rem .55rem; }
}
.zeilenform select.feld-klein { width: 10.5rem; max-width: 10.5rem; }
.arbeitsliste thead th {
  background: transparent; border-bottom: 1px solid var(--blau-20);
  text-transform: uppercase; letter-spacing: .06em; font-size: .74rem;
  /* Kopfzeile im Markenton statt Grau (Punkt 6.3): Die Spaltennamen sind
     die eine Zeile, die auf jeder Liste steht — in `--held-schrift` traegt
     sie den Grundton, ohne wie ein Knopf zu wirken. */
  color: var(--held-schrift);
}

/* 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; }

/* ---- Ein Kopf, eine Höhe (0.39.0) ---------------------------------------

   **Beim Durchklicken springt nichts mehr.** Die Reiterleiste unter dem Kopf
   stand je nach Seite verschieden hoch: mit oder ohne Satz, mit oder ohne
   Modulbild, und Datensatz-Seiten (Hochladen, Konto …) hatten statt des
   Bands einen eigenen Kopf mit Marke und Knopf untereinander. Jetzt gilt für
   jede Seite dasselbe Band — gleiche Fläche, gleiches Zeichen links, am
   Rechner gleiche Höhe, Titel und Satz je einzeilig. */
:root { --held-hoehe: 5.5rem; }

/* Das Zeichen links ist überall gleich groß: Modulbild, Initialen oder das
   Symbol einer Kernseite. Sonst begänne der Titel mal hier, mal dort. */
.held-mit-modulbild .modul-emblem { width: 80px; height: 45px; }
.modul-emblem-symbol .symbol { width: 22px; height: 22px; }
/* **Dasselbe Zeichen wie auf der Startseite** (0.42.0): ein getöntes Quadrat
   mit dem Modulsymbol in seiner Farbe (`kachel-<farbe>`), statt eines
   gezeichneten Bilds im Querformat. Überall gleich groß. */
.held-mit-modulbild .modul-emblem-symbol,
.held-datensatz > .modul-emblem-symbol { width: 44px; height: 44px; border-radius: var(--radius-xs); }

/* Der Datensatz-Kopf trägt dasselbe Band wie jede andere Seite. */
.held-datensatz {
  position: relative;
  margin: 0 calc(var(--raum-5) * -1) var(--raum-4);
  padding: var(--raum-3) var(--raum-5);
  background: var(--held);
  color: var(--held-schrift);
  border-bottom: 0;
  align-items: center; flex-wrap: nowrap;
}
.huelle-arbeitsflaeche .inhalt > .held-datensatz:first-child { margin-top: calc(var(--raum-6) * -1); }
.krume + .held-datensatz { margin-top: var(--raum-1); }
.held-datensatz > .avatar { width: 45px; height: 45px; font-size: 1rem; }
/* Titel oben, darunter Kennung, Satz und Marken **in einer Zeile** — vorher
   stapelten sie sich und machten den Kopf doppelt so hoch. */
.held-datensatz-text { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: .6rem; }
.held-datensatz-titel {
  flex: 1 0 100%;
  margin: 0; font-size: var(--titel-held); line-height: 1.12; color: var(--held-schrift);
}
.held-datensatz-kennung, .held-datensatz-lead {
  margin: .15rem 0 0; font-size: var(--schrift-s); color: var(--held-leise);
}
.held-datensatz-marken { margin: .15rem 0 0; display: inline-flex; gap: .35rem; }
.held-datensatz-aktion { flex: 0 0 auto; }
.held-datensatz .knopf { background: var(--blau); color: var(--schrift-auf-farbe); border-color: var(--blau); }
.held-datensatz .knopf-rand { background: transparent; color: var(--held-schrift); border-color: var(--held-leise); }
.held-datensatz .knopf-rand:hover { background: var(--kachel-blau); color: var(--held-schrift); border-color: var(--held-schrift); }

@media (pointer: fine) and (min-width: 1024px) {
  /* Gleiche Höhe am Rechner — der Start-Empfang (`held-zeile` bzw. mit
     Zusatzsatz) ist keine Arbeitsseite und bleibt, wie er ist. */
  .held:not(.held-zeile):not(:has(.held-zusatz)):not(:has(.held-aktionen)),
  .held-datensatz { min-height: var(--held-hoehe); box-sizing: border-box; }
  .held:not(.held-zeile) { display: flex; align-items: center; }
  .held-mit-modulbild { flex-wrap: nowrap; }
  .held-inhalt, .held-datensatz-text { flex: 1 1 auto; min-width: 0; }
  /* Einzeilig: Ein langer Titel kürzt sich, statt den Kopf höher zu machen;
     der volle Titel steht im Pfad und im Fenstertitel. */
  .held:not(.held-zeile) .held-titel,
  .held:not(.held-zeile) .held-lead,
  .held-datensatz-titel,
  .held-datensatz-lead {
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
}

@media (max-width: 900px) {
  .held-datensatz {
    margin: calc(var(--raum-5) * -1) calc(var(--raum-4) * -1) var(--raum-5);
    padding: var(--raum-4);
    flex-wrap: wrap;
  }
}
/* Modulbild und Symbol im Datensatz-Kopf: dieselbe Größe wie im Band. */
.held-datensatz > .modulbild { order: -1; flex: 0 0 auto; width: 80px; height: 45px; border-radius: var(--radius-xs); }
.held-datensatz > .modul-emblem { order: -1; flex: 0 0 auto; width: 80px; height: 45px; border-radius: var(--radius-xs); }

/* ---- Kopfband ohne Fläche (0.41.0) --------------------------------------
   Kein Hintergrund mehr — Zeichen, Titel und Satz stehen direkt auf der
   Seite, eine Haarlinie trennt den Kopf vom Inhalt (0.40.0: weiß mit
   Haarlinie, davor Pastellverlauf). Die Illustration steht ohnehin im
   Seitenhintergrund. Die Fläche kommt aus `--held` (jetzt transparent). */
.held:not(.held-zeile), .held-datensatz {
  /* Auch die Haarlinie ist weg (0.42.0): Der Kopf steht frei auf der Seite. */
  border-bottom: 0;
}
.held:not(.held-zeile)::after { display: none; }

/* ---- Mein Profil (Findings 02.10.) ---------------------------------------
   Kennung im Löschweg und der Erklärblock „Was erhalten bleibt". */
.kennung { padding: .1rem .5rem; background: var(--grund-2); border-radius: var(--radius-xs); letter-spacing: .03em; }
.kennung-hinweis { font-size: 1.05rem; }
.loeschung-bleibt { margin: 0 0 1.25rem; padding: .25rem 1rem 1rem; border: 1px solid var(--linie); border-radius: var(--radius-s); background: var(--grund-2); }
.loeschung-bleibt h2 { margin-top: .75rem; font-size: 1.05rem; }
.loeschung-bleibt .angaben { display: block; margin: 0; }
.loeschung-bleibt .angaben > div { display: grid; grid-template-columns: minmax(7rem, 9rem) 1fr; gap: 0 1rem; margin: 0 0 .6rem; }
.loeschung-bleibt .angaben dt { margin: 0; }
@media (max-width: 40rem) { .loeschung-bleibt .angaben > div { grid-template-columns: 1fr; } }

/* ==== Formularbausteine (Paket kern) =======================================
   Zu `formular.js`: Fehlerliste mit Sprungverweisen, Mehrfach-Dateiauswahl,
   durchsuchbare Auswahl, bedingte Anzeige, klappbarer Erklärkasten,
   abschaltbare Feld-Erklärung. Alles hier wirkt nur auf Klassen, die diese
   Bausteine selbst setzen — bestehende Formulare bleiben unberührt. */

/* Die Verweise in der Fehlerliste sehen aus wie Verweise: Sie führen zur
   Stelle, und das soll man ihnen ansehen. */
.fehlerliste a { color: inherit; text-decoration: underline; text-underline-offset: .15em; }
.fehlerliste a:focus-visible { outline: 2px solid var(--blau); outline-offset: 2px; }

/* Ausgeblendet heißt ausgeblendet — auch bei Elementen, die ein Raster oder
   eine Flexbox tragen (`.feld` im Subgrid). Ohne `!important` gewänne dort die
   `display`-Regel, und der Bereich stünde trotz `hidden` da. */
[data-zeige-wenn][hidden],
.dateiliste[hidden],
.suchauswahl-liste[hidden],
select[data-suchauswahl][hidden] { display: none !important; }

/* -- Dateiauswahl -- */
.dateiliste { list-style: none; margin: var(--raum-2) 0 0; padding: 0; display: grid; gap: .35rem; }
.dateiliste-eintrag {
  display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .75rem;
  padding: .45rem .75rem; border: 1px solid var(--linie); border-radius: var(--radius-xs);
  background: var(--karte);
}
.dateiliste-name { flex: 1 1 12rem; min-width: 0; overflow-wrap: anywhere; font-weight: 600; }
.dateiliste-groesse { color: var(--schrift-leise); font-size: var(--schrift-s); white-space: nowrap; }
.dateiliste-entfernen { display: inline-flex; align-items: center; gap: .35rem; font-weight: 400; margin: 0; cursor: pointer; }
.feld .dateiliste-entfernen { display: inline-flex; font-weight: 400; margin: 0; }
.dateiauswahl-vorhanden { border: 0; margin: 0 0 var(--raum-2); padding: 0; min-width: 0; }
.dateiauswahl-vorhanden > legend { font-size: var(--schrift-s); color: var(--schrift-weich); padding: 0; margin-bottom: .25rem; }
.dateiauswahl-vorhanden > .dateiliste { margin-top: 0; }

/* -- Durchsuchbare Auswahl -- */
.suchauswahl { position: relative; }
/* Das Eingabefeld trägt denselben Pfeil wie eine Klappliste: Es IST eine
   Auswahl, nur eine, in die man tippen kann. */
.feld .suchauswahl-eingabe {
  padding-right: 2.2rem;
  background-image: var(--auswahlpfeil);
  background-repeat: no-repeat;
  background-position: right .75rem center;
  background-size: .7rem;
}
.suchauswahl-liste {
  position: absolute; z-index: 30; left: 0; right: 0; top: calc(100% + 2px);
  max-height: 18rem; overflow-y: auto;
  margin: 0; padding: .25rem 0; list-style: none;
  background: var(--karte); color: var(--schrift);
  border: 1px solid var(--linie); border-radius: var(--radius-xs);
  box-shadow: var(--schatten-md);
}
.suchauswahl-gruppe { list-style: none; margin: 0; padding: 0; }
.suchauswahl-gruppentitel {
  padding: .4rem .75rem .2rem; font-size: var(--schrift-s); font-weight: 700;
  color: var(--schrift-leise);
}
.suchauswahl-option { padding: .45rem .75rem; cursor: pointer; }
.suchauswahl-gruppe .suchauswahl-option { padding-left: 1.25rem; }
.suchauswahl-option[hidden] { display: none; }
.suchauswahl-option[aria-selected="true"] { font-weight: 700; }
/* Die aktive Zeile an Fläche UND Rand erkennbar — nie an der Farbe allein. */
.suchauswahl-option.aktiv, .suchauswahl-option:hover {
  background: var(--kachel-blau); box-shadow: inset 3px 0 0 var(--blau);
}
.suchauswahl-option[aria-disabled="true"] { color: var(--schrift-leise); cursor: not-allowed; }

/* -- Klappbarer Erklärkasten -- */
details.hilfe-block-klappbar { padding: 0; }
details.hilfe-block-klappbar > summary {
  cursor: pointer; font-weight: 600; padding: .65rem 1rem; list-style-position: inside;
}
details.hilfe-block-klappbar > summary:focus-visible { outline: 2px solid var(--blau); outline-offset: 2px; }
details.hilfe-block-klappbar[open] > summary { padding-bottom: .35rem; }
details.hilfe-block-klappbar > .hilfe-block-inhalt { padding: 0 1rem .75rem; }
details.hilfe-block-klappbar > .hilfe-block-inhalt > p { max-width: none; }

/* Die abschaltbare Feld-Erklärung (`.feld-erklaerung`) bekommt bewusst keine
   eigene Gestalt: Zwei Gestalten hießen, zwei Sorten Hinweis lesen zu lernen.
   Der Unterschied liegt nur darin, ob sie dem Schalter folgt. */
/* ==== Ende Formularbausteine (Paket kern) ================================= */

/* ==== Öffentliche Startseite und Begrüßung (Paket auth, Findings 02.10.) ====

   Die Wege ohne Anmeldung (Newsletter, Akkreditierung) sind auf der
   öffentlichen Startseite die erste Wahl und stehen deshalb als Kacheln im
   Willkommensbereich, nicht mehr als umrandete Knöpfe unter der Vorstellung.
   Die ganze Kachel ist der Verweis — eine Fläche, ein Ziel. */
.oeffentlich-kacheln {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: var(--raum-3);
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}
.oeffentlich-kacheln li { display: flex; }
.oeffentlich-kachel {
  display: flex; align-items: center; gap: .9rem; flex: 1 1 auto;
  padding: 1rem 1.1rem;
  background: var(--karte); color: var(--schrift);
  border: 1.5px solid var(--linie); border-radius: var(--radius-s);
  box-shadow: var(--schatten);
  text-decoration: none;
  transition: border-color var(--dauer-schnell) var(--uebergang), box-shadow var(--dauer-schnell) var(--uebergang);
}
.oeffentlich-kachel:hover { border-color: var(--blau); box-shadow: var(--schatten-md); }
.oeffentlich-kachel:focus-visible { outline: 3px solid var(--fokusring); outline-offset: 2px; }
.oeffentlich-kachel-symbol {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: 0 0 44px;
  border-radius: var(--radius-xs);
  background: var(--blau-20); color: var(--blau-dunkel);
}
.oeffentlich-kachel-symbol .symbol { width: 22px; height: 22px; }
.oeffentlich-kachel-text { display: flex; flex-direction: column; gap: .2rem; flex: 1 1 auto; min-width: 0; }
.oeffentlich-kachel-text strong { color: var(--blau-dunkel); font-size: 1.05rem; }
.oeffentlich-kachel-text span { color: var(--schrift-weich); font-size: .9rem; line-height: 1.45; }
.oeffentlich-kachel-pfeil { transform: rotate(-90deg); flex: 0 0 auto; color: var(--blau); }

/* Im Willkommensbereich steht „Ohne Anmeldung" direkt unter der Einleitung —
   ohne Trennlinie davor, die gehört zwischen die beiden Abschnitte. */
.anmeldung-vorstellung .oeffentlich { margin-top: var(--raum-5); padding-top: 0; border-top: 0; }
.anmeldung-nutzen { margin-top: var(--raum-5); padding-top: var(--raum-4); border-top: 1px solid var(--linie); }
.anmeldung-nutzen h2 { margin: 0 0 .6rem; font-size: var(--titel-3); }
.anmeldung-nutzen .nutzen-liste { margin-bottom: 0; }

/* Sprungverweis zur Anmeldung — nur dort, wo die Anmeldung unter dem
   Willkommensbereich steht. */
.anmeldung-sprung { margin: 0 0 var(--raum-3); font-size: .93rem; }
@media (min-width: 940px) {
  .anmeldung-sprung { display: none; }
}

/* Hinweis am E-Mail-Feld: Die Adresse gehört zur Anmeldung der Organisation.
   Hinweiston, keine Fehlerfarbe — es ist ein Wegweiser, kein Fehler. */
.sso-hinweis {
  margin: .45rem 0 0; padding: .55rem .8rem;
  border-left: 4px solid var(--blau); border-radius: var(--radius-xs);
  background: var(--blau-20); color: var(--schrift);
  font-size: .9rem; line-height: 1.45;
}

/* Die Begrüßung auf der Startseite ist nach dem Wegfall von Satz und
   Erklärtext das Einzige im Kopf — also groß. Nur beim ersten Aufruf der
   Sitzung; danach bleibt die Zeile in Krumen-Größe (`held-zeile`). */
.held-gruss .held-titel { font-size: clamp(2rem, 1.4rem + 2.2vw, 3rem); line-height: 1.1; }
@media (pointer: fine) and (min-width: 1024px) {
  .held-gruss { min-height: calc(var(--held-hoehe) + 1.5rem); }
}
/* ==== Ende Öffentliche Startseite und Begrüßung (Paket auth) ============== */
