/* SPDX-License-Identifier: Apache-2.0 — Webkultur GmbH
 *
 * Eigenes, schlankes CSS. Kein Framework, kein CDN: die App darf nichts aus
 * dem Netz holen (VPN-intern), und ein Tailwind-Werkzeugkasten waere fuer
 * eine Handvoll Ansichten mehr Bau als Nutzen.
 *
 * ANMUTUNG bewusst wie die zugekauften Schwester-Apps (Urlaubsverwaltung und
 * Zeiterfassung von focus shift), weil die Praxis alle drei im selben Atemzug
 * benutzt: ruhige Zinc-Graustufen, gruene Hauptaktion, 0.875rem in
 * Bedienelementen, 6px Eckenradius, blauer Fokusring, drei Themen
 * (System/Hell/Dunkel) ueber eine Klasse am <html>.
 *
 * Herkunft der Werte: die Farbrollen und Abstaende sind an der
 * **Urlaubsverwaltung** (Apache-2.0, github.com/urlaubsverwaltung/urlaubsverwaltung,
 * src/main/css/theme.css und components/*.css) abgelesen; die dortigen Werte
 * sind die Tailwind-Standardpalette (MIT). Uebernommen sind nur Farbwerte und
 * Maße — kein Code, kein CSS, keine Templates. Aus der Zeiterfassung ist
 * NICHTS uebernommen (AGPL-3.0, Netzwerk-Copyleft; siehe
 * docs/konzept-dienstplanung.md).
 */

/* --- Farbrollen: hell ---------------------------------------------------- */
:root {
  color-scheme: light;

  --grund: #fafafa;          /* zinc-50   */
  --flaeche: #ffffff;
  --flaeche-leise: #f4f4f5;  /* zinc-100  */
  --flaeche-tot: #e4e4e7;    /* zinc-200  */
  --linie: #e4e4e7;          /* zinc-200  */
  --linie-stark: #d4d4d8;    /* zinc-300  */
  --text: #27272a;           /* zinc-800  */
  --text-leise: #52525b;     /* zinc-600  */
  --text-schwach: #71717a;   /* zinc-500  */

  --haupt: #15803d;          /* green-700 */
  --haupt-rand: #166534;     /* green-800 */
  --haupt-leise: #f0fdf4;    /* green-50  */
  --haupt-text: #ffffff;

  --info: #1d4ed8;           /* blue-700  */
  --info-leise: #eff6ff;     /* blue-50   */
  --fokus: #93c5fd;          /* blue-300  */

  --warn: #b45309;           /* amber-700 */
  --warn-leise: #fffbeb;     /* amber-50  */
  --warn-rand: #fcd34d;      /* amber-300 */

  --gefahr: #b91c1c;         /* red-700   */
  --gefahr-leise: #fef2f2;   /* red-50    */
  --gefahr-rand: #fca5a5;    /* red-300   */

  --besetzt: #dbeafe;        /* blue-100  */
  --besetzt-rand: #1d4ed8;
  --besetzt-text: #1e3a8a;   /* blue-900  */

  --radius: 6px;
  --radius-klein: 4px;
  --schrift: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    sans-serif;
  --bedien-groesse: 0.875rem;
  --kopf-hoehe: 3.5rem;
  /* 32px je Kachel-Spur = Balkenhoehe der Vorlage (ohne Kopfzeile). */
  --kachelhoehe: 2rem;
  --schatten: 0 1px 2px rgb(0 0 0 / 0.05);
}

/* --- Farbrollen: dunkel -------------------------------------------------- */
/* Zwei Wege, dasselbe Ergebnis: System-Einstellung (Klasse theme-system, der
 * Startwert) und ausdrueckliche Wahl (theme-dark). Jede Rolle wird hier neu
 * gesetzt -- genau das fehlte vorher, weshalb dunkel schwarze Baender ueber
 * den Zellen zeigte. */
@media (prefers-color-scheme: dark) {
  html.theme-system {
    color-scheme: dark;
    --grund: #18181b;          /* zinc-900 */
    --flaeche: #27272a;        /* zinc-800 */
    --flaeche-leise: #1f1f23;
    --flaeche-tot: #202024;
    --linie: #3f3f46;          /* zinc-700 */
    --linie-stark: #52525b;    /* zinc-600 */
    --text: #f4f4f5;           /* zinc-100 */
    --text-leise: #d4d4d8;     /* zinc-300 */
    --text-schwach: #a1a1aa;   /* zinc-400 */

    --haupt: #15803d;
    --haupt-rand: #16a34a;
    --haupt-leise: #14251a;
    --haupt-text: #f0fdf4;

    --info: #93c5fd;
    --info-leise: #1e293b;
    --fokus: #93c5fd;

    --warn: #fcd34d;
    --warn-leise: #2a2010;
    --warn-rand: #b45309;

    --gefahr: #fca5a5;
    --gefahr-leise: #2a1516;
    --gefahr-rand: #b91c1c;

    --besetzt: #1e3a5f;
    --besetzt-rand: #60a5fa;
    --besetzt-text: #dbeafe;

    --schatten: 0 1px 2px rgb(0 0 0 / 0.4);
  }
}

html.theme-dark {
  color-scheme: dark;
  --grund: #18181b;
  --flaeche: #27272a;
  --flaeche-leise: #1f1f23;
  --flaeche-tot: #202024;
  --linie: #3f3f46;
  --linie-stark: #52525b;
  --text: #f4f4f5;
  --text-leise: #d4d4d8;
  --text-schwach: #a1a1aa;

  --haupt: #15803d;
  --haupt-rand: #16a34a;
  --haupt-leise: #14251a;
  --haupt-text: #f0fdf4;

  --info: #93c5fd;
  --info-leise: #1e293b;
  --fokus: #93c5fd;

  --warn: #fcd34d;
  --warn-leise: #2a2010;
  --warn-rand: #b45309;

  --gefahr: #fca5a5;
  --gefahr-leise: #2a1516;
  --gefahr-rand: #b91c1c;

  --besetzt: #1e3a5f;
  --besetzt-rand: #60a5fa;
  --besetzt-text: #dbeafe;

  --schatten: 0 1px 2px rgb(0 0 0 / 0.4);
}

/* --- Grundlagen --------------------------------------------------------- */
* { box-sizing: border-box; }

/* Das `hidden`-Attribut muss auch Elemente mit eigenem `display` verbergen
 * (z.B. `.knopf { display: inline-flex }`) — sonst zeigt der Bedarfs-Dialog
 * „zurueck zum Template" auch bei einem Template-Balken. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font: 15px/1.5 var(--schrift);
  color: var(--text);
  background: var(--grund);
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 { font-weight: 600; letter-spacing: -0.01em; }
a { color: var(--info); }

:focus-visible {
  outline: 2px solid var(--fokus);
  outline-offset: 2px;
}

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

/* --- Kopfzeile ---------------------------------------------------------- */
.kopf {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: var(--kopf-hoehe);
  padding: 0 1.25rem;
  background: var(--flaeche);
  border-bottom: 1px solid var(--linie);
  box-shadow: var(--schatten);
}

.kopf .marke {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--text);
  text-decoration: none;
}

.marke-punkt {
  width: 0.7rem; height: 0.7rem;
  border-radius: 999px;
  background: var(--haupt);
  box-shadow: 0 0 0 3px var(--haupt-leise);
}

/* `> nav`, NICHT `nav`: der Wechsler ist selbst ein `<nav>` im Kopf, und mit
   dem Nachfahren-Selektor wurde sein Aufklapp-Panel zu einer waagerechten
   Flex-Zeile ueber die halbe Bildschirmbreite. Gemeint war immer nur die
   Hauptnavigation — sie ist ein direktes Kind. */
.kopf > nav { display: flex; gap: 1rem; }
.kopf > nav a {
  color: var(--text-leise);
  text-decoration: none;
  font-size: var(--bedien-groesse);
  padding: 0.35rem 0.5rem;
  border-radius: var(--radius-klein);
}
.kopf > nav a:hover { background: var(--flaeche-leise); color: var(--text); }

.kopf-rechts { margin-left: auto; display: flex; align-items: center; gap: 1rem; }
.benutzer { color: var(--text-schwach); font-size: var(--bedien-groesse); }

/* Segmentierter Umschalter System / Hell / Dunkel */
.thema-wahl {
  display: flex;
  gap: 0;
  margin: 0;
  padding: 2px;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  background: var(--flaeche-leise);
}
.thema-wahl label {
  position: relative;
  font-size: 0.78rem;
  color: var(--text-leise);
  padding: 0.25rem 0.55rem;
  border-radius: var(--radius-klein);
  cursor: pointer;
}
.thema-wahl input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.thema-wahl input:checked + span { font-weight: 600; color: var(--text); }
.thema-wahl label:has(input:checked) { background: var(--flaeche); box-shadow: var(--schatten); }
.thema-wahl label:has(input:focus-visible) { outline: 2px solid var(--fokus); outline-offset: 1px; }

main { padding: 1.25rem; }

/* Band ueber dem Inhalt: eine ablaufende Frist (Testzeitraum). Bewusst kein
   Dialog und nichts zum Wegklicken -- eine Warnung, die man schliessen kann,
   ist am dritten Tag geschlossen und am siebten vergessen. */
.frist-band {
  margin: 0;
  padding: 0.6rem 1.25rem;
  border-bottom: 1px solid var(--warn-rand);
  background: var(--warn-leise);
  color: var(--text);
  font-size: var(--bedien-groesse);
  line-height: 1.45;
}

.fuss {
  padding: 1rem 1.25rem 2rem;
  border-top: 1px solid var(--linie);
  color: var(--text-schwach);
  font-size: 0.8rem;
}

/* --- Knoepfe ------------------------------------------------------------ */
.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0.45rem 0.75rem;
  font: 500 var(--bedien-groesse)/1.2 var(--schrift);
  color: var(--text-leise);
  background: var(--flaeche-leise);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  text-decoration: none;
  cursor: pointer;
  transition: background 100ms ease-in-out, border-color 100ms ease-in-out;
}
.knopf:hover:not(:disabled) { background: var(--flaeche-tot); color: var(--text); }
.knopf:disabled { opacity: 0.6; cursor: not-allowed; }
.knopf-schmal { padding: 0.3rem 0.55rem; }
.knopf-haupt {
  color: var(--haupt-text);
  background: var(--haupt);
  border-color: var(--haupt-rand);
}
.knopf-haupt:hover:not(:disabled) { background: var(--haupt-rand); color: var(--haupt-text); }
.knopf-gefahr { color: var(--gefahr); border-color: var(--gefahr-rand); background: var(--gefahr-leise); }

/* --- Kopf des Rasters --------------------------------------------------- */
.raster-kopf {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  margin-bottom: 0.9rem;
}
.wochenwahl { display: flex; align-items: center; gap: 0.6rem; }
.wochenwahl h1 { font-size: 1.15rem; margin: 0; }
.wochenwahl h1 small { display: block; font-weight: 400; font-size: 0.78rem; color: var(--text-schwach); }

/* Freie Wochenwahl: Liste + Jahr + Anzeigen, dahinter die beiden Schnellspruenge.
   Bewusst dieselbe Hoehe und Randfarbe wie die Pfeilknoepfe daneben — es ist eine
   Leiste, nicht zwei. `flex-wrap` laesst sie auf schmalen Fenstern umbrechen,
   statt das Raster nach rechts zu schieben. */
