/* =====================================================================
   PMLS Zeiterfassung — aufbauendes Stylesheet (DS-01)

   Baut ausschliesslich auf den Tokens aus pmls/colors_and_type.css auf und
   ueberschreibt dort nichts. KEINE eigenen Hex-Werte (DS-02, Testfall T-101).

   Dies ist die einzige Stelle im Projekt, an der Stile fuer die Weboberflaeche
   entstehen (Block B2, Kollisionsregel R-2). Andere Bloecke benutzen die
   Klassen und die Bausteine unter templates/bausteine/ und fordern fehlende
   Klassen in ihrem Blockbericht an.

   Gliederung
     1  Eigene Masse
     2  Lexend
     3  Grundlayout und Fokus
     4  Kopfleiste
     5  Seitenkopf
     6  Karte
     7  Schaltflaechen
     8  Formulare
     9  Tabellen
    10  Badges
    11  Saldo
    12  Hinweisbanner und Meldungen
    13  Leerer Zustand
    14  Icons
    15  Beschreibungsliste, Reiter, Trennlinie, Raster
    16  Anmeldeseite (Verlauf, DS-08)
    17  Hilfsklassen und Bewegung
    18  Kalenderraster (Block B18, CSS-Hoheit fuer diese Welle)
   ===================================================================== */

/* ---------------------------------------------------------------------
   1  Eigene Masse

   Nur Laengen, die das Design-System nicht kennt. Farben, Radien und
   Schatten kommen ausnahmslos aus den Tokens (DS-02).
   --------------------------------------------------------------------- */

:root {
  --zeit-inhalt-breite: 96rem; /* Lesebreite der Arbeitsflaechen (B-119, von Christopher im Browser gewaehlt) */
  --zeit-schmal-breite: 34rem; /* Formulare und Dialoge */
  --zeit-zeile: 2.75rem; /* 44 px Zeilenhoehe, Shop-Dichte (docs/10 Abschnitt 3) */
  --zeit-ziel: 2.75rem; /* 44 px kleinste Bedienflaeche im Web */
  --zeit-rand: 1px; /* Rahmenstaerke, im Design-System nie ueber 2 px */
  --zeit-kalender-spalte: 2.5rem; /* Breite einer Tagesspalte im Kalenderraster (Block B18) */
  --zeit-kalender-namensspalte: 10rem; /* Breite der Namensspalte, damit sie nicht umbricht */
  --zeit-jahr-spalte: 1.5rem; /* Tagesspalte der Jahresansicht - 31 davon muessen nebeneinander passen */
  --zeit-jahr-monatsspalte: 3rem; /* Monatskuerzel links */
  --zeit-feld-schmal: 8rem; /* Zahlen, Tage, Stunden (S-7, B67) */
  --zeit-feld-mittel: 18rem; /* Datum, Namen, Auswahllisten (S-7, B67) */
  --zeit-feld-breit: 40rem; /* Grund, Notiz - lesbare Zeilenlaenge statt Bildschirmbreite (S-12) */
}

/* ---------------------------------------------------------------------
   2  Lexend, lokal eingebunden (DS-03)

   Kein Google-Fonts-Abruf, kein CDN. Die variable Fassung liegt unter
   theme/pmls/fonts/lexend/, die Lizenz (SIL Open Font License) daneben in
   OFL.txt. Einmal eingelagert, danach laeuft nichts mehr nach aussen.

   Zwei Schnitte: "latin" deckt Deutsch vollstaendig ab, "latin-ext" faengt
   Namen mit osteuropaeischer Schreibung. Der Browser laedt nur, was die
   Seite tatsaechlich braucht.
   --------------------------------------------------------------------- */

@font-face {
  font-family: "Lexend";
  src: url("pmls/fonts/lexend/Lexend-Variable-latin.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2212, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Lexend";
  src: url("pmls/fonts/lexend/Lexend-Variable-latin-ext.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------------------------------------------------------------------
   3  Grundlayout und Fokus
   --------------------------------------------------------------------- */

body {
  margin: 0;
  background: var(--color-bg-alt);
  color: var(--color-text);
  font-family: var(--font-main);
  line-height: var(--leading-normal);
}

.zeit-inhalt {
  max-width: var(--zeit-inhalt-breite);
  margin: 0 auto;
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.zeit-inhalt--schmal {
  max-width: var(--zeit-schmal-breite);
}

/* Fokus ist immer sichtbar (DS-10). Das ist die einzige Stelle, an der
   outline entfernt wird — und sie ersetzt die Kontur in derselben Regel
   durch den Fokusring aus dem Design-System. */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* Sprungmarke: erstes Ziel der Tabulatortaste, damit die Kopfleiste
   uebersprungen werden kann (Testfall T-106). */
.zeit-sprungmarke {
  position: absolute;
  left: var(--space-4);
  top: calc(var(--space-4) * -4);
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  background: var(--color-bg);
  border: var(--zeit-rand) solid var(--color-border-strong);
  border-radius: var(--radius-md);
  font-weight: 600;
  transition: top var(--dur-fast) var(--ease-standard);
}

.zeit-sprungmarke:focus {
  top: var(--space-4);
}

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

   Aufbau und Hoehe wie im Shop (sticky, weiss, 12 px Blur) — der Inhalt ist
   eigenstaendig: kein Warenkorb, kein Mega-Menue (docs/10 Abschnitt 4).
   --------------------------------------------------------------------- */

.zeit-kopf {
  position: sticky;
  top: 0;
  z-index: 10;
  padding: var(--space-3) 0;
  background: var(--color-bg);
  border-bottom: var(--zeit-rand) solid var(--color-border);
  backdrop-filter: saturate(180%) blur(12px);
}

/* Begrenzt die Kopfleiste auf dieselbe Breite wie .zeit-inhalt, damit Marke
   und Inhaltskante auf breiten Bildschirmen fluchten. .zeit-kopf selbst
   bleibt ueber die volle Fensterbreite sticky und behaelt Hintergrund und
   Unterkante. */
.zeit-kopf__innen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  max-width: var(--zeit-inhalt-breite);
  margin-inline: auto;
  padding-inline: var(--space-6);
}

/* Zwei Reihen mit Absicht (Durchgang 16.09.2026). Als Leitung mit
   Administrationsrechten stehen neun Navigationspunkte neben Marke und
   Benutzerblock; das passt in der Lesebreite nicht in eine Zeile. Vorher
   brach `.zeit-kopf__rechts` als Rest um und klebte allein am rechten Rand
   einer sonst leeren Zeile — ein Umbruch, der nach Unfall aussah.

   Jetzt tragen Marke und Benutzerblock die erste Reihe, die Navigation
   bekommt die zweite ganz fuer sich. Das geschieht ueber `order` und eine
   volle Zeilenbreite, nicht ueber eine Aenderung an der Vorlage: Die
   Reihenfolge im Markup bleibt Marke, Navigation, Benutzerblock, weil sie
   beim Durchtabben die richtige ist. Die Begrenzung auf
   `--zeit-inhalt-breite` bleibt, die Marke fluchtet also weiter mit der
   Inhaltskante darunter. */
.zeit-kopf__marke {
  order: 1;
}

.zeit-kopf__rechts {
  order: 2;
}

.zeit-kopf__navigation {
  order: 3;
  flex-basis: 100%;
}

.zeit-kopf__marke {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  color: var(--color-text);
  font-family: var(--font-brand);
  font-weight: 600;
  text-decoration: none;
}

.zeit-kopf__marke:hover {
  color: var(--color-text);
  text-decoration: none;
}

.zeit-kopf__marke img {
  height: var(--space-8);
  width: auto;
}

.zeit-kopf__navigation {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  /* Kein Einzug mehr: Die Navigation steht jetzt in eigener Reihe und
     beginnt buendig mit Marke und Inhalt darunter. */
}

.zeit-kopf__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--zeit-ziel);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--color-text);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-standard);
}

