/* Aufsichtenplanung WIAI — Basis-Stil.
   Eine Datei, kein Build-Step, keine Frameworks (PRD §8.3).

   Herkunft der Gestaltung: das Design-System des WIAI-Neubaus
   (~/Desktop/wiai-webseiten-analyse/neubau/designsystem). Übernommen sind
   Palette, Kantenführung (1 px Haarlinie statt Schatten), quadratische
   Kästen, eine führende linke Kante und die Regel „höchstens zwei
   Flächenfarben je Seite".

   Zwei bewusste Abweichungen, beide begründet:
   1. Systemschriften statt der CD-Webfonts Open Sans und Copse — Webfonts
      wären ein zusätzlicher Auslieferungsweg ohne fachlichen Gewinn.
   2. Meldungen tragen eine einheitliche graue Kante statt einer Kante in der
      Signalfarbe: Gelb (1,44:1) und Grün (2,15:1) erreichen auf Weiß die für
      Bedienelemente geforderten 3:1 nicht (WCAG 1.4.11). Die Bedeutung trägt
      ohnehin die Textmarke, nicht die Farbe (WCAG 1.4.1).
   ========================================================================== */

/* --- Merkmale (Tokens) ---------------------------------------------------- */

:root {
  /* Palette der Universität Bamberg. Nur diese Werte plus Weiß und Schwarz —
     kein eigenes Farbvokabular (Vorgabe des Design-Systems). */
  --uni-blau: #00457d;
  --uni-blau-80: #336a97;
  --uni-blau-40: #99b5cb;
  --uni-blau-20: #ccdae5;
  --uni-gelb-20: #fff6cc;
  --uni-gruen-20: #eaf2cf;
  --uni-rot: #e6444f;
  --uni-rot-20: #fadadc;
  --uni-grau: #878783;
  --uni-grau-40: #cfcfce;
  --uni-grau-20: #e7e7e6;

  /* Rollen. Textstufen als Schwarz mit Alpha statt als Grautöne — so halten
     sie ihren Kontrast auch auf dem Flächenton. */
  --grund: #ffffff;
  --flaeche-ton: #e8eef3; /* Blau-20 zu 45 % in Weiß */
  --text: #000000;
  --text-zweit: rgba(0, 0, 0, 0.72);
  --text-leise: rgba(0, 0, 0, 0.55);
  --akzent: var(--uni-blau);

  /* Haarlinie schmückt, Kante bedient: Grau-40 ist als Trennstrich gedacht,
     Grau (3,61:1) trägt jede Kante, die ein Bedienelement begrenzt. */
  --linie: var(--uni-grau-40);
  --kante: var(--uni-grau);

  --schrift: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    Arial, sans-serif;
  /* Ersatz für Copse. Wie dort gilt: ausschließlich h1, sonst nichts —
     die Anzeige-Schrift soll sich nicht ausbreiten. */
  --schrift-anzeige: Georgia, "Iowan Old Style", "Times New Roman", Times, serif;

  --fs-anzeige: clamp(2rem, 1.4rem + 2.6vw, 2.9rem);
  --fs-h2: 1.55rem;
  --fs-h3: 1.2rem;
  --fs-lead: 1.2rem;
  --fs-body: 1.0625rem; /* 17 px */
  --fs-klein: 0.95rem;
  --fs-mikro: 0.8rem;

  --raum-1: 0.25rem;
  --raum-2: 0.5rem;
  --raum-3: 0.75rem;
  --raum-4: 1rem;
  --raum-5: 1.5rem;
  --raum-6: 2rem;
  --raum-7: 3rem;
  --raum-8: 4.5rem;

  --breite: 1200px;
  /* Zeilenlänge: die px-Grenze gewinnt auf schmalen Schirmen, die ch-Grenze
     bei großer Schrift — so hält die Grenze in beide Richtungen. */
  --mass: min(680px, 72ch);
  --mass-weit: min(980px, 96ch);

  --radius-kasten: 0; /* Kästen sind quadratisch, ausnahmslos */
  --radius-steuer: 4px; /* Rundung gibt es nur für Bedienelemente */
  --uebergang: 0.2s ease;
}

/* --- Grundlagen ----------------------------------------------------------- */

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

/* Ohne das setzt jede Autorenregel mit `display` das UA-`[hidden]` außer
   Kraft, und per JS gesetztes `hidden` bleibt wirkungslos. */
[hidden] {
  display: none !important;
}

html {
  color-scheme: light;
}

/* Spaltenaufbau, damit das Fußband auch auf kurzen Seiten unten sitzt statt
   mitten im Bild zu enden. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  margin: 0;
  background: var(--grund);
  color: var(--text);
  font-family: var(--schrift);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
}

/* Spalte, damit ein Kind sich per `margin-block: auto` im freien Raum
   ausrichten kann (siehe `.tuerseite`). Ohne freien Raum ändert sich nichts. */
main {
  display: flex;
  flex-direction: column;
  flex: 1 0 auto;
}

/* Fließtext darf trennen (deutsche Komposita), Überschriften nicht. */
p,
li,
dd {
  hyphens: auto;
  text-wrap: pretty;
}

h1,
h2,
h3,
h4 {
  margin: 0 0 var(--raum-3);
  line-height: 1.2;
  letter-spacing: -0.01em;
  hyphens: manual;
  overflow-wrap: break-word;
  text-wrap: balance;
}

/* Hierarchie kommt aus der Größe, nicht aus dem Fettgrad. */
h1 {
  margin-bottom: var(--raum-5);
  font-family: var(--schrift-anzeige);
  font-size: var(--fs-anzeige);
  font-weight: 400;
  color: var(--uni-blau);
  line-height: 1.12;
}

h2 {
  font-size: var(--fs-h2);
  font-weight: 400;
  color: var(--uni-blau);
}

h3 {
  font-size: var(--fs-h3);
  font-weight: 400;
  color: var(--uni-blau);
}

h4 {
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--uni-blau);
}

p {
  margin: 0 0 var(--raum-4);
}

ul,
ol {
  margin: 0 0 var(--raum-4);
  padding-left: 1.3rem;
}

li + li {
  margin-top: var(--raum-1);
}

a {
  color: var(--uni-blau);
  text-decoration: underline;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--uni-blau-80);
  text-decoration-thickness: 2px;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

/* --- Fokus und Sprungmarke ------------------------------------------------ */

/* Ein Ring für alles. Auf dem blauen Band wäre Blau unsichtbar — dort
   überschreibt `.kopfband` die Farbe auf Weiß. */
:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 2px;
}

/* `main` ist nur Sprungziel, kein Bedienelement. Ein Ring um die halbe Seite
   hilft niemandem; die Ansage der Landmarke leistet die Rückmeldung. */