.wochensprung { display: flex; flex-wrap: wrap; align-items: center; gap: 0.35rem; margin-left: 0.4rem; }
.wochensprung select, .wochensprung input {
  font: var(--bedien-groesse) var(--schrift);
  padding: 0.3rem 0.4rem; color: var(--text); background: var(--flaeche);
  border: 1px solid var(--linie-stark); border-radius: var(--radius);
}
.wochensprung-jahr { width: 5.2rem; }
/* Man steht schon in dieser Woche: der Knopf bleibt bedienbar (Neuladen), sagt
   den Zustand aber an — aria-current traegt die Aussage, die Farbe folgt ihr. */
.wochensprung-jetzt[aria-current] {
  color: var(--haupt-text); background: var(--haupt); border-color: var(--haupt-rand);
}

/* Kennzahlen = Filter. Drei Kacheln sind Knoepfe (aria-pressed), „Fehlende
   Stunden" ist eine Summe ohne Knopf. Masse aus der Vorlage: Name 10.5px
   Versalien, Wert 17px. Gedrueckt = gefuellt in der Signalfarbe des Fensters,
   das der Filter zeigt (gelb = unter Soll, rot = unter Minimum). */
.kennzahlen { display: flex; gap: 0.5rem; margin: 0; }
.kennzahl {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0.3rem 0.65rem;
  font: inherit;
  color: var(--text);
  text-align: left;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 100ms ease-in-out, border-color 100ms ease-in-out;
}
.kennzahl:hover:not(.kennzahl-summe) { background: var(--flaeche-leise); border-color: var(--linie-stark); }
.kennzahl-summe { cursor: default; border-color: transparent; background: transparent; }
.kennzahl-name {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-schwach);
  white-space: nowrap;
}
.kennzahl-name small { font-size: 9px; letter-spacing: 0; text-transform: none; opacity: 0.8; }
.kennzahl-wert { font-size: 17px; font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; }
.kennzahl.warnung .kennzahl-wert { color: var(--gefahr); }
.kennzahl[aria-pressed="true"] { background: var(--info-leise); border-color: var(--info); }
.kennzahl[aria-pressed="true"] .kennzahl-name { color: var(--text); }
.kennzahl-soll[aria-pressed="true"] { background: var(--warn-leise); border-color: var(--warn); }
.kennzahl-minimum[aria-pressed="true"] { background: var(--gefahr-leise); border-color: var(--gefahr); }

.status {
  margin-left: auto;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  font-size: 0.78rem;
  border: 1px solid var(--linie-stark);
  background: var(--flaeche-leise);
  color: var(--text-leise);
}
.status-veroeffentlicht { background: var(--haupt-leise); border-color: var(--haupt); color: var(--haupt); }

/* --- Veroeffentlichen-Ablauf (Ebene 4) --------------------------------- */
.veroeffentlichung {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.7rem;
  margin-left: auto;
}
.veroeffentlichung .status { margin-left: 0; }
.veroeff-info {
  font-size: 0.72rem;
  color: var(--text-schwach);
  font-variant-numeric: tabular-nums;
}
.veroeff-geaendert {
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.72rem;
  border: 1px solid var(--gefahr-rand);
  background: var(--gefahr-leise);
  color: var(--gefahr);
}

.meldung {
  margin: 0 0 0.8rem;
  min-height: 1.2rem;
  font-size: var(--bedien-groesse);
  color: var(--text-leise);
}
.meldung:empty { margin: 0; min-height: 0; }
.meldung[data-art="fehler"] {
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--gefahr-rand);
  border-left: 4px solid var(--gefahr);
  border-radius: var(--radius);
  background: var(--gefahr-leise);
  color: var(--gefahr);
}
.meldung[data-art="erfolg"] {
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--linie-stark);
  border-left: 4px solid var(--haupt);
  border-radius: var(--radius);
  background: var(--haupt-leise);
}

.hinweis {
  padding: 0.9rem 1.1rem;
  background: var(--warn-leise);
  border: 1px solid var(--warn-rand);
  border-radius: var(--radius);
  color: var(--text);
}

/* --- Arbeitsflaeche: Leute + Raster ------------------------------------- */
.arbeitsflaeche {
  display: grid;
  grid-template-columns: 292px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
@media (max-width: 900px) {
  .arbeitsflaeche { grid-template-columns: minmax(0, 1fr); }
}

.leute {
  position: sticky;
  top: calc(var(--kopf-hoehe) + 1rem);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
}
.leute h2 { margin: 0 0 2px; font-size: 14px; }
.leute-hilfe { margin: 0 0 6px; font-size: 12px; line-height: 1.4; color: var(--text-schwach); }
.leute-lage { margin: 0; font-size: 12px; color: var(--text-leise); }
.leute-lage:empty { display: none; }
/* Im Abschnitt-Modus wird die Lagezeile der Filter-Chip der Vorlage. */
.leute[data-modus="slot"] .leute-lage {
  padding: 8px 10px;
  background: var(--haupt-leise);
  border: 1px solid var(--haupt);
  border-radius: var(--radius);
}
/* „andere Zeiten" nur, wenn ein Abschnitt aktiv ist (freie Zeitwahl im Dialog). */
.leute-zeiten { display: none; }
.leute[data-modus="slot"] .leute-zeiten { display: inline-flex; align-self: flex-start; }
.leute-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }

/* Person = Avatar + Info (Name, Quali-Chips, Stunden, Hinweis). Masse aus der
   Vorlage: Avatar 34px, Rand 2px, Innenabstand 10/12px. Der Rand ist immer
   2px (Vorlage: 1.5 -> 2 im gewaehlten Zustand), damit die Auswahl nichts um
   einen halben Pixel verschiebt. */
.person {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  width: 100%;
  padding: 10px 10px 10px 12px;
  text-align: left;
  font: inherit;
  color: var(--text);
  background: var(--flaeche);
  border: 2px solid var(--linie);
  border-radius: var(--radius);
  cursor: grab;
  transition: opacity 150ms ease-in-out, border-color 100ms ease-in-out, background 100ms ease-in-out;
}
.person:hover:not(:disabled) { border-color: var(--linie-stark); background: var(--flaeche-leise); }
.person:disabled { cursor: default; opacity: 0.65; }
.person-kuerzel {
  flex: none;
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  border-radius: 999px;
  background: var(--besetzt);
  color: var(--besetzt-text);
  font-size: 11px;
  font-weight: 700;
  text-transform: lowercase;
}
.person-info { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; }
.person-name {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
}
.person-check { flex: none; display: none; }
.person-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.quali {
  font-size: 10.5px;
  line-height: 1.3;
  padding: 2px 7px;
  border: 1px solid var(--linie-stark);
  border-radius: 999px;
  color: var(--text-leise);
  background: var(--flaeche);
  white-space: nowrap;
}
.quali-arzt { border-color: var(--haupt); color: var(--haupt); background: var(--haupt-leise); }
.person-stunden { font-size: 12px; color: var(--text-schwach); font-variant-numeric: tabular-nums; }
.person-hinweis { font-size: 12px; line-height: 1.25; }
.person-hinweis:empty { display: none; }

/* Gewaehlt: Flaeche, kraeftiger Rand, Ring, Haekchen. */
.person[aria-pressed="true"] {
  background: var(--haupt-leise);
  border-color: var(--haupt);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--haupt) 22%, transparent);
}
.person[aria-pressed="true"] .person-check { display: block; }
/* Sobald EINE Person gewaehlt ist, werden ALLE anderen gedimmt -- daran erkennt
   man den aktiven Zustand ohne Nachdenken (Vorlage: opacity .42). */
.leute[data-modus="person"] .person:not([aria-pressed="true"]) { opacity: 0.42; }
.leute[data-modus="person"] .person:not([aria-pressed="true"]):hover:not(:disabled) { opacity: 0.8; }

/* --- Panel reagiert auf den gewaehlten Abschnitt (Richtung A) ---------- */
/* Geeignet: angeboten, hervorgehoben. Der Hinweis nennt den moeglichen
   Abschnitt. */
.person-geeignet { border-color: var(--haupt); }
.person-geeignet .person-hinweis { color: var(--haupt); }
/* Moeglich mit Hinweis: bleibt angeboten (ziehbar), aber sichtbar markiert —
   NICHT dasselbe wie gesperrt. */
.person-moeglich { border-color: var(--warn-rand); }
.person-moeglich .person-hinweis { color: var(--warn); }
/* Gesperrt: gezeigt MIT Grund, aber nicht angeboten. Form (durchgestrichenes
   Kuerzel, gedaempft) trage die Aussage mit, nicht nur die Farbe. */
.person-gesperrt {
  opacity: 0.55;
  cursor: not-allowed;
}
.person-gesperrt .person-kuerzel {
  background: var(--flaeche-tot);
  color: var(--text-schwach);
  text-decoration: line-through;
}
.person-gesperrt .person-hinweis { color: var(--gefahr); }
.person[aria-disabled="true"] { cursor: not-allowed; }

/* Kopf des Panels im Filterzustand: kleiner „zuruecksetzen"-Hinweis. */
.leute[data-modus="slot"] .leute-hilfe,
.leute[data-modus="person"] .leute-hilfe { display: none; }
.leute-zuruecksetzen { display: none; }
.leute[data-modus="person"] .leute-zuruecksetzen { display: inline-flex; align-self: flex-start; }

/* --- Bedienfluss „Zuweisen ist eine Handlung" (Konzept 2026-09-05) ------ */
/* EINE Akzentfarbe verbindet den aktiven Abschnitt im Raster mit der Kopfzeile
   der Liste -- daran erkennt man den Bezug Raster <-> Liste ohne Nachdenken. */
:root { --akzent-aktiv: var(--info); --akzent-aktiv-leise: var(--info-leise); }
.leute-ziel {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  align-items: center;
  padding: 8px 10px;
  border: 2px solid var(--akzent-aktiv);
  border-radius: var(--radius);
  background: var(--akzent-aktiv-leise);
}
.leute-ziel-titel { grid-column: 1; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-leise); }
.leute-ziel-text { grid-column: 1; font-size: 13px; line-height: 1.3; }
.leute-abbrechen { grid-column: 2; grid-row: 1 / span 2; }
/* Im Abschnitt-Modus traegt die Kopfzeile den Bezug; die Lagezeile darunter
   ist dann nur noch die Zaehlung (anbietbar / gesperrt). */
.leute[data-modus="slot"] .leute-lage { padding: 0; background: transparent; border: 0; }
.leute-fehler {
  margin: 0;
  padding: 0.5rem 0.7rem;
  font-size: 12px;
  line-height: 1.35;
  border: 1px solid var(--gefahr-rand);
  border-left: 4px solid var(--gefahr);
  border-radius: var(--radius);
  background: var(--gefahr-leise);
  color: var(--gefahr);
}

/* Aktionstext am Kandidaten: „einteilen" bzw. „trotzdem einteilen…". Nur im
   Abschnitt-Modus sichtbar (JS fuellt ihn), als kleiner Knopf-im-Knopf. */
