/*
 * Meta-Interface — bewusst ohne Build-Schritt und ohne Styled Components.
 * Das Admin-Werkzeug muss auch dann funktionieren, wenn der Frontend-Build
 * kaputt ist; es darf deshalb nicht von diesem Build abhaengen.
 * Die Farben spiegeln Denotatos Theme (packages/frontend/src/theme/theme.ts).
 */

/*
 * Die Neutralen sind die der Sternwarte (Guide §4.2, `theme/szenen.ts`):
 * Nacht ist Indigo, nicht Anthrazit; Tag ist warm-rose, nicht Papierweiss.
 * Kein reines Schwarz, kein reines Weiss — beides liest sich als „noch
 * nicht fertig gestrichen". Uebernommen wird nur die *Basis*: eine Szene
 * waehlt man in Denotato, nicht im Betriebswerkzeug.
 */
:root {
  color-scheme: dark;
  --accent: #a631ff;
  --accent-hover: #7b1fd9;
  --accent-glow: rgba(166, 49, 255, 0.22);
  --bg: #0f0e1a;
  --bg-raised: #1a1826;
  --bg-alt: #201d2d;
  --text: #f1eef7;
  --text-dim: rgba(241, 238, 247, 0.66);
  --text-faint: rgba(241, 238, 247, 0.4);
  --line: rgba(255, 255, 255, 0.12);
  --glass: rgba(255, 255, 255, 0.045);
  --glass-hover: rgba(255, 255, 255, 0.08);
  --ok: #3ddc84;
  --warn: #ffc400;
  --bad: #ff5470;
  /*
   * Hinweis — die vierte Zustandsfarbe aus Denotatos Theme (status.info,
   * Guide §3.3). Dazu die Tinte auf einer vollen Zustandsflaeche: in
   * der Nacht sind alle vier hell, also dunkle Schrift (N132).
   */
  --info: #4d9bff;
  /* Admin in Amethyst (Styleguide §8.3, N144) — Nacht #b56cf7, Tag #7d33d1. */
  --admin: #b56cf7;
  --tinte-auf-signal: #2a2230;
  --radius: 14px;
  --radius-sm: 9px;
  --shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
  --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
    Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

:root[data-theme='light'] {
  color-scheme: light;
  --accent: #8b23e0;
  --accent-hover: #7418c4;
  --accent-glow: rgba(139, 35, 224, 0.14);
  --bg: #f7eee9;
  --bg-raised: #fbf5f1;
  --bg-alt: #f1e6df;
  --text: #2a2230;
  --text-dim: rgba(42, 34, 48, 0.62);
  --text-faint: rgba(42, 34, 48, 0.42);
  --line: rgba(60, 35, 45, 0.14);
  --glass: rgba(60, 35, 45, 0.035);
  --glass-hover: rgba(60, 35, 45, 0.07);
  --ok: #0f7a45;
  --warn: #8a5a00;
  --bad: #c02338;
  --info: #1558c0;
  --admin: #7d33d1;
  --tinte-auf-signal: #ffffff;
  --shadow: 0 8px 28px rgba(80, 50, 40, 0.13);
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    900px 500px at 78% -12%,
    var(--accent-glow),
    transparent 65%
  );
  z-index: 0;
}

.shell {
  position: relative;
  z-index: 1;
  max-width: 1180px;
  margin: 0 auto;
  padding: 28px 22px 72px;
}

/* ---------- Zeichen (N132) ---------- */

/*
 * Ein Zeichen aus dem Sprite in index.html (<svg class="z"><use …>).
 *
 * Duotone wie in Denotato (Guide §7.2): der Strich 2 px in der Farbe des
 * Orts (`currentColor`), die Flaeche mit 38 % Deckkraft in `--z-ton` —
 * ohne Angabe Violett, die Farbe dieser Anwendung; wo das Zeichen einen
 * Zustand traegt, setzt der Ort `--z-ton: currentColor`, und dann ist
 * beides in der Farbe der Stufe. Die Pfade selbst tragen keine Farbe:
 * sie erben `fill` und `stroke` von hier.
 *
 * Der Sprite selbst steht unsichtbar, aber nicht `display: none` — ein
 * <symbol> in einem ausgeblendeten <svg> zeichnen manche Browser nicht.
 */
svg.zeichensatz {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

svg.z {
  width: 1.2em;
  height: 1.2em;
  flex: none;
  vertical-align: -0.22em;
  fill: var(--z-ton, var(--accent));
  stroke: currentColor;
  stroke-width: 2px;
  stroke-linejoin: round;
  stroke-linecap: round;
  overflow: visible;
}

/* ---------- Kopfzeile ---------- */

header.top {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 26px;
  flex-wrap: wrap;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
}

.brand .dot {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: linear-gradient(135deg, #a631ff, #7b1fd9);
  box-shadow: 0 0 12px var(--accent-glow);
}

.brand small {
  font-weight: 500;
  color: var(--text-faint);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.top .spacer {
  flex: 1;
}

.kopfknoepfe {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

/*
 * Am Telefon zwei Zeilen, nicht drei (H1): oben Marke und Uhrzeit,
 * darunter die Knoepfe als ein Block. „aktualisiert" und „Umbruch"
 * verlieren ihr Wort und behalten es als aria-label bzw. im Text des
 * Ganzen; „alles" mit dem Auge bleibt ungekuerzt (Kommentar in index.html),
 * „Abmelden" auch — ein Zeichen dafuer liest niemand sicher.
 */
@media (max-width: 640px) {
  header.top {
    gap: 8px 12px;
    margin-bottom: 16px;
  }

  .kopfknoepfe {
    flex-basis: 100%;
    justify-content: flex-end;
    gap: 6px;
  }

  .nur-breit {
    display: none;
  }
}

/*
 * Guide §16.1: unter einem Finger 40 × 40.
 *
 * Der Selektor ist mit Absicht schwerer als `button.tiny`: Die Regel fuer
 * die kleinen Knoepfe (36 px, weiter unten) hat sonst dieselbe
 * Spezifitaet, steht spaeter und gewinnt — alle vier Kopfknoepfe sind
 * `.tiny`, und bis zur Nachbesserung am 22.09.2026 waren sie deshalb nur
 * 36 px hoch.
 */
@media (pointer: coarse) {
  header.top .kopfknoepfe button {
    min-width: 40px;
    min-height: 40px;
  }
}

/* ---------- Karten ---------- */

.grid {
  display: grid;
  gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(310px, 1fr));
}

.card {
  position: relative;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  box-shadow: var(--shadow);
  /*
   * Ein Sprung aus dem Cockpit (C1) landet nicht buendig an der
   * Oberkante, sondern mit etwas Luft — sonst saehe die Karte
   * abgeschnitten aus. Die Kopfzeile klebt nicht, mehr braucht es nicht.
   */
  scroll-margin-top: 14px;
}

/*
 * Nach einem Sprung haelt die Karte den Fokus (C1). Mit der Maus
 * soll davon nichts zu sehen sein, mit der Tastatur schon.
 */
.card:focus:not(:focus-visible) {
  outline: none;
}

.card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.card.wide {
  grid-column: 1 / -1;
}

.card h2 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 4px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/* Das Zeichen des Abschnitts: Strich gedaempft, Flaeche in Violett (N132). */
.card h2 > svg.z {
  width: 18px;
  height: 18px;
  color: var(--text-dim);
}

.card .hint {
  margin: 0 0 14px;
  color: var(--text-dim);
  font-size: 12.5px;
}

/* ---------- Units ---------- */

.unit {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 0;
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
}

.unit:first-of-type {
  border-top: 0;
}

.unit .info {
  flex: 1;
  min-width: 170px;
}

.unit .name {
  font-weight: 600;
}

.unit .meta {
  color: var(--text-faint);
  font-size: 12px;
  font-family: var(--mono);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  border: 1px solid transparent;
  white-space: nowrap;
}

/*
 * Vor dem Wort das Zeichen der Stufe (N132) — bis dahin ein Punkt aus
 * CSS, der nur die Farbe sagte. Strich und Flaeche in der Farbe der
 * Marke: hier ist das Zeichen Zustand, nicht Bereich (Guide §3.3).
 */
.pill > svg.z {
  width: 14px;
  height: 14px;
  margin-left: -3px;
  stroke-width: 1.6px;
  --z-ton: currentColor;
}

.pill.ok {
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 13%, transparent);
  border-color: color-mix(in srgb, var(--ok) 30%, transparent);
}

.pill.bad {
  color: var(--bad);
  background: color-mix(in srgb, var(--bad) 13%, transparent);
  border-color: color-mix(in srgb, var(--bad) 30%, transparent);
}

.pill.warn {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  border-color: color-mix(in srgb, var(--warn) 32%, transparent);
}

.pill.idle {
  color: var(--text-faint);
  background: var(--glass);
  border-color: var(--line);
}

/* ---------- Bedienelemente ---------- */

button {
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 7px 13px;
  cursor: pointer;
  transition: background 0.14s ease, transform 0.14s ease, border-color 0.14s ease;
}

button:hover:not(:disabled) {
  background: var(--glass-hover);
  transform: translateY(-1px);
}

button:disabled {
  opacity: 0.42;
  cursor: not-allowed;
}

button.primary {
  background: linear-gradient(135deg, #a631ff, #7b1fd9);
  border-color: transparent;
  color: #fff;
}

/*
 * Der Verlauf bleibt beim Ueberfahren. Die allgemeine Regel darueber
 * (`button:hover:not(:disabled)`) wiegt schwerer als `button.primary` und
 * setzte sonst das Grau der Glasknoepfe — der Hauptknopf sah unter der
 * Maus aus wie abgeschaltet.
 */
button.primary:hover:not(:disabled) {
  background: linear-gradient(135deg, #a631ff, #7b1fd9);
  box-shadow: 0 0 16px var(--accent-glow);
}

button.danger:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--bad) 55%, transparent);
  color: var(--bad);
}

button.tiny {
  padding: 4px 9px;
  font-size: 12px;
  font-weight: 500;
}

/*
 * Gewaehrte Bereiche heben sich ab, ausgeschaltete tragen den Warnton.
 * Ein Knopf, dessen Zustand man nicht sieht, ist ein Knopf, den man
 * zweimal drueckt.
 */
button.tiny.ok {
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 13%, transparent);
  border-color: color-mix(in srgb, var(--ok) 30%, transparent);
}

