/* ZEROADMINS — Oberfläche.
 *
 * Reihenfolge: Grundlagen, Gerüst, Seitenleiste, Kopfzeile, Inhaltsbausteine,
 * Bedienelemente, Meldungen, Dialog, schmale Hülle, Hilfsklassen.
 *
 * Zwei Regeln, die das Bild zusammenhalten:
 *  - Trennung entsteht durch Fläche und Abstand, nicht durch Rahmen um alles.
 *    Ein Rahmen steht nur dort, wo etwas wirklich abgegrenzt ist.
 *  - Zahlen, Kennungen und Zeitangaben laufen in der dicktengleichen Schrift
 *    mit `tabular-nums`, damit Spalten untereinander stehen.
 *
 * Geschrieben wird dicht: verwandte Eigenschaften stehen in einer Zeile.
 * Das hält die Datei überschaubar — eine Regel ist ein Block, nicht ein
 * halber Bildschirm.
 */

/* ── Grundlagen ───────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--grund); color: var(--text);
  font-family: var(--schrift-text); font-size: var(--text-basis); line-height: var(--zeilen-normal);
  font-synthesis-weight: none; -webkit-font-smoothing: antialiased;
}

h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
[hidden] { display: none !important; }

code, kbd, samp, .zahl, .kennung {
  font-family: var(--schrift-zahl);
  font-variant-numeric: tabular-nums; font-feature-settings: "zero" 1;
}

:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; border-radius: var(--radius-s); }
::selection { background: var(--akzent-still); color: var(--text); }

.sprungmarke {
  position: absolute; left: var(--raum-3); top: -3rem; z-index: 40;
  padding: var(--raum-2) var(--raum-3);
  background: var(--flaeche-hoch); border: 1px solid var(--linie-stark); border-radius: var(--radius-m);
  transition: top var(--dauer-schnell) var(--kurve);
}
.sprungmarke:focus { top: var(--raum-3); }

.nur-lesehilfe {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ── Gerüst ───────────────────────────────────────────────────────────── */
.gestell { display: block; }
.gestell__spalte { display: flex; flex-direction: column; min-height: 100dvh; }

.inhalt {
  flex: 1; width: 100%; max-width: var(--inhalt-max); margin: 0 auto;
  padding: var(--raum-6) var(--raum-4) var(--raum-8);
}

@media (min-width: 900px) {
  .gestell { display: grid; grid-template-columns: var(--leiste-breite) minmax(0, 1fr); }
  .inhalt { padding: var(--raum-6) var(--raum-6) var(--raum-8); }
}

/* ── Seitenleiste ─────────────────────────────────────────────────────── */
.seitenleiste { display: none; }

@media (min-width: 900px) {
  .seitenleiste {
    display: flex; flex-direction: column; gap: var(--raum-5);
    position: sticky; top: 0; height: 100dvh; overflow-y: auto;
    padding: var(--raum-4) var(--raum-3);
    background: var(--flaeche); border-right: 1px solid var(--linie);
  }
}

.marke {
  display: flex; align-items: center; gap: var(--raum-2);
  padding: var(--raum-1) var(--raum-2); letter-spacing: 0.04em;
}
.marke:hover { text-decoration: none; }

.marke__zeichen {
  display: grid; place-items: center; width: 1.5rem; height: 1.5rem;
  border: 1px solid var(--linie-stark); border-radius: var(--radius-s);
  font-family: var(--schrift-zahl); font-size: var(--text-xs); color: var(--text-leise);
}
.marke__name { font-weight: 600; font-size: var(--text-m); letter-spacing: 0.09em; }
.marke__name span { color: var(--text-schwach); font-weight: 400; }

.navigation { display: flex; flex-direction: column; gap: var(--raum-5); }
.navigation__gruppe { display: flex; flex-direction: column; gap: 1px; }

.navigation__wort {
  padding: 0 var(--raum-2) var(--raum-2);
  font-size: var(--text-xs); letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-schwach);
}

.navigation__eintrag {
  display: flex; align-items: center; gap: var(--raum-2);
  min-height: 2rem; padding: 0 var(--raum-2);
  border-left: 2px solid transparent; border-radius: var(--radius-s);
  color: var(--text-leise); font-size: var(--text-m);
  transition: background-color var(--dauer-schnell) var(--kurve), color var(--dauer-schnell) var(--kurve);
}
.navigation__eintrag:hover { background: var(--flaeche-still); color: var(--text); text-decoration: none; }
.navigation__eintrag svg { flex: none; color: var(--text-schwach); }