main:focus {
  outline: none;
}

.sprungmarke {
  position: absolute;
  left: var(--raum-4);
  top: -100vh;
  z-index: 100;
  padding: var(--raum-3) var(--raum-5);
  background: var(--grund);
  color: var(--uni-blau);
  border: 2px solid var(--uni-blau);
  border-radius: 0 0 var(--radius-steuer) var(--radius-steuer);
  font-weight: 600;
  text-decoration: none;
}

.sprungmarke:focus {
  top: 0;
}

/* Die Marke liegt immer über dem blauen Band — ein blauer Ring wäre dort
   unsichtbar. Weiß mit Versatz ergibt eine erkennbare Doppellinie. */
.sprungmarke:focus-visible {
  outline-color: #ffffff;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Aufbau --------------------------------------------------------------- */

/* Vollbreite Bänder sind außen Fläche, innen Container — nie ein Container,
   der selbst blutet. Alle Container teilen sich eine linke Kante. */
/* `width: 100%` ist nicht überflüssig: `main` ist eine Flex-Spalte, und dort
   hebelt ein `margin-inline: auto` das `align-items: stretch` aus — der
   Container schrumpfte sonst auf seine Inhaltsbreite und die linke Kante
   wanderte weg vom Wortzeichen. */
.container {
  width: 100%;
  max-width: var(--breite);
  margin-inline: auto;
  padding-inline: var(--raum-5);
}

.band--ton {
  background: var(--flaeche-ton);
}

.abschnitt {
  padding-block: var(--raum-7);
}

.abschnitt--weit {
  padding-block: var(--raum-8);
}

/* Türseiten tragen wenig Inhalt. Statt ihn oben kleben und darunter ein
   totes Feld entstehen zu lassen, richtet er sich im freien Raum aus; auf
   schmalen Schirmen gibt es keinen freien Raum und nichts passiert. */
.tuerseite {
  margin-block: auto;
}

.fliesstext {
  max-width: var(--mass);
}

.fliesstext--weit {
  max-width: var(--mass-weit);
}

/* --- Kopfband ------------------------------------------------------------- */

.kopfband {
  background: var(--uni-blau);
  color: #ffffff;
}

.kopfband :focus-visible {
  outline-color: #ffffff;
}

.kopfzeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--raum-4) var(--raum-5);
  padding-block: var(--raum-3);
}

.marke {
  margin: 0;
}

/* Der Schub nach rechts sitzt hier und nicht mehr an der Marke: Die Marke ist
   der Name der Anwendung, kein Abstandhalter. Die Haarlinie trennt Sitzung von
   Weg — 40 % Weiß auf Uni-Blau, dieselbe Zurückhaltung wie `--linie` auf
   hellem Grund. Bei schmaler Fläche bricht der Kasten um; dann trägt die Linie
   nichts mehr und weicht. */
.kopfzeile__rechts {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--raum-4) var(--raum-5);
  margin-left: auto;
  padding-left: var(--raum-5);
  border-left: 1px solid rgba(255, 255, 255, 0.4);
}

@media (max-width: 60rem) {
  .kopfzeile__rechts {
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
  }
}

.marke a {
  display: block;
  color: inherit;
  text-decoration: none;
}

.marke a:hover .marke__name {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.marke__traeger {
  display: block;
  font-size: var(--fs-mikro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--uni-blau-20);
}

.marke__name {
  display: block;
  font-size: 1.15rem;
  font-weight: 400;
}

/* Hauptnavigation im Kopfband. Wenige Ziele, deshalb eine Reihe ohne
   Aufklappmenü: Ein Menü, das man erst öffnen muss, ist auf jedem Gerät ein
   Klick mehr und mit der Tastatur zwei. */
.hauptnav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-2) var(--raum-4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.hauptnav li + li {
  margin-top: 0;
}

.hauptnav a {
  display: block;
  padding: var(--raum-1) 0;
  color: #ffffff;
  text-decoration: none;
  font-weight: 600;
}

.hauptnav a:hover {
  color: #ffffff;
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* Die aktuelle Rubrik trägt eine Unterkante — die Ansage `aria-current`
   erledigt dasselbe für die Sprachausgabe. */
.hauptnav a[aria-current] {
  border-bottom: 2px solid #ffffff;
}

/* Wer angemeldet ist und wie man das beendet — im Kopfband, weil es auf jeder
   Seite gilt. */
.nutzerband {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--raum-2);
  margin: 0;
  font-size: var(--fs-klein);
}

.nutzerband__name {
  color: #ffffff;
}

/* „Abmelden" borgte sich die Pillenform der Sprachknöpfe und sah damit wie
   eine dritte Sprache aus. Eigene Form: Rechteck mit Haarlinie, kein Radius —
   eine Aktion, keine Auswahl. */
.abmelden {
  padding: var(--raum-1) var(--raum-3);
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: transparent;
  color: #ffffff;
  font-family: inherit;
  font-size: var(--fs-klein);
  line-height: 1.4;
  cursor: pointer;
  transition: background var(--uebergang);
}

.abmelden:hover {
  background: rgba(255, 255, 255, 0.15);
}

.sprachwahl {
  margin: 0;
}

.sprachwahl__gruppe {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--raum-2);
  font-size: var(--fs-klein);
}

.sprachwahl__titel {
  font-size: var(--fs-mikro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--uni-blau-20);
}

.sprachwahl__aktiv,
.sprachwahl__knopf {
  padding: var(--raum-1) var(--raum-3);
  font-size: var(--fs-klein);
  line-height: 1.4;
}

.sprachwahl__knopf {
  border-radius: 999px;
}

/* Unterkante wie bei `.hauptnav a[aria-current]` statt weißer Füllung: Die
   gefüllte Pille war das kontrastreichste Element des ganzen Kopfbands und wog
   damit schwerer als der Name der Anwendung. Die Bedeutung trägt weiterhin
   `aria-current`, sie hängt also nicht an der Fläche (WCAG 1.4.1). */
.sprachwahl__aktiv {
  border-bottom: 2px solid #ffffff;
  color: #ffffff;
  font-weight: 600;
}

.sprachwahl__knopf {
  border: 1px solid rgba(255, 255, 255, 0.55);
  background: transparent;
  color: #ffffff;
  font-family: inherit;
  cursor: pointer;
  transition: background var(--uebergang);
}

.sprachwahl__knopf:hover {
  background: rgba(255, 255, 255, 0.15);
}

/* --- Kontextleiste -------------------------------------------------------- */