button.tiny.warn {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  border-color: color-mix(in srgb, var(--warn) 32%, transparent);
}

/*
 * Die Administration (N144) traegt Amethyst — dieselbe Farbe, mit der
 * Denotato Admin kennzeichnet (Styleguide §8.3). Zeichen und Wort stehen
 * immer dabei (N134); die Farbe allein sagt nichts.
 */
button.tiny.admin {
  color: var(--admin);
  background: color-mix(in srgb, var(--admin) 14%, transparent);
  border-color: color-mix(in srgb, var(--admin) 34%, transparent);
  --z-ton: currentColor;
}

/*
 * Eine Faehigkeit, die ueber eine Gruppe kommt, ist kein Knopf: Sie
 * laesst sich hier nicht wegnehmen, nur an der Gruppe. Deshalb sieht sie
 * aus wie ein Etikett, nicht wie etwas zum Druecken.
 */
.rechtmarke {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--line);
  color: var(--text-dim);
  font-size: 12px;
}

.rechte-einzeln {
  margin-top: 6px;
}

.rechte-einzeln > summary {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12px;
}

.rechte-einzeln .actions {
  margin-top: 6px;
}

.card .hint.admin-lage {
  color: var(--warn);
}

.actions {
  display: flex;
  gap: 7px;
  flex-wrap: wrap;
}

.zugangsformular {
  align-items: center;
  margin-top: 13px;
}

.zugangsformular > input {
  margin-bottom: 0;
}

@media (max-width: 640px) {
  #abschnitt-zugaenge .scroll {
    overflow-x: visible;
  }

  #operators,
  #operators tbody,
  #operators tr,
  #operators td {
    display: block;
    width: 100%;
  }

  #operators > tr:first-child {
    display: none;
  }

  #operators > tr:not(:first-child) {
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--glass);
  }

  #operators > tr + tr {
    margin-top: 10px;
  }

  #operators td {
    display: grid;
    grid-template-columns: minmax(92px, 0.8fr) minmax(0, 1.4fr);
    gap: 8px;
    align-items: start;
    padding: 6px 0;
    border: 0;
    overflow-wrap: anywhere;
  }

  #operators td::before {
    content: attr(data-label);
    color: var(--text-faint);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  #operators td.zeilenknoepfe > div {
    min-width: 0;
  }

  #operators td.zeilenknoepfe input {
    width: 100%;
    min-width: 0;
  }

  .eigener-faktor {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
  }

  .eigener-faktor > input {
    width: 100%;
    min-width: 0;
  }
}

/* ---------- Admin-MCP (AM03) ---------- */

/*
 * Der neue Schluessel steht genau einmal da: mit einem Klick ganz
 * markiert (user-select: all), daneben „kopieren". Die Angaben fuer
 * claude.ai darunter als kurze Liste — Adresse, Anmeldung, Anfragekopf —,
 * damit sie sich Feld fuer Feld abschreiben lassen. Der Rand im Warnton
 * sagt: Das hier verschwindet und kommt nicht wieder.
 */
.adminmcp-neu {
  margin: 0 0 14px;
  padding: 12px 13px;
  border: 1px solid color-mix(in srgb, var(--warn) 32%, transparent);
  border-radius: var(--radius-sm);
  background: var(--glass);
}

.adminmcp-neu-titel {
  margin: 0 0 9px;
  font-size: 13px;
}

.adminmcp-geheimnis {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 12px;
}

.adminmcp-geheimnis code {
  flex: 1;
  min-width: 0;
  padding: 9px 11px;
  overflow-wrap: anywhere;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  user-select: all;
}

.adminmcp-satz {
  margin: 0 0 8px;
  color: var(--text-dim);
  font-size: 12.5px;
}

.adminmcp-angaben {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: 4px 14px;
  margin: 0 0 10px;
  font-size: 12.5px;
}

.adminmcp-angaben dt {
  color: var(--text-faint);
}

.adminmcp-angaben dd {
  margin: 0;
  overflow-wrap: anywhere;
}

/* Die Zustandszelle traegt Zeichen und Wort in einer Huelle (app.js). */
#adminmcp-schluessel td > span > svg.z {
  margin-right: 6px;
  --z-ton: currentColor;
}

/* Wie die Zugangstabelle: unter 640 Pixel Karten ohne seitliches Rollen. */
@media (max-width: 640px) {
  .adminmcp-geheimnis {
    flex-direction: column;
    align-items: stretch;
  }

  .adminmcp-angaben {
    grid-template-columns: minmax(0, 1fr);
  }

  .adminmcp-angaben dd {
    margin-bottom: 6px;
  }

  #abschnitt-admin-mcp .scroll {
    overflow-x: visible;
  }

  #adminmcp-schluessel,
  #adminmcp-schluessel tbody,
  #adminmcp-schluessel tr,
  #adminmcp-schluessel td {
    display: block;
    width: 100%;
  }

  #adminmcp-schluessel > tr:first-child {
    display: none;
  }

  #adminmcp-schluessel > tr:not(:first-child) {
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--glass);
  }

  #adminmcp-schluessel > tr + tr {
    margin-top: 10px;
  }

  #adminmcp-schluessel td {
    display: grid;
    grid-template-columns: minmax(92px, 0.8fr) minmax(0, 1.4fr);
    gap: 8px;
    align-items: start;
    padding: 6px 0;
    border: 0;
    overflow-wrap: anywhere;
  }

  #adminmcp-schluessel td::before {
    content: attr(data-label);
    color: var(--text-faint);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
}

/* ---------- Admin-MCP-Protokoll (AM08) ---------- */

.adminmcp-protokoll-wahl {
  margin: 0 0 12px;
}

/* Ein Zuschauer hat nichts zu waehlen; `.actions` ist sonst flex und schluege `hidden`. */
.adminmcp-protokoll-wahl[hidden] {
  display: none;
}

/*
 * Parameter und Meldung koennen bis 2000 und 500 Zeichen lang sein. Sie
 * brechen in ihrer Spalte um, statt die Tabelle in die Breite zu ziehen;
 * Zeit, Geraet und Dauer bleiben einzeilig.
 */
#adminmcp-protokoll td {
  vertical-align: top;
}

#adminmcp-protokoll td:nth-child(1),
#adminmcp-protokoll td:nth-child(5) {
  white-space: nowrap;
}

#adminmcp-protokoll td.adminmcp-protokoll-text {
  min-width: 180px;
  max-width: 420px;
  overflow-wrap: anywhere;
  font-size: 12.5px;
}

#adminmcp-protokoll td.adminmcp-protokoll-text code {
  white-space: pre-wrap;
}

#adminmcp-protokoll td > span > svg.z {
  margin-right: 6px;
  --z-ton: currentColor;
}

/* Wie die Schluesseltabelle: unter 640 Pixel Karten ohne seitliches Rollen. */
@media (max-width: 640px) {
  #abschnitt-admin-mcp-protokoll .scroll {
    overflow-x: visible;
  }

  #adminmcp-protokoll,
  #adminmcp-protokoll tbody,
  #adminmcp-protokoll tr,
  #adminmcp-protokoll td {
    display: block;
    width: 100%;
  }

  #adminmcp-protokoll > tr:first-child {
    display: none;
  }

  #adminmcp-protokoll > tr:not(:first-child) {
    padding: 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--glass);
  }

  #adminmcp-protokoll > tr + tr {
    margin-top: 10px;
  }

  #adminmcp-protokoll td,
  #adminmcp-protokoll td.adminmcp-protokoll-text {
    display: grid;
    grid-template-columns: minmax(92px, 0.8fr) minmax(0, 1.4fr);
    gap: 8px;
    align-items: start;
    min-width: 0;
    max-width: none;
    padding: 6px 0;
    border: 0;
    white-space: normal;
    overflow-wrap: anywhere;
  }

  #adminmcp-protokoll td::before {
    content: attr(data-label);
    color: var(--text-faint);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
}

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

.stats {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
}

.stat {
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
}

.stat .label {
  color: var(--text-faint);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.stat .value {
  font-size: 19px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}

.stat .value small {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-faint);
}