.zeit-kopf__link:hover {
  background: var(--color-bg-alt);
  color: var(--color-primary);
  text-decoration: none;
}

/* Der aktive Punkt ist zusaetzlich zur Farbe unterstrichen — Farbe allein
   traegt nie eine Bedeutung (DS-09). */
.zeit-kopf__link[aria-current="page"] {
  color: var(--color-primary);
  box-shadow: inset 0 -2px 0 0 var(--color-primary);
  font-weight: 600;
}

.zeit-kopf__rechts {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-left: auto;
}

.zeit-kopf__person {
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* ---------------------------------------------------------------------
   5  Seitenkopf (Baustein seitenkopf.html)
   --------------------------------------------------------------------- */

.zeit-seitenkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
}

.zeit-seitenkopf__titel {
  margin: 0;
  font-size: var(--text-3xl);
  font-weight: 700;
}

.zeit-seitenkopf__beschreibung {
  margin: var(--space-1) 0 0;
  max-width: 52rem;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.zeit-seitenkopf__zurueck {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.zeit-seitenkopf__aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Abschnittsueberschrift: gruppiert mehrere Karten auf einer Seite
   (OP-83, B-45). Kleiner als der Seitentitel (--text-3xl), groesser als
   eine Kartenueberschrift (--text-xl) — die Rangfolge Seite -> Abschnitt
   -> Karte bleibt damit an der Schriftgroesse ablesbar. */
.zeit-abschnitt__titel {
  margin: 0 0 var(--space-4);
  font-size: var(--text-2xl);
  font-weight: 600;
}

/* ---------------------------------------------------------------------
   6  Karte (Baustein karte.html)

   Weisse Flaeche, 1 px Rahmen, 12 px Radius, --shadow-sm in Ruhe.
   Kein farbiger linker Rand — im Design-System ausdruecklich als
   Fehlmuster benannt (DS-07).
   --------------------------------------------------------------------- */

.zeit-karte {
  background: var(--color-bg);
  border: var(--zeit-rand) solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6);
}

/* Nur fuer Karten, die als Ganzes zu einer Seite fuehren. Eine Karte, die
   nichts tut, hebt sich auch nicht an.

   Die Klickflaeche selbst kommt ueber .zeit-karte__titel-link::after
   (gestreckter Link, B67): Die Karte braucht dafuer position:relative, der
   Titel-Link bleibt der einzige <a> der Karte (Screenreader lesen ihn nicht
   doppelt), sein ::after legt sich unsichtbar ueber die ganze Flaeche.
   :hover auf der Karte greift dadurch unveraendert ueberall, nicht nur auf
   dem Titeltext - keine Hover-Abhaengigkeit fuer die Bedienung, nur ein
   zusaetzlicher Hinweis fuer die Maus.

   Rueckmeldung Christopher (24.09.2026): kein unterstrichener Titel beim
   Hovern, stattdessen der Kartenrahmen in der Markenfarbe - und derselbe
   Zustand bei Tastaturfokus, nicht nur bei der Maus. :has() bindet den
   Fokus des Links an die Karte, ohne eine zweite Markierung zu brauchen. */
.zeit-karte--klickbar {
  position: relative;
  cursor: pointer;
  transition:
    box-shadow var(--dur-base) var(--ease-standard),
    transform var(--dur-base) var(--ease-standard),
    border-color var(--dur-base) var(--ease-standard);
}

.zeit-karte--klickbar:hover,
.zeit-karte--klickbar:has(.zeit-karte__titel-link:focus-visible) {
  box-shadow: var(--shadow-md);
  border-color: var(--color-primary);
  transform: translateY(-2px);
}

.zeit-karte--klickbar .zeit-karte__titel-link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.zeit-karte--klickbar .zeit-karte__titel-link:hover {
  text-decoration: none;
}

/* Der Fokusring aus der globalen :focus-visible-Regel liegt sonst eng am
   Titeltext an - hier stattdessen auf dem gestreckten ::after, damit der
   Ring um die ganze Karte sichtbar wird (DS-10). */
.zeit-karte--klickbar .zeit-karte__titel-link:focus-visible {
  /* outline: none kommt schon aus der globalen :focus-visible-Regel oben
     (DS-10 verlangt den Ersatz in derselben Regel - dort steht er). */
  box-shadow: none;
  text-decoration: none;
}

.zeit-karte--klickbar .zeit-karte__titel-link:focus-visible::after {
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-xl);
}

.zeit-karte--ruhig {
  box-shadow: none;
}