/* Die aktive Seite trägt einen Balken links, keine Füllfarbe: der Balken
   liest sich auch dann noch, wenn zwei Einträge untereinander stehen. */
.navigation__eintrag[aria-current="page"] {
  background: var(--flaeche-hoch); border-left-color: var(--akzent);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  color: var(--text); font-weight: 500;
}
.navigation__eintrag[aria-current="page"] svg { color: var(--akzent); }

.seitenleiste__fuss { margin-top: auto; padding: var(--raum-2); font-size: var(--text-xs); color: var(--text-schwach); }

/* ── Kopfzeile ────────────────────────────────────────────────────────── */
.kopf {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: var(--raum-3);
  min-height: var(--kopf-hoehe); padding: var(--raum-2) var(--raum-4);
  background: color-mix(in oklab, var(--grund) 88%, transparent);
  backdrop-filter: blur(8px); border-bottom: 1px solid var(--linie);
}

.seitentitel {
  font-size: var(--text-l); font-weight: 600; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kopf__rechts { display: flex; align-items: center; gap: var(--raum-3); margin-left: auto; }

/* Zustandsanzeige: drei Punkte mit Wort. Kein Symbol, keine Ampel-Grafik —
   die Farbe ist das Signal, das Wort ist die Erklärung. Unter 720px fällt
   sie weg; dort zählt der Platz für den Seitentitel mehr. */
.zustand { display: none; align-items: center; gap: var(--raum-3); }
@media (min-width: 720px) { .zustand { display: flex; } }

.punkt { display: flex; align-items: center; gap: var(--raum-2); font-size: var(--text-s); color: var(--text-leise); }
.punkt__auge {
  width: 7px; height: 7px; border-radius: 50%; background: var(--unbekannt);
  transition: background-color var(--dauer-normal) var(--kurve);
}
.punkt[data-stand="ok"] .punkt__auge { background: var(--ok); }
.punkt[data-stand="warnung"] .punkt__auge { background: var(--warnung); }
.punkt[data-stand="fehler"] .punkt__auge { background: var(--fehler); }
.zustand__hinweis { font-size: var(--text-s); color: var(--warnung); }

/* Beide Klappflächen hängen an ihrem Auslöser — deshalb `relative`.
   Die kleine Navigation ist natives `details`: sie braucht kein JavaScript. */
.kleinnav, .konto { position: relative; }
@media (min-width: 900px) { .kleinnav { display: none; } }

.kleinnav__knopf, .konto__knopf {
  display: flex; align-items: center; gap: var(--raum-2);
  padding: var(--raum-2) var(--raum-3);
  border: 1px solid var(--linie); border-radius: var(--radius-m);
  color: var(--text-leise); font-size: var(--text-s); cursor: pointer; list-style: none;
}
.kleinnav__knopf::-webkit-details-marker, .konto__knopf::-webkit-details-marker { display: none; }
.konto__knopf { color: var(--text); }

.kleinnav__flaeche, .konto__flaeche {
  position: absolute; z-index: 30; top: calc(100% + var(--raum-2));
  min-width: 15rem; padding: var(--raum-3);
  background: var(--flaeche-hoch); border: 1px solid var(--linie-stark);
  border-radius: var(--radius-l); box-shadow: var(--schatten-dialog);
}
.kleinnav__flaeche { left: 0; }
.konto__flaeche { right: 0; display: flex; flex-direction: column; gap: var(--raum-3); }
.konto__name { max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.konto__zeile { font-size: var(--text-s); color: var(--text-schwach); }

/* ── Inhaltsbausteine ─────────────────────────────────────────────────── */
.abschnitt { margin-bottom: var(--raum-7); }
/* `flex-wrap` ist der Unterschied zwischen „Titel und Knopfreihe stehen
   nebeneinander" und „sie stehen ineinander": ohne Umbruch quetscht ein
   schmales Gerät beides in eine Zeile. Der Zeilenabstand steht getrennt vom
   Spaltenabstand, weil er nur im umgebrochenen Fall überhaupt wirkt — auf dem
   Bildschirm, wo nichts umbricht, ändert sich nichts. */
.abschnitt__kopf {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: var(--raum-2) var(--raum-4); margin-bottom: var(--raum-4);
}
.abschnitt__titel { font-size: var(--text-l); font-weight: 600; letter-spacing: -0.01em; }
.abschnitt__hinweis, .hinweis { font-size: var(--text-s); color: var(--text-schwach); }

.karte {
  padding: var(--raum-5); background: var(--flaeche);
  border: 1px solid var(--linie); border-radius: var(--radius-l);
}

.kennzahl { display: flex; flex-direction: column; gap: var(--raum-1); }
.kennzahl__wort { font-size: var(--text-xs); letter-spacing: 0.08em; text-transform: uppercase; color: var(--text-schwach); }
.kennzahl__wert {
  font-family: var(--schrift-zahl); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xl); font-weight: 500; letter-spacing: -0.02em;
}

.raster { display: grid; gap: var(--raum-4); grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }

/* ── Tabelle ──────────────────────────────────────────────────────────── */
.tabellenfeld {
  overflow-x: auto; background: var(--flaeche);
  border: 1px solid var(--linie); border-radius: var(--radius-l);
}
.tabellenfeld--hoch { max-height: 70dvh; overflow: auto; }

.tabelle { width: 100%; border-collapse: collapse; font-size: var(--text-m); }

/* Der Spaltenkopf klebt am oberen Rand des Tabellenfeldes. Wirksam wird das
   erst mit `.tabellenfeld--hoch`: ohne Deckelung ist die Tabelle so hoch wie
   ihr Inhalt, und dann gibt es nichts, woran etwas kleben könnte. */
.tabelle th {
  position: sticky; top: 0; z-index: 1;
  padding: var(--raum-3) var(--raum-4);
  background: var(--flaeche-hoch); border-bottom: 1px solid var(--linie);
  font-size: var(--text-xs); font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; text-align: left; color: var(--text-schwach); white-space: nowrap;
}

.tabelle td { padding: var(--raum-3) var(--raum-4); border-bottom: 1px solid var(--linie); vertical-align: top; }
.tabelle tbody tr:last-child td { border-bottom: 0; }
.tabelle tbody tr:hover td { background: var(--flaeche-still); }
.tabelle .zahl, .tabelle .kennung { white-space: nowrap; }

/* ── Bedienelemente ───────────────────────────────────────────────────── */
.knopf {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--raum-2);
  min-height: 2.125rem; padding: 0 var(--raum-4);
  background: var(--flaeche-hoch); color: var(--text);
  /* Nicht --linie-stark: der Umriss eines Knopfes muss zeigen, wo man klicken
     kann. Mit der Trennlinienfarbe waren es 1.73:1 gegen die eigene Fläche —
     auf einem hellen Arbeitsplatz war der Knopf schlicht nicht als Knopf zu
     erkennen. Jetzt 3.14:1, siehe --linie-bedienung in tokens.css. */
  border: 1px solid var(--linie-bedienung); border-radius: var(--radius-m);
  font: inherit; font-size: var(--text-m); font-weight: 500; cursor: pointer;
  transition: background-color var(--dauer-schnell) var(--kurve), border-color var(--dauer-schnell) var(--kurve);
}
.knopf:hover { background: var(--flaeche-still); border-color: var(--text-schwach); text-decoration: none; }
.knopf:active { background: var(--flaeche); }
.knopf[disabled], .knopf[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }

.knopf--haupt { background: var(--akzent); border-color: var(--akzent); color: var(--akzent-auf); }
.knopf--haupt:hover { background: color-mix(in oklab, var(--akzent) 88%, var(--grund)); border-color: var(--akzent); }

/* Gefahr wird umrandet, nicht gefüllt: eine rote Fläche zieht das Auge
   dorthin, wo man am seltensten hin soll. */
.knopf--gefahr { background: transparent; border-color: var(--fehler); color: var(--fehler); }
.knopf--gefahr:hover { background: var(--fehler-still); border-color: var(--fehler); }

.knopf--leise { background: transparent; border-color: transparent; color: var(--text-leise); }
.knopf--leise:hover { background: var(--flaeche-still); color: var(--text); }

.knopf--klein { min-height: 1.75rem; padding: 0 var(--raum-3); font-size: var(--text-s); }
.knopf--breit { width: 100%; }
.knopfreihe { display: flex; flex-wrap: wrap; gap: var(--raum-2); }

.formular { display: flex; flex-direction: column; gap: var(--raum-4); }
.feld { display: flex; flex-direction: column; gap: var(--raum-2); }
.feld__wort { font-size: var(--text-s); font-weight: 500; color: var(--text-leise); }
.feld__hinweis { font-size: var(--text-s); color: var(--text-schwach); }