/*
 * Eine Kachel, deren Wert ein Zustand ist (markiereKachel, N132):
 * Zeichen und Farbe am Wert, Gelb und Rot auch am Rand. Gruen bleibt
 * ohne Rand — sonst stuenden sechs gruene Kaesten nebeneinander, und
 * der eine rote fiele weniger auf.
 */
.stat .value > svg.z {
  width: 0.9em;
  height: 0.9em;
  margin-right: 6px;
  vertical-align: -0.08em;
  --z-ton: currentColor;
}

.stat[data-stufe='ok'] .value {
  color: var(--ok);
}

.stat[data-stufe='warn'] {
  border-color: color-mix(in srgb, var(--warn) 45%, transparent);
}

.stat[data-stufe='warn'] .value {
  color: var(--warn);
}

.stat[data-stufe='bad'] {
  border-color: color-mix(in srgb, var(--bad) 50%, transparent);
  background: color-mix(in srgb, var(--bad) 7%, var(--glass));
}

.stat[data-stufe='bad'] .value {
  color: var(--bad);
}

/*
 * Die zweite Zeile einer Kachel (17.09.2026).
 *
 * Was den Wert erklaert, steht oben; was nur danebensteht, hier. Der
 * Anlass war die Speicheranzeige, deren erste Zeile umbrach.
 */
.stat .note {
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bar {
  height: 5px;
  border-radius: 999px;
  background: var(--glass-hover);
  overflow: hidden;
  margin-top: 7px;
}

.bar > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #a631ff, #ff66cc);
  transition: width 0.4s ease;
}

.bar.hot > i {
  background: linear-gradient(90deg, var(--warn), var(--bad));
}

/* ---------- Tabellen und Logs ---------- */

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

th {
  text-align: left;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-faint);
  font-weight: 600;
  padding: 6px 8px 6px 0;
  border-bottom: 1px solid var(--line);
}

td {
  padding: 6px 8px 6px 0;
  border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums;
}

td.mono,
.mono {
  font-family: var(--mono);
  font-size: 12px;
}

/*
 * Ein Pfad in einem Hinweis bricht, wo er muss. „Buch: /home/…/zweige…"
 * machte die Seite am Telefon 4 px breiter als den Schirm, sobald man
 * das Zweig-Werkzeug aufklappte.
 */
.hint.mono {
  overflow-wrap: anywhere;
}

.scroll {
  max-height: 260px;
  overflow-y: auto;
}

/*
 * Mehr Hoehe fuer Tabellen mit hohen Zeilen.
 *
 * Eine Zeile der Zugangstabelle traegt ein Passwortfeld und bis zu fuenf
 * Knoepfe und ist deshalb doppelt so hoch wie eine Datenzeile. Bei 260px
 * blieben vier Zugaenge sichtbar, waehrend unter der Karte Platz frei
 * war — man haette in einem Kasten gescrollt, statt die Seite zu lesen.
 */
.scroll.hoch {
  max-height: 560px;
}

pre.log {
  margin: 0;
  padding: 13px;
  background: #0f0e1a;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  font-family: var(--mono);
  font-size: 11.5px;
  line-height: 1.6;
  color: rgba(241, 238, 247, 0.82);
  max-height: 420px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

:root[data-theme='light'] pre.log {
  /* Das Protokoll bleibt dunkel: es ist eine Konsole, kein Dokument. */
  background: #1a1826;
}

/*
 * Das echte `<select>` bleibt stehen und haelt den Wert — sichtbar ist die
 * eigene Auswahl daneben (siehe app.js). Es wird deshalb weggeblendet und
 * nicht `display: none`: ein ausgeblendetes Feld waere aus dem Formular
 * verschwunden, und `.value` soll weiter lesbar sein.
 */
.auswahl > select {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.auswahl {
  position: relative;
  display: inline-block;
}

.auswahl-knopf {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}

.auswahl-knopf:hover:not(:disabled) {
  background: var(--glass-hover);
  border-color: var(--accent);
}

.auswahl-knopf:disabled {
  opacity: 0.5;
  cursor: default;
}

.auswahl-knopf:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.auswahl-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

svg.z.auswahl-pfeil {
  width: 12px;
  height: 12px;
  margin-left: auto;
  opacity: 0.6;
  stroke-width: 1.5px;
  --z-ton: currentColor;
}

/*
 * `fixed` und nicht `absolute`: die Rollenauswahl steht in der
 * Kontentabelle, und die steht in einem `.scroll`. Der schneidet ab, was
 * ueber seinen Rand hinausragt — eine halb sichtbare Liste waere
 * schlimmer als die des Betriebssystems. Wohin sie gehoert, rechnet
 * `stelle()` in app.js beim Oeffnen aus.
 */
.auswahl-liste {
  position: fixed;
  z-index: 40;
  max-width: min(420px, 86vw);
  max-height: 280px;
  overflow-y: auto;
  padding: 4px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}

.auswahl-eintrag {
  padding: 6px 9px;
  border-radius: 6px;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}

.auswahl-eintrag:hover {
  background: var(--glass-hover);
}

.auswahl-eintrag.gewaehlt {
  background: var(--accent);
  color: #fff;
}

/*
 * Zeilenumbruch in Tabellen — ein Schalter fuer die ganze Seite.
 * Aus: ein Datensatz ist eine Zeile, Langes schiebt seitlich.
 * An: Langes bricht um, die Zeile wird so hoch, wie sie sein muss.
 */
:root[data-umbruch='aus'] td,
:root[data-umbruch='aus'] th {
  white-space: nowrap;
}

:root[data-umbruch='aus'] .scroll {
  overflow-x: auto;
}

/*
 * `break-word`, nicht `anywhere`: Beide brechen ein Wort, das nicht in
 * die Zeile passt. Nur `anywhere` zaehlt dabei jede Stelle als moegliche
 * Bruchstelle, wenn die Tabelle ihre Spalten verteilt — die Spalte darf
 * dann auf ein Zeichen schrumpfen. Am Telefon stand eine UUID in
 * `auth.users` so bis zum 27.09.2026 Zeichen fuer Zeichen untereinander,
 * die Zeile wurde 36 Zeilen hoch, und der Aufdeck-Knopf, senkrecht in
 * ihrer Mitte, lag ausserhalb des Kastens (V06). Mit `break-word` ist die
 * schmalste Spalte so breit wie ihr laengstes Stueck zwischen zwei
 * Bruchstellen: eine UUID bricht an ihren Bindestrichen.
 */
:root[data-umbruch='an'] td {
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

#umbruch-toggle.an {
  border-color: var(--accent);
  color: var(--accent);
}

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

.login-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 22px;
  position: relative;
  z-index: 1;
}

.login {
  width: 100%;
  max-width: 360px;
  background: var(--bg-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 28px;
  box-shadow: var(--shadow);
}

.login h1 {
  margin: 0 0 3px;
  font-size: 21px;
  letter-spacing: -0.02em;
}

.login p.sub {
  margin: 0 0 22px;
  color: var(--text-faint);
  font-size: 13px;
}

label {
  display: block;
  font-size: 12px;
  color: var(--text-dim);
  margin-bottom: 5px;
  font-weight: 500;
}

input {
  font: inherit;
  width: 100%;
  padding: 10px 12px;
  margin-bottom: 14px;
  color: var(--text);
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
}

input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-glow);
}

.error {
  color: var(--bad);
  font-size: 12.5px;
  margin: 0 0 12px;
  min-height: 17px;
}

/*
 * Der zweite Faktor (B60): der Code nach dem Passwort und die
 * Einrichtung. Dieselbe Karte wie die Anmeldung; die Einrichtung ist
 * breiter, weil Schluessel und Wiederherstellungscodes darin stehen.
 */
.login.einrichten {
  max-width: 440px;
}

/* Der zweite Knopf unter dem Hauptknopf — „Abbrechen", „Abmelden". */
.login .nebenknopf {
  width: 100%;
  margin-top: 9px;
}

/*
 * „Schlüssel fehlt" steht nur, wenn es so ist. Leer haelt die Zeile
 * keinen Platz frei — anders als die Fehlerzeilen unter den Feldern, die
 * es tun, damit nichts springt, wenn eine Meldung kommt.
 */
#einrichten-schluessel:empty {
  display: none;
}

.login p.hint {
  margin: -6px 0 12px;
  color: var(--text-faint);
  font-size: 12px;
}

.login p.schritt {
  margin: 0 0 12px;
  color: var(--text-dim);
  font-size: 13px;
  line-height: 1.5;
}

/* Ein Verweis in der Karte — Blau wie der Hinweis, nicht Violett wie ein Knopf. */
.login a {
  color: var(--info);
}

/*
 * Das QR-Bild (B66): Weiss mit Ruhezone, auch im dunklen Panel — ein
 * umgekehrter Code liest nicht jede Kamera. 200 px geben einem
 * Verweis (Version 7 oder 8) gut drei Pixel je Modul; leer haelt das
 * Feld keinen Platz frei.
 */