.person-aktion { flex: none; font-size: 11px; font-weight: 600; color: var(--haupt); white-space: nowrap; }
.person-aktion:empty { display: none; }
.person-name-text { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.person-weich .person-aktion { color: var(--warn); }
.leute[data-modus="slot"] .person:not(:disabled):hover .person-aktion,
.leute[data-modus="slot"] .person:not(:disabled):focus-visible .person-aktion { text-decoration: underline; }

/* Stammkraft der gefragten Position: kleines Kennzeichen (Empfehlung, keine Sperre). */
.stamm {
  font-size: 10px;
  line-height: 1.3;
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid var(--besetzt-rand);
  background: var(--besetzt);
  color: var(--besetzt-text);
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* Weich gesperrt: gedimmt wie gesperrt, aber anklickbar -- der Klick oeffnet
   „trotzdem einteilen?". Der gelbe Rand sagt: hier geht noch etwas. */
.person-weich { opacity: 0.7; border-color: var(--warn-rand); cursor: pointer; }
.person-weich .person-kuerzel { background: var(--warn-leise); color: var(--warn); }
.person-weich .person-hinweis { color: var(--warn); }
.person-weich:hover:not(:disabled) { opacity: 1; }

/* Waehrend der Anfrage: Knopf beschaeftigt, Zelle laedt (kein Layout-Sprung --
   die Zelle behaelt ihre Hoehe, nur die Deckkraft pulsiert). */
.person[aria-busy="true"] { cursor: progress; }
.person[aria-busy="true"] .person-aktion::after { content: " …"; }
td.zelle[data-laedt] .spuren { animation: zelle-laedt 900ms ease-in-out infinite alternate; }
@keyframes zelle-laedt { from { opacity: 1; } to { opacity: 0.6; } }
/* Zellen brauchen eine stabile Mindesthoehe, damit die optimistische Kachel
   nichts verschiebt (die Spurenhoehe ist ohnehin ausgerechnet). */
.spuren { min-height: var(--kachelhoehe); }

/* Optimistische Kachel („wird eingeteilt"): sofort sichtbar, gedaempft und
   pulsierend, bis der Server bestaetigt -- dann kommt die echte Zelle. */
.kachel-vorlaeufig {
  background: color-mix(in srgb, var(--besetzt) 70%, var(--flaeche));
  color: var(--besetzt-text);
  border: 1px dashed var(--besetzt-rand);
  cursor: progress;
  animation: kachel-pulst 900ms ease-in-out infinite alternate;
  z-index: 2;
}
@keyframes kachel-pulst { from { opacity: 0.55; } to { opacity: 0.95; } }
/* Vorschau beim Hover ueber einen Kandidaten: „so saehe es aus". */
.kachel-vorschau {
  background: transparent;
  color: var(--besetzt-text);
  border: 2px dashed var(--besetzt-rand);
  opacity: 0.75;
  pointer-events: none;
  z-index: 2;
}
.kachel-vorschau.kachel-vorschau-weich { border-color: var(--warn); color: var(--warn); }

/* Abweichend (Sperre mit Grund uebersteuert): Fahne + gestrichelter Innenrand,
   Grund im Tooltip -- die Aussage haengt nicht an der Farbe. */
.kachel-abweichend { box-shadow: inset 0 0 0 1px var(--warn), inset 0 0 0 2px var(--flaeche); }
.kachel-marke { flex: none; font-size: 10px; color: var(--warn); }
.legende-abweichend { display: inline-grid; place-items: center; font-size: 9px; color: var(--warn); border-color: var(--warn); }

/* Richtung B: Luecke, in die die gewaehlte Person nur mit Begruendung darf. */
.luecke.slot-weich {
  box-shadow: inset 0 0 0 1px var(--warn);
  background-image: repeating-linear-gradient(
    135deg, transparent 0 6px, color-mix(in srgb, var(--warn) 40%, transparent) 6px 7px);
}
.raster-rolle[data-person-aktiv] .luecke.slot-weich { opacity: 0.85; }

/* Der Uebersteuern-Dialog: Gruende als Liste, Vorschlaege als Chips. */
.ueber-gruende { margin: 0 0 0.6rem; padding-left: 1.1rem; font-size: var(--bedien-groesse); color: var(--gefahr); }
.ueber-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; margin: 0 0 0.5rem; }
.chip {
  padding: 0.2rem 0.6rem;
  font: 500 0.78rem/1.2 var(--schrift);
  color: var(--text-leise);
  background: var(--flaeche-leise);
  border: 1px solid var(--linie-stark);
  border-radius: 999px;
  cursor: pointer;
}
.chip:hover, .chip[aria-pressed="true"] { border-color: var(--haupt); color: var(--haupt); background: var(--haupt-leise); }
.ueber-grund-label { display: grid; gap: 0.25rem; font-size: 0.8rem; color: var(--text-leise); }
.ueber-grund-label small { color: var(--text-schwach); }
.ueber-grund-label textarea {
  font: var(--bedien-groesse) var(--schrift);
  padding: 0.4rem 0.5rem;
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  resize: vertical;
}
.ueber-grund-label textarea:invalid { border-color: var(--warn-rand); }

/* --- Slots reagieren auf die gewaehlte Person (Richtung B) ------------- */
/* Aktiver Slot (Richtung A ausgeloest): deutlich umrandet. */
.luecke.slot-aktiv, .balken.slot-aktiv {
  outline: 2px solid var(--info);
  outline-offset: 1px;
}
/* Andockbar fuer die gewaehlte Person: hervorgehoben. */
.luecke.slot-passend {
  box-shadow: inset 0 0 0 1px var(--haupt);
  background-image: repeating-linear-gradient(
    135deg, transparent 0 6px, color-mix(in srgb, var(--haupt) 45%, transparent) 6px 7px);
  color: var(--haupt);
  font-weight: 700;
}
/* Nicht passend, solange eine Person gewaehlt ist: gedaempft. */
.raster-rolle[data-person-aktiv] .luecke:not(.slot-passend) { opacity: 0.4; }

/* --- Kennzahlen-Filter: „wo muss ich noch ran?" -------------------------- */
/* data-zeige am Raster (offen | unter_soll | unter_minimum), data-lage am
   Balken (voll | unter_soll | unter_minimum). Ein Attribut, keine Klassen je
   Element: alles, was NICHT passt, wird gedimmt und entsaettigt, die Treffer
   bekommen einen Ring. Zusammen mit einer gewaehlten Person gilt: der Filter
   waehlt die FENSTER, die Person die LUECKEN darin -- die Treffer-Fenster
   bleiben voll sichtbar, nur ihre nicht passenden Luecken werden gedaempft. */
.raster-rolle[data-zeige="unter_minimum"] .balken:not([data-lage="unter_minimum"]),
.raster-rolle[data-zeige="unter_soll"] .balken:not([data-lage="unter_soll"]),
.raster-rolle[data-zeige="offen"] .balken[data-lage="voll"],
/* Eine Fortsetzung ist derselbe Bedarf wie am Vortag; der Filter zaehlt
   Fenster und nicht Haelften, also wird sie hier immer gedimmt. */
.raster-rolle[data-zeige] .balken[data-lage="fortsetzung"] {
  opacity: 0.3;
  filter: saturate(0.15);
}
.raster-rolle[data-zeige="unter_minimum"] .balken[data-lage="unter_minimum"],
.raster-rolle[data-zeige="unter_soll"] .balken[data-lage="unter_soll"],
.raster-rolle[data-zeige="offen"] .balken:not([data-lage="voll"]):not([data-lage="fortsetzung"]) {
  box-shadow: 0 0 0 3px var(--fokus);
}
/* Im gedimmten Fenster nicht doppelt daempfen -- sonst verschwinden die
   Luecken ganz und das Fenster sieht leer aus. */
.raster-rolle[data-zeige="unter_minimum"] .balken:not([data-lage="unter_minimum"]) .luecke,
.raster-rolle[data-zeige="unter_soll"] .balken:not([data-lage="unter_soll"]) .luecke,
.raster-rolle[data-zeige="offen"] .balken[data-lage="voll"] .luecke { opacity: 1; }

/* --- Das Raster --------------------------------------------------------- */
.raster-rolle { overflow-x: auto; }

table.wochenraster {
  width: 100%;
  min-width: 1080px;
  border-collapse: separate;
  border-spacing: 0;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: var(--bedien-groesse);
}

table.wochenraster th,
table.wochenraster td { border-bottom: 1px solid var(--linie); }

table.wochenraster thead th {
  /* Klebt am oberen Rand des waagerechten Scrollbereichs (.raster-rolle).
     Ein Versatz um die Kopfhoehe wuerde ihn INNERHALB des Bereichs nach
     unten schieben und die erste Zeile verdecken. */
  position: sticky;
  top: 0;
  z-index: 5;
  padding: 10px 12px 8px;
  background: var(--flaeche);
  border-bottom: 2px solid var(--linie-stark);
  font-weight: 600;
  text-align: left;
  vertical-align: top;
}
th.ecke { width: 150px; padding: 12px 14px; font-size: 12px; color: var(--text-leise); }
th.ecke small { display: block; font-weight: 400; color: var(--text-schwach); font-size: 12px; }

/* Tage als klar begrenzte Spalten: 2px Trennlinie links, jede zweite Spalte
   getoent (Vorlage: nth-child(odd) -- Di/Do/Sa, weil die Positionsspalte das
   erste Kind ist). Die Toenung gilt fuer Kopf UND Zellen derselben Spalte. */
th.tag { min-width: 9.5rem; border-left: 2px solid var(--linie-stark); }
th.tag:nth-child(odd), td.zelle:nth-child(odd) { background-color: var(--flaeche-leise); }
th.tag .tag-name { font-size: 14px; font-weight: 700; }
th.tag .tag-datum { margin-left: 4px; color: var(--text-schwach); font-weight: 400; font-size: 14px; }
th.tag-heute { box-shadow: inset 0 3px 0 var(--info); }
th.tag-zu { color: var(--text-schwach); }
.tag-grund {
  display: block;
  margin-top: 6px;
  font-weight: 400;
  font-size: 12px;
  color: var(--warn);
}

/* Zeitmarken unter dem Tag. Anders als in der Vorlage (space-between) stehen
   sie lagegenau auf der Achse -- auf denselben Uhrzeiten wie die Gitterlinien
   der Zellen; verteilt saehe „09 12 15 18" bei einer 07-18-Achse nur gleichmaessig
   aus, waere aber an der falschen Stelle. */
.achse { position: relative; display: block; height: 12px; margin-top: 6px; }
.achse-marke {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 10px;
  line-height: 1;
  font-weight: 400;
  color: var(--text-schwach);
  font-variant-numeric: tabular-nums;
}

/* Gruppen-Baender: Versalien auf --flaeche-tot (Vorlage: 10.5px, .08em). */
.gruppenkopf th {
  padding: 7px 14px;
  background: var(--flaeche-tot);
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-schwach);
  text-align: left;
  border-top: 1px solid var(--linie);
  border-bottom: 1px solid var(--linie);
}

th.position {
  padding: 12px 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: var(--flaeche);
  font-weight: 600;
  text-align: left;
  vertical-align: middle;
}
th.position small { display: block; font-size: 11px; color: var(--text-schwach); font-weight: 400; }

td.zelle {
  padding: 10px 6px;
  vertical-align: top;
  border-left: 2px solid var(--linie-stark);
  /* Hilfslinien auf denselben Uhrzeiten wie die Marken im Spaltenkopf. */
  background-image: repeating-linear-gradient(
    to right, var(--linie) 0 1px, transparent 1px var(--gitter, 25%));
  background-position: 6px 0;
  background-repeat: repeat;
}
/* Kein Bedarf fuer diese Position an dem Tag: nur die Spaltentoenung, kein
   Gitter -- eine leere Zelle sagt „hier ist nichts", wie in der Vorlage. */