/* Der Dauerplatz für „welches Semester, welche Phase, welcher Saldo". Diese
   Anwendung befindet sich immer in einem Semester und in einer Phase — das
   ist die eine Angabe, die auf jeden Bildschirm gehört. Bis Welle 3 gibt es
   nichts zu füllen; der Block bleibt leer statt zu erfinden. */
.kontextleiste {
  border-bottom: 1px solid var(--linie);
  background: var(--grund);
}

.kontextleiste .container {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--raum-2) var(--raum-5);
  padding-block: var(--raum-3);
  font-size: var(--fs-klein);
  color: var(--text-zweit);
}

/* Semester und Phase stehen links beieinander, ein etwaiger Riegel rechts —
   `justify-content: space-between` allein würde die beiden Angaben über die
   ganze Breite auseinanderziehen. */
.kontextleiste .container {
  justify-content: flex-start;
}

.kontextleiste__teil {
  display: inline-flex;
  align-items: baseline;
  gap: var(--raum-2);
  margin: 0;
}

.kontextleiste__teil--riegel {
  margin-left: auto;
  color: var(--text);
  font-weight: 600;
}

/* Die Marke benennt, was die Zahl daneben ist — ohne sie wäre „4 von 7" eine
   Zahl ohne Gegenstand. */
.kontextleiste__marke {
  font-size: var(--fs-mikro);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-leise);
}

.kontextleiste__phase {
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

/* --- Unternavigation ------------------------------------------------------ */

/* Die Arbeitsbereiche eines Semesters. Steht unter der Überschrift, weil sie
   zum Gegenstand der Seite gehört und nicht zur Anwendung. */
.unternav {
  margin-bottom: var(--raum-6);
  border-bottom: 1px solid var(--linie);
}

/* Dieselbe Markierung wie in der Hauptnavigation: Unterkante plus fettere
   Schrift, damit die aktuelle Rubrik nicht allein an der Farbe hängt
   (WCAG 1.4.1). Bei vierzehn Zielen auf zwei Zeilen ist das der Unterschied
   zwischen Orientierung und Suchen (WCAG 2.4.8). */
.unternav a[aria-current] {
  font-weight: 700;
  text-decoration: none;
  box-shadow: inset 0 -3px 0 var(--akzent);
}

.unternav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-2) var(--raum-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Drei Gruppen nebeneinander, getrennt durch eine Haarlinie statt durch ein
   Zeichen: Der Trenner ist Gestaltung und gehört nicht in die Vorlesereihe.
   Bei schmaler Fläche brechen die Gruppen untereinander — dann trägt die Linie
   nichts mehr und weicht dem Abstand (kein horizontaler Bildlauf bei 320 px). */
.unternav--gruppen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-2) var(--raum-5);
}

.unternav__gruppe + .unternav__gruppe {
  padding-left: var(--raum-5);
  border-left: 1px solid var(--linie);
}

@media (max-width: 60rem) {
  .unternav__gruppe + .unternav__gruppe {
    padding-left: 0;
    border-left: 0;
  }
}

.unternav li + li {
  margin-top: 0;
}

.unternav a {
  display: block;
  padding-bottom: var(--raum-2);
  font-size: var(--fs-klein);
  font-weight: 600;
  text-decoration: none;
}

.unternav a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

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

.meldungen {
  padding-top: var(--raum-5);
}

.meldung {
  max-width: var(--mass-weit);
  margin: 0 0 var(--raum-3);
  padding: var(--raum-3) var(--raum-4);
  border: 1px solid var(--kante);
  border-radius: var(--radius-kasten);
  background: var(--uni-grau-20);
  color: var(--text-zweit);
}

/* Die Farbe verstärkt nur — gelesen wird die Textmarke. */
.meldung__art {
  font-weight: 700;
  color: var(--text);
}

.meldung--success {
  background: var(--uni-gruen-20);
}

.meldung--info,
.meldung--debug {
  background: var(--flaeche-ton);
}

.meldung--warning {
  background: var(--uni-gelb-20);
}

.meldung--error {
  background: var(--uni-rot-20);
  border-color: var(--uni-rot);
}

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

/* Höchstens ein bis zwei Vorzeilen je Seite — eine über jedem Abschnitt ist
   Füllmaterial und flacht die Hierarchie ab. */
.vorzeile {
  margin: 0 0 var(--raum-2);
  font-size: var(--fs-mikro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--uni-blau);
}

/* Der Vorspann trennt nicht: Trennstriche in einer hervorgehobenen Zeile
   lesen sich als Fehler, nicht als Satz. */
.lead {
  max-width: var(--mass);
  margin-bottom: var(--raum-5);
  font-size: var(--fs-lead);
  line-height: 1.55;
  color: var(--text-zweit);
  hyphens: manual;
}

.leise {
  color: var(--text-leise);
  font-size: var(--fs-klein);
}

/* Soll, Ist, Saldo. Tabellenziffern, damit Spalten stellenweise fluchten —
   das ist der Grund, warum diese Anwendung überhaupt gelesen wird. */
.zahl {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Bewusst keine dicktengleiche Schrift: die Systemschrift setzt mit
   `tabular-nums` bereits stellengleich, und ein Wechsel der Schriftfamilie
   mitten in einer Zahlenspalte fällt als Bruch auf. */
.saldo {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Das Vorzeichen trägt die Aussage, nicht die Farbe (WCAG 1.4.1). */
.saldo--unterdeckt {
  font-weight: 700;
}

/* Kleine Sach-Etiketten in Tabellen (zentral/dezentral, lange Dauer, …).
   Text trägt die Aussage, die Kontur nur die Gruppierung (WCAG 1.4.1). */
.etikett {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  margin-inline-end: 0.25rem;
  border: 1px solid var(--linie, currentColor);
  border-radius: 0.25rem;
  font-size: 0.85em;
  white-space: nowrap;
}

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

/* Die Hülle scrollt, nicht die Seite. `tabindex="0"`, `role="region"` und
   ein `aria-label` gehören ins Markup: ein scrollbarer Bereich muss mit der
   Tastatur erreichbar sein (WCAG 2.1.1).

   `position: relative` ist keine Kosmetik: `.sr-only` steht auf
   `position: absolute` ohne Versatz. Ohne positionierten Vorfahren ist sein
   Containing Block der Seitenkasten — die 1-px-Marke landet dann an der
   Stelle, an der sie *in der breiten Tabelle* stünde, wird von der Hülle nicht
   beschnitten und schiebt die ganze Seite waagerecht auf. In der Abnahme auf
   vier Seiten gefunden (Fristen, Lehreinheiten, Nicht-Melder, Zuweisung), je
   rund 140 px Bildlauf am `body` (WCAG 1.4.10). */
.tabelle-huelle {
  position: relative;
  max-width: 100%;
  overflow-x: auto;
  margin-bottom: var(--raum-5);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-klein);
  font-variant-numeric: tabular-nums;
}

caption {
  margin-bottom: var(--raum-2);
  text-align: left;
  font-weight: 600;
  color: var(--text-zweit);
}

th,
td {
  padding: var(--raum-2) var(--raum-3);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--linie);
}