.login .qr {
  width: 200px;
  max-width: 100%;
  margin: 0 auto 14px;
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.login .qr:empty {
  display: none;
}

.login .qr svg {
  display: block;
  width: 100%;
  height: auto;
}

.login .geheimnis {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 16px;
}

.login .geheimnis code {
  flex: 1;
  min-width: 0;
  padding: 9px 11px;
  font-size: 14px;
  letter-spacing: 0.06em;
  word-spacing: 0.3em;
  overflow-wrap: anywhere;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  user-select: all;
}

.login .codeliste {
  columns: 2;
  column-gap: 24px;
  margin: 0 0 12px;
  padding-left: 24px;
  font-size: 13px;
  line-height: 1.8;
}

/*
 * Am Telefon eine Spalte: Die Nummern der zweiten Spalte stehen im
 * Spaltenabstand, und bei 390 px stiess „10." an den Code davor.
 */
@media (max-width: 640px) {
  .login .codeliste {
    columns: 1;
  }
}

.login label.haken {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

.login label.haken input {
  width: auto;
  margin: 0;
}

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

#toasts {
  position: fixed;
  right: 18px;
  bottom: 18px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  z-index: 50;
  max-width: min(440px, calc(100vw - 36px));
}

.toast {
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 11px 14px;
  box-shadow: var(--shadow);
  font-size: 13px;
  animation: slide-in 0.22s ease;
}

/* 'err' rufen vierzehn Stellen in app.js — ohne Regel blieben sie grau. */
.toast.bad,
.toast.err {
  border-left-color: var(--bad);
}

.toast.ok {
  border-left-color: var(--ok);
}

/* Das Zeichen der Meldung vor ihrem Text (N132): Haken, Kreuz, Hinweis. */
.toast > svg.z {
  margin-right: 7px;
  color: var(--info);
  --z-ton: currentColor;
}

.toast.ok > svg.z {
  color: var(--ok);
}

.toast.bad > svg.z,
.toast.err > svg.z {
  color: var(--bad);
}

.toast .detail {
  display: block;
  margin-top: 4px;
  color: var(--text-dim);
  font-family: var(--mono);
  font-size: 11.5px;
  white-space: pre-wrap;
  max-height: 130px;
  overflow: auto;
}

@keyframes slide-in {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
}

.hidden {
  display: none !important;
}

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

@media (max-width: 640px) {
  .shell {
    padding: 18px 14px 60px;
  }
  /*
   * Ampel und Knoepfe in einer Zeile (B4). Mit `width: 100%` stand jede
   * Knopfleiste auf einer eigenen Zeile, und jeder Dienst war am
   * Telefon 164 px hoch — fuer zwei Knoepfe.
   */
  .unit .actions {
    margin-left: auto;
  }
}

/*
 * Kleine Knoepfe am Telefon (Guide §16.1, MISSED 4): 29 px waren zu
 * wenig fuer einen Daumen. 36 px ist die Hoehe, die auch die
 * Rueckmeldungsknoepfe haben. Die Kopfknoepfe bekommen 40 — ihre Regel
 * steht weiter oben und ist dafuer schwerer (`header.top .kopfknoepfe
 * button`), sonst gewaenne diese hier.
 */
@media (max-width: 640px), (pointer: coarse) {
  button.tiny,
  button.kennzeichenknopf {
    min-height: 36px;
  }
}

/* ---------- Spoiler ---------- */

/*
 * Hier liegen fremde Daten.
 *
 * Der Tabellenbrowser zeigt Inhalte, und Christians Vorgabe dazu war
 * eindeutig: alles Sensible steht erst nach einem bewussten Klick da — je
 * Zelle, je Spalte, je Zeile, und einmal fuer die ganze Tabelle oder die
 * ganze Seite. Der Grund ist nicht Geheimniskraemerei, sondern der Schirm
 * selbst: wer ihn im Betrieb offen hat, hat ihn oft neben sich stehen,
 * waehrend jemand anderes im Raum ist.
 *
 * Verdeckt wird mit einem Filter und nicht mit ausgetauschtem Text: der
 * Wert bleibt in der Zelle, die Spaltenbreite springt beim Aufdecken nicht,
 * und ein Bildschirmfoto zeigt trotzdem nichts.
 */
.spoiler {
  cursor: pointer;
  border-radius: 3px;
  filter: blur(5px);
  user-select: none;
  background: rgba(128, 128, 128, 0.14);
  transition: filter 120ms ease;
}

.spoiler:hover {
  filter: blur(4px);
  outline: 1px dashed rgba(166, 49, 255, 0.6);
}

.spoiler.offen {
  cursor: default;
  filter: none;
  user-select: text;
  background: transparent;
  outline: none;
}

/* Der kleine Knopf am Spaltenkopf und am Zeilenanfang. */
.reveal {
  cursor: pointer;
  border: none;
  background: none;
  padding: 0 3px;
  font-size: 11px;
  line-height: 1;
  opacity: 0.55;
  color: inherit;
}

.reveal:hover {
  opacity: 1;
}

.reveal > svg.z {
  width: 14px;
  height: 14px;
  stroke-width: 1.6px;
}

.tabellenkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.tabellenkopf .auswahl-knopf {
  max-width: 280px;
}

.blaettern {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 12px;
}

/* display:flex schlaegt sonst das hidden-Attribut: ◀▶ ohne Tabelle */
.blaettern[hidden] {
  display: none;
}

/* ---------- Rueckmeldungen ---------- */

.meldungskopf {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

/*
 * Eine Zeile je Meldung: Art, erster Satz, Herkunft. Mehr braucht die
 * Entscheidung „schaue ich mir das jetzt an?" nicht.
 */
.meldungszeile {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  margin-bottom: 7px;
  cursor: pointer;
  background: var(--glass);
  transition: background 140ms ease, border-color 140ms ease;
}

.meldungszeile:hover {
  background: var(--glass-hover);
  border-color: var(--accent);
}

.meldungszeile:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.meldungszeile.laedt {
  opacity: 0.5;
  cursor: progress;
}

.meldungszeile .mitte {
  min-width: 0;
  flex: 1;
}

.meldungszeile .mitte:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/*
 * Die zwei Knoepfe am Ende jeder Zeile (N128, W15) — uebernehmen und
 * ablehnen, ohne erst aufzuklappen.
 */
.gleich {
  flex: none;
  display: flex;
  gap: 6px;
  align-self: center;
}

/*
 * `.vorschau` gibt es zweimal: hier der erste Satz einer Meldung, weiter
 * unten die Fussnote unter der Zweig-Auswahl mit Linie und Abstand. Ohne
 * die drei Nullen erbte die Meldung beides und stand eine halbe Zeile
 * tiefer als ihre Art, hinter einem Strich wie ein Zitat.
 */
.meldungszeile .vorschau {
  margin: 0;
  padding-left: 0;
  border-left: 0;
  font-size: 13px;
  line-height: 1.45;
}

.herkunft {
  font-size: 11px;
  color: var(--text-faint);
}

.meldungskarten-kopf {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 9px;
}

.meldungskarten-kopf .spacer {
  flex: 1;
}

/*
 * Fehler und Wunsch tragen dieselbe Form und verschiedene Farben —
 * Zustand, nicht Marke. Der Wunsch ist blau (info), der Fehler rot (bad).
 * Bis N132 stand der Wunsch trotz dieses Satzes in Violett (--accent);
 * seitdem gibt es --info, und dazu je Art ein Zeichen: den Kaefer fuer
 * den Fehler, den Funken fuer den Wunsch.
 */
.art {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: none;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  padding: 3px 7px;
  border-radius: 999px;
  border: 1px solid currentColor;
  line-height: 1.3;
}

.art.bug {
  color: var(--bad);
}

.art.feature {
  color: var(--info);
}

.art > svg.z {
  width: 13px;
  height: 13px;
  stroke-width: 1.5px;
  --z-ton: currentColor;
}

.meldung {
  border: 1px solid rgba(128, 128, 128, 0.25);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 12px;
}

.meldung h3 {
  margin: 0 0 6px 0;
  font-size: 13px;
  font-weight: 600;
}

.meldung textarea {
  width: 100%;
  min-height: 72px;
  resize: vertical;
  font: inherit;
  font-size: 12px;
  margin-bottom: 8px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 9px;
}

.meldung textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.meldung .schalter {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 12px;
  margin-bottom: 8px;
}

.meldung .schalter label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}

/*
 * Die Vorschau eines mitgeschickten Bildes — klein, weil sie nur zeigt,
 * dass eines da ist. Wer mehr sehen will, klickt: der Link darum oeffnet
 * dieselbe Route in voller Groesse in einem eigenen Reiter.
 */
.meldung-bild {
  display: block;
  max-width: 220px;
  max-height: 160px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  margin-bottom: 8px;
  cursor: zoom-in;
}


/* ---------- Staende und Datenbanken ---------- */

/*
 * Zwei Karten nebeneinander, solange Platz ist. Was laeuft, traegt einen
 * Rand in der Anwendungsfarbe — das ist die eine Auskunft, die man aus
 * drei Metern Abstand noch lesen koennen soll.
 */
.staende,
.zweige,
.datenbanken {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 11px;
}

/*
 * Vier Zweige in einer Reihe, wo Platz ist (B2): Mit 320 px Mindestbreite
 * standen drei nebeneinander und der vierte allein darunter — eine
 * ganze Kartenhoehe fuer eine Karte.
 */
.zweige {
  grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr));
}

.stand,
.zweig,
.datenbank {
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px;
  background: var(--glass);
}

.stand.laeuft {
  border-color: var(--accent);
  background: var(--glass-hover);
}

.standkopf {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
}

.standkopf .spacer {
  flex: 1;
}

.standknoepfe {
  display: flex;
  gap: 6px;
}