td.zelle-leer { background-image: none; }
td.zelle-zu {
  background-color: var(--flaeche-tot);
  background-image: repeating-linear-gradient(
    135deg, transparent 0 6px, rgb(120 120 130 / 0.12) 6px 12px);
}

.spuren {
  /* Zeilenhoehe waechst mit den Kachel-Spuren: bei Sollbesetzung 2 stehen
     zwei Zuweisungen gleichzeitig im Fenster und brauchen zwei Ebenen.
     Ohne Kopfzeile ist der Balken genau so hoch wie seine Kacheln (32px je
     Spur, Vorlage) plus ein Abstand zwischen zwei Spuren. */
  --zeilenhoehe: calc(var(--kacheln, 1) * var(--kachelhoehe) + 0.6rem);
  position: relative;
  height: calc(var(--spuren, 1) * var(--zeilenhoehe) - 0.6rem);
}

/* --- Balken = Bedarfsfenster -------------------------------------------- */
/* Ruhig: kein Text auf dem Fenster, nur Kacheln und Luecken. Signal nur, wo
   etwas fehlt -- unter Soll: gelber Rand + gelber Punkt oben rechts; unter
   Minimum: roter 4px-Rand links + rote Flaeche. Voll besetzt: neutral, still. */
.balken {
  position: absolute;
  top: calc(var(--spur, 0) * var(--zeilenhoehe));
  height: calc(var(--kacheln, 1) * var(--kachelhoehe) + 2px);
  min-width: 2.2rem;
  padding: 0;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  background: var(--flaeche);
  overflow: hidden;
  transition: opacity 150ms ease-in-out, box-shadow 150ms ease-in-out;
}
.balken-luecke { border-color: var(--warn); }
.balken-luecke::after {
  content: "";
  position: absolute;
  top: 4px; right: 4px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--warn);
  pointer-events: none;
  z-index: 1;
}
.balken-kritisch {
  border-color: var(--gefahr-rand);
  border-left-width: 4px;
  background: var(--gefahr-leise);
}
.balken-ausnahme { border-style: dashed; }

/* --- Dienst ueber Mitternacht ------------------------------------------- */
/* Ein Fenster 22:00-06:00 passt in keine Tagesspalte: es wird sichtbar
   geteilt und steht in ZWEI Spalten (siehe `dienstplan/ansicht.py`). Die
   Schnittkante wird dort geoeffnet, wo der Balken weiterlaeuft -- gerade
   Kante ohne Radius, gestrichelt, damit sie nicht wie ein Ende aussieht.
   Die AUSSAGE traegt aber der Pfeil und der Titel, nicht die Kante: eine
   fehlende Rundung ist ein Hinweis, kein Satz. */
.balken-weiter {
  border-right: 2px dashed var(--linie-stark);
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.balken-vortag {
  border-left: 2px dashed var(--linie-stark);
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}
/* Die Fortsetzung ist ein Spiegel, kein zweiter Fall: neutraler Rahmen,
   leicht zurueckgenommene Flaeche. Das SIGNAL (gelb/rot) steht am Starttag,
   wo das Fenster gezaehlt wird -- ein Alarm pro Tatsache. Die Luecke darin
   bleibt sichtbar und anklickbar. */
.balken-fortsetzung { border-color: var(--linie-stark); background: var(--flaeche-leise); }
/* Der Filter zaehlt Fenster, nicht Haelften -- die Fortsetzung wird darum
   gedimmt wie alles, was nicht gemeint ist (die Regeln dafuer stehen oben bei
   `[data-zeige]`), und nie hervorgehoben. */
/* Der Pfeil zur Tagesgrenze. Form, nicht Farbe -- und er sitzt UEBER den
   Kacheln, damit er auch in einem voll besetzten Fenster lesbar bleibt. */
.balken-grenze {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  font-size: 11px;
  line-height: 1;
  padding: 1px 2px;
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  color: var(--text-leise);
  pointer-events: none;
}
.balken-weiter > .balken-grenze { right: 1px; }
.balken-vortag > .balken-grenze { left: 1px; }

.balken-flaeche {
  position: relative;
  display: block;
  height: calc(var(--kacheln, 1) * var(--kachelhoehe));
}

/* Luecke: schraffiert + „frei" -- Form UND Text, nicht nur Farbe. Die
   Uhrzeit steht im Titel und im Screenreader-Text. */
.luecke {
  position: absolute;
  top: 0; bottom: 0;
  display: grid;
  place-items: center;
  min-width: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background-color: transparent;
  background-image: repeating-linear-gradient(
    135deg, transparent 0 6px, var(--linie-stark) 6px 7px);
  color: var(--text-schwach);
  font: 400 10.5px/1 var(--schrift);
  cursor: copy;
  overflow: hidden;
}
.luecke:hover:not(:disabled) { box-shadow: inset 0 0 0 1px var(--info); color: var(--text); }
.luecke:disabled { cursor: default; }
/* Unter Mindestbesetzung: dichtere rote Schraffur -- in einem roten Fenster
   zeigt sie, WO niemand da ist (Soll 2/Min 1: nur der 0-von-2-Teil). */
.luecke-kritisch {
  color: var(--gefahr);
  font-weight: 700;
  background-image: repeating-linear-gradient(
    135deg, transparent 0 5px, color-mix(in srgb, var(--gefahr-rand) 55%, transparent) 5px 7px);
}
.luecke-kurz { padding: 0 3px; white-space: nowrap; }

/* Kachel = eine Zuweisung, ein Teilstueck des Fensters. Fuellt ihre Spur
   ganz aus (Vorlage: 11px fett, kein eigener Rand, 1px Fuge zum Nachbarn). */
.kachel {
  position: absolute;
  top: calc(var(--kachel-spur, 0) * var(--kachelhoehe));
  height: calc(var(--kachelhoehe) - 1px);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.3rem;
  min-width: 0;
  padding: 0 3px;
  border: 0;
  border-right: 1px solid var(--flaeche);
  border-radius: 0;
  background: var(--besetzt);
  color: var(--besetzt-text);
  font: 700 11px/1 var(--schrift);
  cursor: grab;
  overflow: hidden;
  white-space: nowrap;
}
.kachel:hover:not(:disabled) { filter: brightness(0.95); }
.kachel:disabled { cursor: default; }
.kachel-kuerzel { flex: 0 0 auto; text-transform: uppercase; letter-spacing: 0.02em; }
/* Die Uhrzeit erscheint nur waehrend des Ziehens am Rand (Live-Rueckmeldung);
   sonst steht sie im Titel und im Dialog. */
.kachel-zeit {
  display: none;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  opacity: 0.8;
}
.kachel.kachel-zieht .kachel-zeit { display: inline; }

/* Ziel beim Ziehen */
.ziel-aktiv {
  outline: 2px solid var(--haupt);
  outline-offset: 1px;
  background-color: var(--haupt-leise);
}
.balken.ziel-aktiv { outline-color: var(--haupt); }

/* --- Verwaiste Zuweisungen + Legende ------------------------------------ */
.verwaist {
  margin-top: 1.2rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--warn-rand);
  border-left: 4px solid var(--warn);
  border-radius: var(--radius);
  background: var(--warn-leise);
}
.verwaist h2 { margin: 0 0 0.3rem; font-size: 0.95rem; }
.verwaist p { margin: 0 0 0.5rem; font-size: 0.8rem; }
.verwaist ul { margin: 0; padding-left: 1.1rem; font-size: var(--bedien-groesse); }