thead th {
  border-bottom: 1.5px solid var(--uni-blau-40);
  font-size: var(--fs-mikro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--uni-blau);
  white-space: nowrap;
}

tbody tr:hover {
  background: var(--flaeche-ton);
}

.spalte-zahl {
  text-align: right;
}

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

.feld {
  margin-bottom: var(--raum-5);
  max-width: var(--mass);
}

.feld > label,
.feld-legende {
  display: block;
  margin-bottom: var(--raum-1);
  font-weight: 600;
}

.feld-hilfe {
  margin: 0 0 var(--raum-2);
  font-size: var(--fs-klein);
  color: var(--text-leise);
}

/* Der Fehler steht über dem Feld, damit er beim Vorlesen vor der Eingabe
   kommt; er wird zusätzlich per `aria-describedby` verknüpft. */
.feld-fehler {
  margin: 0 0 var(--raum-2);
  font-size: var(--fs-klein);
  font-weight: 600;
  color: var(--text);
}

/* Fehler und Feld gehören zusammen: die linke Kante fasst sie zu einem Block,
   sonst klebt der Fehler optisch am gefüllten Feld darüber. Die Bedeutung
   trägt die Textmarke „Fehler" im Markup, nicht die Kante — ein Symbol per
   `content` wäre in der Sprachausgabe je nach Einstellung ein Wortschwall
   („schweres Multiplikationszeichen") oder gar nichts. */
.feld--fehlerhaft {
  padding-left: var(--raum-3);
  border-left: 3px solid var(--uni-rot);
}

/* Fehlerübersicht über dem Formular — Zähler, Anker, Fokusziel. */
.fehleruebersicht {
  max-width: var(--mass);
  margin-bottom: var(--raum-5);
  padding: var(--raum-3) var(--raum-4);
  border-left: 3px solid var(--uni-rot);
  background: var(--uni-rot-20);
}

.fehleruebersicht__titel {
  margin: 0;
}

.fehleruebersicht ul {
  margin: var(--raum-2) 0 0;
  padding-left: var(--raum-5);
}

/* Maschinenlesbare Eingaben (JSON-Zuordnung des PA-Imports): In der
   Proportionalschrift sind Spaltenbuchstaben und Klammern nicht abzuzählen. */
.feld--maschine {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* Ein Zusatz im Spaltenkopf steht auf eigener Zeile und nicht fett — sonst
   liest sich der Kopf als Satz und die Spalte wird breiter als ihre Zahlen. */
.th-zusatz {
  display: block;
  font-weight: 400;
}

/* Schalter: Kästchen und Beschriftung in einer Zeile, die Beschriftung ist
   Teil der Klickfläche. */
.feld--schalter > label,
.feld-schalter label {
  display: inline;
  font-weight: 400;
}

.feld-schalter {
  display: flex;
  align-items: baseline;
  gap: var(--raum-2);
  margin: 0;
}

/* Zahlenfelder in Tabellenzellen: nur so breit wie nötig, damit die Spalte
   nicht die Tabelle auseinanderzieht. */
td input[type="text"],
td input[type="date"] {
  max-width: 9rem;
}

input[type="text"],
input[type="email"],
input[type="number"],
input[type="date"],
input[type="search"],
input[type="password"],
select,
textarea {
  width: 100%;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--kante);
  border-radius: var(--radius-steuer);
  background: var(--grund);
  color: var(--text);
  font-family: inherit;
  font-size: var(--fs-body);
  line-height: 1.5;
}

input[type="number"],
input[type="date"] {
  font-variant-numeric: tabular-nums;
}

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

input:hover,
select:hover,
textarea:hover {
  border-color: var(--uni-blau);
}

[aria-invalid="true"] {
  border-color: var(--uni-rot);
  border-width: 2px;
}

fieldset {
  margin: 0 0 var(--raum-5);
  padding: var(--raum-4);
  border: 1px solid var(--linie);
  border-radius: var(--radius-kasten);
}

legend {
  padding-inline: var(--raum-2);
  font-weight: 600;
  color: var(--uni-blau);
}

/* Radiogruppe: Die Gruppe ist das Feld, deshalb ohne Rahmen und Innenabstand —
   ein Kasten je Auswahlfrage zerlegte das Formular optisch in Bausteine. */
.feld-gruppe {
  margin: 0;
  padding: 0;
  border: 0;
}

.feld-gruppe > .feld-legende {
  padding-inline: 0;
  color: var(--text);
}

.feld-gruppe label {
  display: inline;
  font-weight: 400;
}

.feld-gruppe input[type="radio"] {
  margin-right: var(--raum-1);
}

/* --- Listen und Hinweise -------------------------------------------------- */

/* Eine Liste von Verweisen ohne Aufzählungszeichen: Die Einträge sind Wege,
   keine Aufzählung. */
.liste-klar {
  margin: 0 0 var(--raum-5);
  padding: 0;
  list-style: none;
}

.liste-klar li {
  padding: var(--raum-2) 0;
  border-bottom: 1px solid var(--linie);
}

.liste-klar .leise {
  margin-left: var(--raum-2);
}

/* Ein stehender Hinweis zum Zustand der Seite — anders als `.meldung`, die auf
   eine gerade ausgeführte Aktion antwortet. */
.hinweis {
  max-width: var(--mass);
  margin: 0 0 var(--raum-5);
  padding: var(--raum-3) var(--raum-4);
  border-left: 4px solid var(--uni-blau);
  background: var(--flaeche-ton);
}

/* Bearbeiten und Löschen nebeneinander; die Spalte soll nicht umbrechen. */
.spalte-aktion {
  display: flex;
  align-items: baseline;
  gap: var(--raum-3);
  white-space: nowrap;
}

/* --- Knöpfe --------------------------------------------------------------- */

.knopf {
  display: inline-block;
  padding: 0.55rem 1.4rem;
  border: 1px solid var(--uni-blau);
  border-radius: var(--radius-steuer);
  background: var(--grund);
  color: var(--uni-blau);
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--uebergang), color var(--uebergang);
}

.knopf:hover {
  background: var(--flaeche-ton);
  color: var(--uni-blau);
  text-decoration: none;
}

.knopf--primaer {
  background: var(--uni-blau);
  color: #ffffff;
}