/*
 * Der Punkt einer Karte ist seit N132 das Zeichen ihrer Stufe — Haken,
 * Warndreieck, Kreuz, Strich —, in der Farbe der Stufe. Fuer Vorleser
 * traegt es das Wort (läuft, nicht sauber, fehlt …) als aria-label.
 */
.standkopf svg.dot {
  width: 17px;
  height: 17px;
  color: var(--text-faint);
  --z-ton: currentColor;
}

.standkopf .dot.ok {
  color: var(--ok);
}

.standkopf .dot.bad {
  color: var(--bad);
}

/* Nicht sauber (zweigklasse): gelb wie die Cockpitzeile, nicht rot. */
.standkopf .dot.warn {
  color: var(--warn);
}

.standkopf .dot.off {
  color: var(--text-faint);
}

/* Nicht eingerichtet: nur der Strich, keine Flaeche — es gibt ihn nicht. */
.standkopf .dot.unknown {
  color: var(--text-faint);
  --z-ton: transparent;
}

.stand .hint,
.zweig .hint,
.datenbank .hint {
  margin: 7px 0 9px;
}

.standfuss {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 11.5px;
  align-items: center;
}

/*
 * Die Beschreibung stand zwischen Kopf und Fuss und hielt beide
 * auseinander; seit sie im Erklaerbaustein steht (G1), tut es dieser Abstand.
 */
.standkopf + .standfuss {
  margin-top: 9px;
}

.kennzeichen {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid var(--line);
  color: var(--text-faint);
}

.kennzeichen.an {
  border-color: var(--accent);
  color: var(--accent);
}

/*
 * Eine Marke, die widerspricht.
 *
 * Sie steht neben einem Stand, der laeuft, und sagt trotzdem „nicht
 * erreichbar" — genau dafuer braucht sie eine Farbe, die auffaellt. Die
 * Warnfarbe und nicht die Fehlerfarbe: Der Dienst ist nicht kaputt,
 * sondern der Weg dorthin.
 */
.kennzeichen.warn {
  border-color: color-mix(in srgb, var(--warn) 45%, transparent);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  color: var(--warn);
}

.kennzeichen > svg.z {
  width: 12px;
  height: 12px;
  margin-right: 4px;
  vertical-align: -0.2em;
  stroke-width: 1.5px;
  --z-ton: currentColor;
}

/* Der Winkel am Ende der Marke „n Commits offen": sie fuehrt weiter. */
button.kennzeichenknopf > svg.z {
  margin-right: 0;
  margin-left: 4px;
}

.uebertragung {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 9px;
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid var(--line);
}

.wahlreihe {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.tiny.gewaehlt {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--glass-hover);
}

/*
 * Der Knopf, der nicht rueckgaengig zu machen ist, sieht auch so aus.
 * Rot, aber nicht schreiend: er ist die richtige Handlung, wenn man ihn
 * braucht — nur eben nie versehentlich.
 */
.tiny.warnend {
  border-color: var(--bad);
  color: var(--bad);
}

.tiny.warnend:hover:not(:disabled) {
  background: var(--bad);
  color: #fff;
}

.auswahlpaar {
  display: flex;
  align-items: center;
  gap: 7px;
}

.auswahlpaar .pfeil {
  width: 16px;
  height: 16px;
  color: var(--text-faint);
  --z-ton: currentColor;
}

/*
 * Die Stufe, in die uebertragen wird, traegt den Rand der Anwendungsfarbe
 * — dieselbe Auskunft wie bei einem laufenden Stand: „hier passiert etwas".
 * Eine Stufe, in der nichts aussteht, bleibt still.
 */
.zweig.faellig {
  border-color: var(--accent);
  background: var(--glass-hover);
}

#db-bestaetigung,
#zweig-bestaetigung,
#zweig-zurueck-bestaetigung {
  font: inherit;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 6px 10px;
  min-width: 240px;
}

#db-bestaetigung:focus-visible,
#zweig-bestaetigung:focus-visible,
#zweig-zurueck-bestaetigung:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/*
 * Die Vorschau haengt unter der Auswahl, nicht daneben.
 *
 * Sie gehoert zu dem Knopf darueber und soll wie seine Fussnote
 * aussehen — eingerueckt an einer Linie, damit man sieht, worauf sie
 * sich bezieht, und nicht als zweiter Kasten, der um Aufmerksamkeit
 * mit der Liste der Zweige konkurriert.
 */
.vorschau {
  margin: 9px 0 0 3px;
  padding-left: 11px;
  border-left: 2px solid var(--line);
}

.vorschau .hint {
  margin: 0 0 6px;
}

/*
 * Gruen heisst „so, wie es jetzt steht, ginge das durch" — und nur das.
 * Es ist keine Empfehlung; ob der Stand uebertragen werden *soll*,
 * beantwortet kein Farbton.
 */
.vorschau-ja {
  color: var(--ok);
}

.vorschau-nein {
  color: var(--warn);
}

/* Die Sperre vor prod (N470): rot, weil ohne Grund nichts geht. */
.vorschau-sperre {
  color: var(--bad);
}

/* Die letzten Zeilen eines roten Glieds, eingerueckt unter seinem Namen. */
.sperrzeile {
  font-size: 11px;
  padding-left: 14px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ueberstimmen {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 9px 0 0 3px;
  padding-left: 11px;
  border-left: 2px solid var(--bad);
}

.ueberstimmen[hidden] {
  display: none;
}

.ueberstimmen label.haken {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}

.ueberstimmen label.haken input {
  width: auto;
  margin: 0;
}

.ueberstimmen textarea {
  width: 100%;
  min-height: 52px;
  resize: vertical;
  font: inherit;
  font-size: 12px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 8px 9px;
}

.ueberstimmen textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.vorschauzeile {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  align-items: baseline;
  font-size: 11.5px;
  padding: 2px 0;
}

/*
 * Eine Meldung, die sich selbst geschrieben hat, tritt zurueck.
 * Nicht versteckt — leiser. Sie steht ohnehin unter allen, die ein Mensch
 * geschrieben hat, und ihr Rand soll nicht um dieselbe Aufmerksamkeit
 * bitten wie deren.
 */
.meldungszeile.selbstgemeldet {
  border-style: dashed;
  background: transparent;
}

.meldungszeile .kennzeichen {
  margin-bottom: 4px;
  display: inline-block;
}

/*
 * Der Stand einer Rueckmeldung (N470): prod schlicht, beta in der
 * Akzentfarbe, denn dort landen die Meldungen aus der Probe — und dort
 * wirkt auch jede Entscheidung, nicht in prod.
 */
.kennzeichen.stand {
  margin-right: 6px;
}

.cockpit-meldungstext .kennzeichen.stand {
  padding: 1px 6px;
}

/*
 * Ein Stand, der nicht gelesen wurde, ist ein Hinweis und kein Ausfall:
 * gelb und nicht rot, solange prod lesbar ist (N470).
 */
.staendehinweis {
  color: var(--warn);
}

.umstand {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-dim);
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 7px 9px;
  margin-bottom: 8px;
  overflow-wrap: anywhere;
}

/* ---------- Mail ---------- */

/*
 * Eine Zwischenueberschrift innerhalb einer Karte.
 *
 * Der Mailabschnitt ist der erste, der vier Tabellen untereinander
 * traegt. Ohne Zwischenkopf waeren es vier Gitter ohne Angabe, wovon
 * sie handeln — und mit einem <h2> je Tabelle waeren es vier Karten.
 */
.unterkopf {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 22px 0 8px;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}

/*
 * Was der Kette fehlt — in Worten, nicht als Kennung.
 *
 * Wer hier hinsieht, sucht keine Diagnose, sondern den naechsten
 * Schritt. Deshalb ein Kasten mit ganzen Saetzen und nicht eine Reihe
 * roter Haken. Er verschwindet vollstaendig, wenn nichts fehlt: ein
 * leerer Kasten mit der Ueberschrift „Alles in Ordnung" ist Laerm.
 */
.mail-fehlt {
  margin-top: 16px;
  padding: 13px 16px;
  border: 1px solid color-mix(in srgb, var(--warn) 32%, transparent);
  background: color-mix(in srgb, var(--warn) 9%, transparent);
  border-radius: var(--radius-sm);
  font-size: 0.86rem;
}

.unterkopf > svg.z {
  width: 16px;
  height: 16px;
  color: var(--text-dim);
}

.mail-fehlt strong > svg.z {
  margin-right: 6px;
  color: var(--warn);
  --z-ton: currentColor;
}

.mail-fehlt ul {
  margin: 8px 0 0;
  padding-left: 20px;
}

.mail-fehlt li {
  margin: 4px 0;
  color: var(--text-dim);
}

/*
 * Zellen mit Zustand (zustandszelle, N132): das Zeichen vor dem Wort,
 * beides in der Farbe der Zelle. In der DNS-Tabelle steht es allein und
 * sagt „stimmt" oder „stimmt nicht" als aria-label — bis N132 standen
 * dort ein voller und ein leerer Kreis aus der Schrift.
 */
td > svg.z,
.card .hint > svg.z:first-child {
  margin-right: 6px;
  --z-ton: currentColor;
}

/*
 * Allein in der Zelle (zustandszelle ohne Wort, das Schloss der
 * Umgebungsdateien). Nicht `:only-child`: das zaehlt nur Elemente, und
 * jedes Zeichen vor einem blossen Text waere dann ohne Abstand.
 */