.eingabe, select.eingabe, textarea.eingabe {
  width: 100%; min-height: 2.25rem; padding: var(--raum-2) var(--raum-3);
  background: var(--grund); color: var(--text);
  /* Gleicher Grund wie beim Knopf: ein Eingabefeld, dessen Rand mit 1.86:1
     gegen die Fläche steht, ist kein sichtbares Feld, sondern ein Stück
     Hintergrund, in das man zufällig tippen kann. Jetzt 3.57:1. */
  border: 1px solid var(--linie-bedienung); border-radius: var(--radius-m);
  font: inherit; font-size: var(--text-basis);
  transition: border-color var(--dauer-schnell) var(--kurve);
}
.eingabe::placeholder { color: var(--text-schwach); }
.eingabe:hover { border-color: var(--text-schwach); }
.eingabe:focus-visible { outline: 2px solid var(--akzent); outline-offset: 0; border-color: var(--akzent); }

.eingabe--code {
  font-family: var(--schrift-zahl); font-size: var(--text-xl);
  letter-spacing: 0.35em; text-align: center;
}
.filterfeld { max-width: 20rem; }

.chip {
  display: inline-flex; align-items: center; gap: var(--raum-1);
  padding: 0.0625rem var(--raum-2);
  border: 1px solid var(--linie-stark); border-radius: 999px;
  font-size: var(--text-xs); letter-spacing: 0.04em; color: var(--text-leise); white-space: nowrap;
}
.chip--ok { border-color: var(--ok); color: var(--ok); }
.chip--warnung { border-color: var(--warnung); color: var(--warnung); }
.chip--fehler { border-color: var(--fehler); color: var(--fehler); }

/* ── Meldungen und Leerzustand ────────────────────────────────────────── */
.meldung {
  display: flex; gap: var(--raum-3); padding: var(--raum-3) var(--raum-4);
  background: var(--flaeche); border: 1px solid var(--linie);
  border-left: 2px solid var(--text-schwach); border-radius: var(--radius-m);
  font-size: var(--text-m);
}
.meldung--ok { border-left-color: var(--ok); background: var(--ok-still); }
.meldung--warnung { border-left-color: var(--warnung); background: var(--warnung-still); }
.meldung--fehler { border-left-color: var(--fehler); background: var(--fehler-still); }
.meldung--hinweis { border-left-color: var(--akzent); background: var(--akzent-still); }

.leer {
  display: flex; flex-direction: column; align-items: center; gap: var(--raum-2);
  padding: var(--raum-7) var(--raum-4); text-align: center; color: var(--text-leise);
}
.leer__text { font-size: var(--text-basis); }
.leer__hinweis { font-size: var(--text-s); color: var(--text-schwach); max-width: 34rem; }

/* ── Seitenwahl ───────────────────────────────────────────────────────── */
.seitenwahl { display: flex; align-items: center; gap: var(--raum-3); margin-top: var(--raum-4); }
.seitenwahl__stand {
  font-family: var(--schrift-zahl); font-variant-numeric: tabular-nums;
  font-size: var(--text-s); color: var(--text-schwach);
}

/* ── Dialog ───────────────────────────────────────────────────────────── */
.dialog {
  width: min(28rem, calc(100vw - 2rem)); padding: var(--raum-5);
  background: var(--flaeche); color: var(--text);
  border: 1px solid var(--linie-stark); border-radius: var(--radius-l);
  box-shadow: var(--schatten-dialog);
}
.dialog::backdrop { background: var(--schleier); }
.dialog__titel { font-size: var(--text-l); font-weight: 600; margin-bottom: var(--raum-2); }
.dialog__text { font-size: var(--text-m); color: var(--text-leise); margin-bottom: var(--raum-5); }
.dialog__aktionen { display: flex; justify-content: flex-end; gap: var(--raum-2); }

/* ── Schmale Hülle: Anmeldung, zweiter Faktor, Fehlerseite ────────────── */
.koerper--schmal { display: grid; place-items: center; min-height: 100dvh; padding: var(--raum-5) var(--raum-4); }
.schmal { width: 100%; max-width: var(--schmal-max); display: flex; flex-direction: column; }
.schmal--weit { max-width: 34rem; }

/* Marke und Fusszeile liegen INNERHALB der Karte — die Anmeldung ist eine
   zusammenhängende Fläche, kein Formular, das zufällig unter einem Logo
   steht. Getrennt wird durch feine Linien, nicht durch Abstand: Abstand
   liest sich als „das gehört nicht zusammen". */
.schmal__karte {
  display: flex; flex-direction: column; gap: var(--raum-4);
  padding: var(--raum-5);
  background: var(--flaeche); border: 1px solid var(--linie); border-radius: var(--radius-l);
}
.schmal__marke {
  display: flex; justify-content: center;
  padding-bottom: var(--raum-4); border-bottom: 1px solid var(--linie);
}
.schmal__titel { font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.01em; }