.zeit-karte--gefuellt {
  background: var(--color-bg-alt);
}

.zeit-karte__kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.zeit-karte__titel {
  margin: 0;
  font-size: var(--text-xl);
  font-weight: 600;
}

.zeit-karte__unterzeile {
  margin: var(--space-1) 0 0;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* Unterueberschrift innerhalb einer Karte (OP-83, B-45). Kleiner als
   .zeit-karte__titel, damit sie den Kartentitel nicht ueberragt. */
.zeit-karte__untertitel {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--text-lg);
  font-weight: 600;
}

/* Direkt unter einer Tabelle braucht die Unterueberschrift mehr Luft, sonst
   liest sie sich als letzte Tabellenzeile (S-12). */
.zeit-tabelle__huelle + .zeit-karte__untertitel {
  margin-top: var(--space-8);
}

.zeit-karte__inhalt > :last-child {
  margin-bottom: 0;
}

.zeit-karte__fuss {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: var(--zeit-rand) solid var(--color-border);
}

/* Das Merkblatt (Anzeigezwang nach Art. 13 DSGVO) haengt sonst als
   schmale Karte am linken Rand einer vollen Zeile: `.zeit-inhalt--schmal`
   begrenzt nur die Breite, zentriert die Karte aber nicht selbst (Befund
   Christopher 23.09.2026, B62). Eigene, auf diese Seite beschraenkte
   Klassen statt einer Aenderung an `.zeit-inhalt--schmal` oder
   `.zeit-karte__fuss` — die anderen 24 schmalen Formularseiten sind davon
   nicht Teil dieses Befunds und bleiben unveraendert. Der Fliesstext
   selbst bleibt linksbuendig lesbar, nur Rahmen und Absendeknopf werden
   geordnet. */
.zeit-merkblatt__karte {
  margin-inline: auto;
}

.zeit-merkblatt__fuss {
  justify-content: center;
}

/* ---------------------------------------------------------------------
   7  Schaltflaechen

   Shop-Stil: 8 px Radius, Primaer gefuellt Tekhelet, Sekundaer outline,
   Hover mit --shadow-brand, Press ein Pixel nach unten. Niemals
   verkleinern — das wirkt billig (docs/10 Abschnitt 3).
   --------------------------------------------------------------------- */

.zeit-knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--zeit-ziel);
  padding: var(--space-2) var(--space-5);
  border: var(--zeit-rand) solid transparent;
  border-radius: var(--radius-md);
  background: none;
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition:
    background var(--dur-fast) var(--ease-standard),
    border-color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard);
}

.zeit-knopf:hover {
  text-decoration: none;
}

.zeit-knopf:active {
  transform: translateY(1px);
  box-shadow: var(--shadow-xs);
}

.zeit-knopf[disabled],
.zeit-knopf[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
  box-shadow: none;
  transform: none;
}

.zeit-knopf--primaer {
  background: var(--color-primary);
  color: var(--color-white);
}

.zeit-knopf--primaer:hover {
  background: var(--pmls-tekhelet-90);
  box-shadow: var(--shadow-brand);
  color: var(--color-white);
}

.zeit-knopf--sekundaer {
  background: var(--color-bg);
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.zeit-knopf--sekundaer:hover {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* Fuer Nebenhandlungen in Tabellenzeilen und Karten. */
.zeit-knopf--dezent {
  color: var(--color-text-muted);
}

.zeit-knopf--dezent:hover {
  background: var(--color-bg-alt);
  color: var(--color-primary);
}

/* Nur fuer wirklich zerstoerende Handlungen — Rot ist Verstoessen und
   Systemfehlern vorbehalten (docs/10 Abschnitt 2). */
.zeit-knopf--gefahr {
  background: var(--color-bg);
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.zeit-knopf--gefahr:hover {
  background: var(--color-danger-bg);
  color: var(--color-danger);
}

.zeit-knopf--klein {
  min-height: var(--space-8);
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs);
}

.zeit-knopf--gross {
  min-height: var(--space-12);
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-base);
}

.zeit-knopf--breit {
  display: flex;
  width: 100%;
}

/* Reine Symbolschaltflaeche. Braucht immer ein aria-label, sonst ist sie
   fuer Screenreader stumm (DS-10). */
.zeit-knopf--symbol {
  min-width: var(--zeit-ziel);
  padding: var(--space-2);
}

.zeit-knopfreihe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* ---------------------------------------------------------------------
   8  Formulare (Baustein feld.html)

   Sichtbare Beschriftung statt Platzhalter (DS-12), Fehlermeldung am Feld
   statt nur am Seitenkopf (DS-13), Fokusring statt Rahmenfarbwechsel.
   --------------------------------------------------------------------- */

.zeit-feld {
  display: block;
  margin-bottom: var(--space-4);
}

/* Hilfetext unter dem Feld, nicht daneben: Seit breite Felder gedeckelt sind
   (S-12), rutschte das inline stehende <small> sonst rechts neben ein
   Textfeld. Gestaltung wie .zeit-feld__hinweis. */
.zeit-feld > small {
  display: block;
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

.zeit-feld > label,
.zeit-feld__beschriftung {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--text-sm);
  font-weight: 600;
}

.zeit-feld__pflicht {
  margin-left: var(--space-1);
  color: var(--color-text-muted);
  font-weight: 400;
}

.zeit-feld input,
.zeit-feld select,
.zeit-feld textarea {
  width: 100%;
  box-sizing: border-box;
  min-height: var(--zeit-ziel);
  padding: var(--space-2) var(--space-3);
  border: var(--zeit-rand) solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-text);
  font: inherit;
  font-size: var(--text-sm);
  transition: border-color var(--dur-fast) var(--ease-standard);
}

.zeit-feld textarea {
  min-height: var(--space-20);
  line-height: var(--leading-normal);
  resize: vertical;
}

.zeit-feld input[type="checkbox"],
.zeit-feld input[type="radio"] {
  width: auto;
  min-height: 0;
  margin-right: var(--space-2);
}

.zeit-feld input:disabled,
.zeit-feld select:disabled,
.zeit-feld textarea:disabled {
  background: var(--color-bg-alt);
  color: var(--color-text-muted);
  cursor: not-allowed;
}