td > svg.z.allein {
  margin-right: 0;
}

td.gut {
  color: var(--ok);
  font-weight: 600;
}

td.schlecht {
  color: var(--bad);
  font-weight: 600;
}

/*
 * Ein Hinweis, der keiner mehr ist, sondern eine Warnung: „die SSD ist
 * nicht eingehaengt" darf nicht in derselben Farbe dastehen wie der
 * Satz darueber, der nur erklaert.
 */
.card .hint.schlecht {
  color: var(--bad);
}

/*
 * Ein Zustand, der weder gut noch kaputt ist: ein Startpasswort, das
 * noch gewechselt werden muss. Gelb, weil es weitergeht — aber nicht
 * so bleiben soll.
 */
td.warnung {
  color: var(--warn);
  font-weight: 600;
}

/*
 * Lange Werte brechen um, statt die Tabelle zu sprengen.
 *
 * Ein DKIM-Schluessel ist vierhundert Zeichen lang. Ohne diese Regel
 * schiebt eine einzige Zelle die ganze Karte seitlich aus dem Bild.
 */
td.lang {
  max-width: 30ch;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/*
 * Die Tabellen des Mailabschnitts brechen um, statt seitlich zu schieben.
 *
 * Ohne das bekommt die DNS-Tabelle eine waagerechte Bildlaufleiste: der
 * Wert ist bis vierhundert Zeichen lang, der Hinweis daneben ein ganzer
 * Satz. Beides zusammen sprengt jede Bildschirmbreite.
 *
 * Und Schieben waere hier die schlechtere Loesung als anderswo: die
 * Spalte ganz rechts ist die, die den naechsten Schritt nennt. Wer sie
 * erst herholen muss, liest sie nicht.
 */
#mail-dns,
#mail-adressen,
#mail-konfig {
  width: 100%;
  table-layout: fixed;
}

#mail-dns td:last-child,
#mail-adressen td:last-child {
  overflow-wrap: anywhere;
  white-space: normal;
}

/* Der Punkt vorn braucht nur seine eigene Breite. */
#mail-dns td:first-child,
#mail-dns th:first-child {
  width: 2.2rem;
}

/*
 * Das Probefeld bleibt in der Reihe.
 *
 * Ohne Breitenangabe nimmt es die ganze Zeile und schiebt den Knopf
 * darunter — dann sieht es aus wie zwei getrennte Dinge statt wie ein
 * Feld mit seinem Knopf.
 */
/*
 * Eingabefelder bleiben in ihrer Reihe.
 *
 * Ohne Breitenangabe nimmt ein <input> in einem Flex-Container die ganze
 * Zeile; drei davon stapeln sich dann untereinander und der Knopf sitzt
 * verloren darunter. Mit fester Breite liest sich die Reihe als das, was
 * sie ist: ein Formular mit seinem Knopf.
 */
#mail-ziel {
  width: 17rem;
  flex: 0 0 auto;
}

#adr-name,
#adr-ziel {
  width: 15rem;
  flex: 0 0 auto;
}

#adr-zweck {
  width: 13rem;
  flex: 1 1 13rem;
  min-width: 10rem;
}

/*
 * Die Knopfreihe in einer Tabellenzeile.
 *
 * Passwortfeld, „setzen", „Zugang entziehen" und „löschen" stehen
 * nebeneinander und brechen nicht um — sonst wird aus einer Zeile ein
 * Block und die Tabelle verliert ihre Zeilen.
 */
/*
 * Die Knopfreihe in einer Tabellenzeile.
 *
 * `display: flex` stand hier zuerst direkt auf dem `<td>`. Das war
 * falsch: eine Tabellenzelle, die zur Flex-Box wird, verliert ihre
 * Zellbreite und laeuft in die Nachbarspalte hinein — am 16.09.2026
 * gemeldet als „das Textfeld sitzt im Text und wird von ihm verdeckt".
 *
 * Die Zelle bleibt jetzt eine Zelle, und ein `div` darin ordnet.
 */
td.zeilenknoepfe > div {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}

td.zeilenknoepfe {
  overflow: hidden;
}

/*
 * Schmal, und type=password.
 *
 * Nicht aus Gewohnheit: dieser Schirm steht auf einem Rechner, an dem
 * jemand vorbeigeht. Ein Postfachpasswort im Klartext in einer Tabelle
 * ist der Fall, für den type=password erfunden wurde.
 */
input.pw-feld {
  width: 10rem;
  flex: 0 0 auto;
}

/*
 * Ein Eingabefeld in einer Knopfreihe ist keine Zeile fuer sich.
 *
 * `input` hat hier `width: 100%` — sinnvoll im Anmeldeformular, falsch
 * in einer Reihe aus Feld, Auswahl und Knopf: jedes Feld schob sich auf
 * eine eigene Zeile, und aus drei Bedienelementen wurden drei Zeilen.
 */
input.feld-schmal {
  width: 16rem;
  flex: 0 1 auto;
}

/*
 * Die Adresstabelle bleibt im Bild.
 *
 * Fuenf Spalten, darunter eine mit einem Eingabefeld und bis zu drei
 * Knoepfen — ohne feste Aufteilung sprengt die letzte Spalte die Karte
 * und die Adresse links wandert aus dem Bild. Gerade sie ist aber die,
 * an der man die Zeile wiedererkennt.
 */
#mail-adressen {
  width: 100%;
  table-layout: fixed;
}

#mail-adressen th:nth-child(1),
#mail-adressen td:nth-child(1) {
  width: 21%;
}

#mail-adressen th:nth-child(2),
#mail-adressen td:nth-child(2) {
  width: 11%;
}

#mail-adressen th:nth-child(3),
#mail-adressen td:nth-child(3) {
  width: 17%;
}

/*
 * „wofuer" ist die Spalte, die am ehesten Platz abgeben kann: sie
 * erklaert, waehrend die Spalte daneben bedient wird.
 */
#mail-adressen th:nth-child(4),
#mail-adressen td:nth-child(4) {
  width: 15%;
}

/* Und die Knopfspalte bekommt, was sie braucht: Feld plus drei Knoepfe. */
#mail-adressen th:nth-child(5),
#mail-adressen td:nth-child(5) {
  width: 36%;
}

#mail-adressen td {
  overflow-wrap: anywhere;
  vertical-align: middle;
}

/* ---------- Reiter (B42) ---------- */

/*
 * Sechs Reiter, das Cockpit vorn (N127, 22.09.2026).
 *
 * Die Leiste sitzt unter der Kopfzeile und ueber dem Raster; der
 * gewaehlte Reiter traegt die Akzentfarbe als Unterstrich, nicht als
 * Fuellung — ein gefuellter Knopf saehe aus wie eine Handlung, und ein
 * Reiter tut nichts, er zeigt.
 */
nav.reiter {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  margin: -8px 0 18px;
  border-bottom: 1px solid var(--line);
}

nav.reiter button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 600;
  padding: 8px 13px;
  margin-bottom: -1px;
}

/*
 * Je Reiter ein Zeichen vor dem Wort (N132) — Zeichen in Violett, Wort
 * neutral, wie Denotatos Leiste (Guide §7.3). Dahinter die Marke: eine Zahl
 * auf Gelb oder Rot, wenn auf dem Reiter etwas nicht gruen ist; die
 * Schrift darauf ist die Tinte der Zustandsflaeche (Guide §3.3).
 */
nav.reiter button > svg.z {
  width: 18px;
  height: 18px;
}

/*
 * Die Marke selbst traegt seit Welle 2 (W15) ihr Stufenzeichen —
 * Warndreieck oder Kreuz, dasselbe wie im Cockpit (STUFENZEICHEN) — vor
 * der Zahl: Gelb und Rot unterscheiden sich dann auch in der Form, nicht
 * nur im Ton. Das Wort dazu steht im `aria-label` der Marke, nicht
 * sichtbar — am Reiter ist knapper Platz, und der Vorleser braucht kein
 * zweites Wort neben dem sichtbaren.
 */
.reitermarke {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-width: 18px;
  height: 18px;
  padding: 0 6px 0 4px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--tinte-auf-signal);
  background: var(--text-faint);
}

.reitermarke > svg.z {
  width: 11px;
  height: 11px;
  stroke-width: 2.4px;
  --z-ton: currentColor;
}

.reitermarke.warn {
  background: var(--warn);
}

.reitermarke.bad {
  background: var(--bad);
}

.reitermarke[hidden] {
  display: none;
}

nav.reiter button:hover:not(:disabled) {
  color: var(--text);
  background: var(--glass);
  transform: none;
}