.knopf--primaer:hover {
  background: var(--uni-blau-80);
  border-color: var(--uni-blau-80);
  color: #ffffff;
}

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

.knopfreihe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-3);
  align-items: center;
  margin-bottom: var(--raum-4);
}

/* --- Kästen --------------------------------------------------------------- */

/* Struktur trägt die Kante, nicht der Schatten. Keine farbige Kante, keine
   Rundung — beides liest sich sofort als Baukasten von der Stange. */
.kasten {
  padding: 1.25rem 1.4rem;
  border: 1px solid var(--linie);
  border-radius: var(--radius-kasten);
  background: var(--grund);
}

/* Merkmalsliste im Kasten: Begriff über Wert, nicht nebeneinander — bei
   langen Werten (mehrere Lehreinheiten) bricht das sauber um. */
dl.kasten {
  margin: 0 0 var(--raum-5);
  max-width: var(--mass);
}

dl.kasten dt {
  font-size: var(--fs-mikro);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-leise);
}

dl.kasten dd {
  margin: 0 0 var(--raum-3);
}

/* Die Phasenzeile trägt jetzt zwei Sätze: „Wer tut was“ und den nächsten
   Schritt. Der zweite steht als eigener Absatz im `dd` und braucht seinen
   Abstand nach oben, nicht den vollen Absatzabstand nach beiden Seiten. */
dl.kasten dd p {
  margin: var(--raum-2) 0 0;
}

/* Ein Etikett im `dt` — „nächste Frist“, „verstrichen“ — erbt sonst
   Versalien und Sperrung der Merkmalsbeschriftung und wird unlesbar. */
dl.kasten dt .etikett {
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

/* Kennzahlenkasten als Raster: Sieben Werte untereinander ergaben eine
   halbbreite Säule von sieben Zeilen; die Tabelle, um die es auf der Seite
   geht, begann erst weit darunter — obwohl man Kennzahlen und Zeilen
   gegeneinander liest (Gesamtbedarf gegen Σ Soll, Faktor gegen die Soll-Spalte).
   `auto-fit` mit Mindestbreite: Auf 1440 px drei bis vier Spalten, bei 320 px
   eine — ohne einen zweiten Umbruchpunkt zu pflegen. `dt`/`dd` bleiben als Paar
   zusammen, weil jedes Paar eine eigene Rasterzelle bekommt. */
dl.kasten--kennzahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--raum-2) var(--raum-5);
  max-width: var(--mass-weit);
}

/* Ein `div` je Paar (in einer `dl` erlaubt und schon das Muster von
   `.begriffe`): Ohne Wrapper wären dt und dd eigene Rasterzellen, und ein
   Begriff könnte am Zeilenende stehen, sein Wert am Anfang der nächsten. */
dl.kasten--kennzahlen .kasten__paar {
  min-width: 0;
}

dl.kasten--kennzahlen dd {
  margin-bottom: 0;
}

dl.kasten dd:last-child {
  margin-bottom: 0;
}

/* --- Fußband -------------------------------------------------------------- */

.fussband {
  margin-top: var(--raum-8);
  border-top: 1px solid var(--linie);
  background: var(--flaeche-ton);
  color: var(--text-zweit);
  font-size: var(--fs-klein);
}

.fussband .container {
  padding-block: var(--raum-5);
}

.fussband p {
  margin: 0 0 var(--raum-1);
  max-width: var(--mass-weit);
}

.fussband .leise {
  font-variant-numeric: tabular-nums;
}

/* Der Dev-User-Switch (PRD §8.4). Er soll erkennbar ein Werkzeug sein und
   nicht wie Teil der Anwendung aussehen — deshalb die gestrichelte Kante. */
.devleiste {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--raum-2);
  margin-top: var(--raum-4);
  padding: var(--raum-3);
  border: 1px dashed var(--linie);
}

.devleiste .sprachwahl__knopf {
  border-color: var(--uni-blau);
  color: var(--uni-blau);
}

.devleiste .sprachwahl__knopf:hover {
  background: var(--flaeche-ton);
}

/* --- Besetzungsboard (Welle 5) --------------------------------------------- */

/* Zwei Spalten ab mittlerer Breite: links Personen, rechts Slots (PRD §6.6).
   Auf schmalen Schirmen stapeln sie — die Personenliste zuerst, weil die
   Auswahl der Person der erste Schritt der Selection-first-Bedienung ist. */
.board-spalten {
  display: grid;
  gap: var(--raum-6);
  align-items: start;
}

/* Grid-Kinder stehen auf `min-width: auto` und können nicht unter die
   min-content-Breite ihres Inhalts schrumpfen. Ohne diese Zeile reicht ein
   einziges breites Element in einer Spalte, um die Seite bei 320 px waagerecht
   scrollen zu lassen (WCAG 1.4.10). */
.board-spalten > * {
  min-width: 0;
}

@media (min-width: 56rem) {
  .board-spalten {
    grid-template-columns: minmax(16rem, 1fr) 2fr;
  }
}

.personenliste,
.slotliste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.personenliste .person,
.slotliste .slot {
  border: 1px solid var(--linie);
  border-radius: 0.25rem;
  padding: var(--raum-3) var(--raum-4);
  margin-block-end: var(--raum-3);
}

/* Die linke Kante trägt den Füllstand — sie wiederholt nur, was der Satz
   „besetzt" / „offen" im Slot ohnehin sagt (WCAG 1.4.1). */
.slotliste .slot {
  border-left: 4px solid var(--linie);
}

.slotliste .slot[data-status="besetzt"] {
  border-left-color: var(--uni-blau);
}

/* Fokusziel nach jeder Aktion: Der Slot bekommt den Fokus, damit die
   Sprachausgabe den geänderten Eintrag als Ganzes liest. Der Abstand hält ihn
   beim Anspringen frei von der klebenden Auswahlleiste. */
.slotliste .slot {
  scroll-margin-top: 4rem;
}

.slotliste .slot:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 2px;
}

.person__name {
  font-weight: 600;
  display: block;
}

.person__status {
  display: block;
  color: var(--text-leise);
}

.slot__kopf {
  margin-block-end: var(--raum-1);
}

.besetzen-formular {
  display: flex;
  flex-wrap: wrap;
  gap: var(--raum-2);
  align-items: center;
  margin-block-start: var(--raum-2);
}

/* Mit JavaScript ist „Hier einteilen" der Hauptweg und die Auswahlliste der
   zweite — zwei gefüllte Knöpfe nebeneinander lasen sich wie zwei Hauptwege.
   Die Rangfolge steht hier und nicht im Skript: Ein Klassenentzug nach dem
   Laden lief durch den 0,2-s-Übergang von `.knopf` und zeigte für einen
   Moment blasse Füllung auf blassem Text (UX-Befund P9). `[data-js]` setzt das
   Modul beim Start am Wurzelelement und nimmt es beim Scheitern wieder weg —
   ohne JavaScript bleibt der Knopf also der Hauptweg, der er dann ist. */
