/* Gestaltungssystem des Gerätemanagers.
 *
 * Die Werte stammen aus dem UI-Entwurf docs/Gerätemanager.html. Dort
 * steht jede Regel als Inline-Stil an jedem einzelnen Element; hier ist
 * sie einmal benannt. Der Entwurf bleibt die verbindliche visuelle
 * Referenz — wo hier etwas abweicht, steht der Grund daneben.
 *
 * Jede Farbe steht als `light-dark(hell, dunkel)` und damit einmal statt
 * zweimal. Die Alternative wäre ein zweiter Block hinter
 * `prefers-color-scheme` plus ein dritter hinter `[data-farbschema]` —
 * dieselben vierzig Werte dreifach, und jede Änderung wäre eine
 * Gelegenheit, eine der Fassungen zu vergessen. Welcher Zweig gilt,
 * entscheidet allein `color-scheme` weiter unten.
 *
 * Vorausgesetzte Browser: Chrome/Edge 123, Firefox 120, Safari 17.5 —
 * das ist die Schwelle von `light-dark()`. Sie liegt fünf Monate über
 * der, die dieses Stylesheet ohnehin schon verlangte: `color-mix()` seit
 * Mai 2023, `:has()` seit Dezember 2023, beide von Anfang an in Gebrauch
 * (Typfarben, gewählte Typkarte). Wer eines davon nicht kann, sah die
 * Oberfläche auch vorher nicht wie vorgesehen. Sollte im Betrieb doch
 * ein älterer Browser auftauchen, gehört hierher ein Block hinter
 * `@supports not (color: light-dark(#fff, #000))` mit dem hellen Satz —
 * nicht ein Rückbau der ganzen Datei.
 */