/* Breite nach Inhalt statt immer voller Breite (S-7, B67). Die Klasse
   traegt `pmls_zeit.kern.feldbreite.feldbreite()` ein (siehe dort); ein
   Feld ohne erkannte Art bleibt ohne Klasse und damit bei voller Breite -
   der unauffaelligere Fehlschlag fuer ein Notizfeld, nicht fuer eine Zahl.

   Die Breite sitzt bewusst nur am Eingabefeld, nicht an .zeit-feld selbst:
   Eine lange Beschriftung wie "Vertraglicher Jahresanspruch (Tage)" ueber
   einem schmalen Feld braeche sonst in vier Zeilen um, weil auch sie in die
   schmale Huelle gezwungen wuerde (B67, beim Screenshot-Vergleich gefunden).
   `max-width: 100%` verhindert zugleich, dass ein Feld seine eigene, u. U.
   schmalere Rasterzelle sprengt (derselbe Fund: das Eintrittsdatum lief
   sonst ueber den Bildschirmrand hinaus). */
.zeit-feld--schmal input,
.zeit-feld--schmal select {
  width: var(--zeit-feld-schmal);
  max-width: 100%;
}

.zeit-feld--mittel input,
.zeit-feld--mittel select {
  width: var(--zeit-feld-mittel);
  max-width: 100%;
}

/* Ein "breites" Feld (Notiz, Grund) soll in einem Raster ueber alle
   Spalten laufen, nicht in einer einzelnen Zelle neben den schmalen
   Zahlenfeldern stecken bleiben. */
.zeit-raster > .zeit-feld--breit {
  grid-column: 1 / -1;
}

/* S-12 (Generalprobe 28.09.2026): Ueber alle Spalten laufen heisst nicht
   ueber die ganze Bildschirmbreite - ein Grund- oder Notizfeld von 1200 px
   liess die Karten "zerklueftet" wirken. */
.zeit-feld--breit input,
.zeit-feld--breit textarea {
  max-width: var(--zeit-feld-breit);
}

/* Von Alpine gesteuerte Bereiche (x-show) bis zum Start verbergen, damit
   aufklappbare Formulare nicht kurz offen aufblitzen. */
[x-cloak] {
  display: none !important;
}

.zeit-feld__hinweis {
  margin-top: var(--space-1);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
}

.zeit-feld__fehler {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  margin-top: var(--space-1);
  color: var(--color-danger);
  font-size: var(--text-xs);
  font-weight: 600;
}

/* Der Fehler wird zusaetzlich zur Farbe durch den staerkeren Rahmen und den
   Klartext darunter getragen (DS-09). */
.zeit-feld--fehlerhaft input,
.zeit-feld--fehlerhaft select,
.zeit-feld--fehlerhaft textarea {
  border-color: var(--color-danger);
}

.zeit-feld--ankreuzen > label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 400;
}

.zeit-feldgruppe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0 var(--space-4);
}