.schmal__fuss {
  display: flex; flex-direction: column; align-items: center; gap: var(--raum-2);
  padding-top: var(--raum-4); border-top: 1px solid var(--linie);
}
.schmal__fuss__wort {
  text-align: center; font-size: var(--text-xs); color: var(--text-schwach);
}

/* ── Im eigenen Programmfenster ist die Karte das Fenster ──────────────────
 *
 * Manu am 2026-08-18 mit zwei Bildschirmabzügen: „der komplette Rand soll
 * verschwinden, so dass nur das, was drinnen ist, angezeigt wird."
 *
 * Zu sehen waren zwei Flächen ineinander — der Fensterrahmen und darin nochmal
 * eine Karte mit eigenem Rand und eigener Rundung, umgeben von leerer Fläche.
 * Eine Karte in einer Karte ist immer falsch: sie zieht eine Grenze, die der
 * Fensterrahmen schon zieht.
 *
 * Im BROWSER bleibt die Karte richtig — dort steht sie in einer grossen leeren
 * Fläche und muss sich abgrenzen. Deshalb hängt das hier an `koerper--programm`
 * und nicht an einer Bildschirmbreite.
 *
 * Die Fensterhöhe folgt dem Inhalt: `desktop/zeroadmins_app.py` misst die
 * Eigenhöhe des Inhalts plus das Körperpolster. Ohne diese Regeln misst es das
 * Polster gleich mit — und das Fenster wäre wieder grösser als das, was
 * drinsteht.
 */
.koerper--schmal.koerper--programm {
  /* `center` in `100dvh` ist genau der leere Rand: die Karte schwebt in einer
     Fläche, die per Definition so hoch ist wie das Fenster. */
  place-items: start stretch;
  min-height: 0;
  padding: 0;
  /* Was hier steht, sieht man NUR in den vier Ecken — überall sonst liegt die
     Karte darüber. Im Programm ersetzt die EXE diese Farbe durch die
     Schlüsselfarbe, mit der Windows die Ecken durchsichtig stanzt
     (`desktop/zeroadmins_app.py`, `_ecken`). Gelingt das nicht, bleibt es bei
     dieser Farbe: dann sind die Ecken eben dunkel statt durchsichtig — ein
     Schönheitsfehler, kein Defekt. */
  background: var(--grund);
}
.koerper--schmal.koerper--programm .schmal { max-width: none; }

/* ── Die Anmeldung als Programmfenster ────────────────────────────────────
 *
 * Vorbild ist die Anmeldemaske des ZeroLoad Bot Managers (Manu, 2026-08-18,
 * mit Bildschirmfoto): eine Karte, die das Fenster IST — Fensterknöpfe oben
 * rechts, Marke senkrecht in der Mitte, Felder mit schwebender Beschriftung
 * und Symbol rechts, ein grosser Hauptknopf, darunter Fassung und Fusszeile.
 *
 * Übernommen ist die FORM, nicht die Farbe: die Vorlage lässt ein Grün vier
 * Rollen gleichzeitig spielen (Knopf, Logo, Statuspunkt, Fokus). ZeroAdmins
 * trennt das bewusst — `--akzent` ist Bedienung, `--ok` ist Zustand
 * (tokens.css:8-10). Ein grüner Knopf neben einem grünen Statuspunkt hiesse
 * zweierlei in derselben Farbe. Deshalb ist der Knopf hier blau.
 *
 * Alles hängt an `.koerper--programm`: im Browser bleibt die Anmeldung, wie
 * sie war.
 */
.koerper--schmal.koerper--programm .schmal__karte {
  position: relative;        /* Bezug für die Fensterknöpfe */
  border: 1px solid var(--linie);
  border-radius: var(--radius-l);
  /* Ohne das Clipping stehen die Kindelemente über die Rundung hinaus und die
     durchsichtigen Ecken zeigen wieder Ecken. */
  overflow: hidden;
  padding: var(--raum-5);
  gap: var(--raum-4);
}

/* ── Fensterknöpfe ─────────────────────────────────────────────────────── */
.ampel { position: absolute; top: var(--raum-3); right: var(--raum-3);
         display: flex; gap: var(--raum-2); z-index: 5; }
.ampel__knopf {
  position: relative; width: 12px; height: 12px; padding: 0;
  border: 0; border-radius: 50%; cursor: pointer;
  transition: opacity var(--dauer-schnell) var(--kurve);
}
/* 12 px sind zum Treffen zu wenig. Die Fläche wächst unsichtbar auf 28 px —
   die Vorlage hat das nicht und ist entsprechend fummelig. */