/* Text-Legende (Bedarfs-Kalender) ... */
.legende {
  margin-top: 1rem;
  color: var(--text-schwach);
  font-size: 0.78rem;
  max-width: 78ch;
}
/* ... und die Musterreihe des Wochenrasters (Vorlage: Swatch + Wort, 11.5px). */
.legende-reihe {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 22px;
  align-items: center;
  margin: 12px 0 0;
  max-width: none;
  font-size: 11.5px;
}
.legende-reihe > span { display: inline-flex; align-items: center; gap: 6px; }
.legende-text { flex-basis: 100%; }
.legende-muster {
  display: inline-block;
  width: 12px; height: 12px;
  border: 1px solid var(--linie-stark);
  border-radius: 3px;
  background: var(--flaeche);
}
.legende-besetzt { background: var(--besetzt); border-color: var(--besetzt-rand); }
.legende-frei { background-image: repeating-linear-gradient(135deg, transparent 0 3px, var(--linie-stark) 3px 4px); }
.legende-soll { position: relative; border-color: var(--warn); }
.legende-soll::after {
  content: ""; position: absolute; top: 1px; right: 1px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--warn);
}
.legende-minimum { border-color: var(--gefahr-rand); border-left-width: 4px; background: var(--gefahr-leise); }
.legende-zu {
  background-color: var(--flaeche-tot);
  background-image: repeating-linear-gradient(135deg, transparent 0 3px, rgb(120 120 130 / 0.25) 3px 5px);
}
/* Dienst ueber Mitternacht: offene Kante rechts + Pfeil, wie am Balken. */
.legende-mitternacht {
  display: inline-grid;
  place-items: center;
  font-size: 9px;
  line-height: 1;
  color: var(--text-leise);
  border-right: 2px dashed var(--linie-stark);
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

/* --- Dialoge ------------------------------------------------------------ */
.dialog {
  width: min(30rem, calc(100vw - 2rem));
  padding: 0;
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px rgb(0 0 0 / 0.18);
}
.dialog::backdrop { background: rgb(24 24 27 / 0.45); }
.dialog-form { padding: 1rem 1.1rem; }
.dialog h2 { margin: 0 0 0.2rem; font-size: 1.05rem; }
.dialog-lage { margin: 0 0 0.8rem; font-size: var(--bedien-groesse); color: var(--text-leise); }
.dialog-hinweis { margin: 0.5rem 0 0.8rem; font-size: 0.75rem; color: var(--text-schwach); }

.zeitwahl { display: flex; align-items: end; gap: 0.6rem; flex-wrap: wrap; }
.zeitwahl label { display: grid; gap: 0.2rem; font-size: 0.75rem; color: var(--text-leise); }
.zeitwahl input {
  font: var(--bedien-groesse) var(--schrift);
  padding: 0.35rem 0.45rem;
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
}

.kandidaten { display: grid; gap: 0.3rem; max-height: 40vh; overflow-y: auto; }
.kandidat {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.2rem 0.5rem;
  align-items: center;
  padding: 0.45rem 0.55rem;
  border: 1px solid var(--linie);
  border-left: 4px solid var(--linie-stark);
  border-radius: var(--radius);
  background: var(--flaeche-leise);
}
.kandidat-geeignet { border-left-color: var(--haupt); }
.kandidat-moeglich { border-left-color: var(--warn); }
.kandidat-gesperrt { border-left-color: var(--gefahr); }
.kandidat-name { font-size: var(--bedien-groesse); font-weight: 600; }
.kandidat-klasse { font-size: 0.7rem; color: var(--text-schwach); }
.kandidat-grund { grid-column: 1 / -1; font-size: 0.72rem; color: var(--text-leise); }
.kandidat-knoepfe { display: flex; gap: 0.3rem; }

.dialog-fuss {
  display: flex;
  gap: 0.4rem;
  justify-content: flex-end;
  margin: 0.9rem 0 0;
  padding: 0;
}

/* --- Bewegung nur, wenn erwuenscht -------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* --- Tage ohne Bedarf: standardmaessig ausgeblendet ---------------------- */
/* Datengetrieben (`.tag-leer` am th UND an jeder Zelle der Spalte), nicht
 * Sa/So fest verdrahtet. Ausgeblendet ist der Standard; nur im
 * „alle Tage"-Modus (:root[data-alle-tage="ja"]) werden die Spalten gezeigt.
 * Der Standard greift auch ohne das Kopf-Skript (Attribut fehlt) — dann ist
 * die sichere Wahl „ausblenden". */
:root:not([data-alle-tage="ja"]) .tag-leer { display: none; }

.tage-leiste {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin: 0 0 0.8rem;
}
.tage-ausgeblendet {
  margin: 0;
  font-size: 0.8rem;
  color: var(--text-schwach);
}
/* Die Ausblend-Zeile gilt nur, wenn wirklich ausgeblendet wird. */
:root[data-alle-tage="ja"] .tage-ausgeblendet { display: none; }

/* Der Umschalter zeigt die passende Beschriftung zum Zustand. */
.tage-umschalter .wenn-alle { display: none; }
:root[data-alle-tage="ja"] .tage-umschalter .wenn-ausgeblendet { display: none; }
:root[data-alle-tage="ja"] .tage-umschalter .wenn-alle { display: inline; }

/* =======================================================================
 * Bedarfs-Kalender (Ebene 2 grafisch: „was muss besetzt sein")
 * ===================================================================== */
.bedarf-intro { margin: 0 0 0.9rem; font-size: var(--bedien-groesse); color: var(--text-leise); max-width: 80ch; }
.bedarf-intro code { font-size: 0.8em; }

td.bedarf-zelle { position: relative; }
td.zelle-abweichung { background-color: color-mix(in srgb, var(--info-leise) 60%, transparent); }

.bedarf-spuren {
  --zeilenhoehe: 2.1rem;
  position: relative;
  height: calc(var(--spuren, 1) * var(--zeilenhoehe));
  margin-bottom: 0.15rem;
}

.bedarf-balken {
  position: absolute;
  top: calc(var(--spur, 0) * var(--zeilenhoehe));
  height: calc(var(--zeilenhoehe) - 0.3rem);
  min-width: 2.4rem;
  container-type: inline-size;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.1rem;
  padding: 0.1rem 0.3rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius-klein);
  background: var(--flaeche-leise);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
}
.bedarf-balken:hover:not(:disabled) { border-color: var(--info); }
.bedarf-balken:disabled { cursor: default; }
/* Aus dem Muster: ruhiger, blauer Akzent. */
.bedarf-muster { border-color: var(--besetzt-rand); background: var(--besetzt); color: var(--besetzt-text); }
/* Tagesausnahme: gestrichelt + Sternchen -- Form traegt die Aussage mit. */
.bedarf-tagesausnahme {
  border-style: dashed;
  border-color: var(--warn); border-width: 1px 1px 1px 3px;
  background: var(--warn-leise); color: var(--text);
}
/* Ghost: was das Template an der Stelle saehe (ersetzt durch die Ausnahme). */
.bedarf-ghost {
  border-style: dotted;
  background: transparent;
  color: var(--text-schwach);
  opacity: 0.55;
  pointer-events: none;
}
.bedarf-kopf { display: flex; align-items: baseline; gap: 0.3rem; font-size: 0.66rem; line-height: 1; }
.bedarf-zeit { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.bedarf-soll {
  margin-left: auto;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  padding: 0 0.15rem;
  border-radius: 3px;
  background: color-mix(in srgb, var(--flaeche) 70%, transparent);
}
.bedarf-marke { font-size: 0.6rem; color: var(--warn); font-weight: 800; }
@container (max-width: 4.2rem) { .bedarf-zeit { display: none; } }

.ausnahme-chip {
  display: flex; align-items: center; gap: 0.35rem;
  margin: 0.15rem 0 0;
  padding: 0.15rem 0.35rem;
  font-size: 0.68rem;
  border-radius: var(--radius-klein);
  background: var(--gefahr-leise);
  border: 1px solid var(--gefahr-rand);
  color: var(--text);
}
.ausnahme-chip .knopf { padding: 0.1rem 0.35rem; font-size: 0.66rem; }

.bedarf-plus {
  display: inline-block;
  margin-top: 0.2rem;
  padding: 0.15rem 0.4rem;
  font-size: 0.66rem;
  color: var(--text-schwach);
  background: transparent;
  border: 1px dashed var(--linie-stark);
  border-radius: var(--radius-klein);
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 100ms;
}
td.bedarf-zelle:hover .bedarf-plus,
td.bedarf-zelle:focus-within .bedarf-plus { opacity: 1; }
.bedarf-plus:hover { border-color: var(--haupt); color: var(--haupt); }

.bedarf-art { border: 1px solid var(--linie); border-radius: var(--radius); padding: 0.5rem 0.7rem; margin: 0 0 0.7rem; }
.bedarf-art legend { padding: 0 0.3rem; font-size: 0.75rem; color: var(--text-schwach); }
.bedarf-art label { display: flex; align-items: center; gap: 0.4rem; font-size: var(--bedien-groesse); padding: 0.15rem 0; cursor: pointer; }

/* --- Wochenraster-Zeile: welches Muster gilt und warum -------------------- */
/* Eine ruhige Karte ueber dem Kalender. Der Name traegt die Aussage, die
 * Quelle steht als Satzteil daneben („aus Rotation ‚Standard', Woche 2 von 2"
 * bzw. „fuer diese Woche gewaehlt") — nie nur eine Farbe. */
.wochenmuster {
  display: flex; flex-direction: column; gap: 0.5rem;
  margin: 0 0 0.9rem;
  padding: 0.7rem 0.9rem;
  background: var(--flaeche);
  border: 1px solid var(--linie);
  border-left: 4px solid var(--besetzt-rand);
  border-radius: var(--radius);
}
.wochenmuster-lage { margin: 0; font-size: var(--bedien-groesse); color: var(--text-leise); display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.5rem; }
.wochenmuster-titel { text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.7rem; color: var(--text-schwach); }
.wochenmuster-name { color: var(--text); font-size: 1rem; }
.wochenmuster-quelle { color: var(--text-leise); }
.wochenmuster-notiz { font-style: italic; color: var(--text-leise); }
.wochenmuster-spur { font-size: 0.72rem; color: var(--text-schwach); }
.wochenmuster-bedienung { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
.wochenmuster-wahl { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.78rem; color: var(--text-schwach); }
.wochenmuster-wahl select, .wochenmuster-notizfeld, .musterwahl input, .musterwahl select {
  font: var(--bedien-groesse) var(--schrift);
  padding: 0.35rem 0.45rem; color: var(--text); background: var(--flaeche);
  border: 1px solid var(--linie-stark); border-radius: var(--radius);
}
.wochenmuster-notizfeld { min-width: 14rem; }
.wochenmuster-hinweis {
  margin: 0; padding: 0.45rem 0.7rem;
  font-size: 0.78rem; color: var(--text);
  background: var(--warn-leise); border: 1px solid var(--warn-rand); border-radius: var(--radius);
}
/* Vorlage-Modus: das Banner ist gelb — hier wird die Vorlage geaendert, nicht die Woche. */
.wochenmuster-vorlage { border-left-color: var(--warn); background: var(--warn-leise); }
.wochenmuster-vorlage .wochenmuster-lage { color: var(--text); display: block; }
.musterwahl { display: grid; gap: 0.6rem; }
.musterwahl label { display: grid; gap: 0.2rem; font-size: 0.75rem; color: var(--text-leise); }
.dialog-hinweis-warnung { color: var(--warn); }
/* „gewaehlt" an der Muster-Kennzahl: kleiner Zusatz statt zweiter Kachel. */
.kennzahl-zusatz { font-size: 0.6rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--warn); vertical-align: middle; }

/* =======================================================================
 * Mitarbeiter-Ansicht („so arbeitest du"): ruhige Agenda
 * ===================================================================== */
.mitarbeiter-kopf {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.8rem 1.4rem; margin-bottom: 0.7rem;
}
.mitarbeiter-werkzeuge { display: flex; align-items: center; gap: 0.8rem; margin-left: auto; flex-wrap: wrap; }

.segmentwahl { display: inline-flex; border: 1px solid var(--linie-stark); border-radius: var(--radius); overflow: hidden; }
.segmentwahl a {
  padding: 0.3rem 0.7rem; font-size: 0.8rem; color: var(--text-leise); text-decoration: none;
  background: var(--flaeche-leise);
}
.segmentwahl a + a { border-left: 1px solid var(--linie-stark); }
.segmentwahl a.aktiv { background: var(--haupt); color: var(--haupt-text); font-weight: 600; }

.person-wahl { display: inline-flex; align-items: center; gap: 0.4rem; font-size: 0.78rem; color: var(--text-schwach); }
.person-wahl select {
  font: var(--bedien-groesse) var(--schrift);
  padding: 0.3rem 0.4rem; color: var(--text); background: var(--flaeche);
  border: 1px solid var(--linie-stark); border-radius: var(--radius);
}

.mitarbeiter-kennzahlen { display: flex; gap: 1.4rem; margin: 0 0 0.8rem; }
.mitarbeiter-kennzahlen dt { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-schwach); }
.mitarbeiter-kennzahlen dd { margin: 0; font-size: 1.15rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.mitarbeiter-kennzahlen .entwurf-hinweis dd { color: var(--warn); font-size: 0.9rem; }

.agenda {
  border: 1px solid var(--linie); border-radius: var(--radius); overflow: hidden;
  background: var(--flaeche); box-shadow: var(--schatten);
}
.agenda-tag { display: grid; grid-template-columns: 8.5rem 1fr; gap: 0.5rem; padding: 0.6rem 0.9rem; border-bottom: 1px solid var(--linie); }
.agenda-tag:last-child { border-bottom: 0; }
.agenda-tag.agenda-frei { background: var(--flaeche-leise); }
.agenda-datum { display: flex; flex-direction: column; gap: 0.1rem; }
.agenda-wtag { font-weight: 700; }
.agenda-dtext { font-size: 0.8rem; color: var(--text-schwach); font-variant-numeric: tabular-nums; }
.agenda-summe { font-size: 0.72rem; color: var(--text-schwach); font-variant-numeric: tabular-nums; }
.agenda-schichten { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.agenda-leer { font-size: 0.8rem; color: var(--text-schwach); font-style: italic; }

.schicht {
  display: inline-flex; align-items: baseline; gap: 0.5rem;
  padding: 0.35rem 0.6rem;
  border: 1px solid var(--besetzt-rand);
  border-left-width: 4px;
  border-radius: var(--radius);
  background: var(--besetzt); color: var(--besetzt-text);
}
.schicht-entwurf { background: var(--warn-leise); color: var(--text); border-color: var(--warn); }
.schicht-zeit { font-weight: 700; font-variant-numeric: tabular-nums; }
.schicht-position { font-weight: 600; }
.schicht-gruppe { font-size: 0.72rem; opacity: 0.75; }
.schicht-status { font-size: 0.68rem; padding: 0.05rem 0.35rem; border-radius: 999px; border: 1px solid var(--warn); color: var(--warn); }
.schicht-notiz { font-size: 0.72rem; opacity: 0.8; }
/* „Weicht von deiner ueblichen Zeit ab: <Grund>" -- eigene Zeile unter der Schicht. */
.schicht-abweichend { flex-basis: 100%; font-size: 0.72rem; color: var(--warn); font-weight: 600; }
.schicht:has(.schicht-abweichend) { flex-wrap: wrap; }

/* Nachtdienst: der Satz „endet am Folgetag um 06:00" bekommt eine eigene
   Zeile, damit er nicht neben der Uhrzeit untergeht -- die Aussage traegt der
   Text, nicht die Farbe. Was aus der Nacht HEREINlaeuft, ist keine eigene
   Schicht: gestrichelter Rand statt voller Kachel, damit die Stunden nicht
   zweimal gelesen werden. */
.schicht-nacht { flex-basis: 100%; font-size: 0.72rem; color: var(--text-leise); }
.schicht:has(.schicht-nacht) { flex-wrap: wrap; }
.schicht-aus-nacht { border-style: dashed; background: var(--flaeche-leise); }

.ical-box {
  margin-top: 1.2rem; padding: 0.9rem 1.1rem;
  border: 1px solid var(--linie); border-radius: var(--radius); background: var(--flaeche);
}
.ical-box h2 { margin: 0 0 0.3rem; font-size: 0.95rem; }
.ical-box p { margin: 0 0 0.6rem; font-size: 0.8rem; color: var(--text-leise); max-width: 70ch; }
.ical-zeile { display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center; margin-bottom: 0.5rem; }
.ical-zeile input {
  flex: 1 1 20rem; min-width: 0;
  font: 0.78rem var(--schrift); padding: 0.35rem 0.45rem;
  color: var(--text); background: var(--flaeche-leise);
  border: 1px solid var(--linie-stark); border-radius: var(--radius);
}

/* =======================================================================
 * Drucken
 * ===================================================================== */
/* Gedruckt wird NICHT die Web-Ansicht, sondern eine eigene Druckseite
   (/dienstplan/druck/..., static/css/druck.css) -- die „Drucken"-Knoepfe oeffnen sie
   im neuen Tab. Landet doch jemand mit Strg+P auf einer Web-Seite, bleibt nur
   das Bedien-Chrome weg; ein zweiter Druckweg wird hier bewusst nicht gepflegt. */
@media print {
  :root { color-scheme: light; }
  .kopf, .fuss, .nur-bildschirm, .thema-wahl, dialog, [data-meldung] { display: none !important; }
}
/* Druck-Link unter dem Bedarfskalender (der Kopf dort gehoert dem Bedarf-Strang). */
.druck-leiste { display: flex; justify-content: flex-end; margin: 0.6rem 0 0; }

/* =======================================================================
 * Stammdaten (/dienstplan/stammdaten/): Reiter, Karten, Tabellen, Formulare
 * ===================================================================== */
.stammdaten { max-width: 76rem; }
.stamm-kopf { display: flex; align-items: center; flex-wrap: wrap; gap: 0.8rem 1.2rem; margin-bottom: 1rem; }
.stamm-kopf h1 { margin: 0; font-size: 1.15rem; }
.stamm-admin { margin-left: auto; font-size: 0.78rem; color: var(--text-schwach); }

/* Reiter wie der Woche/Monat-Umschalter der Mitarbeiter-Ansicht. */
.reiter { display: inline-flex; border: 1px solid var(--linie-stark); border-radius: var(--radius); overflow: hidden; }
.reiter a {
  padding: 0.35rem 0.8rem; font-size: var(--bedien-groesse); color: var(--text-leise); text-decoration: none;
  background: var(--flaeche-leise);
}
.reiter a + a { border-left: 1px solid var(--linie-stark); }
.reiter a:hover { background: var(--flaeche-tot); color: var(--text); }
.reiter a.aktiv { background: var(--haupt); color: var(--haupt-text); font-weight: 600; }

.karte {
  padding: 0.9rem 1.1rem; margin-bottom: 1rem;
  border: 1px solid var(--linie); border-radius: var(--radius);
  background: var(--flaeche); box-shadow: var(--schatten);
}
.karte-kopf { display: flex; align-items: center; gap: 0.8rem; margin-bottom: 0.5rem; }
.karte-kopf h2 { margin: 0; font-size: 0.95rem; }
.karte-kopf h2 small { font-weight: 400; color: var(--text-schwach); margin-left: 0.3rem; }
.karte-kopf > .knopf { margin-left: auto; }
.karten-raster { display: grid; grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr)); gap: 1rem; align-items: start; }
.leise { color: var(--text-schwach); font-size: 0.78rem; }
p.leise { margin: 0 0 0.7rem; max-width: 80ch; line-height: 1.45; }