.zeit-formular__fuss {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

/* ---------------------------------------------------------------------
   9  Tabellen (Baustein tabelle.html)

   Shop-Dichte: 44 px Zeilenhoehe, Trennlinien --color-border,
   Zebrastreifen --color-bg-alt (docs/10 Abschnitt 3).
   --------------------------------------------------------------------- */

.zeit-tabelle__huelle {
  overflow-x: auto;
}

.zeit-tabelle {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.zeit-tabelle caption {
  margin-bottom: var(--space-2);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  text-align: left;
}

.zeit-tabelle th,
.zeit-tabelle td {
  height: var(--zeit-zeile);
  padding: var(--space-2) var(--space-3);
  border-bottom: var(--zeit-rand) solid var(--color-border);
  text-align: left;
  vertical-align: middle;
}

/* Kein Verlauf auf dem Tabellenkopf (DS-08). */
.zeit-tabelle thead th {
  background: var(--color-bg-alt);
  border-bottom: var(--zeit-rand) solid var(--color-border-strong);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  white-space: nowrap;
}

.zeit-tabelle tbody tr:nth-child(even) {
  background: var(--color-bg-alt);
}

.zeit-tabelle tfoot td {
  border-top: var(--zeit-rand) solid var(--color-border-strong);
  border-bottom: none;
  font-weight: 700;
}

/* Zahlen stehen rechts und in gleicher Zeichenbreite, damit Spalten
   untereinander vergleichbar bleiben (DS-06). */
.zeit-zahl {
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* Ein klaerungsbeduerftiger Tag ist flaechig gekennzeichnet, nicht durch
   einen farbigen linken Rand (DS-07). */
.zeit-tabelle tbody tr.zeit-zeile--klaerung,
.zeit-tabelle tbody tr.zeit-zeile--klaerung:nth-child(even) {
  background: var(--color-warning-bg);
}

.zeit-tabelle tbody tr.zeit-zeile--gesperrt,
.zeit-tabelle tbody tr.zeit-zeile--gesperrt:nth-child(even) {
  background: var(--color-info-bg);
}

.zeit-tabelle tbody tr.zeit-zeile--storniert td {
  color: var(--color-text-subtle);
  text-decoration: line-through;
}

/* Urlaubsrechnung im Reiter Urlaub (Generalprobe 28.09.2026): eine schmale
   Aufstellung, keine Datentabelle ueber die volle Breite. Eine Zeile, die
   nicht mitzaehlt (hergeleiteter, noch nicht gebuchter Anspruch), steht
   gedaempft; die Summenzeile traegt einen Strich darueber. */
.zeit-urlaubsrechnung {
  width: auto;
  max-width: var(--zeit-feld-breit);
}

.zeit-urlaubsrechnung th {
  white-space: nowrap;
  font-weight: 400;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
}

.zeit-tabelle tbody tr.zeit-zeile--gedaempft th,
.zeit-tabelle tbody tr.zeit-zeile--gedaempft td {
  color: var(--color-text-subtle);
}

.zeit-tabelle tbody tr.zeit-zeile--summe th,
.zeit-tabelle tbody tr.zeit-zeile--summe td {
  border-top: calc(var(--zeit-rand) * 2) solid var(--color-text);
  font-weight: 700;
}

/* Wochenendzeile: bleibt lückenlos stehen (das PDF verlangt es, B-130),
   tritt auf dem Bildschirm aber zurück - gedaempfte Schrift statt
   Streichung, die Zeile ist ja nicht storniert. */
.zeit-tabelle tbody tr.zeit-zeile--wochenende td {
  color: var(--color-text-muted);
}

/* ---------------------------------------------------------------------
   10  Badges (Baustein badge.html)

   Volle Radien, Hintergrund aus den *-bg-Tokens. Rot ist ausschliesslich
   dem Verstoss vorbehalten (docs/10 Abschnitt 2).

   Zur Schriftfarbe: --color-warning auf --color-warning-bg ergibt 2,96:1 und
   --color-success auf --color-success-bg 3,70:1 — beides unter den 4,5:1 aus
   DS-11. Deshalb traegt die Beschriftung --color-text (13:1 und besser) und
   der Zustand steckt in Flaeche und Icon. Verstoss und Information erreichen
   mit ihrer Akzentfarbe 5,45:1 bzw. 8,71:1 und behalten sie.
   --------------------------------------------------------------------- */

.zeit-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  background: var(--color-bg-alt);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: 600;
  line-height: var(--leading-snug);
  white-space: nowrap;
}

.zeit-badge--erfolg {
  background: var(--color-success-bg);
  color: var(--color-text);
}

.zeit-badge--erfolg .zeit-icon {
  color: var(--color-success);
}

.zeit-badge--hinweis {
  background: var(--color-warning-bg);
  color: var(--color-text);
}

.zeit-badge--hinweis .zeit-icon {
  color: var(--color-warning);
}

/* Klaerungsbeduerftiger Tag: gleicher Grund wie der Hinweis, eigener Name,
   damit die Fachbedeutung im Template lesbar bleibt. */
.zeit-badge--klaerung {
  background: var(--color-warning-bg);
  color: var(--color-text);
}

.zeit-badge--klaerung .zeit-icon {
  color: var(--color-warning);
}

.zeit-badge--verstoss {
  background: var(--color-danger-bg);
  color: var(--color-danger);
}

.zeit-badge--info {
  background: var(--color-info-bg);
  color: var(--color-info);
}

.zeit-badge--neutral {
  background: var(--color-bg-alt);
  color: var(--color-text-muted);
}

/* ---------------------------------------------------------------------
   11  Saldo (Baustein saldo.html)

   Ein Minus im Gleitzeitkonto ist kein Fehler. Es rot einzufaerben machte
   aus der Zeiterfassung ein Bewertungsinstrument — genau das schliesst
   docs/02 R-20 aus. Rot bleibt Verstoessen vorbehalten.

   Entscheidung zu OP-32: Die Zahl steht IMMER in --color-text. Gemessen
   erreichen --color-success 4,31:1 und --color-warning 3,25:1 auf Weiss;
   DS-11 verlangt 4,5:1, und die Palette hat kein dunkleres Gruen oder
   Amber. Den Zustand traegt daher das Vorzeichen (immer da) und ein Badge
   auf der zugehoerigen -bg-Flaeche, auf der --color-text 4,5:1 sicher
   ueberschreitet. Eine Regel, keine Groessenfallunterscheidung.
   --------------------------------------------------------------------- */

.zeit-saldo {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  white-space: nowrap;
}

/* Der Zustandshinweis. Klein, in Klartext, auf einer Tokenflaeche - und
   damit auch in Graustufen unterscheidbar (DS-09). */
.zeit-saldo__zustand {
  padding: 0 var(--space-2);
  border-radius: var(--radius-full);
  color: var(--color-text);
  font-size: var(--text-xs);
  font-weight: 600;
  white-space: nowrap;
}

.zeit-saldo__zustand--positiv {
  background: var(--color-success-bg);
}

.zeit-saldo__zustand--ausserhalb {
  background: var(--color-warning-bg);
}

/* ---------------------------------------------------------------------
   12  Hinweisbanner und Meldungen (Baustein hinweisbanner.html)
   --------------------------------------------------------------------- */

.zeit-banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: var(--zeit-rand) solid transparent;
  border-radius: var(--radius-md);
  background: var(--color-bg-alt);
  color: var(--color-text);
  font-size: var(--text-sm);
}

.zeit-banner__icon {
  flex: none;
  margin-top: var(--space-1);
}

.zeit-banner__text {
  flex: 1;
}

.zeit-banner__titel {
  display: block;
  margin-bottom: var(--space-1);
  font-weight: 700;
}

.zeit-banner__aktion {
  flex: none;
  align-self: center;
}

.zeit-banner--info {
  background: var(--color-info-bg);
  border-color: var(--pmls-tekhelet-20);
}

.zeit-banner--info .zeit-banner__icon {
  color: var(--color-info);
}

.zeit-banner--hinweis {
  background: var(--color-warning-bg);
}

.zeit-banner--hinweis .zeit-banner__icon {
  color: var(--color-warning);
}

.zeit-banner--erfolg {
  background: var(--color-success-bg);
}

.zeit-banner--erfolg .zeit-banner__icon {
  color: var(--color-success);
}

.zeit-banner--verstoss {
  background: var(--color-danger-bg);
}

.zeit-banner--verstoss .zeit-banner__icon {
  color: var(--color-danger);
}

/* Meldungen aus django.contrib.messages nutzen dieselbe Gestalt. Die
   Klassennamen stammen aus Block B0 und bleiben erhalten. */
.zeit-meldung {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
  font-size: var(--text-sm);
}

.zeit-meldung--hinweis {
  background: var(--color-warning-bg);
  color: var(--color-text);
}

.zeit-meldung--fehler {
  background: var(--color-danger-bg);
  color: var(--color-text);
}

.zeit-meldung--info {
  background: var(--color-info-bg);
  color: var(--color-text);
}

.zeit-meldung--erfolg {
  background: var(--color-success-bg);
  color: var(--color-text);
}

/* ---------------------------------------------------------------------
   13  Leerer Zustand (Baustein leerer_zustand.html)

   Shop-Muster: ein Icon, ein kurzer Satz, eine Handlung.
   --------------------------------------------------------------------- */

.zeit-leer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-10) var(--space-6);
  text-align: center;
}

.zeit-leer__icon {
  color: var(--color-text-subtle);
}