.ampel__knopf::before {
  content: ""; position: absolute; inset: -8px; border-radius: 50%;
}
.ampel__knopf:hover { opacity: 0.7; }
.ampel__knopf--klein { background: var(--warnung); }
.ampel__knopf--zu { background: var(--fehler); }

/* ── Marke: senkrecht statt waagerecht, und zugleich der Ziehbereich ───── */
.koerper--schmal.koerper--programm .schmal__marke {
  flex-direction: column; align-items: center; gap: var(--raum-2);
  padding-bottom: 0; border-bottom: 0;
  cursor: move;
  /* Sonst markiert ein Ziehversuch den Text, statt das Fenster zu bewegen. */
  user-select: none; -webkit-user-select: none;
}
.koerper--schmal.koerper--programm .marke { flex-direction: column; gap: var(--raum-2); padding: 0; }
.koerper--schmal.koerper--programm .marke__zeichen {
  width: 3rem; height: 3rem; border-radius: var(--radius-l);
  background: var(--akzent-still); border-color: var(--akzent);
  color: var(--akzent); font-size: var(--text-l);
}
.koerper--schmal.koerper--programm .marke__name { font-size: var(--text-xl); letter-spacing: 0.02em; }
.schmal__unterzeile {
  font-size: var(--text-xs); letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--text-schwach);
}

/* ── Felder: Beschriftung schwebt, Symbol steht rechts ────────────────────
 * `:has()` statt eines Geschwister-Wählers, weil die Beschriftung im Markup
 * VOR dem Feld steht — und dort bleibt sie auch, damit der Browserzweig und
 * die Vorleseprogramme sie in der gewohnten Reihenfolge finden.
 */
.feld__symbol { display: none; }
.koerper--schmal.koerper--programm .feld { position: relative; gap: 0; }
.koerper--schmal.koerper--programm .eingabe {
  min-height: 3.25rem;
  padding: var(--raum-5) 2.75rem var(--raum-2) var(--raum-3);
}
.koerper--schmal.koerper--programm .feld__wort {
  position: absolute; left: var(--raum-3); top: 1.05rem;
  pointer-events: none; font-size: var(--text-basis); color: var(--text-schwach);
  transition: top var(--dauer-schnell) var(--kurve),
              font-size var(--dauer-schnell) var(--kurve),
              color var(--dauer-schnell) var(--kurve);
}
.koerper--schmal.koerper--programm .feld:focus-within .feld__wort,
.koerper--schmal.koerper--programm .feld:has(.eingabe:not(:placeholder-shown)) .feld__wort {
  top: 0.5rem; font-size: var(--text-xs); color: var(--text-leise);
}
/* Die Fensterknöpfe gibt es nur auf den schmalen Programmseiten — eigene
   Klasse, damit sie nirgendwo sonst greifen kann. */
.koerper--schmal.koerper--programm .feld:focus-within .feld__wort { color: var(--akzent); }
.koerper--schmal.koerper--programm .feld__symbol {
  display: block; position: absolute; right: var(--raum-3); top: 50%;
  transform: translateY(-50%); width: 1rem; height: 1rem;
  color: var(--text-schwach); pointer-events: none;
}
.koerper--schmal.koerper--programm .feld__symbol svg { width: 100%; height: 100%; display: block; }

/* ── Hauptknopf: im Foto deutlich grösser als der Regelknopf ──────────── */
.koerper--schmal.koerper--programm .knopf--haupt.knopf--breit {
  min-height: 2.75rem; font-weight: 600;
}

/* ── Fassungszeile: links Punkt und Fassung, rechts der Zustand ───────── */
.koerper--schmal.koerper--programm .fassung { justify-content: space-between; width: 100%; }
/* Der Statuspunkt aus dem Foto — ohne neue Auszeichnung im Markup. Er nimmt
   die Farbe des Zustands an, weil `.fassung__lage` sie bereits trägt. */
.koerper--schmal.koerper--programm .fassung__lage::before {
  content: ""; display: inline-block; width: 7px; height: 7px;
  border-radius: 50%; background: currentColor;
  margin-right: var(--raum-2); vertical-align: middle;
}

.koerper--schmal.koerper--programm .schmal__fuss { padding-top: var(--raum-3); }
.koerper--schmal.koerper--programm .schmal__fuss__wort { letter-spacing: 0.04em; }