:root {
  /* Ohne Wahl folgt die Oberfläche dem Betriebssystem; das
   * data-Attribut setzt der Umschalter in der Kopfzeile. */
  color-scheme: light dark;

  --akzent:        light-dark(#3b82f6, #60a5fa);
  --akzent-dunkel: light-dark(#2563eb, #93c5fd);
  --akzent-hauch:  light-dark(#eff6ff, #1b2740);

  /* Verweise tragen Schrift, nicht Fläche, und brauchen deshalb einen
   * eigenen Ton: der Akzent #3b82f6 kommt auf Weiss nur auf 3,7:1 und
   * fiele damit unter die Schwelle für Fliesstext. #2563eb sind 5,2:1,
   * beim Überfahren #1d4ed8 mit 6,3:1. Als Fläche bleibt der Akzent,
   * was er ist — dort trägt er keine Schrift. */
  --verweis:       light-dark(#2563eb, #93c5fd);
  --verweis-hover: light-dark(#1d4ed8, #bfdbfe);

  --text:        light-dark(#1f2430, #e8eaed);
  --text-mittel: light-dark(#55595f, #b8bcc4);

  /* Der Entwurf schreibt #8a8f98 vor. Auf Weiss ergibt das 3,25:1, und
   * damit fielen Feldbezeichnungen, Kennungen, Seitenleitsätze und die
   * halbe Seitenleiste unter die 4,5:1 für Fliesstext. #6f747d kommt auf
   * 4,71:1 und bleibt erkennbar zurückgenommen — der Abstand zu
   * --text-mittel (6,8:1) trägt die Stufe weiterhin. Im dunklen Schema
   * stellt sich die Frage nicht: #949aa4 auf #14161b sind 6,4:1. */
  --text-leise:  light-dark(#6f747d, #949aa4);

  /* Vergangene Tage im Kalender. Deaktivierte Bedienelemente sind von
   * der Kontrastforderung ausgenommen, ablesbar müssen die Zahlen
   * trotzdem bleiben: wer den Monat überblickt, sucht an ihnen. */
  --text-blass:  light-dark(#9aa1aa, #5a606b);

  --flaeche:        light-dark(#ffffff, #14161b);
  --flaeche-hover:  light-dark(#f4f5f7, #23262e);
  --flaeche-zeile:  light-dark(#fafbfc, #1b1e25);
  --flaeche-ruhig:  light-dark(#fafbfc, #1b1e25);
  /* Die kaum wahrnehmbare Abtönung hinter gesperrten und
   * Formularzeilen. Im Dunkeln muss sie heller werden statt dunkler:
   * unter der Grundfläche liegt kein Raum mehr. */
  --flaeche-gedaempft: light-dark(#fcfcfd, #191c22);

  --linie:          light-dark(#e5e7eb, #2b2f38);
  --linie-kraeftig: light-dark(#d0d3d8, #3a3f4a);
  --linie-zart:     light-dark(#eef0f2, #24272f);
  --linie-zarter:   light-dark(#f1f2f4, #1f222a);

  /* Die Hauptaktion ist die dunkelste Fläche der hellen Oberfläche. Im
   * Dunkeln kann sie das nicht bleiben — sie kippt und wird die
   * hellste. Deshalb zwei Namen: die Fläche und was darauf steht. */
  --dunkel:       light-dark(#16181d, #e8eaed);
  --dunkel-hover: light-dark(#000000, #ffffff);
  --auf-dunkel:   light-dark(#ffffff, #16181d);

  /* Schrift auf einer Typfarbe — das Datumsabzeichen eines Balkens.
   * Sie bleibt in beiden Schemata weiss: die Typfarbe ist ein
   * Stammdatum und kippt nicht mit dem Schema. */
  --auf-farbe: #ffffff;

  /* Schrift auf der Akzentfläche. Der Akzent selbst wird im Dunkeln
   * heller, damit er auf dunklem Grund noch als Verweis lesbar ist —
   * weisse Schrift darauf käme dann auf 2,3:1. Sie kippt deshalb mit. */
  --auf-akzent: light-dark(#ffffff, #10182a);

  --auswahl: light-dark(#dbe8ff, #26406e);

  --radius: 10px;
  --radius-klein: 8px;
  --radius-winzig: 6px;
  --schatten-karte: light-dark(0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 2px rgba(0, 0, 0, 0.4));
  --schatten-schwebend: light-dark(0 4px 16px rgba(16, 24, 40, 0.1), 0 6px 24px rgba(0, 0, 0, 0.55));

  --seitenleiste-breite: 224px;

  --schrift: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --schrift-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* Der Umschalter setzt eines der beiden Attribute und überstimmt damit
 * die Vorgabe des Betriebssystems. Mehr braucht es nicht: alle Farben
 * hängen an `color-scheme`. */
:root[data-farbschema="hell"]   { color-scheme: light; }
:root[data-farbschema="dunkel"] { color-scheme: dark; }

/* Zustandsfarben. Die ersten sieben entsprechen der Tabelle COLORS im
 * Entwurf. `reparatur` kommt neu hinzu (Spec Kap. 6) und ist bewusst
 * NICHT aus dem Rot von `gesperrt` abgeleitet: die beiden Zustände haben
 * verschiedene Konsequenzen - Reparatur heisst defekt, Sperrung heisst in
 * aller Regel Fälligkeit überschritten - und müssen auf einen Blick
 * unterscheidbar sein. Ein zweiter Rotton wäre das nicht.
 *
 * Die dunklen Gegenstücke sind nicht die hellen mit vertauschten Rollen:
 * eine helle Plakettenfläche auf dunklem Grund leuchtet wie eine
 * Warnleuchte. Stattdessen trägt jede Plakette eine tief abgesetzte
 * Fläche und eine helle Schrift derselben Familie — jedes Paar über
 * 4,5:1. */
:root {
  --z-verfuegbar-bg:   light-dark(#dcf5e3, #10331d);  --z-verfuegbar-fg:   light-dark(#177230, #7ee2a0);
  --z-teilweise-bg:    light-dark(#fff2d6, #3a2c0c);  --z-teilweise-fg:    light-dark(#92650b, #f0c45a);
  --z-reserviert-bg:   light-dark(#eef0f2, #262a33);  --z-reserviert-fg:   light-dark(#55595f, #c1c6cf);
  --z-faellig-bg:      light-dark(#ffe4cc, #3d2410);  --z-faellig-fg:      light-dark(#a04d08, #f2a15e);
  --z-gesperrt-bg:     light-dark(#fde3e3, #3d1717);  --z-gesperrt-fg:     light-dark(#c22a2a, #f28b8b);
  --z-ausgemustert-bg: light-dark(#eef0f2, #24272f);  --z-ausgemustert-fg: light-dark(#5f656d, #949aa4);
  --z-inverwendung-bg: light-dark(#e3edff, #17244a);  --z-inverwendung-fg: light-dark(#2b5fd9, #8fb2ff);
  --z-reparatur-bg:    light-dark(#ede9fe, #2a1f4d);  --z-reparatur-fg:    light-dark(#6d28d9, #bda6f7);

  /* Die Rahmen der Meldungskästen und Balken. Sie liegen zwischen
   * Fläche und Schrift desselben Zustands. */
  --z-gesperrt-linie:   light-dark(#f6c9c9, #6b2626);
  --z-verfuegbar-linie: light-dark(#bfe6cb, #1d5c33);
  --z-reparatur-linie:  light-dark(#d9cffb, #4a3a80);

  /* Das Datumsabzeichen eines Sperr- oder Reparaturbalkens trägt weisse
   * Schrift. Hell taugt dafür die Schriftfarbe des Zustands; dunkel
   * nicht — dort ist sie ein helles Rosa, auf dem Weiss verschwände.
   * Die Fläche braucht deshalb ihren eigenen Wert. */
  --z-gesperrt-marke:  light-dark(#c22a2a, #8f2222);
  --z-reparatur-marke: light-dark(#6d28d9, #5b21b6);

  /* Der Vorbehalt: keine Sperre, aber auch kein grünes Licht. Er hat
   * eine eigene Fläche, weil er weder Fehler noch Erfolg ist. */
  --warnung-bg:    light-dark(#fffaf0, #33290f);
  --warnung-fg:    light-dark(#92650b, #f0c45a);
  --warnung-linie: light-dark(#f3e2c0, #6b5518);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

/* Alpine wird mit defer geladen; bis es die Steuerung übernimmt, blieben
 * die nur bedingt sichtbaren Teile sonst kurz stehen. Die Regel gehört
 * hierher und nicht in eine einzelne Seite: sie gilt überall, wo Alpine
 * läuft. */
[x-cloak] { display: none !important; }

/* Sichtbarer Fokus. Bisher trug ihn allein das Eingabefeld: wer die
 * Oberfläche mit der Tastatur bedient, sah auf Knöpfen, Verweisen,
 * Typkarten und Tageszellen nicht, wo er steht.
 *
 * :focus-visible und nicht :focus — der Ring gehört zur Tastatur. Bei
 * der Maus wäre er Lärm, und genau deshalb entfernen ihn viele
 * Stylesheets ganz. */
:focus-visible {
  outline: 2px solid var(--verweis);
  outline-offset: 2px;
}

/* Wer Bewegung abbestellt hat, meint es. Viel gibt es hier nicht — der
 * Rahmenwechsel an der Typkarte —, aber die Regel gilt für alles, was
 * später dazukommt. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

body {
  font-family: var(--schrift);
  color: var(--text);
  background: var(--flaeche);
  min-height: 100vh;
}

a { color: var(--verweis); text-decoration: none; }
a:hover { color: var(--verweis-hover); text-decoration: underline; }
input[type="date"] { font-family: inherit; }
::selection { background: var(--auswahl); }

/* ------------------------------------------------------------- Rahmen */

/* Der Sprungverweis liegt über dem oberen Rand, bis ihn die Tastatur
 * erreicht. `display: none` täte es nicht — was nicht angezeigt wird,
 * bekommt auch keinen Fokus.
 *
 * Nach oben und nicht nach links: die alte Regel `left: -9999px` legt
 * den Kasten neben die Seite, und je nach Umgebung wächst dadurch der
 * waagerechte Bildlaufbereich mit. Oben ist immer abgeschnitten. */
.sprungverweis {
  position: absolute;
  left: 12px;
  top: -6rem;
  z-index: 100;
  background: var(--flaeche);
  color: var(--verweis);
  border: 1px solid var(--linie-kraeftig);
  border-radius: var(--radius-klein);
  padding: 10px 16px;
  font-size: 13.5px;
  font-weight: 600;
  box-shadow: var(--schatten-schwebend);
}
.sprungverweis:focus {
  top: 12px;
  text-decoration: none;
}

/* Das Sprungziel bekommt tabindex="-1", damit der Fokus wirklich dort
 * landet. Sein Fokusring wäre ein Rahmen um die halbe Seite. */
.hauptbereich:focus { outline: none; }

.akzentbalken { height: 3px; background: var(--akzent); }

.rahmen {
  display: flex;
  align-items: stretch;
  min-height: calc(100vh - 3px);
}

.seitenleiste {
  width: var(--seitenleiste-breite);
  flex-shrink: 0;
  background: var(--flaeche);
  border-right: 1px solid var(--linie);
  padding: 20px 14px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.seitenleiste__kopf { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.seitenleiste__marke { font-weight: 700; font-size: 15px; padding: 0 8px; }

/* Der Schalter erscheint erst im schmalen Umbruch. Breit steht die
 * Navigation offen — dort wäre er ein Klick ohne Zweck. */
.seitenleiste__schalter {
  display: none;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--linie-kraeftig);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  color: var(--text-mittel);
  cursor: pointer;
  flex-shrink: 0;
}
.seitenleiste__schalter:hover { background: var(--flaeche-hover); color: var(--text); }

/* Breit löst sich die Hülle auf: ihre Kinder stehen wieder unmittelbar
 * im Flex-Fluss der Seitenleiste und behalten deren Abstand. */
.seitenleiste__klapp { display: contents; }

.seitenleiste__gruppe {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-leise);
  padding: 0 8px 8px;
}

.seitenleiste__liste { display: flex; flex-direction: column; gap: 2px; }

.navlink {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-klein);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-mittel);
  text-decoration: none;
}
.navlink:hover { background: var(--flaeche-hover); text-decoration: none; color: var(--text); }
.navlink[aria-current="page"] { background: var(--flaeche-hover); color: var(--text); }

/* Seitenleistenfuss: Konto und Abmeldung. Der Entwurf zeigt ihn nicht -
 * er kennt keine Anmeldung. Ohne ihn gäbe es keinen Weg hinaus, deshalb
 * steht er hier, zurückgenommen und in derselben Sprache. */
.seitenleiste__fuss {
  margin-top: auto;
  padding: 14px 8px 0;
  border-top: 1px solid var(--linie);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.konto__name { font-size: 13px; font-weight: 600; }
.konto__rolle { font-size: 11px; color: var(--text-leise); text-transform: capitalize; }

.hauptbereich { flex: 1; min-width: 0; }

.kopfzeile {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 32px;
  border-bottom: 1px solid var(--linie);
  font-size: 14px;
  color: var(--text-leise);
}
.kopfzeile strong { color: var(--text); font-weight: 600; }
.kopfzeile__weg { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Der Farbschema-Umschalter. Sichtbar ist immer genau ein Symbol: das
 * des Schemas, in das er wechselt. */
.farbschema { flex-shrink: 0; }
:root[data-farbschema="dunkel"] .farbschema__mond,
:root[data-farbschema="hell"]   .farbschema__sonne { display: none; }

/* Ohne Skript steht kein Attribut an der Wurzel, und beide Symbole
 * stünden nebeneinander. Dann gilt der Mond — die Seite ist in dem Fall
 * hell, weil auch das Umschalten nicht ginge. */
:root:not([data-farbschema]) .farbschema__sonne { display: none; }

.anmeldung__leiste { display: flex; justify-content: flex-end; padding: 16px 16px 0; }

/* Der Entwurf gibt jeder Seite ihre eigene Maximalbreite: die Startseite
 * ist die breiteste, Formular und Detail die schmalsten. */
.inhalt { max-width: 1320px; margin: 0 auto; padding: 32px 32px 80px; }
.inhalt--breit    { max-width: 1180px; }
.inhalt--mittel   { max-width: 1000px; }
.inhalt--schmal   { max-width: 820px; }
.inhalt--formular { max-width: 640px; }

.seitenkopf { margin-bottom: 24px; }
.seitenkopf--start { margin-bottom: 22px; }
.seitenkopf--plan { margin-bottom: 16px; }

.seitentitel { font-size: 24px; margin: 0 0 6px; font-weight: 700; }
.seitentitel--gross { font-size: 26px; }

.seitenlead { font-size: 16px; color: var(--text-leise); margin: 0; }
.seitenlead--klein { font-size: 15px; }

/* Zurück-Verweis über einem Detail. Im Entwurf ein Knopf ohne Rahmen. */
.zurueck {
  border: none;
  background: none;
  color: var(--verweis);
  font-size: 13px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  padding: 0;
  display: inline-block;
  margin-bottom: 20px;
}
.zurueck:hover { color: var(--verweis-hover); text-decoration: underline; }

/* ---------------------------------------------------------- Bausteine */

.karte {
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  padding: 22px;
  background: var(--flaeche);
  box-shadow: var(--schatten-karte);
}
.karte--eng { padding: 20px; }
.karte--blank { padding: 0; box-shadow: none; overflow: hidden; }

/* Eine Karte, die eine Auskunft trägt statt einer Handlung: im Entwurf
 * an der ruhigen Fläche zu erkennen. */
.karte--ruhig { background: var(--flaeche-ruhig); box-shadow: none; }

.kartentitel {
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.kartenkopf { padding: 18px 22px 0; }

/* Das Mikro-Label über einem Feld oder Abschnitt. */
.feldbezeichnung,
.mikrotitel {
  display: block;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-leise);
  font-weight: 600;
  margin-bottom: 6px;
}
.mikrotitel { font-weight: 400; margin-bottom: 8px; }

.eingabe {
  width: 100%;
  border: 1px solid var(--linie-kraeftig);
  border-radius: var(--radius-klein);
  padding: 10px 12px;
  font-size: 13.5px;
  font-family: inherit;
  color: var(--text);
  background: var(--flaeche);
}
.eingabe:focus-visible { outline: 2px solid var(--verweis); outline-offset: -1px; }
.eingabe--schmal { padding: 9px 12px; }

/* Eine Eingabe, die wie ein Wert aussieht: im Zusammenzug der
 * Reservierungsliste steht rechts kein Feld, sondern eine Angabe. */
.eingabe--blank {
  border: none;
  background: transparent;
  color: var(--text);
  text-align: right;
  font-weight: 600;
  font-size: 13px;
  width: 150px;
  /* Ohne Polster wäre das Feld 19 px hoch und mit der Maus kaum, mit
   * dem Finger gar nicht zu treffen. */
  padding: 6px 0;
}
.eingabe--blank:focus-visible { outline: 2px solid var(--verweis); outline-offset: 2px; }

.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border: 1px solid var(--linie-kraeftig);
  background: var(--flaeche);
  border-radius: 999px;
  padding: 8px 14px;
  font-size: 12.5px;
  font-weight: 600;
  font-family: inherit;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.knopf:hover { background: var(--flaeche-hover); text-decoration: none; color: var(--text); }

.knopf--stark { border: none; background: var(--dunkel); color: var(--auf-dunkel); }
.knopf--stark:hover { background: var(--dunkel-hover); color: var(--auf-dunkel); }

.knopf--akzent {
  border: none;
  /* --verweis und nicht --akzent: die Fläche trägt hier Schrift, und
   * Weiss auf #3b82f6 sind 3,7:1. Auf #2563eb 5,2:1, beim Überfahren
   * auf #1d4ed8 6,3:1. */
  background: var(--verweis);
  color: var(--auf-akzent);
  padding: 10px 18px;
  font-size: 13px;
  gap: 8px;
}
.knopf--akzent:hover { background: var(--verweis-hover); color: var(--auf-akzent); }

.knopf--klein { padding: 6px 14px; font-size: 12px; }
.knopf--schmal { padding: 6px 12px; font-size: 12px; width: 100%; }
.knopf--voll { width: 100%; padding: 12px 18px; font-size: 14px; font-weight: 600; }

/* Runde Pfeilknöpfe der Wochen- und Monatsnavigation. */
.knopf--rund { width: 28px; height: 28px; padding: 0; font-size: 14px; color: var(--text-mittel); }
.knopf--rund-klein { width: 24px; height: 24px; padding: 0; font-size: 13px; color: var(--text-mittel); }

.knopf[disabled], .knopf:disabled { opacity: .5; cursor: not-allowed; }

/* Zustandsplakette. Die Klasse benennt den fachlichen Zustand aus
 * Spec Kap. 6, nicht die Farbe. */
.plakette {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}
.plakette--gross { padding: 4px 12px; font-size: 12.5px; }

.plakette--verfuegbar    { background: var(--z-verfuegbar-bg);    color: var(--z-verfuegbar-fg); }
.plakette--teilweise     { background: var(--z-teilweise-bg);     color: var(--z-teilweise-fg); }
.plakette--reserviert    { background: var(--z-reserviert-bg);    color: var(--z-reserviert-fg); }
.plakette--faellig       { background: var(--z-faellig-bg);       color: var(--z-faellig-fg); }
.plakette--gesperrt      { background: var(--z-gesperrt-bg);      color: var(--z-gesperrt-fg); }
.plakette--ausgemustert  { background: var(--z-ausgemustert-bg);  color: var(--z-ausgemustert-fg); }
.plakette--inverwendung  { background: var(--z-inverwendung-bg);  color: var(--z-inverwendung-fg); }
.plakette--reparatur     { background: var(--z-reparatur-bg);     color: var(--z-reparatur-fg); }

/* Gerätetypen tragen ihre Farbe als Stammdatum (Spec Kap. 34). Sie wird
 * pro Element als --typ-farbe gesetzt, nicht als feste Klasse - die Liste
 * der Typen ist pflegbar und darf nicht im Stylesheet festgeschrieben
 * sein. Fläche und Abzeichenfarbe leiten sich daraus ab: der Entwurf
 * führt je Typ vier abgestimmte Farben, die Stammdaten führen eine. */
.typ {
  --typ-flaeche: light-dark(
      color-mix(in srgb, var(--typ-farbe, #8a8f98) 18%, #ffffff),
      color-mix(in srgb, var(--typ-farbe, #8a8f98) 26%, #14161b));
  --typ-abzeichen-bg: light-dark(
      color-mix(in srgb, var(--typ-farbe, #8a8f98) 10%, #ffffff),
      color-mix(in srgb, var(--typ-farbe, #8a8f98) 22%, #14161b));
  /* Hell wird die Typfarbe zum Lesen abgedunkelt, dunkel aufgehellt —
   * derselbe Zweck, entgegengesetzte Richtung. Ein gemeinsamer
   * Mischanteil gäbe es nicht her: 78 % Typfarbe auf dunklem Grund
   * bliebe zu dunkel zum Lesen. Und 78 statt der zuerst gewählten 88
   * Prozent, weil das helle Grün der Waage (#16a34a) sonst bei 4,2:1
   * stehen bliebe; der dunkelste Typ verliert dadurch nichts. */
  --typ-abzeichen-fg: light-dark(
      color-mix(in srgb, var(--typ-farbe, #8a8f98) 78%, #000000),
      color-mix(in srgb, var(--typ-farbe, #8a8f98) 55%, #ffffff));

  /* Die Fläche des Datumsabzeichens auf einem Balken. Sie trägt weisse
   * Schrift, und die rohe Typfarbe hält das nicht: das Türkis der
   * Temperaturmessgeräte kommt auf 3,7:1. Um 28 Prozent abgedunkelt
   * sind es 6,4:1, und der Farbton bleibt erkennbar derselbe.
   *
   * Die Rechnung setzt voraus, dass die Stammdaten mittlere Töne
   * führen. Ein sehr helles Gelb bliebe auch abgedunkelt zu hell für
   * weisse Schrift — dagegen hilft kein Stylesheet, sondern die
   * Farbwahl in der Typverwaltung. */
  --typ-marke-bg: color-mix(in srgb, var(--typ-farbe, #8a8f98) 72%, #000000);
}

.typmarke {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--typ-farbe, var(--text-leise));
  display: inline-block;
  flex-shrink: 0;
}
.typmarke--legende { width: 10px; height: 10px; border-radius: 3px; }

/* Sperrung und Reparatur sind Zustände, keine Typen: ihre Marke nimmt
 * die Zustandsfarbe und kippt damit von selbst mit dem Schema. */
.typmarke--sperre    { background: var(--z-gesperrt-fg); }
.typmarke--reparatur { background: var(--z-reparatur-fg); }

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

.tabellenhuelle { overflow-x: auto; }

.tabelle { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.tabelle th {
  text-align: left;
  font-size: 12.5px;
  color: var(--text-leise);
  font-weight: 600;
  padding: 12px 16px;
  border-bottom: 1px solid var(--linie);
}
.tabelle td { padding: 12px 16px; border-bottom: 1px solid var(--linie-zart); }
.tabelle tbody tr:last-child td { border-bottom: none; }
.tabelle tbody tr:hover { background: var(--flaeche-zeile); }

.zellrechts { text-align: right; white-space: nowrap; }
.zellrechts form { display: inline-block; margin-left: 6px; }
.zellmono { font-family: var(--schrift-mono); font-size: 12.5px; color: var(--text-mittel); }
.zellleise { color: var(--text-mittel); }

/* Eine Zeile, die ein Formular zur darüberstehenden Zeile trägt. Sie
 * gehört optisch dazu und bekommt deshalb keine eigene Trennlinie. */
.zeile--formular td { border-top: none; padding-top: 0; background: var(--flaeche-gedaempft); }
.zeile--formular:hover { background: transparent; }

/* --------------------------------------------------------- Startseite */

/* minmax(0,1fr) und nicht 1fr: `1fr` ist die Kurzform von
 * minmax(auto, 1fr), und `auto` weigert sich, unter die Mindestbreite
 * seines Inhalts zu gehen. Die Geräteliste enthält lange, nicht
 * umbrechbare Namen — zwischen 1100 und rund 1400 px schob die erste
 * Spalte den Korb dadurch aus dem Fenster und die ganze Seite bekam
 * einen waagerechten Bildlauf. */
.start-raster { display: grid; grid-template-columns: minmax(0, 1fr) 380px; gap: 20px; align-items: start; }

/* Dasselbe eine Ebene tiefer: ein Rasterkind hat von sich aus
 * min-width: auto und weigert sich, unter die Mindestbreite seines
 * Inhalts zu gehen — auch dann, wenn die Spalte längst schmaler ist. */
.start-raster > * { min-width: 0; }
.korb-tafel { position: sticky; top: 24px; }

@media (max-width: 1100px) {
  .start-raster { grid-template-columns: 1fr; }
  .korb-tafel { position: static; }
}

.kartenzeile {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 18px;
  gap: 12px;
}

.feldpaar { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; }
@media (max-width: 700px) { .feldpaar { grid-template-columns: 1fr; } }

/* Das Datumsfeld sieht aus wie eine Eingabe, ist aber ein Schalter. */
.datumsfeld {
  border: 1px solid var(--linie-kraeftig);
  border-radius: var(--radius-klein);
  padding: 10px 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  background: var(--flaeche);
  width: 100%;
  font-family: inherit;
  color: var(--text);
  gap: 8px;
}
.datumsfeld__wert { font-size: 13.5px; font-weight: 600; white-space: nowrap; }
.datumsfeld__symbol { stroke: var(--text-leise); flex-shrink: 0; }
.datumsdauer { font-size: 11px; color: var(--text-leise); margin-top: 5px; }

.datumswahl {
  margin-top: 10px;
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  padding: 16px;
  background: var(--flaeche);
  box-shadow: var(--schatten-schwebend);
  position: absolute;
  z-index: 20;
}
.datumswahl__monate { display: flex; gap: 28px; }
@media (max-width: 700px) { .datumswahl__monate { flex-direction: column; gap: 16px; } }

.monat__kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
  gap: 16px;
}
.monat__name { font-weight: 700; font-size: 13px; white-space: nowrap; }
.monat__platz { width: 20px; }

.wochentage, .monatswoche { display: grid; grid-template-columns: repeat(7, 26px); gap: 2px; }
.wochentage { margin-bottom: 4px; }
.wochentage span { text-align: center; font-size: 10px; color: var(--text-leise); font-weight: 600; }

.tagzelle {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 26px;
  border-radius: 999px;
  font-size: 12px;
  cursor: pointer;
  color: var(--text);
  border: none;
  background: none;
  font-family: inherit;
  padding: 0;
}
.tagzelle--leer { visibility: hidden; }
.tagzelle--vergangen { color: var(--text-blass); cursor: not-allowed; }
/* Der Rand des gewählten Zeitraums nimmt --akzent-dunkel, nicht
 * --akzent: weisse Schrift auf #3b82f6 sind 3,7:1, auf #2563eb 5,2:1.
 * Die Zelle trägt zwölf Pixel, da gilt die Schwelle für Fliesstext. */
.tagzelle--rand { background: var(--akzent-dunkel); color: var(--auf-akzent); font-weight: 700; }
.tagzelle--drin { background: var(--akzent-hauch); color: var(--text); border-radius: 4px; }

/* Typkarten: die Auswahl der Gerätetypen. */
.typkarten {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 10px;
  margin-bottom: 22px;
}
.typkarte {
  display: block;
  position: relative;
  min-width: 0;
  border: 1px solid var(--linie-kraeftig);
  border-radius: var(--radius);
  padding: 12px 14px;
  background: var(--flaeche);
  cursor: pointer;
  transition: border-color .15s;
}
.typkarte:hover { border-color: var(--akzent); }

/* Das Häkchen der Typkarte ist unsichtbar; sein Fokusring wäre es
 * auch. Er wandert deshalb auf die Karte, die man tatsächlich sieht. */
.typkarte:has(input:focus-visible) { outline: 2px solid var(--verweis); outline-offset: 2px; }
/* Name und Plakette rutschen untereinander, sobald die Karte zu schmal
 * wird, und ein langer Typname bricht notfalls im Wort. Ohne beides
 * bestimmt das längste Wort der Typliste die Mindestbreite der Seite —
 * „Drehmomentschlüssel" allein sind 130 Pixel, die nirgends kleiner
 * werden. */
.typkarte__kopf { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; flex-wrap: wrap; }
.typkarte__name { font-weight: 600; font-size: 13.5px; overflow-wrap: anywhere; min-width: 0; }
.typkarte input { position: absolute; opacity: 0; pointer-events: none; }
/* Der Entwurf setzt bei Wahl einen zwei Pixel starken Rahmen. Damit die
 * Karte dabei nicht springt, wird das Wachstum vom Innenabstand
 * abgezogen. */
.typkarte:has(input:checked) {
  border: 2px solid var(--akzent);
  background: var(--akzent-hauch);
  padding: 11px 13px;
}

/* Die Geräteliste der Schnellreservierung: Zeilen, keine Tabelle. */
.geraetzeile {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 0;
  border-top: 1px solid var(--linie-zart);
}
/* Ein Gerät mit Vorbehalt bekommt seine eigene Fläche: es steht in der
 * Liste, verlangt aber eine Entscheidung. */
.geraetzeile--pruefen {
  background: var(--warnung-bg);
  border-top: 1px solid var(--warnung-linie);
  border-radius: var(--radius-klein);
  margin: 0 -10px;
  padding: 12px 10px;
}
.geraetzeile__text { min-width: 0; }
.geraetzeile__kopf {
  display: flex;
  align-items: baseline;
  gap: 8px;
  white-space: nowrap;
  overflow: hidden;
}
.geraetzeile__name { font-weight: 600; font-size: 14px; flex-shrink: 0; }
.geraetzeile__meta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--text-leise);
  overflow: hidden;
  min-width: 0;
}
/* Der Typname nimmt die abgestimmte Schriftfarbe, nicht die rohe
 * Stammdatenfarbe: #0f9488 auf Weiss sind 3,7:1, die abgedunkelte
 * Fassung 4,7:1. Die Marke daneben trägt den Farbton unverfälscht —
 * dort ist er Fläche und muss nichts tragen. */
.geraetzeile__typ { color: var(--typ-abzeichen-fg, var(--text-leise)); font-weight: 600; flex-shrink: 0; }
.geraetzeile__rest { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.geraetzeile__hinweis { font-size: 11.5px; color: var(--text-leise); margin-top: 4px; }

/* Reservierungsliste (der Korb). */
.korb__kopf {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  gap: 12px;
}
.korb__titel { font-size: 16px; font-weight: 700; }
.korb__posten { display: flex; flex-direction: column; gap: 10px; margin-bottom: 16px; }
.korb__post {
  border: 1px solid var(--linie);
  border-radius: var(--radius-klein);
  padding: 12px 14px;
}
.korb__postkopf { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
.korb__name { font-weight: 600; font-size: 14px; }
.korb__meta { font-size: 12px; color: var(--text-leise); margin-top: 4px; }
.entfernen {
  border: none;
  background: none;
  color: var(--text-leise);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
  padding: 0;
}
.entfernen:hover { color: var(--text); }

.korb__zusammenzug {
  border-top: 1px solid var(--linie-zart);
  border-bottom: 1px solid var(--linie-zart);
  padding: 12px 0;
  margin-bottom: 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.korb__zeile { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.korb__begriff { font-size: 12.5px; color: var(--text-leise); }
.korb__wert { font-weight: 600; font-size: 13px; }
.korb__wert--mono { font-family: var(--schrift-mono); }

/* ---------------------------------------------------------- Detailplan */

.legende { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 18px; }
.legende__eintrag { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-mittel); }

.wochennavigation { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.wochennavigation__wert { font-weight: 600; font-size: 13.5px; font-family: var(--schrift-mono); }

.plan { border: 1px solid var(--linie); border-radius: var(--radius); overflow: hidden; }

/* Der Wochenplan ist fachlich breiter als ein Telefon. Er rollt im
 * eigenen Behälter statt im Dokument, und die Leiste bleibt schmal:
 * eine kräftige Leiste läse sich wie ein Fehler im Seitenumbruch. */
.plan__rolle {
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: color-mix(in srgb, var(--text-leise) 55%, transparent) transparent;
  overscroll-behavior-x: contain;
}
.plan__rolle::-webkit-scrollbar { height: 6px; }
.plan__rolle::-webkit-scrollbar-track { background: transparent; }
.plan__rolle::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--text-leise) 55%, transparent);
  border-radius: 999px;
}
.plan__tafel { min-width: 860px; }

.plan__kopf, .plan__zeile { display: grid; grid-template-columns: 220px 1fr; }
.plan__kopf { border-bottom: 1px solid var(--linie); }
.plan__zeile { border-bottom: 1px solid var(--linie-zart); }
.plan__zeile:last-child { border-bottom: none; }

.plan__ecke {
  padding: 12px 16px;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-leise);
  align-self: end;
}
.plan__tage { display: grid; grid-template-columns: repeat(7, 1fr); }
.plan__tag { text-align: center; padding: 10px 4px; border-left: 1px solid var(--linie-zarter); }
.plan__tagnummer { font-size: 15px; font-weight: 700; color: var(--text-leise); }
.plan__tagname { font-size: 11px; color: var(--text-leise); margin-top: 1px; }
.plan__tag--heute .plan__tagnummer,
.plan__tag--heute .plan__tagname { color: var(--verweis); }

.plan__geraet {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  color: inherit;
  text-decoration: none;
  min-width: 0;
}
.plan__geraet:hover { background: var(--flaeche-zeile); text-decoration: none; color: inherit; }

/* Das Abzeichen trägt den Anfangsbuchstaben des Gerätetyps in dessen
 * Farbe: die Zeile ist damit auch ohne Legende einem Typ zuzuordnen. */
.plan__abzeichen {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: var(--radius-klein);
  background: var(--typ-abzeichen-bg, var(--flaeche-hover));
  color: var(--typ-abzeichen-fg, var(--text-mittel));
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 13px;
}
/* Die Kennung trägt die Zeile, der Name steht darunter — siehe den
 * Vermerk im Template. */
.plan__kennung {
  display: flex;
  align-items: center;
  gap: 5px;
  font-weight: 600;
  font-size: 13px;
  font-family: var(--schrift-mono);
  white-space: nowrap;
}
.plan__name {
  font-size: 11.5px;
  color: var(--text-leise);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 2px;
}

.plan__spur { position: relative; height: 64px; }
.plan__gitter { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(7, 1fr); }
.plan__gitter span { border-left: 1px solid var(--linie-zarter); }

/* Ein Balken ist eine Belegung, nicht ein Tag: er zeigt Anfang, Ende und
 * Zweck in einem Zug. Position und Breite kommen als Prozentwerte aus
 * dem Handler; das Template rechnet nicht. */
.plan__balken {
  position: absolute;
  top: 12px;
  height: 40px;
  background: var(--typ-flaeche, var(--flaeche-hover));
  border: 1px solid var(--typ-farbe, var(--linie-kraeftig));
  border-radius: var(--radius-klein);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px;
  box-sizing: border-box;
  overflow: hidden;
  color: inherit;
  text-decoration: none;
}
.plan__balken:hover { text-decoration: none; color: inherit; }
.plan__balkendatum {
  background: var(--typ-marke-bg, var(--text-mittel));
  color: var(--auf-farbe);
  font-size: 10.5px;
  font-weight: 700;
  padding: 3px 7px;
  border-radius: var(--radius-winzig);
  white-space: nowrap;
  flex-shrink: 0;
}
.plan__balkentext {
  font-size: 12.5px;
  color: var(--text);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.plan__leer { padding: 28px; text-align: center; }

/* ------------------------------------------------------ Monatskalender */

.kalender__kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
  gap: 12px;
}
.kalender__navigation { display: flex; align-items: center; gap: 10px; }
.kalender__monat { font-weight: 600; font-size: 13px; min-width: 110px; text-align: center; }

.kalender__wochentage {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 3px;
  margin-bottom: 4px;
}
.kalender__wochentage span { text-align: center; font-size: 10.5px; color: var(--text-leise); font-weight: 600; }

.kalender__raster { border: 1px solid var(--linie); border-radius: var(--radius-klein); overflow: hidden; }
.kalender__woche { position: relative; height: 52px; border-bottom: 1px solid var(--linie-zart); }
.kalender__woche:last-child { border-bottom: none; }
.kalender__zellen { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(7, 1fr); }
.kalender__zelle {
  border-left: 1px solid var(--linie-zarter);
  padding: 4px 6px;
  font-size: 11px;
  color: var(--text-leise);
}
.kalender__zelle--heute { color: var(--verweis); font-weight: 700; }
.kalender__balken {
  position: absolute;
  top: 20px;
  height: 28px;
  background: var(--typ-flaeche, var(--flaeche-hover));
  border: 1px solid var(--typ-farbe, var(--linie-kraeftig));
  border-radius: var(--radius-winzig);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  box-sizing: border-box;
  overflow: hidden;
}
.kalender__balkendatum {
  background: var(--typ-marke-bg, var(--text-mittel));
  color: var(--auf-farbe);
  font-size: 9.5px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 5px;
  white-space: nowrap;
  flex-shrink: 0;
}
.kalender__balkentext {
  font-size: 11px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Ein Balken, der keine Belegung meldet, sondern einen Zustand: er
 * trägt dessen Farbe statt der des Typs.
 *
 * Die Klasse gehört zu keiner der beiden Darstellungen. Wochenplan und
 * Monatskalender bekommen ihre Balken aus derselben Ableitung
 * (darstellung.go, belegungsbalken); eine Klasse mit `plan__` davor
 * stünde im Kalender als Fremdwort und griffe dort nur zur Hälfte — das
 * Datumsabzeichen heisst da anders und behielte die Typfarbe.
 *
 * Sie steht hinter beiden Blöcken, weil sie mit .plan__balken und
 * .kalender__balken dieselbe Spezifität teilt und die Reihenfolge
 * entscheidet. */
.balken--sperre {
  background: var(--z-gesperrt-bg);
  border-color: var(--z-gesperrt-linie);
}
.balken--sperre .plan__balkendatum,
.balken--sperre .kalender__balkendatum { background: var(--z-gesperrt-marke); }

.balken--reparatur {
  background: var(--z-reparatur-bg);
  border-color: var(--z-reparatur-linie);
}
.balken--reparatur .plan__balkendatum,
.balken--reparatur .kalender__balkendatum { background: var(--z-reparatur-marke); }

/* --------------------------------------------------------- Kennzahlen */

.kennzahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 14px;
  margin-bottom: 24px;
}
.kennzahl {
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  padding: 16px;
  text-decoration: none;
  color: inherit;
  background: var(--flaeche);
  display: block;
}
.kennzahl:hover { background: var(--flaeche-zeile); text-decoration: none; color: inherit; }
.kennzahl__text {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--text-leise);
  margin-bottom: 6px;
}
.kennzahl__wert { font-size: 26px; font-weight: 700; line-height: 1.1; }
.kennzahl__wert--gesperrt     { color: var(--z-gesperrt-fg); }
.kennzahl__wert--faellig      { color: var(--z-faellig-fg); }
.kennzahl__wert--teilweise    { color: var(--z-teilweise-fg); }
.kennzahl__wert--verfuegbar   { color: var(--z-verfuegbar-fg); }
.kennzahl__wert--ausgemustert { color: var(--z-ausgemustert-fg); }

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

/* Getrennt nach Bedeutung, nicht nach Farbe: eine Sperre ist etwas
 * anderes als ein Fehlschlag, auch wenn beides Aufmerksamkeit will. */
.meldung {
  border-radius: var(--radius-klein);
  padding: 12px 14px;
  font-size: 13.5px;
  margin-bottom: 16px;
  border: 1px solid transparent;
}
.meldung--fehler  { background: var(--z-gesperrt-bg);   color: var(--z-gesperrt-fg);   border-color: var(--z-gesperrt-linie); }
.meldung--erfolg  { background: var(--z-verfuegbar-bg); color: var(--z-verfuegbar-fg); border-color: var(--z-verfuegbar-linie); }
.meldung--warnung { background: var(--warnung-bg);      color: var(--warnung-fg);      border-color: var(--warnung-linie); }
.meldung--sperre  { background: var(--z-gesperrt-bg);   color: var(--z-gesperrt-fg);   border-color: var(--z-gesperrt-linie); }

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

/* Filter und Suche zeigt der Entwurf nicht; Spec Kap. 31 und 32
 * verlangen sie. Sie stehen deshalb in der Sprache des Entwurfs: eine
 * ruhige Leiste über der Tabelle, keine eigene Gestaltungsinsel. */
.filterleiste {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 14px;
  padding: 16px 18px;
  margin-bottom: 20px;
}
.filterleiste__feld { flex: 0 1 190px; min-width: 150px; }
.filterleiste__feld--breit { flex: 1 1 320px; }
.filterleiste__knoepfe { display: flex; gap: 8px; margin-left: auto; }

.formularraster { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.formularraster__breit { grid-column: 1 / -1; }
@media (max-width: 700px) { .formularraster { grid-template-columns: 1fr; } }

.formularkarte {
  border: 1px solid var(--linie);
  border-radius: var(--radius);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: var(--flaeche);
}

.wahl { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 700px) { .wahl { grid-template-columns: 1fr; } }
.wahl__feld {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  border: 1px solid var(--linie-kraeftig);
  border-radius: var(--radius-klein);
  padding: 12px;
  cursor: pointer;
  font-size: 13.5px;
}
.wahl__feld:hover { background: var(--flaeche-hover); }
.wahl__feld span span { display: block; }
.wahl__feld:has(input:checked) { border-color: var(--akzent); background: var(--akzent-hauch); }

/* ------------------------------------------------------------- Detail */

.detailkopf {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 24px;
}
.detailkennung {
  color: var(--text-leise);
  margin: 0;
  font-family: var(--schrift-mono);
  font-size: 13px;
}

.infopaar { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 20px; }
@media (max-width: 700px) { .infopaar { grid-template-columns: 1fr; } }

.angaben {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 8px 16px;
  font-size: 13.5px;
}
.angaben dt { color: var(--text-leise); }
.angaben dd { margin: 0; }

.historie { list-style: none; display: flex; flex-direction: column; gap: 14px; }
.historie li { display: grid; grid-template-columns: 130px 1fr; gap: 14px; font-size: 13.5px; }
.historie__zeit { color: var(--text-leise); font-size: 12px; font-family: var(--schrift-mono); }

/* --------------------------------------------------------- Anmeldung */

.anmeldung {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.anmeldung .karte { width: 100%; max-width: 380px; }

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

.leise { color: var(--text-leise); }
.mittel { color: var(--text-mittel); }
.mono { font-family: var(--schrift-mono); }
.kennung {
  font-size: 11px;
  color: var(--text-leise);
  font-family: var(--schrift-mono);
  margin-top: 2px;
}
.kleintext { font-size: 11.5px; margin-top: 3px; }
.zeile { display: flex; align-items: center; gap: 12px; }
.zeile--verteilt { justify-content: space-between; }
.stapel { display: flex; flex-direction: column; gap: 8px; }
.uebergabe {
  margin-top: 4px;
  font-size: 11.5px;
  color: var(--z-faellig-fg);
  background: var(--z-faellig-bg);
  border-radius: var(--radius-klein);
  padding: 4px 8px;
  display: inline-block;
}


/* ======================================================== Fingerbedienung
 *
 * Diese Grössen hängen am Eingabegerät und nicht an der Fensterbreite.
 * Ein iPad misst hochkant 768 px und wird trotzdem mit dem Daumen
 * bedient; ein schmal gezogenes Fenster auf dem Desktop nicht. Die
 * zweite Bedingung bleibt trotzdem stehen — nicht jedes Gerät meldet
 * `pointer: coarse` verlässlich, und ein etwas grösserer Knopf in einem
 * schmalen Fenster schadet niemandem.
 */
@media (pointer: coarse), (max-width: 900px) {
  /* 12,5 px Schrift bei 8 px Polster ergeben 30 px Höhe. Das ist mit
     der Maus zu treffen und mit dem Daumen nicht. */
  .knopf { padding: 10px 14px; min-height: 40px; }
  .knopf--klein, .knopf--schmal { padding: 8px 14px; min-height: 36px; font-size: 12.5px; }
  .knopf--rund { width: 38px; height: 38px; min-height: 0; padding: 0; }
  .knopf--rund-klein { width: 32px; height: 32px; min-height: 0; padding: 0; }
  .zellrechts .knopf { margin-bottom: 4px; }

  input[type="checkbox"], input[type="radio"] { width: 18px; height: 18px; }
  /* Die versteckten Häkchen der Typkarten sind keine Ziele: getroffen
     wird die Karte, das Feld liegt nur unsichtbar darunter. */
  .typkarte input { width: 0; height: 0; }

  /* iOS zoomt in jedes Feld, dessen Schrift unter 16 px liegt — auch
     auf dem iPad. Der Zoom bleibt danach stehen und verschiebt die
     halbe Seite. */
  .eingabe, .datumsfeld__wert { font-size: 16px; }
  .eingabe--blank { width: auto; max-width: 60%; }
}

/* ============================================================== Schmal
 *
 * Zwei Umbruchpunkte, und beide stehen am Ende der Datei: was oben bei
 * einzelnen Bausteinen steht, gilt für deren inneres Raster, hier geht
 * es um die Gestalt der Seite. Stünden diese Regeln oben, hübe eine
 * spätere Grundregel derselben Spezifität sie wieder auf.
 *
 * 900 px trennt Desktop von Tablet — das iPad misst hochkant 768 px und
 * soll die eingeklappte Navigation bekommen, nicht die 224 px breite
 * Seitenleiste neben einem Rest von 544 px.
 *
 * 700 px trennt Tablet von Telefon: ab hier hört eine Tabelle auf, eine
 * Tabelle zu sein.
 */

@media (max-width: 900px) {
  /* Die Seitenleiste wird zur Kopfleiste. Sie bleibt oben stehen: die
     Navigation ist auf jeder Seite der Weg zurück. */
  .rahmen { display: block; min-height: 0; }

  .seitenleiste {
    width: auto;
    height: auto;
    padding: 10px 14px;
    gap: 0;
    border-right: none;
    border-bottom: 1px solid var(--linie);
    position: sticky;
    top: 0;
    z-index: 30;
  }
  .seitenleiste__marke { padding: 0 4px; }
  .seitenleiste__schalter { display: inline-flex; }

  .seitenleiste__klapp { display: none; }
  .seitenleiste__klapp--offen {
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 14px 0 4px;
  }

  /* Ausgeklappt ist die Navigation nicht mehr eine Spalte neben dem
     Inhalt, sondern eine Fläche darüber. Zwei Punkte je Zeile halten
     sie kurz genug, dass der Inhalt darunter sichtbar bleibt. */
  .seitenleiste__liste { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
  .navlink { padding: 10px; }
  .seitenleiste__fuss {
    margin-top: 0;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px 4px 0;
  }
  .seitenleiste__fuss form { flex-shrink: 0; }
  .knopf--schmal { width: auto; }

  .kopfzeile { padding: 12px 16px; }
  .inhalt { padding: 20px 16px 56px; }

  /* Schmalere Gerätespalte, damit von der Woche mehr sichtbar bleibt. */
  .plan__kopf, .plan__zeile { grid-template-columns: 150px 1fr; }
  .plan__tafel { min-width: 680px; }
  .plan__geraet { padding: 10px 12px; gap: 8px; }
  .plan__abzeichen { width: 28px; height: 28px; font-size: 12px; }

  .detailkopf { flex-direction: column; gap: 10px; }
  .historie li { grid-template-columns: 1fr; gap: 2px; }

  /* Die Filterleiste hat vier Felder; nebeneinander bleibt von jedem
     nichts übrig. Sie stehen deshalb untereinander, die Knöpfe darunter
     über die volle Breite. */
  .filterleiste__feld,
  .filterleiste__feld--breit { flex: 1 1 100%; min-width: 0; }
  .filterleiste__knoepfe { margin-left: 0; width: 100%; }
  .filterleiste__knoepfe .knopf { flex: 1 1 0; }
}

@media (max-width: 700px) {
  .seitenkopf { margin-bottom: 18px; }
  .seitentitel, .seitentitel--gross { font-size: 21px; }
  .seitenlead, .seitenlead--klein { font-size: 14px; }
  .karte { padding: 16px; }
  .karte--eng { padding: 14px; }
  .kartenkopf { padding: 16px 16px 0; }
  .formularkarte { padding: 16px; }

  /* --- Tabellen werden zu Karten ------------------------------------
   *
   * Sieben Spalten sind auf 375 px keine Tabelle mehr, auch nicht mit
   * seitlichem Bildlauf: wer die Fälligkeit sucht, rollt an Typ,
   * Zustand und Standort vorbei und verliert dabei die Zeile. Jede
   * Zeile wird deshalb eine Karte, jede Zelle ein Paar aus Etikett und
   * Wert. Das Etikett steht als data-titel am td — dieselbe Angabe, die
   * breit in der Kopfzeile steht.
   *
   * Zellen ohne data-titel bleiben Blöcke: das sind die Zeilen über die
   * volle Breite (Formulare, "nichts gefunden") und die Zelle mit den
   * Knöpfen, die kein Etikett braucht. */
  .tabellenhuelle { overflow-x: visible; }
  .tabelle, .tabelle tbody, .tabelle tr, .tabelle td { display: block; width: 100%; }
  .tabelle thead { display: none; }

  .tabelle tbody tr {
    border-bottom: 1px solid var(--linie);
    padding: 12px 16px;
  }
  .tabelle tbody tr:last-child { border-bottom: none; }
  .tabelle td { border-bottom: none; padding: 3px 0; min-width: 0; }

  .tabelle td[data-titel] {
    display: grid;
    grid-template-columns: minmax(92px, 0.36fr) minmax(0, 1fr);
    gap: 10px;
    align-items: baseline;
    overflow-wrap: anywhere;
  }
  .tabelle td[data-titel]::before {
    content: attr(data-titel);
    font-size: 12px;
    color: var(--text-leise);
  }

  /* Die Knopfzelle steht als eigene Zeile unter den Angaben, links
     ausgerichtet wie alles andere. */
  .zellrechts { text-align: left; white-space: normal; padding-top: 8px; }
  .zellrechts form { display: inline-block; margin: 0 6px 0 0; }
  .zeile--formular td { padding-top: 8px; background: transparent; }
  .zeile--formular { border-top: 1px dashed var(--linie); }

  /* --- Übriges ------------------------------------------------------ */
  .angaben { grid-template-columns: minmax(88px, 0.38fr) minmax(0, 1fr); gap: 8px 10px; }
  .angaben dd { overflow-wrap: anywhere; }
  .kennzahlen { grid-template-columns: 1fr 1fr; gap: 10px; }
  .kennzahl { padding: 12px; }
  .kennzahl__wert { font-size: 22px; }
  /* Einspaltig, nicht zweispaltig: zwei Karten nebeneinander sind auf
     375 px je 150 px breit, und darin steht kein Typname mehr ohne
     Wortbruch. */
  .typkarten { grid-template-columns: minmax(0, 1fr); }

  /* Die Gerätezeile stapelt: Text über Knopf, der Knopf über die volle
     Breite. Nebeneinander bliebe dem Namen kein Platz. */
  .geraetzeile { flex-direction: column; align-items: stretch; gap: 10px; }
  .geraetzeile__kopf { white-space: normal; }
  .geraetzeile .knopf { width: 100%; }

  /* Der Zeitraumwähler ist breiter als das Fenster. Er löst sich
     deshalb aus dem Fluss und spannt sich über die Seitenränder, mit
     eigenem Bildlauf, falls zwei Monate übereinander nicht passen. */
  .datumswahl {
    position: fixed;
    left: 12px;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    max-height: calc(100dvh - 32px);
    overflow-y: auto;
    z-index: 40;
  }
  .wochentage, .monatswoche { grid-template-columns: repeat(7, 1fr); }
  .tagzelle { height: 34px; }

  .korb-tafel { position: static; }
  .kartenzeile { flex-wrap: wrap; }
  .legende { gap: 10px; }
}