#besetzungsboard[data-js] .besetzen-formular [data-aktion="besetzen"] {
  background: transparent;
  border-color: var(--uni-blau);
  color: var(--uni-blau);
  font-weight: 600;
}

#besetzungsboard[data-js] .besetzen-formular [data-aktion="besetzen"]:hover {
  background: var(--flaeche-ton);
  border-color: var(--uni-blau);
  color: var(--uni-blau);
}

/* Der Satz gehört zur Auswahlliste und nicht in die Knopfreihe: Er erklärt,
   was die Wahl einer fremden Person bedeutet (UX-Befund P1). */
.slot__fremdhinweis {
  flex-basis: 100%;
}

/* `min-width: 0` statt eines Mindestmaßes: Ein `select` zieht seine
   min-content-Breite aus der längsten Option („Bea Semamann (Wissenschaft-
   liche:r Mitarbeiter:in)") und schiebt sonst die ganze Seite über 320 px
   hinaus — WCAG 1.4.10. Die Wunschbreite trägt weiterhin die flex-basis. */
.besetzen-formular select {
  width: auto;
  min-width: 0;
  max-width: 100%;
  flex: 1 1 12rem;
}

/* Finalisierungs-Arbeitsliste (PRD §6.6): die beiden Entscheidungswege je
   Slot nebeneinander, gleichwertig — keiner ist der Hauptweg. `min-width: 0`
   aus demselben Grund wie bei .board-spalten (WCAG 1.4.10). */
.entscheidungswege {
  display: grid;
  gap: var(--raum-6);
  align-items: start;
}

.entscheidungswege > * {
  min-width: 0;
}

@media (min-width: 56rem) {
  .entscheidungswege {
    grid-template-columns: 1fr 1fr;
  }
}

/* --- Fortschritt ---------------------------------------------------------- */

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

/* Ein Balken ohne UA-Verlauf: dieselbe Kantenführung wie alles andere. */
progress.fortschritt {
  flex: 0 0 auto;
  width: min(18rem, 100%);
  height: 0.85rem;
  appearance: none;
  border: 1px solid var(--kante);
  border-radius: 0;
  background: var(--grund);
}

progress.fortschritt::-webkit-progress-bar {
  background: var(--grund);
}

progress.fortschritt::-webkit-progress-value {
  background: var(--uni-blau);
}

progress.fortschritt::-moz-progress-bar {
  background: var(--uni-blau);
}

/* --- Selection-first (nur mit JavaScript) --------------------------------- */

/* Alles darunter erscheint erst, wenn das Board-Modul die Seite verbessert
   hat. Ohne JavaScript bleibt die Seite so, wie der Server sie ausliefert. */

.personensuche {
  margin-block-end: var(--raum-4);
}

.personensuche label {
  display: block;
  margin-block-end: var(--raum-1);
  font-weight: 600;
}

.personensuche__treffer {
  margin: var(--raum-1) 0 0;
  font-size: var(--fs-klein);
  color: var(--text-leise);
}

/* Der Name ist die Schaltfläche: ein Ziel statt „Eintrag plus Knopf daneben"
   (WCAG 2.5.5, größere Trefferfläche). */
.person__waehlen {
  display: block;
  width: 100%;
  margin: 0 0 var(--raum-1);
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

/* Der Name muss als Bedienelement zu erkennen sein — sonst sieht die
   Personenliste aus wie eine Liste und niemand klickt sie an. */
.person__waehlen .person__name {
  color: var(--uni-blau);
  text-decoration: underline;
  text-decoration-color: var(--uni-blau-40);
  text-underline-offset: 3px;
}

.person__waehlen:hover .person__name {
  text-decoration-color: currentColor;
  text-decoration-thickness: 2px;
}

/* Die Textmarke trägt die Auswahl; Kante und Fläche verstärken sie nur. */
.person__marke {
  display: none;
}

.person__waehlen[aria-pressed="true"] .person__marke {
  display: inline-block;
  margin-block-start: var(--raum-1);
  padding: 0.05rem 0.4rem;
  border: 1px solid var(--uni-blau);
  border-radius: 0.25rem;
  font-size: var(--fs-mikro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--uni-blau);
}

.personenliste .person:has(.person__waehlen[aria-pressed="true"]) {
  border-left: 4px solid var(--uni-blau);
  background: var(--flaeche-ton);
}

.person--fremd .person__status {
  font-size: var(--fs-klein);
}

/* Die Auswahl bleibt beim Scrollen sichtbar — sonst wählt man eine Person und
   verliert auf dem Weg zum Slot die Rückmeldung, wen man eigentlich setzt. */
.auswahlleiste {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--raum-3);
  margin-block-end: var(--raum-4);
  padding: var(--raum-2) var(--raum-3);
  border: 1px solid var(--uni-blau);
  border-left-width: 4px;
  background: var(--flaeche-ton);
}

.auswahlleiste__name {
  font-weight: 600;
}

.auswahlleiste .knopf {
  padding: 0.25rem 0.8rem;
  font-size: var(--fs-klein);
}

/* Der Knopf ist nie wirklich deaktiviert: Ohne gewählte Person sagt er beim
   Auslösen, was fehlt. Ausgegraut wäre er ein bedienbares Element unterhalb
   des geforderten Kontrasts — die Beschriftung trägt den Zustand. */
.slot__zuweisen[aria-disabled="true"] {
  opacity: 1;
  cursor: pointer;
}

/* Drop-Ziel und Tastaturziel sind dasselbe Element und sehen gleich aus. */
.slot--zielaktiv {
  outline: 2px dashed var(--uni-blau);
  outline-offset: 2px;
  background: var(--flaeche-ton);
}

.slot__meldungen:empty {
  display: none;
}

.slot__meldung {
  margin: var(--raum-2) 0 0;
  padding: var(--raum-2) var(--raum-3);
  border: 1px solid var(--kante);
  font-size: var(--fs-klein);
}

.slot__meldung--warnung {
  background: var(--uni-gelb-20);
}

.slot__meldung--fehler {
  background: var(--uni-rot-20);
  border-color: var(--uni-rot);
}

.slot__meldung__art {
  font-weight: 700;
}

/* --- Schmale Schirme ------------------------------------------------------ */