.zeit-leer__text {
  margin: 0;
  max-width: 32rem;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

/* ---------------------------------------------------------------------
   14  Icons (Baustein icon.html)

   Inline-SVG aus theme/pmls/icons/lucide/, Strichstaerke 1.5, 20 oder
   24 px (DS-04). Kein CDN, kein Nachladen.
   --------------------------------------------------------------------- */

.zeit-icon {
  display: inline-block;
  flex: none;
  vertical-align: text-bottom;
  color: inherit;
}

/* ---------------------------------------------------------------------
   15  Beschreibungsliste, Reiter, Trennlinie, Raster
   --------------------------------------------------------------------- */

.zeit-liste {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-2) var(--space-6);
  margin: 0;
  font-size: var(--text-sm);
}

.zeit-liste dt {
  color: var(--color-text-muted);
}

.zeit-liste dd {
  margin: 0;
  font-weight: 600;
}

.zeit-reiter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  border-bottom: var(--zeit-rand) solid var(--color-border);
}

.zeit-reiter__punkt {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--zeit-ziel);
  padding: var(--space-2) var(--space-4);
  border-bottom: 2px solid transparent;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
  font-weight: 500;
  text-decoration: none;
}

.zeit-reiter__punkt:hover {
  color: var(--color-primary);
  text-decoration: none;
}

.zeit-reiter__punkt[aria-current="page"] {
  border-bottom-color: var(--color-primary);
  color: var(--color-primary);
  font-weight: 700;
}

.zeit-trenner {
  height: var(--zeit-rand);
  margin: var(--space-6) 0;
  border: none;
  background: var(--color-border);
}

.zeit-raster {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
}

/* Fuer kurze Kacheln wie Kennzahlen: mehr Spalten auf gleicher Breite. */
.zeit-raster--eng {
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
}

/* Wegweiser-Kacheln der Startseite: auto-fill haelt leere Spalten frei, damit
   eine Gruppe mit nur zwei Kacheln so breit bleibt wie die volle Gruppe
   darueber, statt sich ueber die ganze Zeile zu dehnen (Generalprobe,
   28.09.2026). */
.zeit-raster--wegweiser {
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
}

.zeit-stapel {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* Kennzahl, wie sie die Monatsuebersicht braucht. Keine Kachelwand — die
   Zeiterfassung zeigt Listen (docs/10 Abschnitt 4). */
.zeit-kennzahl__beschriftung {
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
}

.zeit-kennzahl__wert {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-3xl);
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  line-height: var(--leading-tight);
}

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

   Einer der beiden Orte, an denen der Markenverlauf erlaubt ist — der
   andere ist der PDF-Kopf (DS-08).
   --------------------------------------------------------------------- */

.zeit-anmeldung {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: var(--gradient-brand);
  padding: var(--space-6);
}

.zeit-anmeldung__karte {
  width: 100%;
  max-width: 26rem;
  background: var(--color-bg);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: var(--space-8);
}

/* Die Bildmarke allein, in Lesegroesse und mittig ueber der Ueberschrift.
   In der Kopfleiste steht sie bei --space-8; hier ist Platz und sie traegt
   die Seite (Befund B-11). */
.zeit-anmeldung__marke {
  display: block;
  height: var(--space-16);
  width: auto;
  margin: 0 auto var(--space-4);
}

/* Der Name unter der Bildmarke. Eigene Klasse statt zeit-seitenkopf__titel:
   Diese Seite hat keinen Seitenkopf, und eine Anleihe dort haette bedeutet,
   dass eine spaetere Aenderung am Seitenkopf die Anmeldeseite mitzieht, ohne
   dass es jemand bemerkt. Bis zum 02.09.2026 trug die Ueberschrift gar keine
   Klasse und damit die Browservorgaben fuer Groesse und Abstand (Befund B-43,
   fuenfzehnte Fundstelle). */
.zeit-anmeldung__titel {
  margin: 0 0 var(--space-6);
  font-size: var(--text-3xl);
  font-weight: 700;
  line-height: var(--leading-tight);
  /* Mittig unter der Bildmarke, die schon zentriert steht (22.09.2026). */
  text-align: center;
}

/* Der Absendeknopf steht mittig unter den beiden Feldern. Eigene Klasse statt
   einer Regel auf `form .zeit-knopf`: Die Felder darueber sollen weiterhin
   die volle Breite behalten, nur der Knopf wird zentriert. */
.zeit-anmeldung__absenden {
  display: block;
  margin-inline: auto;
}

/* Der Nebenweg unter dem Knopf steht ebenfalls mittig — sonst waere er das
   einzige linksbuendige Element der Karte (22.09.2026). Der groessere Abstand
   nach oben trennt ihn vom Absendeknopf: Er ist eine Alternative zum
   Anmelden, keine Fussnote dazu. */
.zeit-anmeldung__nebenweg {
  text-align: center;
  margin-block: var(--space-6) 0;
}

/* ---------------------------------------------------------------------
   17  Hilfsklassen und Bewegung
   --------------------------------------------------------------------- */

/* Text, den nur ein Screenreader liest — etwa die Klartextfassung einer
   Kennzeichnung, die auf dem Schirm das Icon traegt (DS-09). */
.nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.zeit-gedaempft {
  color: var(--color-text-muted);
}

.zeit-rechts {
  text-align: right;
}

/* Bewegung ist funktional. Wer sie abbestellt hat, bekommt keine. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* Bildschirmausdruck einer Weboberflaeche. Der eigentliche Nachweis wird
   von WeasyPrint mit pdf.css erzeugt. */
@media print {
  .zeit-kopf,
  .zeit-sprungmarke,
  .zeit-seitenkopf__aktionen,
  .zeit-knopfreihe {
    display: none;
  }

  body {
    background: var(--color-bg);
  }

  .zeit-karte {
    border-color: var(--color-border-strong);
    box-shadow: none;
  }
}