.meldungen { display: grid; gap: 0.4rem; margin: 0 0 0.8rem; }
.meldungen .meldung { margin: 0; }
.meldung[data-art="warn"], .meldung[data-art="info"] {
  padding: 0.55rem 0.8rem;
  border: 1px solid var(--linie-stark);
  border-left: 4px solid var(--warn);
  border-radius: var(--radius);
  background: var(--warn-leise);
  color: var(--text);
}
.meldung[data-art="info"] { border-left-color: var(--info); background: var(--info-leise); }

/* Tabellen der Stammdaten: ruhig, eine Zeile = ein Objekt, Aktionen rechts. */
.stamm-tabelle { width: 100%; border-collapse: collapse; font-size: var(--bedien-groesse); }
.stamm-tabelle th, .stamm-tabelle td {
  padding: 0.45rem 0.5rem; text-align: left; vertical-align: middle;
  border-bottom: 1px solid var(--linie);
}
.stamm-tabelle thead th { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-schwach); font-weight: 600; }
.stamm-tabelle .gruppenkopf th { background: var(--flaeche-leise); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-leise); }
.stamm-tabelle tr.inaktiv td { color: var(--text-schwach); }
.stamm-tabelle tr.inaktiv .zeilen-name { text-decoration: line-through; text-decoration-color: var(--linie-stark); }
.stamm-tabelle .zeilen-name { font-weight: 600; }
.stamm-tabelle a.zeilen-link { color: inherit; text-decoration: none; }
.stamm-tabelle a.zeilen-link:hover { text-decoration: underline; color: var(--info); }
.stamm-tabelle code { font-size: 0.8em; padding: 0.05rem 0.3rem; background: var(--flaeche-leise); border-radius: 4px; }
.stamm-tabelle td.aktionen, .stamm-tabelle th.aktionen { text-align: right; white-space: nowrap; }
.aktionen form { display: inline; }
.aktionen .knopf { padding: 0.2rem 0.45rem; font-size: 0.75rem; vertical-align: middle; }
.aktionen .leise { margin-left: 0.3rem; }
.zeile-form td { background: var(--flaeche-leise); }

.stamm-status {
  display: inline-block; padding: 0.05rem 0.5rem; border-radius: 999px; font-size: 0.72rem;
  border: 1px solid var(--haupt); color: var(--haupt); background: var(--haupt-leise);
}
.stamm-status-inaktiv { border-color: var(--linie-stark); color: var(--text-schwach); background: var(--flaeche-leise); }

/* Formulare: Raster aus Feldern; Textbereiche und Mehrfach-Haken ueber die volle Breite. */
.stamm-form {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 0.6rem 0.9rem; align-items: start;
}
.stamm-form-neu { padding: 0.8rem 0.9rem; margin-bottom: 0.9rem; border: 1px dashed var(--linie-stark); border-radius: var(--radius); background: var(--flaeche-leise); }
.stamm-form h3 { margin: 0; font-size: 0.85rem; }
.feld-breit { grid-column: 1 / -1; }
.stamm-form menu { grid-column: 1 / -1; display: flex; gap: 0.4rem; margin: 0.2rem 0 0; padding: 0; }
.feld { display: grid; gap: 0.2rem; font-size: 0.75rem; color: var(--text-leise); align-content: start; }
.feld label { font-weight: 500; }
.feld .pflicht { color: var(--text-schwach); }
.feld small { color: var(--text-schwach); line-height: 1.35; }
.feld input:not([type="checkbox"]):not([type="radio"]), .feld select, .feld textarea {
  width: 100%; font: var(--bedien-groesse) var(--schrift); padding: 0.35rem 0.45rem;
  color: var(--text); background: var(--flaeche);
  border: 1px solid var(--linie-stark); border-radius: var(--radius);
}
.feld textarea { resize: vertical; }
.feld-fehler input, .feld-fehler select, .feld-fehler textarea { border-color: var(--gefahr); }
.feld-meldung { color: var(--gefahr); font-size: 0.72rem; }
.feld-haken { grid-template-columns: auto 1fr; align-items: center; column-gap: 0.4rem; padding-top: 1.3rem; }
.feld-haken input { width: 1rem; height: 1rem; margin: 0; }
/* CheckboxSelectMultiple rendert eine <ul> */
.feld > div, .feld ul { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.3rem 0.9rem; }
.feld ul label { display: inline-flex; align-items: center; gap: 0.3rem; font-size: var(--bedien-groesse); color: var(--text); font-weight: 400; }

.chip-leiste { display: inline-flex; flex-wrap: wrap; gap: 0.3rem; }
.chip-still { cursor: default; }
.chip-still:hover { border-color: var(--linie-stark); color: var(--text-leise); background: var(--flaeche-leise); }

/* Mitarbeiter-Detail: Karten-Formulare in einer Zeile, Stamm-Chips, Zeit-Bloecke. */
.form-inline { display: flex; flex-wrap: wrap; gap: 0.5rem 0.7rem; align-items: end; margin-top: 0.7rem; padding-top: 0.7rem; border-top: 1px dashed var(--linie); }
.form-inline .feld { flex: 1 1 8rem; }
.form-inline .feld-breit { flex-basis: 100%; }
.form-inline .feld-haken { padding-top: 0; }
.form-inline > .knopf { flex: none; }
.stamm-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.4rem; }
.stamm-chip {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.2rem 0.3rem 0.2rem 0.7rem;
  border: 1px solid var(--linie-stark); border-radius: 999px; background: var(--flaeche-leise);
  font-size: var(--bedien-groesse);
}
.stamm-chip .rang { font-weight: 700; color: var(--haupt); }
.stamm-chip form { display: inline-flex; gap: 0.15rem; }
.stamm-chip .knopf { padding: 0.05rem 0.4rem; font-size: 0.72rem; border-radius: 999px; }
.zeiten { display: grid; gap: 0; }
.zeiten-tag { display: grid; grid-template-columns: 6.5rem 1fr; gap: 0.4rem; align-items: center; padding: 0.3rem 0; border-bottom: 1px solid var(--linie); font-size: var(--bedien-groesse); }
.zeiten-tag:last-child { border-bottom: 0; }
.zeiten-tag-name { font-weight: 600; }
.zeiten-bloecke { display: flex; flex-wrap: wrap; gap: 0.3rem; }
.zeiten-frei { color: var(--text-schwach); font-style: italic; }
.zeit-block {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.1rem 0.2rem 0.1rem 0.55rem;
  border: 1px solid var(--besetzt-rand); border-radius: var(--radius);
  background: var(--besetzt); color: var(--besetzt-text); font-variant-numeric: tabular-nums; font-weight: 600;
}
.zeit-block form { display: inline; }
.zeit-block .knopf { padding: 0 0.35rem; font-size: 0.72rem; }