/* ── Reiter ───────────────────────────────────────────────────────────── */
.reiter {
  display: flex; gap: var(--raum-1); flex-wrap: wrap;
  border-bottom: 1px solid var(--linie); margin-bottom: var(--raum-5);
}
.reiter__blatt {
  padding: var(--raum-3) var(--raum-4);
  color: var(--text-leise); font-size: var(--text-m); font-weight: 500;
  /* Der Streifen liegt IMMER da, nur durchsichtig. Sonst springt die Zeile
     beim Wechseln um einen Pixel — eine Kleinigkeit, die eine Oberfläche
     billig wirken lässt. */
  border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color var(--dauer-schnell) var(--kurve),
              border-color var(--dauer-schnell) var(--kurve);
}
.reiter__blatt:hover { color: var(--text); text-decoration: none; border-bottom-color: var(--linie-bedienung); }
.reiter__blatt--offen { color: var(--text); border-bottom-color: var(--akzent); }
.reiter__blatt:focus-visible { outline: 2px solid var(--akzent); outline-offset: -2px; }

/* ── Kopfzeile einer Detailseite ──────────────────────────────────────── */
.gegenstand {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--raum-4); flex-wrap: wrap; margin-bottom: var(--raum-4);
}
.gegenstand__wer { display: flex; flex-direction: column; gap: var(--raum-2); }
.gegenstand__name { font-size: var(--text-xl); font-weight: 600; letter-spacing: -0.01em; }
.gegenstand__zeile { display: flex; align-items: center; gap: var(--raum-2); flex-wrap: wrap; }

/* ── Fassungszeile ────────────────────────────────────────────────────── */
.fassung { display: flex; align-items: center; justify-content: center; gap: var(--raum-2); flex-wrap: wrap; }
.fassung__wort { font-size: var(--text-xs); color: var(--text-leise); }
.fassung__lage { font-size: var(--text-xs); color: var(--ok); }
a.chip:hover { text-decoration: none; border-color: currentColor; }

.geheimnis {
  display: block; padding: var(--raum-3);
  background: var(--grund); border: 1px solid var(--linie); border-radius: var(--radius-m);
  font-size: var(--text-m); letter-spacing: 0.12em; word-break: break-all;
}

/* Ein QR-Bild braucht hellen Grund, sonst liest es keine Kamera — das ist
   die eine Stelle, an der eine feste Farbe richtig ist. */