/* ---------------------------------------------------------------------
   18  Kalenderraster (Baustein _kalenderraster.html, Block B18)

   Eine Zeile je Person, eine Spalte je Tag — dieselbe Tabellendichte wie
   .zeit-tabelle, nur mit schmalen Tagesspalten. Wochenenden, Feiertage und
   Betriebsruhetage sind ueber die Flaeche abgesetzt (--color-bg-alt), eine
   belegte Zelle traegt zusaetzlich zur Flaeche ein sichtbares Zeichen — Farbe
   allein ist nie die einzige Auskunft (DS-09). Ob eine Zelle die Art oder nur
   "belegt" zeigt, entscheidet die Datenaufbereitung (OP-71), nicht diese
   Datei.
   --------------------------------------------------------------------- */

.zeit-kalender__huelle {
  overflow-x: auto;
}

/* `table-layout: fixed` nimmt die Spaltenbreiten aus der **ersten Zeile** und
   ignoriert jedes `min-width` an den Zellen. Zusammen mit `width: 100%` aus
   .zeit-tabelle teilte der Browser die Breite auf 32 gleiche Spalten auf: Die
   Namensspalte war so breit wie ein Tag, und weil sie `white-space: nowrap`
   und `position: sticky` traegt, lief der Name ueber die ersten Tagesspalten
   ("Clara Testschmidt steht bis zum 03. Tag", 03.09.2026).

   Deshalb `width` statt `min-width`, und `width: auto` statt der geerbten
   100 % — erst dann darf die Tabelle breiter werden als ihre Huelle, und erst
   dann greift deren `overflow-x: auto`. */
.zeit-kalender {
  table-layout: fixed;
  width: auto;
  min-width: 100%;
}