nav.reiter button.gewaehlt {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/*
 * Am Telefon eine Zeile (H1). Die sechs Beschriftungen sind zusammen
 * rund 270 px breit; neben ein Zeichen gestellt passten sie nicht mehr
 * in 362 px. Deshalb steht das Zeichen seit N132 ueber dem Wort, das
 * Wort in 11,5 px, und die Marke sitzt oben rechts neben dem Zeichen.
 * Nichts wird versteckt oder gewischt. `flex-wrap` bleibt als Rueckfall
 * fuer eine groessere Schrift — dann bricht ein ganzer Reiter um, nie
 * „Proto-koll".
 *
 * Neben, nicht auf dem Zeichen (V06): Seit die Marke ihr Stufenzeichen
 * traegt, ist sie gut 26 px breit; an den Rand des Zeichens gesetzt,
 * deckte sie dessen rechte obere Ecke ab. Sie beginnt deshalb einen
 * Pixel hinter dem Zeichen und steht hoeher als es. Damit ragt sie ueber
 * den Rand des schmalen Reiters in die leere Ecke des Nachbarn. Leer ist
 * diese Ecke nur, wenn die Reiter gleich breit sind (`flex: 1 1 0`): mit
 * `auto` war „Daten" so schmal, dass seine Marke das Zeichen von „Post"
 * verdeckte. `pointer-events: none` laesst ein Tippen in diese Ecke beim
 * Nachbarn ankommen, dem sie gehoert.
 */
@media (max-width: 640px) {
  nav.reiter {
    gap: 2px;
    margin-top: -4px;
    margin-bottom: 14px;
  }

  nav.reiter button {
    position: relative;
    flex: 1 1 0;
    flex-direction: column;
    gap: 2px;
    padding: 6px 4px;
    font-size: 11.5px;
    white-space: nowrap;
  }

  nav.reiter .reitermarke {
    position: absolute;
    z-index: 1;
    top: 0;
    left: calc(50% + 10px);
    pointer-events: none;
    min-width: 16px;
    height: 16px;
    padding: 0 5px 0 3px;
    font-size: 10px;
    line-height: 16px;
  }

  nav.reiter .reitermarke > svg.z {
    width: 9px;
    height: 9px;
  }
}

/*
 * Die 40 px Breite (Guide §16.1) sichert das Wort, nicht der Knopf: Ein
 * `min-width: 40px` am Knopf ersetzte das `auto` der Flexbox, und die
 * gleich breiten Reiter am Telefon durften dann schmaler werden als ihr
 * Wort — „Protokoll" lief bis an den Rand (V06). So bleibt jeder Reiter
 * mindestens sein Wort breit und nie unter 32 + 8 px.
 */
@media (pointer: coarse) {
  nav.reiter button {
    min-height: 40px;
  }

  nav.reiter .reiterwort {
    min-width: 32px;
    text-align: center;
  }
}

/* ---------- Cockpit ---------- */

/*
 * Eine Zeile je Frage: Zeichen, Titel, Ampel, ein Satz. Die ganze Zeile
 * ist der Knopf zum Reiter — nicht ein Pfeil am Ende, den man erst
 * suchen muss.
 *
 * Seit N132 sagt die Zeile ihre Stufe dreimal: am Rand links, am Zeichen
 * vorn und in der Marke mit dem Wort. Rand und Zeichen sind fuer den
 * Blick aus dem Augenwinkel, das Wort bleibt die Auskunft (Guide §17).
 * Das Zeichen steht vor dem Titel, damit die Titel untereinander stehen
 * und die Marken auch.
 */
.cockpit {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.cockpitzeile {
  display: grid;
  grid-template-columns: 22px 104px 140px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  background: var(--glass);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px 13px;
  font-weight: 500;
}

/* Der Rand und das Zeichen einer Zeile — und des Bauen-Blocks — in ihrer Stufe. */
svg.zeilenzeichen {
  width: 22px;
  height: 22px;
  color: var(--text-faint);
  --z-ton: currentColor;
}

.cockpitzeile[data-stufe='ok'],
.bauen[data-stufe='ok'] {
  border-left-color: var(--ok);
}

.cockpitzeile[data-stufe='warn'],
.bauen[data-stufe='warn'] {
  border-left-color: var(--warn);
}

.cockpitzeile[data-stufe='bad'],
.bauen[data-stufe='bad'] {
  border-left-color: var(--bad);
  background: color-mix(in srgb, var(--bad) 6%, var(--glass));
}

[data-stufe='ok'] svg.zeilenzeichen {
  color: var(--ok);
}

[data-stufe='warn'] svg.zeilenzeichen {
  color: var(--warn);
}

[data-stufe='bad'] svg.zeilenzeichen {
  color: var(--bad);
}

.cockpitzeile .pill {
  justify-self: start;
}

.cockpittitel {
  font-weight: 600;
}

.cockpittext {
  color: var(--text-dim);
  font-size: 12.5px;
  min-width: 0;
  overflow-wrap: anywhere;
}

/*
 * Der Bauen-Block steht in denselben Spalten wie die Zeilen darunter —
 * Zeichen, Titel, Marke, Satz —, dazu der Knopf am Ende. So liest er
 * sich als siebte Zeile, die man anfassen kann, nicht als fremder
 * Kasten. Den Rand in der Farbe der Stufe traegt er auch (N132).
 */
.bauen {
  margin-bottom: 8px;
  font-size: 13px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-left: 4px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px 13px;
}

.bauen-kopf {
  display: grid;
  grid-template-columns: 22px 104px 140px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
}

.bauen-kopf .pill {
  justify-self: start;
}

.bauen-knoepfe {
  display: flex;
  align-items: center;
  gap: 8px;
}

.bauen-protokoll {
  margin-top: 10px;
}

.bauen-protokoll > summary {
  cursor: pointer;
  color: var(--text-dim);
  font-size: 12.5px;
  margin-bottom: 8px;
}

/*
 * „Wandern" (B60 Stufe 2): die Zeile wie „Auslieferung", darunter beim
 * Klick das Formular — eingerueckt auf die Spalte des Satzes (22 + 104 +
 * 140 und drei Luecken zu 12), damit Liste und Code als Teil der Zeile
 * lesen und nicht als neuer Kasten.
 */
.wandern-form {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 10px 0 0 302px;
}

.wandern-satz {
  margin: 0;
  color: var(--text-dim);
  font-size: 12.5px;
}

/* Nach zehn Zeilen rollt die Liste; es koennen zwanzig sein. */
.wandern-liste {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 16em;
  overflow-y: auto;
  font-size: 12.5px;
  line-height: 1.6;
}

.wandern-liste li {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.wandern-liste code {
  font-family: var(--mono);
}

.wandern-eingabe {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.wandern-eingabe label {
  color: var(--text-dim);
  font-size: 12.5px;
}

input#wandern-code {
  width: 8rem;
  font-family: var(--mono);
  letter-spacing: 0.12em;
}

.wandern-form .error {
  margin: 0;
}

/*
 * Die offenen Rueckmeldungen unter „Menschen" (N128, W15). Eingerueckt
 * auf die Spalte des Satzes — der Rand von 4, der Innenrand von 13,
 * 22 + 104 + 140 und drei Luecken zu 12 (N132) —, damit sie sich als
 * Unterzeilen lesen und nicht als achte Frage.
 */
.cockpit-meldungen {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  margin: -2px 0 2px 319px;
}

.cockpit-meldung {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
}

.cockpit-meldung.laedt {
  opacity: 0.5;
}

.cockpit-meldungstext {
  min-width: 0;
  padding: 2px 0;
  border: 0;
  background: none;
  color: var(--text-dim);
  font-size: 12.5px;
  font-weight: 400;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cockpit-meldungstext:hover:not(:disabled) {
  background: none;
  color: var(--text);
  text-decoration: underline;
  transform: none;
}

.cockpit-meldungen > button.tiny {
  align-self: flex-start;
}

@media (max-width: 640px) {
  /*
   * Zeichen, Titel und Ampel in einer Zeile, der Satz darunter ueber die
   * ganze Breite (C2). Mit einer Spalte stand jedes untereinander, und
   * sechs Zeilen waren zusammen 650 px hoch.
   */
  .cockpitzeile {
    grid-template-columns: auto auto minmax(0, 1fr);
    gap: 4px 10px;
  }

  .cockpitzeile .cockpittext {
    grid-column: 1 / -1;
  }

  .cockpit-meldungen {
    margin-left: 0;
  }

  /*
   * Schmal: Art und Knoepfe in eine Zeile, der Satz darunter ueber die
   * ganze Breite. Neben zwei Knoepfen blieben ihm sonst siebzig Pixel.
   */
  .cockpit-meldung {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas:
      'art . knoepfe'
      'text text text';
    row-gap: 4px;
  }

  .cockpit-meldung .art {
    grid-area: art;
    justify-self: start;
  }

  .cockpit-meldung .gleich {
    grid-area: knoepfe;
  }

  .cockpit-meldungstext {
    grid-area: text;
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
  }

  .meldungszeile {
    flex-wrap: wrap;
  }

  .meldungszeile .gleich {
    width: 100%;
    justify-content: flex-end;
  }

  .gleich button {
    min-height: 36px;
  }

  .bauen-kopf {
    grid-template-columns: auto auto minmax(0, 1fr);
    gap: 6px 10px;
  }

  .bauen-kopf .cockpittext,
  .bauen-knoepfe {
    grid-column: 1 / -1;
  }

  .bauen-kopf button {
    min-height: 40px;
  }

  .wandern-form {
    margin-left: 0;
  }

  .wandern-eingabe label {
    flex-basis: 100%;
  }

  input#wandern-code {
    flex: 1 1 8rem;
    min-height: 40px;
  }

  .wandern-eingabe button {
    min-height: 40px;
  }
}

/* ---------- Erklaerungen und Aufklapper (G1, N128) ---------- */

/*
 * Der Erklaerbaustein (G1) — seit N132 mit dem Zeichen `hinweis` statt
 * des ⓘ aus der Schrift, die Flaeche in der Hinweisfarbe.
 *
 * Christian (N128): Erklaertexte werden nicht gestrichen und nicht bloss
 * zum title — am Telefon gibt es kein Hover. Sie ruecken hinter einen
 * Aufklapper. Das Zeichen sitzt oben rechts in der Karte, auf Hoehe der
 * Ueberschrift; aufgeklappt steht der Text darunter, eingerueckt an
 * einer Linie wie die Vorschau der Zweige. Zugeklappt nimmt der Baustein
 * keinen Platz ein ausser dem Abstand, den vorher der Absatz hielt.
 *
 * Gebraucht wird er so, in jedem Abschnitt direkt unter dem h2:
 *   <details class="erklaerung">
 *     <summary aria-label="Erklärung" title="Erklärung">
 *       <svg class="z" aria-hidden="true"><use href="#z-hinweis"></use></svg>
 *     </summary>
 *     <div class="erklaerung-text">…</div>
 *   </details>
 * Ein <details> ist von Haus aus mit Tab, Eingabe und Leertaste
 * bedienbar; dafuer braucht es kein Skript.
 */
details.erklaerung {
  margin: 0 0 12px;
}

details.erklaerung > summary {
  position: absolute;
  top: 13px;
  right: 13px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid transparent;
  border-radius: 50%;
  background: transparent;
  color: var(--text-dim);
  line-height: 1;
  cursor: pointer;
  list-style: none;
  user-select: none;
}

details.erklaerung > summary > svg.z {
  width: 22px;
  height: 22px;
  --z-ton: var(--info);
}

/* Der Finger trifft 40 × 40, auch wenn der Kreis kleiner ist (§16.1). */
details.erklaerung > summary::after {
  content: '';
  position: absolute;
  inset: -6px;
}

details.erklaerung > summary::-webkit-details-marker {
  display: none;
}

details.erklaerung > summary:hover {
  color: var(--text);
  background: var(--glass-hover);
}

details.erklaerung > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

details.erklaerung[open] > summary {
  color: var(--accent);
  background: var(--glass);
}

.card:has(> details.erklaerung) > h2 {
  padding-right: 40px;
}

.erklaerung-text {
  margin-top: 8px;
  padding-left: 11px;
  border-left: 2px solid var(--line);
  color: var(--text-dim);
  font-size: 12.5px;
}

.erklaerung-text p {
  margin: 0 0 8px;
}

.erklaerung-text p:last-child,
.erklaerung-liste p:last-child {
  margin-bottom: 0;
}

.erklaerung-liste {
  margin-top: 8px;
}

.erklaerung-liste:empty {
  display: none;
}

/*
 * Die Aufklapper fuer Seltenes (B1, B2, B4, B5, B7, D1).
 *
 * Eine Zeile mit Dreieck, abgesetzt durch eine Linie wie die Formulare
 * vorher. Der Satz im summary sagt, was darin liegt — und bei dem, was
 * sich nicht rueckgaengig machen laesst, dass es sich nicht rueckgaengig
 * machen laesst: „unwiderruflich" steht schon zugeklappt da.
 */
details.werkzeug,
details.ruhig,
details.autostart {
  margin-top: 14px;
  padding-top: 11px;
  border-top: 1px solid var(--line);
}

details.werkzeug > summary,
details.ruhig > summary,
details.autostart > summary,
details.envalle > summary {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 8px;
  min-height: 28px;
  color: var(--text-dim);
  font-size: 12.5px;
  cursor: pointer;
  list-style: none;
}

details.werkzeug > summary::-webkit-details-marker,
details.ruhig > summary::-webkit-details-marker,
details.autostart > summary::-webkit-details-marker,
details.envalle > summary::-webkit-details-marker {
  display: none;
}

/*
 * Der Winkel vorn ist das Zeichen `weiter` (N132), nicht mehr `▸` aus
 * der Schrift; er steht als erstes Kind im summary (class „z auf") und
 * dreht sich beim Aufklappen nach unten.
 */
summary > svg.z.auf {
  width: 12px;
  height: 12px;
  color: var(--text-faint);
  stroke-width: 1.5px;
  --z-ton: currentColor;
  transition: transform 0.14s ease;
}

details[open] > summary > svg.z.auf {
  transform: rotate(90deg);
}

details.werkzeug > summary:hover,
details.ruhig > summary:hover,
details.autostart > summary:hover,
details.envalle > summary:hover {
  color: var(--text);
}

details.werkzeug > summary:focus-visible,
details.ruhig > summary:focus-visible,
details.autostart > summary:focus-visible,
details.envalle > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (pointer: coarse) {
  details.werkzeug > summary,
  details.ruhig > summary,
  details.autostart > summary,
  details.envalle > summary {
    min-height: 40px;
  }
}

.card details.werkzeug > .hint {
  margin: 9px 0 0;
}

details.werkzeug > .actions {
  margin-top: 11px;
}

.warnwort {
  color: var(--bad);
  font-weight: 600;
}

.warnwort > svg.z {
  margin-right: 4px;
  --z-ton: currentColor;
}

/* Gewaehrte Bereiche: der Haken, abgeschaltet das Warnzeichen (N132). */
#accounts button.tiny > svg.z {
  margin-right: 4px;
  --z-ton: currentColor;
}

/* Die gesunden Zeitgeber beginnen ohne eigene Trennlinie zur Summenzeile. */
details.ruhig > div > .unit:first-child {
  border-top: 0;
}

details.autostart > summary strong {
  color: var(--text);
}

details.autostart .aendern {
  margin-left: auto;
}

details.autostart > .wahlreihe {
  margin-top: 10px;
}

/*
 * Weiterschalten in zwei Zeilen (B2): Auswahl — Vorschau — Name und
 * Knopf. Die zweite Zeile gehoert zur ersten und traegt deshalb keine
 * eigene Trennlinie.
 */
.uebertragung.folgt {
  margin-top: 9px;
  padding-top: 0;
  border-top: 0;
}

/* Die Marke „n Commits offen" als Knopf zum Formular (B2). */
button.kennzeichenknopf {
  font-weight: 600;
  cursor: pointer;
}

button.kennzeichenknopf:hover:not(:disabled) {
  background: var(--glass-hover);
  transform: none;
}

/* Umgebungsdateien: Kopf je Datei, die volle Liste zum Aufklappen (B6). */
.envkopf {
  margin: 10px 0 6px;
}

details.envalle {
  margin: 6px 0 10px;
}

details.envalle > table {
  margin-top: 6px;
}

/* Eine Zeile der Tabellenliste zeigt ihre Tabelle (D2). */
table.waehlbar tr + tr {
  cursor: pointer;
}

table.waehlbar tr + tr:hover td {
  background: var(--glass);
}

button.tabellenname {
  padding: 0;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 400;
  text-align: left;
}

button.tabellenname:hover:not(:disabled) {
  background: none;
  color: var(--accent);
  text-decoration: underline;
  transform: none;
}

button.tabellenname:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/*
 * Der Hinweis an einer gesperrten Unit (F48) — zugeklappt eine Zeile,
 * aufgeklappt der Satz aus `ManagedUnit.uebersprungen`, eingerueckt an
 * einer Linie wie der Erklaertext der Karten.
 */
details.unit-hinweis {
  margin-top: 4px;
  font-size: 12.5px;
}

details.unit-hinweis > summary {
  display: inline-block;
  min-height: 28px;
  padding: 4px 0;
  color: var(--text-faint);
  cursor: pointer;
}

details.unit-hinweis > summary:hover {
  color: var(--text);
}

details.unit-hinweis > summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.unit-hinweis-text {
  margin-top: 4px;
  padding-left: 11px;
  border-left: 2px solid var(--line);
  color: var(--text-dim);
}

/*
 * Unter dem Finger 40 × 40 (Guide §16.1) — am laufenden Panel gemessen
 * (V06, 27.09.2026). Die kleinen Knoepfe standen am Telefon bei 36 px:
 * uebernehmen, ablehnen, „Weitere N anzeigen", jetzt sichern, pull. 36
 * war die Zahl aus MISSED 4, vor §16.1; die Regel oben bleibt fuer ein
 * schmales Fenster mit Maus. Die Auswahlknoepfe (Verwalter, beta → prod,
 * die Datenbanken) waren 34 hoch, ein Reiter mit nur dem Zeichen 36
 * breit, der Aufklapper am Dienst 28 hoch, das Auge zum Aufdecken an
 * Zeile und Spalte einer Tabelle 20 × 14. Die Breite der Reiter regelt
 * ihr eigener Block bei der Leiste.
 *
 * Der Block steht mit Absicht am Ende: `.gleich button` in der
 * Telefonregel hat dieselbe Spezifitaet wie `button.tiny` und gewaenne
 * sonst mit seinen 36 px. Die Kopfknoepfe regelt ihre schwerere Regel
 * weiter oben; sie bleiben 40 × 40.
 */
@media (pointer: coarse) {
  button.tiny,
  button.kennzeichenknopf,
  .gleich button,
  .auswahl-knopf {
    min-height: 40px;
  }

  button.tiny {
    min-width: 40px;
  }

  details.unit-hinweis > summary {
    min-height: 40px;
  }

  .reveal {
    min-width: 40px;
    min-height: 40px;
  }
}