/* „Uebernehmen aus ...": zwei Quellen nebeneinander, je Person eine Zeile. */
.sync-block h3 { margin: 0 0 0.3rem; font-size: 0.9rem; }
.sync-block h3 small { font-weight: 400; color: var(--text-schwach); }
.sync-leer { margin: 0; padding: 0.6rem 0.8rem; font-size: var(--bedien-groesse); color: var(--text-leise); background: var(--flaeche-leise); border-radius: var(--radius); }
.sync-zeile {
  display: flex; flex-wrap: wrap; gap: 0.5rem 0.7rem; align-items: end;
  padding: 0.6rem 0.7rem; margin-bottom: 0.5rem;
  border: 1px solid var(--linie); border-radius: var(--radius); background: var(--flaeche-leise);
}
.sync-zeile .feld { flex: 1 1 7rem; }
.sync-quelle { flex-basis: 100%; display: flex; flex-wrap: wrap; gap: 0.2rem 0.6rem; align-items: baseline; font-size: var(--bedien-groesse); }
.sync-grund { flex-basis: 100%; font-size: 0.75rem; color: var(--haupt); }
.sync-wahl { display: flex; gap: 0.5rem; align-items: end; flex: 1 1 100%; }
.sync-wahl .feld { flex: 1 1 auto; }
.sync-wahl .knopf { flex: none; }

/* --- Einstellungen: Rotation/Muster/Schliesstage (gleiche Bausteine wie Stammdaten) --- */
.einstellungen .karte-innen { margin-bottom: 0; }
.einstellungen .vorschau-titel { margin: 1rem 0 0.4rem; font-size: 0.85rem; }
.einstellungen .vorschau-titel small { font-weight: 400; }
.einstellungen .wirksam { margin: 0.8rem 0 0; padding: 0.5rem 0.7rem; font-size: 0.78rem; color: var(--text-leise); background: var(--flaeche-leise); border-radius: var(--radius); }
.einstellungen .wirksam dt { display: inline; font-weight: 600; margin-right: 0.4rem; }
.einstellungen .wirksam dd { display: inline; margin: 0; }
.einstellungen tr.gewaehlt td { background: var(--haupt-leise); }
.einstellungen tr.vorschau-gewaehlt td { background: var(--haupt-leise); }
.einstellungen tr.vorbei td { color: var(--text-schwach); }
.einstellungen tr.wochenende td { color: var(--text-schwach); }
.einstellungen .form-inline { margin-top: 0.2rem; border-top: 0; padding-top: 0; }

/* =======================================================================
 * Hilfe (/dienstplan/hilfe/): docs/anleitung.md als Lesetext mit Inhaltsverzeichnis
 * ===================================================================== */
/* Link in der Kopfzeile, gleiche Anmutung wie die Hauptnavigation. */
.hilfe-link {
  color: var(--text-leise); text-decoration: none; font-size: var(--bedien-groesse);
  padding: 0.35rem 0.5rem; border-radius: var(--radius-klein);
}
.hilfe-link:hover { background: var(--flaeche-leise); color: var(--text); }

/* Kontext-Hilfe „?" neben einer Ueberschrift: klein, rund, unaufdringlich. */
.hilfe-punkt {
  display: inline-grid; place-items: center; width: 1.35rem; height: 1.35rem;
  border: 1px solid var(--linie-stark); border-radius: 999px;
  font-size: 0.78rem; font-weight: 600; line-height: 1; text-decoration: none;
  color: var(--text-schwach); background: var(--flaeche);
}
.hilfe-punkt:hover { color: var(--info); border-color: var(--info); background: var(--info-leise); }

/* Zwei Spalten: klebendes Verzeichnis links, Text in Lesebreite rechts. */
.hilfe { display: grid; grid-template-columns: 17rem minmax(0, 72ch); gap: 2rem; align-items: start; }
.hilfe-toc {
  position: sticky; top: calc(var(--kopf-hoehe) + 1rem);
  max-height: calc(100vh - var(--kopf-hoehe) - 2rem); overflow: auto;
  padding: 0.9rem 1rem; font-size: 0.82rem;
  border: 1px solid var(--linie); border-radius: var(--radius); background: var(--flaeche); box-shadow: var(--schatten);
}
.hilfe-toc-titel { margin: 0 0 0.4rem; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-schwach); }
.hilfe-toc ul { list-style: none; margin: 0; padding: 0; }
.hilfe-toc ul ul { padding-left: 0.85rem; margin: 0.15rem 0 0.35rem; }
.hilfe-toc li { margin: 0.15rem 0; }
.hilfe-toc a { color: var(--text-leise); text-decoration: none; display: block; padding: 0.12rem 0.3rem; border-radius: var(--radius-klein); }
.hilfe-toc > .toc > ul > li > a { font-weight: 600; color: var(--text); }
.hilfe-toc a:hover { background: var(--flaeche-leise); color: var(--text); }
.hilfe-toc-fuss { margin: 0.6rem 0 0; }

.hilfe-text { font-size: 0.95rem; line-height: 1.6; }
.hilfe-text h1 { font-size: 1.5rem; margin: 0 0 1rem; }
.hilfe-text h2 { font-size: 1.2rem; margin: 2.2rem 0 0.6rem; padding-top: 1rem; border-top: 1px solid var(--linie); }
.hilfe-text h3 { font-size: 1rem; margin: 1.5rem 0 0.4rem; }
/* Sprungziele nicht unter der klebenden Kopfzeile verschwinden lassen. */
.hilfe-text h2, .hilfe-text h3 { scroll-margin-top: calc(var(--kopf-hoehe) + 0.75rem); }
.hilfe-text p, .hilfe-text ul, .hilfe-text ol { margin: 0 0 0.8rem; }
.hilfe-text li { margin: 0.2rem 0; }
.hilfe-text blockquote {
  margin: 0 0 1rem; padding: 0.6rem 0.9rem; color: var(--text-leise);
  border-left: 4px solid var(--haupt); background: var(--haupt-leise); border-radius: var(--radius);
}
.hilfe-text blockquote p:last-child { margin: 0; }
.hilfe-text code { font-size: 0.85em; padding: 0.05rem 0.3rem; background: var(--flaeche-leise); border: 1px solid var(--linie); border-radius: var(--radius-klein); }
.hilfe-text table { border-collapse: collapse; width: 100%; margin: 0 0 1rem; font-size: 0.88rem; }
.hilfe-text th, .hilfe-text td { padding: 0.4rem 0.6rem; border: 1px solid var(--linie); vertical-align: top; text-align: left; }
.hilfe-text th { background: var(--flaeche-leise); font-weight: 600; }
/* Begriffe und Fragen als Definitionsliste: Begriff fett, Erklaerung eingerueckt. */
.hilfe-text dl { margin: 0 0 1rem; }
.hilfe-text dt { font-weight: 600; margin-top: 0.7rem; }
.hilfe-text dd { margin: 0.15rem 0 0 1.2rem; color: var(--text-leise); }
.hilfe-text hr { border: 0; border-top: 1px solid var(--linie); margin: 1.5rem 0; }

@media (max-width: 900px) {
  .hilfe { grid-template-columns: minmax(0, 1fr); }
  .hilfe-toc { position: static; max-height: none; }
}
@media print {
  .hilfe { display: block; }
  .hilfe-punkt, .hilfe-link { display: none !important; }
}

/* --- Vorlage: kopieren (Tag / Zeile / Fenster) ---------------------------- */
/* Die Kopier-Knoepfe sitzen in Spalten- und Zeilenkopf; leise, damit sie das
   Raster nicht dominieren, aber immer sichtbar (kein Hover-Raetsel). */
.kopier-knopf { display: block; margin-top: 0.25rem; font-size: 0.66rem; padding: 0.1rem 0.4rem; color: var(--text-schwach); }
th.tag .kopier-knopf { display: inline-block; margin: 0 0 0 0.4rem; vertical-align: middle; }
.kopier-knopf:hover { color: var(--haupt); border-color: var(--haupt); }
.kopier-felder { display: grid; gap: 0.7rem; }
.kopier-quelle { display: grid; gap: 0.2rem; font-size: 0.75rem; color: var(--text-leise); }
.kopier-quelle select {
  font: var(--bedien-groesse) var(--schrift);
  padding: 0.35rem 0.45rem;
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
}
.kopier-ziele { display: flex; flex-wrap: wrap; gap: 0.3rem 0.7rem; margin: 0; padding: 0.4rem 0.6rem; border: 1px solid var(--linie); border-radius: var(--radius); }
.kopier-ziele legend { font-size: 0.75rem; color: var(--text-leise); padding: 0 0.2rem; }
.kopier-ziele label { display: inline-flex; align-items: center; gap: 0.25rem; font-size: var(--bedien-groesse); }
.kopier-ziele input:disabled + span { color: var(--text-schwach); text-decoration: line-through; }
.fenster-kopie { margin: 0.7rem 0 0; padding: 0.5rem 0.6rem; border: 1px solid var(--linie); border-radius: var(--radius); }
.fenster-kopie legend { font-size: 0.75rem; color: var(--text-leise); padding: 0 0.2rem; }
.tag-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 0.3rem; }
.tag-chips .chip:disabled { opacity: 0.45; cursor: not-allowed; }
.tag-chips .knopf { margin-left: auto; }

/* =====================================================================
 * Klammer: Werkzeug-Umschalter in der Kopfzeile und die Startseite /ich/
 * ===================================================================== */

/* Der Umschalter ist ein <details> — ohne JavaScript bedienbar. */
.wechsler { position: relative; flex: none; }
.wechsler > summary {
  list-style: none; cursor: pointer; user-select: none;
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-weight: 700; color: var(--text); text-decoration: none;
  padding: 0.3rem 0.5rem; margin-left: -0.5rem; border-radius: var(--radius);
}
.wechsler > summary::-webkit-details-marker { display: none; }
.wechsler > summary:hover { background: var(--flaeche-leise); }
.wechsler[open] > summary { background: var(--flaeche-leise); }
.marke-pfeil { font-size: 0.7em; color: var(--text-schwach); }
.wechsler-panel {
  /* Ein gewoehnliches Menue: senkrecht, direkt unter der Marke, schmal.
     Vorher lief es waagerecht ueber die halbe Breite (siehe `.kopf > nav`) —
     das ist nicht nur ungewohnt, es sind auch lange Mauswege bis zum letzten
     Eintrag. Senkrecht liegt jeder Eintrag zwei Zentimeter unter dem Zeiger. */
  display: block;
  position: absolute; top: calc(100% + 0.3rem); left: 0; z-index: 30;
  width: max-content; min-width: 17rem; max-width: 24rem; padding: 0.35rem;
  background: var(--flaeche); border: 1px solid var(--linie-stark);
  border-radius: var(--radius); box-shadow: 0 8px 24px rgb(0 0 0 / 0.18);
}
.wechsler-titel {
  margin: 0.2rem 0.5rem 0.3rem; font-size: 0.68rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-schwach);
}
.wechsler-panel hr { border: 0; border-top: 1px solid var(--linie); margin: 0.3rem 0.4rem; }
.wechsler-eintrag {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.4rem 0.5rem; border-radius: var(--radius-klein);
  color: var(--text); text-decoration: none;
}
.wechsler-eintrag:hover { background: var(--flaeche-leise); }
.wechsler-eintrag.aktiv { background: var(--haupt-leise); }
/* Die Modulzeichen: `currentColor` heisst, sie nehmen die Textfarbe an — also
   auch das dunkle Thema, ohne zweiten Satz Bilder. Fein gestrichelt statt
   flaechig, damit sie neben 0.875rem Text nicht schreien. */