.zeit-kalender th,
.zeit-kalender td {
  width: var(--zeit-kalender-spalte);
  height: var(--space-8);
  padding: var(--space-1);
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.zeit-kalender th[scope="row"],
.zeit-kalender thead th:first-child {
  width: var(--zeit-kalender-namensspalte);
}

.zeit-kalender th[scope="row"] {
  position: sticky;
  left: 0;
  z-index: 1;
  padding-right: var(--space-3);
  background: var(--color-bg);
  text-align: left;
  font-size: var(--text-sm);
  font-weight: 600;
  /* Ein Name, der laenger ist als die Spalte, wird abgeschnitten statt ueber
     den Kalender zu laufen. Vollstaendig steht er in der vorlesbaren Fassung
     und im Titel der Zeile. */
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.zeit-kalender thead th[scope="col"] {
  background: var(--color-bg-alt);
  color: var(--color-text-muted);
  font-size: var(--text-xs);
  font-weight: 700;
}

/* Wochenende, Feiertag oder Betriebsruhetag — abgesetzt durch die Flaeche,
   nicht nur durch einen Farbton (die Kopfzeile traegt zusaetzlich den
   Klartext fuer Bildschirmleser in .nur-vorlesen). */
.zeit-kalender th.zeit-kalender__frei,
.zeit-kalender td.zeit-kalender__frei {
  background: var(--color-bg-alt);
}

/* Eine belegte Zelle: eigene Flaeche und ein sichtbares Zeichen (DS-09). */
.zeit-kalender td.zeit-kalender__belegt {
  background: var(--color-info-bg);
  color: var(--color-info);
  font-weight: 700;
}

/* Kuerzel der Abwesenheitsart statt eines blossen Kreuzes (B-131). Mehrere
   Kuerzel bei einer Ueberlagerung (B-133) stehen untereinander, weil die
   Spalte dafuer zu schmal ist. */
.zeit-kalender__kuerzel {
  display: block;
  line-height: 1.2;
  font-size: var(--text-xs);
}

/* Legende unter dem Raster: nur die Arten, die tatsaechlich vorkommen. */
.zeit-kalender__legende {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}

.zeit-kalender__legende-kuerzel {
  display: inline-block;
  min-width: 1.75rem;
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
  background: var(--color-info-bg);
  color: var(--color-info);
  font-weight: 700;
  text-align: center;
}



/* ---------------------------------------------------------------------
   19  Jahresraster (Baustein _jahresraster.html)

   Zwoelf Zeilen, eine je Monat, und einunddreissig Tagesspalten. Die
   Alternative war ein Raster mit einer Zeile und 365 Spalten - technisch
   dasselbe, praktisch nicht zu entziffern (Befund B-29).

   Die Spalten sind schmaler als im Monatsraster, weil hier keine Namen
   stehen, sondern nur Tagesnummern. Farben und Radien kommen wie ueberall
   aus den Tokens (DS-02); eine belegte Zelle traegt zusaetzlich ein
   sichtbares Zeichen (DS-09).
   --------------------------------------------------------------------- */

.zeit-jahr__huelle {
  overflow-x: auto;
}

/* Dieselbe Falle wie beim Kalenderraster darueber: `min-width` ist unter
   `table-layout: fixed` wirkungslos. Hier fiel sie nicht auf, weil in der
   Monatsspalte nur ein Kuerzel steht ("Jan"). Latent war sie trotzdem. */
.zeit-jahr {
  table-layout: fixed;
  border-collapse: collapse;
  width: auto;
  min-width: 100%;
}

.zeit-jahr th,
.zeit-jahr td {
  width: var(--zeit-jahr-spalte);
  height: var(--space-6);
  padding: 0;
  border: 1px solid var(--color-border);
  text-align: center;
  font-size: var(--text-xs);
  font-variant-numeric: tabular-nums;
}

.zeit-jahr th[scope="row"],
.zeit-jahr thead th:first-child {
  width: var(--zeit-jahr-monatsspalte);
}

.zeit-jahr th[scope="row"] {
  position: sticky;
  left: 0;
  z-index: 1;
  padding: 0 var(--space-2);
  background: var(--color-bg);
  text-align: left;
  font-weight: 600;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.zeit-jahr thead th[scope="col"] {
  background: var(--color-bg-alt);
  color: var(--color-text-muted);
  font-weight: 700;
}

/* Wochenende, Feiertag oder Betriebsruhetag. */
.zeit-jahr td.zeit-jahr__frei {
  background: var(--color-bg-alt);
}

/* Ein Tag, den dieser Monat nicht hat (31. Februar) - keine Bedeutung,
   deshalb ohne Rahmen und ohne Flaeche. */
.zeit-jahr td.zeit-jahr__ausserhalb {
  border: 0;
  background: transparent;
}

/* Eine belegte Zelle: eigene Flaeche und ein sichtbares Zeichen (DS-09). */
.zeit-jahr td.zeit-jahr__belegt {
  background: var(--color-info-bg);
  color: var(--color-info);
  font-weight: 700;
}

/* Kuerzel der Abwesenheitsart statt eines blossen Kreuzes (B-131); die
   Schriftgroesse kommt bereits von `.zeit-jahr td` (--text-xs). Mehrere
   Kuerzel bei einer Ueberlagerung (B-133) stehen nebeneinander. */
.zeit-jahr__kuerzel + .zeit-jahr__kuerzel {
  margin-left: 1px;
}

/* ---------------------------------------------------------------------
   Stoerfallfenster (Baustein stoerfallfenster.html, OP-107)

   Ein Fenster, das aktiv weggeklickt werden muss. Nur fuer Stoerfaelle:
   vergessene Ausstempelung, Buchung trotz Abwesenheit, Sperre. Der Knopf
   traegt --gross und --breit, weil dieselbe Vorlage im Kiosk mit Handschuhen
   getippt wird - OP-107 verlangt dort mindestens 64 px.
   --------------------------------------------------------------------- */

.zeit-stoerfall {
  max-width: 34rem;
  padding: var(--space-6);
  border: none;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  background: var(--color-surface);
  color: var(--color-text);
  text-align: center;
}

/* Der abgedunkelte Grund kommt aus dem Token, nicht aus einem eigenen
   Farbwert (DS-02); die Transparenz macht opacity statt rgba(). Das traegt
   auch auf einem aelteren Tablet, das color-mix() nicht kennt. */
.zeit-stoerfall::backdrop {
  background: var(--color-text);
  opacity: 0.55;
}

.zeit-stoerfall__icon {
  margin: 0 0 var(--space-3);
  color: var(--color-danger);
}

.zeit-stoerfall__titel {
  margin: 0 0 var(--space-3);
  font-size: var(--text-2xl);
  font-weight: 600;
}

.zeit-stoerfall__text {
  margin: 0 0 var(--space-6);
  font-size: var(--text-base);
}

/* Derselbe Baustein steht im Kiosk, und dort wird mit Handschuhen getippt:
   OP-107 verlangt mindestens 64 px - dasselbe Mass, das kiosk.css fuer seine
   Tasten benutzt. Die Groesse haengt deshalb am Fenster und nicht daran,
   welche Knopfklasse die aufrufende Seite gerade mitgibt. */
.zeit-stoerfall .zeit-knopf {
  min-height: var(--space-16); /* 64 px */
}

/* --- OP-53 / B-143 (Nacharbeit Welle 16, abschluss/leitung_monat.html) --- */

/* OP-53: Blendet den Freitext-Grund aus, solange „Bestätigung nicht
   einholbar" gewählt ist — reines CSS, kein Skript. Ohne CSS bleibt das
   Feld sichtbar, aber ungenutzt; der Dienst verwirft seinen Inhalt für
   diese Kategorie ohnehin (`freigabe.freigeben`). */
input[name="grund_kategorie"][value="BESTAETIGUNG_NICHT_EINHOLBAR"]:checked
  ~ .ohne-bestaetigung-freitext {
  display: none;
}

/* B-143: <summary> als Knopf (Muster bereits in kontobuchung.html,
   „Stornieren") ohne den Standard-Dreieckmarker des Browsers — nur Tokens,
   keine neue Farbe. Gilt auch rückwirkend für die bestehende Verwendung. */
summary.zeit-knopf {
  list-style: none;
  cursor: pointer;
}

summary.zeit-knopf::-webkit-details-marker {
  display: none;
}

/* B72, G-17: Ein leerer Werktag im Teamkalender der Leitung ist ein Link zu
   „Abwesenheit eintragen" mit Person und Tag. Die Flaeche fuellt die ganze
   Zelle, damit sie mit dem Finger zu treffen ist; sichtbar wird sie erst bei
   Fokus oder Zeigen (die Tastatur bekommt den Fokusring, keine Hover-
   Abhaengigkeit). Nur Tokens, keine eigenen Werte. */
.zeit-kalender__leer {
  display: block;
  width: 100%;
  height: var(--space-8);
  border-radius: var(--radius-md);
}

.zeit-kalender__leer:hover {
  background: var(--color-info-bg);
}

.zeit-kalender__leer:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}

/* B72, G-17: Der Kalender hat keine Zebrastreifen. Mit allen Personen in der
   Tabelle ueberdeckte der Streifen jeder zweiten Zeile die Absetzung von
   Wochenenden und Feiertagen, und ein leerer, anklickbarer Werktag sah aus
   wie ein Samstag. Jede Zeile zeigt Werktage hell, freie Tage abgesetzt. */
.zeit-kalender tbody tr:nth-child(even) {
  background: transparent;
}

/* --- B73 / S-15 (abschluss/_monatskarte.html) -------------------------- */

/* Karte je Person im Monatsabschluss: drei Spalten — Zahlen untereinander,
   Unterlagen, Entscheidung —, der Stand als Plakette im Kopf, Hinweise ueber
   die volle Breite darunter. Auf schmalem Bildschirm untereinander.
   Nur Tokens, keine eigenen Mass- oder Farbwerte (DS-02).

   Knoepfe und Felder fuellen nie die Spalte: Die erste Skizze der
   Personenseite hat Christopher wegen genau dessen abgelehnt (OP-151). */
.zeit-monatskarte__spalten {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-6);
}

.zeit-monatskarte__spalte {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  min-width: 0;
}

.zeit-monatskarte__spalte > form,
.zeit-monatskarte__spalte > details {
  align-self: stretch;
}

.zeit-monatskarte__ueberschrift {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text-muted);
}

.zeit-monatskarte__spalte .zeit-feld {
  margin-bottom: var(--space-3);
}

.zeit-monatskarte__spalte .zeit-feld textarea {
  max-width: 28rem;
}

.zeit-monatskarte__hinweise {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: var(--zeit-rand) solid var(--color-border);
}

.zeit-monatskarte__hinweise p {
  margin: 0;
}

@media (max-width: 56rem) {
  .zeit-monatskarte__spalten {
    grid-template-columns: minmax(0, 1fr);
  }
}