@media (max-width: 40rem) {
  :root {
    --raum-7: 2.25rem;
    --raum-8: 3rem;
  }

  .container {
    padding-inline: var(--raum-4);
  }

  .kopfzeile {
    align-items: flex-start;
  }

  .marke {
    margin-right: 0;
    width: 100%;
  }

  /* Handlungsknöpfe laufen unter 560 px über die volle Breite. */
  .knopfreihe .knopf {
    width: 100%;
  }
}

/* --- Bewegung, Druck, Kontrastmodus --------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Belegliste der Transparenz-Ansicht: aufklappbar, weil sie der Nachweis der
   Zahl daneben ist und nicht das, was man zuerst liest. */
details.beleg {
  margin-block: 1rem;
  border-left: 3px solid var(--linie);
  padding-left: 0.75rem;
}

details.beleg > summary {
  cursor: pointer;
  padding-block: 0.25rem;
}

/* Nebeneingang eines Formulars: die Spaltenzuordnung des PA-Imports ändert man
   nur bei einer Formatumstellung, sehen muss man sie trotzdem. `details`
   bringt die Tastaturbedienung mit, ohne eine Zeile JavaScript. */
details.aufklapp {
  max-width: var(--mass);
  margin-block: var(--raum-4);
  border-left: 3px solid var(--linie);
  padding-left: var(--raum-3);
}

details.aufklapp > summary {
  cursor: pointer;
  padding-block: var(--raum-1);
}

/* Konsistenz-Selbstcheck: eine Ampel-Liste. Die Farbe steht am linken Rand,
   die Stufe zusätzlich als Wort — Farbe allein ist kein Merkmal (WCAG 1.4.1). */
.pruefliste {
  list-style: none;
  margin: var(--raum-4) 0 0;
  padding: 0;
}

.pruefung {
  margin-block: var(--raum-3);
  padding: var(--raum-3);
  border: 1px solid var(--linie);
  border-left: 6px solid var(--uni-grau);
  background: var(--grund);
}

.pruefung--ok {
  border-left-color: var(--uni-blau);
}

/* Ausgefallener Prüfschritt: ausdrücklich neutral, damit er nicht wie ein
   bestandener aussieht. Die Kante bleibt das Grau der Grundregel. */
.pruefung--nicht_anwendbar {
  border-left-color: var(--uni-grau);
}

.pruefung--warnung {
  border-left-color: var(--uni-grau);
  background: var(--uni-gelb-20);
}

.pruefung--fehler {
  border-left-color: var(--uni-rot);
  background: var(--uni-rot-20);
}

.pruefung__titel {
  margin: 0 0 var(--raum-2);
  font-size: var(--fs-h3);
}

.pruefung__stufe {
  display: inline-block;
  margin-right: var(--raum-2);
  padding: 0.1em 0.5em;
  border: 1px solid var(--kante);
  background: var(--grund);
  font-size: var(--fs-klein);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Filterleiste der Historie: die Felder nebeneinander, solange Platz ist. */
.filterleiste {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--raum-3);
  margin-block: var(--raum-4);
}

.filterleiste .feld {
  margin: 0;
}

.blaettern {
  display: flex;
  gap: var(--raum-3);
  margin-block: var(--raum-4);
}

/* --- Symbole (Heroicons, inline) ------------------------------------------ */

/* Ein Symbol steht immer neben Text, nie an seiner Stelle (WCAG 1.4.1) —
   deshalb bemisst es sich an der Schrift und nicht an einer festen Größe. */
.ikone {
  width: 1.15em;
  height: 1.15em;
  /* Ohne die Korrektur sitzt das Quadrat auf der Grundlinie und damit optisch
     zu hoch neben Ziffern. */
  vertical-align: -0.2em;
  flex: 0 0 auto;
}

/* --- Inline-Erklärung am Ort der Zahl ------------------------------------- */

/* Aufklappbar per `details`: nativ mit der Tastatur bedienbar, ohne eine Zeile
   Skript, und dasselbe Muster wie die Belegliste der Transparenz-Ansicht. */
.erklaerung {
  display: inline-block;
  position: relative;
  /* Die Blase liegt über allem, was danach kommt — auch über der nächsten
     Tabellenzeile. */
  z-index: 2;
}

.erklaerung__knopf {
  display: inline-flex;
  align-items: center;
  cursor: help;
  color: var(--akzent);
  /* Die Fläche muss die 24-px-Marke erreichen (WCAG 2.5.8), ohne die Zeile
     auseinanderzuziehen. */
  padding: 0.15rem;
  margin: -0.15rem;
  border-radius: var(--radius-steuer);
  /* Der Dreiecks-Marker von `summary` würde neben dem (i) ein zweites Symbol
     setzen. */
  list-style: none;
}

.erklaerung__knopf::-webkit-details-marker {
  display: none;
}

.erklaerung__knopf:hover {
  color: var(--uni-blau-80);
}

.erklaerung__blase {
  position: absolute;
  /* Rechts ausgerichtet: In den Zahlenspalten steht das (i) am rechten Rand,
     eine linksbündige Blase liefe aus der Tabelle heraus. */
  right: 0;
  top: calc(100% + var(--raum-1));
  width: min(30rem, 78vw);
  padding: var(--raum-4);
  border: 1px solid var(--kante);
  background: var(--grund);
  /* Ohne Schatten (Regelwerk); getrennt wird über die Haarlinie und die
     Fläche. Die Blase liegt auf Weiß, damit sie auch über dem Flächenton
     lesbar bleibt. */
  font-size: var(--fs-klein);
  font-weight: 400;
  text-align: left;
  white-space: normal;
  color: var(--text);
}

.erklaerung__wort {
  margin: 0;
  font-weight: 700;
}

.erklaerung__formel {
  margin: var(--raum-2) 0 0;
  font-variant-numeric: tabular-nums;
  color: var(--text-zweit);
}

.erklaerung__text {
  margin: var(--raum-2) 0 0;
}

.erklaerung__mehr {
  margin: var(--raum-3) 0 0;
  font-size: var(--fs-mikro);
}

/* In einer Kopfzelle klebt die Blase sonst an der Zellgrenze. */
th .erklaerung,
td .erklaerung {
  position: static;
}

th .erklaerung__blase,
td .erklaerung__blase {
  /* Bezug ist dann die Zelle; sie braucht dafür einen Positionskontext. */
  top: auto;
}

th:has(.erklaerung),
td:has(.erklaerung) {
  position: relative;
}

/* --- Offengelegte Rechnung ------------------------------------------------ */

/* Soll, Ist und Saldo nebeneinander sind irreführend, solange der Übertrag
   fehlt: Ein Ist unter dem Soll liest sich als Rückstand, obwohl der Saldo
   positiv sein kann. Deshalb steht die Rechnung als Rechnung da — mit den
   Operatoren zwischen den Gliedern. */