.qr { display: grid; place-items: center; padding: var(--raum-3); background: #fff; border-radius: var(--radius-m); }
/* Der QR-Code wird NICHT kleingerechnet.
   Vorher stand hier 11rem = 176 px. Die Grafik ist von Haus aus 342 px groß und
   trägt 57 Module (inkl. Rand) — macht 3,09 Pixel je Modul. Kameras brauchen
   4–5; darunter verschwimmen benachbarte Module ineinander. Der Code sah auf
   dem Bildschirm sauber aus und war für jedes Lesegerät unbrauchbar: selbst
   eine Software-Erkennung scheiterte an der gerenderten Seite, während dieselbe
   Grafik einzeln gespeichert sofort gelesen wurde.
   `height: auto` statt eines festen Werts, damit das Seitenverhältnis erhalten
   bleibt; `max-width` begrenzt nur auf schmalen Geräten. */
.qr svg { display: block; width: 100%; max-width: 21.5rem; height: auto; }

/* ── Fehlerseite ──────────────────────────────────────────────────────── */
.fehlerzahl {
  font-family: var(--schrift-zahl); font-variant-numeric: tabular-nums;
  font-size: var(--text-3xl); font-weight: 500; letter-spacing: -0.03em; color: var(--text-schwach);
}
.vorgangsnummer { font-family: var(--schrift-zahl); font-size: var(--text-xs); color: var(--text-schwach); word-break: break-all; }

/* ── Hilfsklassen ─────────────────────────────────────────────────────── */
.leise { color: var(--text-leise); }
.schwach { color: var(--text-schwach); }
.klein { font-size: var(--text-s); }
.stapel { display: flex; flex-direction: column; gap: var(--raum-3); }
.reihe { display: flex; align-items: center; gap: var(--raum-3); flex-wrap: wrap; }
.rechts { text-align: right; }

/* ── Bewegung zurücknehmen ────────────────────────────────────────────
 * Wer angibt, weniger Bewegung zu wollen, bekommt keine. Die Oberfläche
 * verliert dadurch nichts — Bewegung erklärt hier nur Zustandswechsel.
 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
}

/* ── Serverkarten ─────────────────────────────────────────────────────────
   Eine Tabellenzeile mit vier Spalten sagt nichts darüber, ob ein Server
   läuft. Der Zustand gehört in die Fläche und in Farbe. */
.kartenraster {
  display: grid; gap: var(--raum-3);
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.serverkarte {
  display: flex; flex-direction: column; gap: var(--raum-3);
  padding: var(--raum-4);
  background: var(--flaeche); border: 1px solid var(--linie); border-radius: var(--radius-l);
  color: inherit;
  transition: border-color var(--dauer-schnell) var(--kurve),
              transform var(--dauer-schnell) var(--kurve);
}
.serverkarte:hover { border-color: var(--linie-bedienung); text-decoration: none; transform: translateY(-1px); }
.serverkarte:focus-visible { outline: 2px solid var(--akzent); outline-offset: 2px; }
/* Der gesperrte Zustand ist am Rand zu sehen, ohne die Karte einzufärben —
   eine rote Fläche in einem Raster erschlägt alles daneben. */
.serverkarte--gesperrt { border-color: var(--fehler); }
.serverkarte__kopf { display: flex; align-items: center; gap: var(--raum-3); }
.serverkarte__zeichen {
  display: grid; place-items: center; flex: none;
  width: 2.25rem; height: 2.25rem;
  background: var(--grund); border: 1px solid var(--linie); border-radius: var(--radius-m);
  font-size: var(--text-s); font-weight: 600; letter-spacing: 0.02em;
}
/* Das echte Symbolbild sitzt an derselben Stelle und in derselben Grösse wie
   das Kürzel — sonst rückt die ganze Zeile, je nachdem ob ein Server ein Bild
   hat. `object-fit: cover` verhindert, dass ein nicht quadratisches Bild
   verzerrt wird. */
.serverkarte__bild {
  flex: none; width: 2.25rem; height: 2.25rem;
  border: 1px solid var(--linie); border-radius: var(--radius-m);
  object-fit: cover; background: var(--grund);
}
.serverkarte__bild--gross { width: 2.75rem; height: 2.75rem; }
.serverkarte__name { font-weight: 500; overflow-wrap: anywhere; }
.serverkarte__marken { display: flex; flex-wrap: wrap; gap: var(--raum-2); margin-top: auto; }

/* ── Team-Chat ────────────────────────────────────────────────────────
 * Ein Verlauf ist keine Liste von Aufsätzen. Vorher stand jede Nachricht
 * als voller Absatz in einem eigenen Block einer grossen Karte — bei zehn
 * Zeilen Inhalt füllte das den Bildschirm.
 *
 * Drei Entscheidungen dagegen:
 *   1. Der Verlauf hat eine Höhe (`max-height`) und rollt in sich. Sonst
 *      wächst die Seite mit jeder Nachricht, und das Eingabefeld — das
 *      man ja braucht — wandert nach unten aus dem Bild.
 *   2. Aufeinanderfolgende Nachrichten desselben Absenders wiederholen
 *      Namen und Zeichen nicht. Das spart bei einem Gespräch die halbe
 *      Höhe und macht sichtbar, dass es EIN Gespräch ist.
 *   3. Nebentext-Grösse für Text und Kopfzeile. Ein Chat ist Nebenläufiges,
 *      keine Überschrift.
 */
.chat {
  display: flex; flex-direction: column;
  max-height: 30rem; overflow-y: auto; overscroll-behavior: contain;
  padding: var(--raum-2); background: var(--flaeche);
  border: 1px solid var(--linie); border-radius: var(--radius-l);
}
.chat__zeile {
  display: grid; grid-template-columns: 1.75rem 1fr; gap: var(--raum-3);
  padding: var(--raum-1) var(--raum-2); border-radius: var(--radius-m);
}
.chat__zeile:hover { background: var(--flaeche-hoch); }
/* Fortsetzung: das Zeichen bleibt leer, die Spalte aber stehen — sonst
   springt der Text bei jeder Fortsetzungszeile nach links. */
.chat__zeile--weiter { padding-top: 0; }
.chat__zeichen {
  width: 1.75rem; height: 1.75rem; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--akzent-still); color: var(--akzent);
  font-size: var(--text-xs); font-weight: 700; letter-spacing: 0.02em;
  user-select: none;
}
.chat__kopf { display: flex; align-items: baseline; gap: var(--raum-2); flex-wrap: wrap; }
.chat__wer { font-size: var(--text-s); font-weight: 600; }
.chat__zeit { font-size: var(--text-xs); color: var(--text-schwach); }
/* `pre-wrap` erhält Absätze, die jemand bewusst gesetzt hat.
   `overflow-wrap: anywhere` verhindert, dass eine lange URL ohne
   Leerzeichen die Spalte auseinanderdrückt. */
.chat__text {
  font-size: var(--text-s); line-height: 1.55; margin: 0;
  white-space: pre-wrap; overflow-wrap: anywhere;
}