.wechsler-zeichen, .marke-zeichen {
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.wechsler-zeichen { width: 1.15rem; height: 1.15rem; color: var(--text-leise); }
.wechsler-eintrag.aktiv .wechsler-zeichen { color: var(--haupt); }
.marke-zeichen { width: 1.15rem; height: 1.15rem; color: var(--haupt); }
.wechsler-text { display: grid; min-width: 0; }
.wechsler-text small { color: var(--text-schwach); font-size: 0.75rem; }
.wechsler-haken { margin-left: auto; color: var(--haupt); font-weight: 700; }
.wechsler-extern { margin-left: auto; color: var(--text-schwach); }
a.benutzer { text-decoration: none; }
a.benutzer:hover { color: var(--text); text-decoration: underline; }

/* --- Startseite „Fuer mich" ------------------------------------------- */
/* Volle Breite wie in jedem anderen Modul. Vorher klebte die Seite auf 44rem
   in der Mitte und liess auf einem gewoehnlichen Monitor links und rechts
   handbreit Nichts stehen — als waere die Seite kaputt geladen.
   Die Zeilenlaenge bleibt trotzdem lesbar, weil die Kaesten NEBENEINANDER
   wachsen statt in die Breite gezogen zu werden. */
.ich-seite { padding: 1rem 1.25rem 2rem; display: grid; gap: 0.9rem; align-content: start; }
.ich-seite > .meine-reiter { grid-column: 1 / -1; }
@media (min-width: 60rem) {
  .ich-seite { grid-template-columns: minmax(22rem, 30rem) minmax(20rem, 1fr); align-items: start; }
  /* „Heute" ist der einzige Kasten, der ueber beide Spalten geht: er muss
     ueber den Flur lesbar sein, und dafuer braucht er Luft. */
  .ich-seite > .ich-heute { grid-column: 1 / -1; }
  .ich-seite > .ich-fuss { grid-column: 1 / -1; }
}
.ich-heute {
  border: 1px solid var(--linie-stark); border-radius: var(--radius);
  background: var(--flaeche); padding: 1rem 1.1rem; box-shadow: var(--schatten);
}
.ich-heute h1 { margin: 0 0 0.6rem; font-size: 1.05rem; color: var(--text-leise); font-weight: 600; }
.ich-schicht {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 0.3rem 0.8rem;
  padding: 0.4rem 0; border-top: 1px solid var(--linie);
}
.ich-schicht:first-of-type { border-top: 0; }
/* „Heute ist gross": die Uhrzeit muss ueber den Flur lesbar sein. */
.ich-zeit { font-size: 1.6rem; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.ich-position { font-size: 1.1rem; font-weight: 600; }
.ich-position small { font-weight: 400; color: var(--text-schwach); font-size: 0.8rem; }
.ich-abweichung { flex-basis: 100%; font-size: 0.8rem; color: var(--warn); font-weight: 600; }
/* Nachtdienst auf „Fuer mich": eigene Zeile fuer den Satz, und was aus der
   Nacht hereinlaeuft bekommt einen gestrichelten Rand -- es ist keine zweite
   Schicht, sondern die von gestern. */
.ich-nacht { flex-basis: 100%; font-size: 0.8rem; color: var(--text-leise); }
.ich-schicht-nacht { border-left: 3px dashed var(--linie-stark); padding-left: 0.5rem; }
.ich-frei { margin: 0; font-size: 1.2rem; color: var(--text-leise); }
.ich-morgen { margin: 0.7rem 0 0; padding-top: 0.5rem; border-top: 1px solid var(--linie); font-size: var(--bedien-groesse); color: var(--text-leise); }
.ich-karte { margin: 0; }
.ich-karte .karte-kopf h2 { font-size: 0.9rem; }
.ich-karte .karte-kopf h2 small { color: var(--text-schwach); font-weight: 400; margin-left: 0.3rem; }
.ich-aufgaben { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }
.ich-aufgaben li { display: flex; align-items: center; gap: 0.5rem; font-size: var(--bedien-groesse); }
.ich-nr {
  flex: none; display: grid; place-items: center; width: 1.4rem; height: 1.4rem; border-radius: 50%;
  background: var(--flaeche-leise); border: 1px solid var(--linie-stark); font-size: 0.7rem; font-weight: 700;
}
.ich-aufgabe-text { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ich-aufgabe-text.erledigt { text-decoration: line-through; color: var(--text-schwach); }
.ich-aufgabe-zeit { flex: none; font-variant-numeric: tabular-nums; color: var(--text-leise); }
.ich-woche { list-style: none; margin: 0 0 0.4rem; padding: 0; display: grid; gap: 0.15rem; font-size: var(--bedien-groesse); }
.ich-woche li { display: flex; gap: 0.6rem; padding: 0.15rem 0.3rem; border-radius: var(--radius-klein); }
.ich-woche li.heute { background: var(--haupt-leise); font-weight: 600; }
.ich-woche li.frei .ich-wschichten { color: var(--text-schwach); }
.ich-wtag { flex: none; width: 2rem; font-weight: 600; color: var(--text-leise); }
.ich-abwesenheiten { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.2rem; font-size: var(--bedien-groesse); }
.ich-fuss { display: flex; gap: 0.4rem; flex-wrap: wrap; margin: 0.2rem 0 0; }
.ich-werkzeuge { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.3rem; }
.ich-werkzeuge a { display: flex; gap: 0.5rem; align-items: baseline; text-decoration: none; color: var(--text); padding: 0.35rem 0.4rem; border-radius: var(--radius-klein); }
.ich-werkzeuge a:hover { background: var(--flaeche-leise); }
.ich-werkzeuge small { color: var(--text-schwach); }

/* Schmale Bildschirme: die Kopfzeile darf umbrechen, die Zeit bleibt gross. */
@media (max-width: 620px) {
  .kopf { height: auto; flex-wrap: wrap; gap: 0.5rem 1rem; padding: 0.5rem 0.9rem; }
  .kopf nav[aria-label="Hauptnavigation"] { order: 3; flex-basis: 100%; overflow-x: auto; }
  .wechsler-panel { min-width: min(20rem, calc(100vw - 2rem)); }
  .ich-seite { padding: 0.8rem 0.9rem 2rem; }
}

/* --- Hilfe: Einstieg je Modul -------------------------------------------
 * EIN Dokument, vier Einstiege. Der Hilfe-Knopf der Kopfzeile springt in das
 * Kapitel des Moduls, in dem man gerade steht; hier oben stehen alle. Vier
 * getrennte Hilfetexte waeren vier Dokumente, die auseinanderdriften. */
.hilfe-module { list-style: none; margin: 0 0 1rem; padding: 0; font-size: 0.9rem; }
.hilfe-module li { margin: 0.15rem 0; }
.hilfe-module a { display: block; padding: 0.2rem 0.3rem; border-radius: 4px; text-decoration: none; }
.hilfe-module a:hover { background: var(--flaeche-leise); }
.hilfe-module a.aktiv { background: var(--flaeche-leise); font-weight: 600; }

/* --- Der Modulkopf: gleiche Dinge an derselben Stelle ---------------------
 *
 * Jedes Modul beantwortet oben dieselben drei Fragen, und zwar in dieser
 * Reihenfolge — waagerecht gelesen, nicht ueber die ganze Breite verteilt:
 *
 *   1. WO bin ich?      Titel, darunter ggf. eine Zeile Erklaerung
 *   2. WAS kann ich?    Aktionen, Hauptaktion zuerst, immer links
 *   3. WELCHER AUSSCHNITT?  Zeitraumwahl — und der Filter DANEBEN
 *
 * Der dritte Punkt ist der Grund fuer diesen Block. Vorher hing der
 * Bereichsfilter der Abwesenheiten per `margin-left: auto` am rechten
 * Bildschirmrand, meterweit von der Tabelle entfernt, die er bestimmt.
 * Wer zwischen den Modulen wechselt, soll nichts suchen muessen.
 */
.modulkopf { margin-bottom: 0.9rem; }
.modulkopf h1 { margin: 0 0 0.15rem; }
.modulkopf > p.leise { margin: 0 0 0.6rem; max-width: 62ch; }
.modulkopf-aktionen {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-items: center;
  margin: 0 0 0.6rem;
}
.modulkopf-aktionen .knopf.aktiv { background: var(--haupt-leise); border-color: var(--haupt); }

/* Zeitraumwahl — `templates/_monatswahl.html` und alles, was so aussehen soll. */
.wahl {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
  margin: 0 0 0.6rem;
}
.wahl select, .wahl input[type="number"], .wahl input[type="date"] {
  font-size: var(--bedien-groesse);
  padding: 0.25rem 0.4rem;
  border: 1px solid var(--linie-stark);
  border-radius: var(--radius);
  background: var(--flaeche);
  color: var(--text);
}
.wahl label:not(.nur-sr) { font-size: 0.78rem; color: var(--text-leise); margin-left: 0.4rem; }
.wahl-jahr { width: 5.5rem; }
.wahl-spruenge { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-left: 0.5rem; }
.wahl [aria-current="page"] {
  background: var(--flaeche-tot);
  border-color: var(--linie-stark);
  font-weight: 600;
}
/* Der Filter sitzt am selben Faden wie die Wahl — nur durch einen Strich
   abgesetzt, damit man sieht: andere Frage, gleiche Leiste. */
.wahl-filter {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: 0.6rem;
  padding-left: 0.7rem;
  border-left: 1px solid var(--linie);
}
.wahl-person { margin-top: -0.2rem; }

@media (max-width: 700px) {
  .wahl-spruenge { margin-left: 0; }
  .wahl-filter { margin-left: 0; padding-left: 0; border-left: 0; }
}

/* --- „Fuer mich": eine Leiste, die mitwandert -----------------------------
 *
 * Wer ausser Stempeln nicht viel darf, sieht von der Software fast nichts:
 * seine Dienste stehen im Dienstplan, seine Zeiten in der Zeiterfassung, sein
 * Urlaub in den Abwesenheiten — drei Werkzeuge fuer drei Fragen, die dieselbe
 * Person zu sich selbst stellt.
 *
 * Die Reiter fuehren auf die vorhandenen Modulseiten, nicht auf Kopien: eine
 * zweite „Meine Zeiten"-Ansicht waere eine zweite Wahrheit. Die Leiste wandert
 * stattdessen mit — sie steht ueberall dort, wo es um die eigene Person geht.
 */
.meine-reiter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
  margin: 0 0 1rem;
  border-bottom: 1px solid var(--linie);
}
.meine-reiter a {
  padding: 0.4rem 0.75rem;
  font-size: var(--bedien-groesse);
  color: var(--text-leise);
  text-decoration: none;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: var(--radius) var(--radius) 0 0;
  margin-bottom: -1px;
  white-space: nowrap;
}
.meine-reiter a:hover { background: var(--flaeche-leise); color: var(--text); }
/* Die aktive Lasche haengt an der Linie, statt darauf zu liegen: so sieht man,
   dass der Inhalt darunter zu ihr gehoert. */
.meine-reiter a[aria-current="page"] {
  background: var(--flaeche);
  border-color: var(--linie);
  border-bottom: 1px solid var(--flaeche);
  color: var(--text);
  font-weight: 600;
}