.bilanz {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--raum-2) var(--raum-3);
  margin-block: var(--raum-3);
}

.bilanz__glied {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
  white-space: nowrap;
  color: var(--text-zweit);
}

.bilanz__glied .zahl {
  color: var(--text);
}

/* Das Ergebnis hebt sich über Schriftfarbe und -stärke ab, nicht über eine
   zusätzliche Kante: Neben dem „=" las sich die 3-px-Kante wie ein
   versehentlicher Strich. Das Gleichheitszeichen markiert das Ergebnis schon. */
.bilanz__glied--ergebnis {
  color: var(--text);
  font-weight: 600;
}

.bilanz__zeichen {
  font-variant-numeric: tabular-nums;
  color: var(--text-leise);
}

/* --- Begriffsliste unter einer Zahlentabelle ------------------------------ */

/* Auf 1440 px lag rechts neben jeder Tabelle die halbe Seitenbreite brach; die
   Liste füllt sie, statt die Seite länger zu machen. */
.begriffe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: var(--raum-4) var(--raum-6);
  margin-block: var(--raum-5);
  max-width: var(--mass-weit);
  font-size: var(--fs-klein);
}

.begriffe__paar {
  border-top: 1px solid var(--linie);
  padding-top: var(--raum-2);
}

.begriffe dt {
  font-weight: 700;
}

.begriffe dd {
  margin: var(--raum-1) 0 0;
  color: var(--text-zweit);
}

/* Die Formel gehört zum Begriff, trägt aber nicht dessen Gewicht. */
.begriffe__formel {
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--text-leise);
  white-space: nowrap;
}

/* Die längste Formel („Restbedarf = Soll − zugeteilt − Anrechnung −
   Übertrag") ist rund 395 px breit und schob mit `nowrap` die Zuweisungsseite
   bei 320 px waagerecht auf (WCAG 1.4.10, in der Abnahme gefunden). Oberhalb
   dieser Schwelle passt sie in eine Zeile und bleibt dort; darunter darf sie
   umbrechen. `normal` erzwingt keinen Umbruch, es erlaubt ihn nur. */
@media (max-width: 30rem) {
  .begriffe__formel {
    white-space: normal;
  }
}

.begriffe__paar--mehr {
  border-top: 0;
  align-self: end;
}

/* --- Glossarseite --------------------------------------------------------- */

.glossar {
  margin: var(--raum-5) 0 0;
  max-width: var(--mass-weit);
}

/* Themengruppe: eine Zwischenüberschrift, kein neues Farbvokabular. Die
   Gruppen sind die Antwort darauf, dass eine Nachschlageseite mit 35 Einträgen
   am Stück nicht mehr durchsucht, sondern gescrollt wird. */
.glossar__gruppe {
  margin-top: var(--raum-7);
  font-size: var(--fs-klein);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-leise);
}

.glossar__eintrag {
  padding-block: var(--raum-4);
  border-top: 1px solid var(--linie);
}

.glossar__eintrag:last-child {
  border-bottom: 1px solid var(--linie);
}

/* Angesprungener Eintrag: Wer aus einer (i)-Erklärung hierher kommt, soll ohne
   Suchen sehen, welcher Begriff gemeint war. */
.glossar__eintrag:target {
  background: var(--flaeche-ton);
  box-shadow: -0.75rem 0 0 var(--flaeche-ton), 0.75rem 0 0 var(--flaeche-ton);
}

.glossar dt {
  font-weight: 700;
}

.glossar dd {
  margin: var(--raum-2) 0 0;
  max-width: var(--mass);
}

.glossar dd p {
  margin: 0;
}

.glossar__formel {
  margin-bottom: var(--raum-2) !important;
  font-variant-numeric: tabular-nums;
  color: var(--text-zweit);
}

.glossar-phasen {
  list-style: none;
  margin: var(--raum-5) 0 0;
  padding: 0;
  max-width: var(--mass-weit);
}

.glossar-phasen__stufe {
  padding: var(--raum-3) 0 var(--raum-3) var(--raum-4);
  border-left: 3px solid var(--uni-blau-40);
}

.glossar-phasen__stufe:target {
  border-left-color: var(--akzent);
  background: var(--flaeche-ton);
}

.glossar-phasen__name {
  margin: 0;
  font-weight: 700;
}

.glossar-phasen__nummer {
  display: inline-block;
  min-width: 1.6em;
  margin-right: var(--raum-2);
  padding: 0.05em 0.35em;
  border: 1px solid var(--kante);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.glossar-phasen__text {
  margin: var(--raum-1) 0 0;
  max-width: var(--mass);
  color: var(--text-zweit);
}

/* Druckansichten sind laut PRD §8.2 der Weg zu PDF — deshalb sind sie hier
   Grundausstattung und keine Nacharbeit. */
@media print {
  .sprungmarke,
  .kopfband,
  .sprachwahl,
  .unternav,
  .nicht-drucken,
  .knopfreihe,
  .erklaerung {
    display: none !important;
  }

  /* Die Tabellen der Druckfassungen (PA-Plan, Einsatzplan, Versandfassung)
     sollen aufs Papier passen, nicht in einen Bildlaufkasten: Der Rahmen mit
     `overflow` ist eine Bildschirmhilfe. */
  .tabelle-huelle {
    overflow: visible !important;
    border: 0;
  }

  .drucktabelle {
    font-size: 9pt;
  }

  /* Aufgeklappte Belege drucken mit; ein `details` ohne `open` bliebe sonst
     leer auf dem Papier. */
  details.beleg > summary {
    font-weight: 700;
  }

  body {
    font-size: 10.5pt;
    color: #000;
    background: #fff;
  }

  h1,
  h2,
  h3,
  h4,
  a {
    color: #000;
  }

  .fussband,
  .kontextleiste {
    background: #fff;
    border-color: #000;
  }

  th,
  td {
    border-bottom: 0.5pt solid #000;
  }

  tr,
  .kasten {
    break-inside: avoid;
  }
}

/* Im Windows-Kontrastmodus verschwinden Flächen; die Kanten müssen bleiben. */
@media (forced-colors: active) {
  .kasten,
  .meldung,
  .knopf,
  .slot__meldung,
  progress.fortschritt,
  input,
  select,
  textarea {
    border: 1px solid CanvasText;
  }

  /* Auswahl- und Drop-Zustand hängen im Kontrastmodus sonst an Flächen, die
     dort verschwinden. */
  .personenliste .person:has(.person__waehlen[aria-pressed="true"]),
  .slot--zielaktiv {
    outline: 2px solid Highlight;
  }

  :focus-visible {
    outline-color: Highlight;
  }
}
