/* Spec: docs/vorhaben/2026-09-02-sichtfeinschliff/spec-ENTWURF.md (T4: .zeitraum
   getrennt vom Startknopf, .tacho-kasten.aussen fuer den Isolations-Tacho,
   groessere Grenzmarken, Typmarke im Geraeteseiten-Titel)
   Spec: docs/vorhaben/2026-09-01-gefuehrte-pruefung/spec-ENTWURF.md (pf-Schritte)
   Spec: docs/vorhaben/2026-09-01-startfluss/spec-ENTWURF.md (wz-Zeile, wz-kurz,
         wz-details, eingeklappter Rumpf)
   Spec: docs/vorhaben/2026-09-01-vorlagen-wizard/spec-ENTWURF.md (wz-Karten)
   Spec: docs/vorhaben/2026-09-01-menueklarheit/spec-ENTWURF.md (Unterzeile)
   Spec: docs/vorhaben/2026-08-21-stack-mvp/spec.md
 * Spec: docs/vorhaben/2026-08-22-nachweis/spec.md (gr-nachweis: Senden-Feld
 * mit Sperr- und Bindungshinweis im Schwellendialog)
 * Spec: docs/vorhaben/2026-09-01-prozeduren/spec-ENTWURF.md (pz-*: die
 * Checkliste wie in der App, und .neben fuer table.auftraege)
 *
 * Dunkel als Vorgabe, hell wenn das System es sagt. Die Kreisfarben sind
 * bewusst NICHT rot/gruen kodiert: rot heisst in dieser Oberflaeche Alarm,
 * und ein Stromkreis ist kein Alarm.
 */
:root {
  --bg:#0d0f14; --karte:#151821; --karte2:#1b1f2a; --linie:#252a37;
  --text:#e8eaf0; --gedaempft:#8f97ab; --leise:#5d6579;
  --akzent:#4ea1ff; --gut:#3ecf8e; --warn:#e5b13a; --alarm:#f2545b;
  --k1:#4ea1ff; --k2:#c58bff; --k3:#3ecf8e; --k4:#f0a35e;
  --band:.16;
}
@media (prefers-color-scheme: light) {
  :root { --bg:#f4f6f9; --karte:#fff; --karte2:#f0f2f6; --linie:#dfe3ea;
          --text:#141821; --gedaempft:#5a6377; --leise:#8b93a5; --band:.13; }
}
* { box-sizing:border-box }
html,body { height:100% }
body { margin:0; background:var(--bg); color:var(--text);
  font:14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,sans-serif;
  -webkit-font-smoothing:antialiased }
a { color:var(--akzent); text-decoration:none }
a:hover { text-decoration:underline }
button, input, select { font:inherit; color:inherit }
.laden { padding:40px; color:var(--gedaempft) }
.mono { font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace }
.tab { font-variant-numeric:tabular-nums }

/* ---------------------------------------------------------------- Kopf */
header { display:flex; align-items:center; gap:14px; padding:10px 18px;
  border-bottom:1px solid var(--linie); background:var(--karte); position:sticky; top:0; z-index:20 }
header .marke { font-weight:650; letter-spacing:-.01em; white-space:nowrap }
header .marke span { color:var(--akzent) }
header nav { display:flex; gap:4px; margin-left:8px }
header nav a { padding:5px 10px; border-radius:6px; color:var(--gedaempft) }
header nav a.aktiv { background:var(--karte2); color:var(--text) }
header .rechts { margin-left:auto; display:flex; align-items:center; gap:12px;
  color:var(--gedaempft); font-size:13px }
.knopf { background:var(--karte2); border:1px solid var(--linie); color:var(--text);
  padding:6px 12px; border-radius:6px; cursor:pointer }
/* Unterzeile der Navigation (menueklarheit#D1): erscheint nur, wenn die
   aktive Gruppe mehr als ein Mitglied hat. Gleiche Linksprache wie oben,
   eine Stufe leiser; nicht sticky -- wie die Verwaltungs-Reiter. */
.unterzeile { display:flex; gap:4px; padding:6px 18px; background:var(--karte);
  border-bottom:1px solid var(--linie) }
.unterzeile a { padding:4px 10px; border-radius:6px; color:var(--gedaempft);
  font-size:13px }
.unterzeile a.aktiv { background:var(--karte2); color:var(--text) }
.knopf:hover { border-color:var(--akzent) }
.knopf.haupt { background:var(--akzent); border-color:var(--akzent); color:#04121f; font-weight:600 }
.knopf:disabled { opacity:.5; cursor:default }

/* ---------------------------------------------------------------- Anmeldung */
/* Spalte, nicht Raster.
   `place-items:center` auf einem Grid mit ZWEI Kindern legt jedes in eine
   eigene Zeile und zentriert beide einzeln -- der Sprachumschalter schwebte
   dadurch losgeloest ueber der Karte, und die Karte rutschte nach unten. Als
   Flex-Spalte gehoeren sie zusammen. */
.anmeldung { min-height:100vh; display:flex; flex-direction:column;
  align-items:center; justify-content:center; gap:14px; padding:20px }
.anmeldung form { width:100%; max-width:380px; background:var(--karte);
  border:1px solid var(--linie); border-radius:12px; padding:26px }
.anmeldung h1 { font-size:19px; margin:0 0 4px }
.anmeldung p.sub { color:var(--gedaempft); margin:0 0 20px; font-size:13px }
/* sichtfeinschliff T1: Tipp unter dem Feld, Hilfezeile unter dem Knopf,
   Hinweis ueber der Werkzeugzeile (unbekannte Route) -- ohne Inline-Stile. */
.anmeldung p.sub.feldtipp { margin:5px 0 0 }
.anmeldung form > p.sub.hilfezeile { margin:14px 0 0; text-align:center }
main > p.meldung { margin:0 0 12px; color:var(--gedaempft); font-size:13px }
.feld { margin-bottom:14px }
.feld label { display:block; font-size:12px; color:var(--gedaempft); margin-bottom:5px }
.feld input { width:100%; padding:9px 11px; background:var(--bg);
  border:1px solid var(--linie); border-radius:7px }
.feld input:focus { outline:none; border-color:var(--akzent) }
.fehler { background:color-mix(in srgb, var(--alarm) 12%, transparent);
  border:1px solid var(--alarm); color:var(--alarm); padding:9px 11px;
  border-radius:7px; margin-bottom:14px; font-size:13px }

/* ---------------------------------------------------------------- Liste */
main { padding:18px }
.werkzeug { display:flex; gap:10px; align-items:center; flex-wrap:wrap; margin-bottom:14px }
.werkzeug input[type=search] { flex:1; min-width:200px; padding:8px 12px;
  background:var(--karte); border:1px solid var(--linie); border-radius:7px }
.pillen { display:flex; gap:6px; align-items:center }
/* Gruppentitel vor jeder Chip-Gruppe (Zustand:/Typ:) und ein Trenner zwischen
   den beiden: sonst stehen zwei aktive 'Alle' unbeschriftet nebeneinander. */
.pillentitel { color:var(--leise); font-size:13px; white-space:nowrap }
.werkzeug .pillen + .pillen { border-left:1px solid var(--linie); padding-left:12px }
.pille { padding:6px 12px; border-radius:20px; border:1px solid var(--linie);
  background:var(--karte); color:var(--gedaempft); cursor:pointer; font-size:13px }
.pille.aktiv { background:var(--akzent); border-color:var(--akzent); color:#04121f; font-weight:600 }
.pille b { font-variant-numeric:tabular-nums }

table { width:100%; border-collapse:collapse; background:var(--karte);
  border:1px solid var(--linie); border-radius:10px; overflow:hidden }
th { text-align:left; font-size:12px; font-weight:600; color:var(--gedaempft);
  padding:9px 12px; border-bottom:1px solid var(--linie); cursor:pointer; white-space:nowrap }
th:hover { color:var(--text) }
th .pfeil { color:var(--akzent) }
td { padding:9px 12px; border-bottom:1px solid var(--linie) }
tbody tr:last-child td { border-bottom:none }
tbody tr:hover { background:var(--karte2) }
td.serial a { font-family:ui-monospace,Menlo,monospace; font-weight:600 }
.punkt { display:inline-block; width:8px; height:8px; border-radius:50%; margin-right:7px;
  vertical-align:baseline }
.z-aktiv .punkt { background:var(--gut) }
.z-still .punkt { background:var(--warn) }
.z-nie   .punkt { background:var(--leise) }
.z-aktiv { color:var(--gut) } .z-still { color:var(--warn) } .z-nie { color:var(--leise) }
.blaettern { display:flex; gap:10px; align-items:center; justify-content:center;
  margin-top:14px; color:var(--gedaempft); font-size:13px }
.leer { padding:44px; text-align:center; color:var(--gedaempft) }

/* ---------------------------------------------------------------- Geraet */
.kopf { display:flex; align-items:flex-start; gap:16px; flex-wrap:wrap; margin-bottom:16px }
.kopf h1 { font-size:20px; margin:0; font-family:ui-monospace,Menlo,monospace }
.kopf .meta { color:var(--gedaempft); font-size:13px; margin-top:3px }
.kopf .rechts { margin-left:auto; display:flex; gap:8px; align-items:center }
/* Die Typmarke im Titel in der Textschrift, nicht in der Festbreite der
   Seriennummer: sie ist ein Wort, keine Adresse. */
.kopf h1 .typmarke { font-family:system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:11.5px; font-weight:600 }
select.zeit { padding:7px 10px; background:var(--karte); border:1px solid var(--linie);
  border-radius:7px }
/* Zeitraumwahl: beschriftet und durch Abstand plus Trennlinie vom Startknopf
   abgesetzt -- daneben las sich "15 Minuten" als Pruefdauer. */
.kopf .zeitraum { display:flex; align-items:center; gap:7px; margin-left:12px;
  padding-left:16px; border-left:1px solid var(--linie) }
.kopf .zeitraum-text { font-size:12px; color:var(--gedaempft); white-space:nowrap }

/* Kacheln nach Stromkreis. Vier Karten mit je sechs Zeilen statt
   vierundzwanzig Einzelkacheln, die quer ueber die Zeilen laufen. */
.kacheln { display:grid; gap:12px; margin-bottom:18px;
  grid-template-columns:repeat(auto-fit,minmax(366px,1fr)) }
/* Jede Kreiskarte traegt die Farbe ihres Stromkreises -- dieselbe wie die
   Kurve unten und die Legende. Sehr leicht: 5 Prozent Beimischung auf der
   Flaeche, 30 auf dem Rand, und ein kraeftiger Streifen links als eigentliche
   Kennung. Satter waere sie ein Wettbewerber der Alarmfarben, und rot heisst
   hier Alarm. */
.kreis { background:color-mix(in srgb, var(--kreisfarbe, transparent) 5%, var(--karte));
  border:1px solid color-mix(in srgb, var(--kreisfarbe, transparent) 30%, var(--linie));
  border-left:3px solid var(--kreisfarbe, var(--linie));
  border-radius:10px;
  padding:12px 14px }
.kreis h2 { font-size:12px; margin:0 0 8px; color:var(--kreisfarbe, var(--gedaempft));
  text-transform:uppercase; letter-spacing:.06em; font-weight:600 }
/* Im Cockpit steht die Messstelle in der MITTE eines Tachos: Wert gross,
   Einheit und Bezeichner klein darunter. Das Raster von frueher (Bezeichner
   links, Wert rechts) galt fuer eine Liste und passt hier nicht mehr. */
.groesse { display:flex; flex-direction:column; align-items:center; gap:0;
  line-height:1.15 }
/* KEIN text-transform und Festbreitenschrift: die Messgroesse heisst i_diff,
   nicht I_DIFF. Die kanonische Schreibweise ist bindend (R9), und eine
   Anzeige, die den Bezeichner anders schreibt als Code, Register und Doku,
   ist genau die Abweichung, nach der spaeter jemand vergeblich sucht. */
.g-key { font-size:9px; color:var(--leise); letter-spacing:.02em;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace }
/* Zahl und Einheit auf EINER Zeile, damit die neue Namenszeile die Kachel
   nicht hoeher macht. */
.g-zahl { display:flex; align-items:baseline; gap:3px; justify-content:center }
.g-wert { font-size:16px; font-variant-numeric:tabular-nums; letter-spacing:-.02em }
.g-einheit { font-size:10px; color:var(--gedaempft) }
/* Der lesbare Name traegt die BEDEUTUNG und steht darum ueber dem Schluessel.
   Der Schluessel bleibt sichtbar -- er ist die Adresse fuer Suche, Beleg und
   Registerabgleich (R9), und eine Anzeige, die ihn verschweigt, zwingt jeden
   Beleg zu einer Uebersetzungstabelle. */
.g-name { font-size:10px; color:var(--text); line-height:1.1; text-align:center;
  max-width:88px }
.g-alt { font-size:10px; color:var(--warn) }
.groesse.fehlt .g-wert { color:var(--leise) }

/* ------------------------------------------------------------------ Tacho */
.tacho-kasten { position:relative; width:100%; max-width:132px; margin:0 auto }
svg.tacho { display:block; width:100%; height:auto; overflow:visible }
.tk-spur   { stroke:var(--karte2) }
.tk-fuell  { stroke:var(--akzent); opacity:.9 }
.tk-zone   { stroke-linecap:butt; opacity:.75 }
.tk-gut      { stroke:var(--gut) }
.tk-warn     { stroke:var(--warn) }
.tk-schlecht { stroke:var(--alarm) }
.tk-marke  { stroke:var(--gedaempft); stroke-width:1.4; opacity:.85 }
.tk-marke-text, .tk-ende { fill:var(--leise); font-size:7.5px;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace }
.tk-ende { fill:var(--gedaempft) }
.tk-nadel  { stroke:var(--text); stroke-width:2.2; stroke-linecap:round }
/* Die Mitte liegt IM Bogen. Sie traegt die data-Anker der Abnahme, deshalb
   darf sie nie durch pointer-events verdeckt werden. */
.tacho-mitte { position:absolute; left:0; right:0; top:52%;
  transform:translateY(-50%); display:flex; justify-content:center;
  pointer-events:none }
/* aussen: die Mitte liegt NICHT im Bogen, sondern darunter (Kreiskarte) bzw.
   daneben (Kopfkachel). Fuer den Isolationswiderstand: die siebenstellige
   Zahl lag auf dem Ring, "kOhm" war winzig, der Zeiger darunter unsichtbar.
   Die Einheit wird lesbar gross, die data-Anker bleiben in .tacho-mitte. */
.tacho-kasten.aussen { display:flex; flex-direction:column; align-items:center;
  max-width:none }
.tacho-kasten.aussen svg.tacho { width:96px; flex:none }
.tacho-kasten.aussen .tacho-mitte { position:static; transform:none; margin-top:-6px }
.tacho-kasten.aussen .g-einheit, .tacho-kasten.aussen .gk-einheit { font-size:12px;
  color:var(--text) }
.tacho-kasten.aussen .g-name { max-width:none }
.gk .tacho-kasten.aussen { flex-direction:row; flex-wrap:wrap; justify-content:center;
  gap:2px 10px }
.gk .tacho-kasten.aussen svg.tacho { width:112px }
.gk .tacho-kasten.aussen .tacho-mitte { margin-top:0 }

/* ------------------------------------------------- Kopfkacheln (Gesamtwerte) */
.gesamt { display:grid; gap:10px; margin-bottom:16px;
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr)) }
.gk { background:var(--karte); border:1px solid var(--linie); border-radius:10px;
  padding:10px 10px 8px; display:flex; flex-direction:column; align-items:center }
.gk-kopf { font-size:11px; color:var(--gedaempft); text-transform:uppercase;
  letter-spacing:.06em; font-weight:600; display:flex; gap:5px; align-items:center;
  align-self:flex-start }
/* Der Operator steht SICHTBAR an der Kachel. Eine Kachel, auf der nur eine
   Zahl steht, laesst offen, ob sie addiert, gemittelt oder ausgewaehlt hat --
   und auf einem Beweismittel ist das der teuerste offene Punkt. */
.gk-op { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px;
  color:var(--akzent); font-weight:700 }
.gk-wert { display:flex; align-items:baseline; gap:3px; justify-content:center }
.gk-wert .tab { font-size:19px; font-variant-numeric:tabular-nums; letter-spacing:-.03em }
.gk-einheit { font-size:10px; color:var(--gedaempft) }
.gk-fuss { font-size:11px; color:var(--leise); margin-top:4px; text-align:center }
.gk-takt { justify-content:space-between }
.takt-block { display:flex; flex-direction:column; align-items:center;
  justify-content:center; flex:1; padding:14px 0 4px }
.takt-seit { font-size:12px; color:var(--gedaempft); margin-top:5px;
  font-variant-numeric:tabular-nums }
.takt-seit.spaet { color:var(--warn); font-weight:600 }

/* ------------------------------------------------------ Kreis-Cockpit */
.betrieb { display:grid; grid-template-columns:repeat(3,1fr); gap:4px;
  margin-bottom:10px }
.schutz { border-top:1px solid var(--linie); padding-top:8px }
.s-titel { font-size:10px; color:var(--gedaempft); text-transform:uppercase;
  letter-spacing:.07em; font-weight:600; margin-bottom:4px;
  display:flex; gap:8px; align-items:baseline; flex-wrap:wrap }
.s-hinweis { text-transform:none; letter-spacing:0; font-weight:400;
  color:var(--leise); font-size:10px }
.s-tachos { display:grid; grid-template-columns:1fr 140px 1fr; gap:6px;
  align-items:start }
.s-tachos > .tacho-kasten, .s-tachos .iso .tacho-kasten { max-width:96px }
.s-tachos .iso .tacho-kasten.aussen { max-width:none; width:100% }
.iso { display:flex; flex-direction:column; align-items:center }
.iso-neben { display:flex; flex-direction:column; align-items:center; margin-top:-2px }
.iso-neben .groesse.fein .g-wert { font-size:12px }
.iso-hinweis { font-size:9.5px; color:var(--leise); margin-top:1px;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace }

.graphen { display:grid; gap:14px; grid-template-columns:repeat(auto-fit,minmax(440px,1fr)) }
.graph { background:var(--karte); border:1px solid var(--linie); border-radius:10px; padding:13px }
.graph h3 { font-size:13px; margin:0 0 2px; display:flex; align-items:baseline; gap:8px }
.graph h3 .einheit { color:var(--gedaempft); font-weight:400; font-size:12px }
.graph .hinweis { font-size:11px; color:var(--leise); margin:0 0 9px }
.graph svg { display:block; width:100%; height:190px; overflow:visible }
.graph .legende { display:flex; gap:12px; flex-wrap:wrap; margin-top:8px; font-size:12px }
.graph .legende span { display:flex; align-items:center; gap:5px; color:var(--gedaempft); cursor:pointer }
.graph .legende span.aus { opacity:.35 }
.graph .legende i { width:11px; height:3px; border-radius:2px; display:inline-block }
.achse { fill:var(--leise); font-size:10px }
.gitter { stroke:var(--linie); stroke-width:1 }
.fuss { margin-top:16px; padding-top:12px; border-top:1px solid var(--linie);
  color:var(--leise); font-size:12px; line-height:1.7 }
.lupe { position:fixed; pointer-events:none; background:var(--karte2);
  border:1px solid var(--linie); border-radius:7px; padding:7px 9px; font-size:12px;
  z-index:50; box-shadow:0 6px 20px rgba(0,0,0,.35); white-space:nowrap }
.lupe .zeile { display:flex; gap:8px; align-items:center; justify-content:space-between }
.lupe .zeit { color:var(--gedaempft); margin-bottom:4px }

/* ---------------------------------------------------------------- Alarme
 * Farbe kodiert Schwere, aber NIE allein: jede Stelle traegt zusaetzlich ein
 * Zeichen oder Text. Rot-gruen-Sehschwaeche ist haeufig, und ein Bildschirm,
 * der Gefahr nur ueber Farbe meldet, meldet sie manchen Leuten gar nicht.
 * "!!" steht fuer unquittiert, "!" fuer quittiert-aber-offen -- quittieren
 * macht still, es schliesst nicht. */
.groesse.alarm-alarm { background:color-mix(in srgb, var(--alarm) 10%, transparent) }
.groesse.alarm-warn  { background:color-mix(in srgb, var(--warn) 10%, transparent) }
.groesse.alarm-info  { background:color-mix(in srgb, var(--akzent) 8%, transparent) }
.groesse.alarm-alarm .g-wert { color:var(--alarm); font-weight:600 }
.groesse.alarm-warn  .g-wert { color:var(--warn) }
.g-marke { color:var(--alarm); font-weight:700; font-size:12px; cursor:help }
.groesse.alarm-warn .g-marke { color:var(--warn) }
.groesse.alarm-info .g-marke { color:var(--akzent) }

/* Ein Alarm sticht die Kreisfarbe: er ist die wichtigere Aussage, und zwei
   konkurrierende Randfarben waeren keine. */
.kreis.hat-alarm { border-color:color-mix(in srgb, var(--alarm) 45%, var(--linie));
  border-left-color:var(--alarm) }
.h-alarm { float:right; color:var(--alarm); font-weight:600; letter-spacing:0 }
.kopf-alarm { display:inline-block; margin-left:10px; padding:1px 7px;
  border-radius:11px; font-size:12px;
  background:color-mix(in srgb, var(--alarm) 16%, transparent); color:var(--alarm) }
.kopf-alarm.warn { background:color-mix(in srgb, var(--warn) 16%, transparent); color:var(--warn) }
.kopf-alarm.info { background:color-mix(in srgb, var(--akzent) 14%, transparent); color:var(--akzent) }

td.a-keine { color:var(--leise) }
td.a-alarm { color:var(--alarm) } td.a-alarm .punkt { background:var(--alarm) }
td.a-warn  { color:var(--warn) }  td.a-warn  .punkt { background:var(--warn) }
td.a-info  { color:var(--akzent) } td.a-info .punkt { background:var(--akzent) }

/* Eine KONFIGURIERTE Schwelle ist die einzige Marke, die dieses System selbst
   verantwortet. Sie sieht deshalb anders aus als die uebernommenen Marken --
   sonst stuenden Zahlen aus config.json und Zahlen aus alarm.schwelle
   gleichrangig nebeneinander, und niemand koennte sie auf einem
   Bildschirmfoto noch auseinanderhalten. */
.tk-marke-konf { stroke:var(--akzent); stroke-width:2 }
/* Die konfigurierte Grenze ist die wichtigste Beschriftung des Tachos: eine
   Stufe groesser als die uebernommenen Marken (Lesbarkeit, Bild 02). */
.tk-marke-text-konf { fill:var(--akzent); font-size:8.5px; font-weight:600 }

/* Aufteilung des Differenzstroms in Wirk- und Blindanteil.
   ABGELEITET, nicht gemessen -- deshalb eine eigene, ruhigere Darstellung
   ohne Tacho: ein Tacho stellt es neben die gemessenen Groessen und macht
   aus einer Rechnung einen Messwert. */
.aufteilung { font-size:11px; padding-top:2px }
.a-titel { font-size:9.5px; color:var(--leise); text-transform:uppercase;
  letter-spacing:.06em; text-align:center; margin-bottom:3px }
.a-balken { height:7px; border-radius:4px; background:var(--k2); overflow:hidden;
  margin-bottom:6px }
/* NEUTRALE Farben, kein gruen/rot. Der Wirkanteil ist nicht "gut" und der
   Blindanteil nicht "schlecht" -- eher umgekehrt, denn Wirkleistung im
   Isolationspfad ist echter Verlust, kapazitiver Blindstrom dagegen normal.
   Eine Ampelfarbe an dieser Stelle waere eine Bewertung, die niemand
   getroffen hat und die kein Grenzwert deckt. */
.a-balken i { display:block; height:100%; background:var(--akzent) }
.a-zeile { display:grid; grid-template-columns:1fr auto auto; gap:3px;
  align-items:baseline; padding:1px 0 }
.a-name { color:var(--gedaempft); font-size:10px }
.a-zeile b { font-weight:500; font-variant-numeric:tabular-nums; font-size:11px }
.a-zeile em { font-style:normal; color:var(--leise); font-size:9px; min-width:19px }
.a-zeile.wirk .a-name { color:var(--akzent) }
.a-zeile.blind .a-name { color:var(--k2) }
.a-trenner { border-top:1px solid var(--linie); margin:4px 0 3px }
.a-cos { text-align:left; margin-top:4px; color:var(--gedaempft); font-size:10px;
  font-variant-numeric:tabular-nums }
/* Der Vorbehalt steht SICHTBAR dran, nicht nur in der Kurzhilfe: ohne die
   Phase ist nur der Betrag der Blindleistung bekannt, nicht ihr Vorzeichen. */
.a-warn { text-align:left; margin-top:2px; color:var(--leise); font-size:8.5px;
  line-height:1.25 }
.a-leer { text-align:center; color:var(--leise); font-size:10px; padding:12px 0 }

/* ------------------------------------------------------------------- Bier
   Bier = Wirkleistung, Schaum = Blindleistung, volles Glas =
   Scheinleistung. Das Glas ist IMMER voll -- der Fuellstand traegt keine
   Aussage, nur die Grenze zwischen Bier und Schaum. */
/* Glas und Zahlen NEBENEINANDER. Das Glas bekommt eine feste Spalte, die
   Zahlen den Rest -- untereinander wuchs der Block auf die doppelte Hoehe
   der Tachos daneben. Kopfraum oben fuer die Schaumkrone, die ueber den
   Glasrand steht. */
/* Das Glas faehrt aus, es steht nicht dauernd da (Simon, 2026-08-22).
   Zusammengeklappt bekommt die Zahlenspalte die volle Breite; die Spalte
   selbst bleibt im Raster stehen, damit die Bewegung eine Breitenaenderung
   ist und kein Umbruch -- ein Umbruch wuerde die ganze Kachel springen
   lassen. */
.a-inhalt { display:grid; grid-template-columns:0 1fr; gap:0;
  align-items:center; transition:grid-template-columns .32s ease, gap .32s ease }
.a-inhalt.offen { grid-template-columns:50px 1fr; gap:7px }
.a-glas { display:flex; justify-content:center; padding-top:5px;
  overflow:hidden; opacity:0; transform:translateX(-6px) scale(.92);
  transition:opacity .28s ease .04s, transform .32s ease }
.a-inhalt.offen .a-glas { opacity:1; transform:none }
.a-zahlen { min-width:0 }

/* Wirk und Blind sind die Griffe. Sie tragen die Aussage, die das Glas
   bebildert -- also fasst man sie an, nicht ein Symbol daneben. */
.a-zeile.klappbar { cursor:pointer; border-radius:5px; margin-inline:-3px;
  padding-inline:3px; transition:background .15s ease }
.a-zeile.klappbar:hover, .a-zeile.klappbar:focus-visible {
  background:color-mix(in srgb, var(--akzent) 14%, transparent); outline:none }
/* Ein kleiner Hinweis, dass da etwas aufgeht -- erst beim Zeigen, sonst
   stuenden an jeder Kachel zwei Pfeile, die nichts ueber die Messung sagen. */
.a-zeile.klappbar::after { content:'▸'; font-size:9px; color:var(--akzent);
  opacity:0; transition:opacity .15s ease, transform .28s ease; margin-left:2px }
.a-zeile.klappbar:hover::after, .a-zeile.klappbar:focus-visible::after { opacity:.9 }
.a-inhalt.offen .a-zeile.klappbar::after { transform:rotate(90deg) }

@media (prefers-reduced-motion: reduce) {
  .a-inhalt, .a-glas, .a-zeile.klappbar, .a-zeile.klappbar::after { transition:none }
}
svg.bier { width:50px; height:auto; display:block; overflow:visible }
.bier-glas { fill:none; stroke:rgba(255,255,255,.42); stroke-width:1.1 }
.bier-rand { fill:none; stroke:rgba(255,255,255,.30); stroke-width:.9 }
/* Umrisstype wie die echte Wortmarke (logo.png ist ebenfalls ein Umriss). */
/* Das Etikett auf dem Glas. Es traegt seinen eigenen blauen Grund (#004b87
   aus der Logodatei), steht also auf Schaum wie auf Bier gleich gut -- das
   war bei der frueheren weissen Wortmarke nicht so, die verschwand im
   Schaum. Leichter Schatten, damit es aufliegt statt zu schweben. */
.bier-logo { filter:drop-shadow(0 .4px .6px rgba(0,0,0,.45)) }
.bier-logo.klingt { cursor:pointer }
.bier-logo.klingt:hover { filter:drop-shadow(0 .4px 1.4px rgba(0,0,0,.6))
  brightness(1.12) }
.bier-logo.klingt:active { transform:translateY(.4px) }
@media (prefers-color-scheme: light) {
  .bier-glas { stroke:rgba(20,24,33,.34) }
  .bier-rand { stroke:rgba(20,24,33,.24) }
}
.perle { animation:steigen 3.4s linear infinite }
@keyframes steigen {
  from { transform:translateY(6px); opacity:0 }
  18%  { opacity:.6 }
  to   { transform:translateY(-38px); opacity:0 }
}
/* Wer Bewegung abgestellt hat, bekommt keine -- die Perlen tragen ohnehin
   keine Information. */
@media (prefers-reduced-motion: reduce) { .perle { animation:none } }

/* ------------------------------------------------------------- Lichtorgel

   Drei Messwerte kommen als Variablen aus dem laufenden Ton:
     --puls    Bass  (86-345 Hz)  traegt Groesse und Halo
     --pegel   Mitten             traegt die Grundhelligkeit
     --hoehen  Hoehen             traegt das Flackern
   Vorgabe 0, damit ohne Musik nichts leuchtet und nichts zappelt.

   Sichtbar NUR bei :root.klang-laeuft. Die Anzeige ist ein Beweismittel --
   solange keine Musik laeuft, darf hier gar nichts blinken, und die Messwerte
   selbst werden von den Effekten NIE eingefaerbt oder ueberdeckt: das Licht
   liegt hinter dem Etikett im Glas, nicht ueber den Zahlen. */
:root { --puls:0; --pegel:0; --hoehen:0 }

.disko { opacity:0; transition:opacity .35s ease }
:root.klang-laeuft .disko { opacity:calc(.62 + var(--pegel) * .38) }

.disko { filter:hue-rotate(calc(var(--hoehen) * 220deg)) }

/* ZWEI Mischmodi, weil das Glas zwei sehr verschiedene Untergruende hat.

   Die Strahlen multiplizieren: auf dem fast weissen Schaum faerbt Multiplikation
   sichtbar ein, waehrend `screen` dort restlos verschwaende -- und bei diesen
   cos-φ-Werten ist der Schaum die Mehrheit des Glases. Auf dem Bier dunkelt sie
   zur Strahlenfarbe hin nach.

   Die Glut dagegen addiert (`screen`): sie soll hinter dem Etikett aufleuchten,
   nicht den Untergrund einfaerben.

   In beiden Faellen bleibt die Grenze zwischen Bier und Schaum als
   Helligkeitssprung erhalten -- der Fuellstand IST der Messwert und darf vom
   Licht nicht verschluckt werden. */
.strahlen { mix-blend-mode:multiply;
  animation:drehen 6s linear infinite;
  transform:scale(calc(.6 + var(--puls) * .9)); transform-origin:0 0 }
.strahlen polygon { fill:#4ea1ff; opacity:calc(.38 + var(--pegel) * .55) }
.strahlen .s1 { fill:#c58bff }
.strahlen .s2 { fill:#3ecf8e }
@keyframes drehen { to { transform:rotate(360deg) } }

.glut { mix-blend-mode:screen; fill:#ffffff;
  opacity:calc(.18 + var(--puls) * .62);
  transform:scale(calc(.45 + var(--puls) * 1.35)); transform-origin:0 0 }

/* Halo um das ganze Glas -- damit die Kachel mitatmet, ohne dass eine Zahl
   ihre Farbe aendert. */
:root.klang-laeuft svg.bier {
  filter:drop-shadow(0 0 calc(1px + var(--puls) * 7px)
                     rgba(78,161,255,calc(.25 + var(--puls) * .6))) }
:root.klang-laeuft .bier-logo.klingt {
  filter:drop-shadow(0 0 calc(.6px + var(--puls) * 2.4px) rgba(255,255,255,.9))
         brightness(calc(1 + var(--puls) * .35)) }

/* Wer Bewegung abgestellt hat, bekommt Licht ohne Drehung und ohne Sprung:
   die Helligkeit folgt weiter dem Ton, die Geometrie steht still. */
@media (prefers-reduced-motion: reduce) {
  .strahlen { animation:none; transform:none }
  .glut { transform:none }
}

/* ---------------------------------------------------------------- Grenzen */

/* Der Tacho IST die Schaltflaeche. Ein Bleistiftsymbol daneben waere auf
   96 Pixel Breite ein Ziel von acht Pixeln -- die Zahl in der Mitte ist neun
   Pixel hoch. Wer eine Grenze setzt, klickt dorthin, wo er den Wert liest. */
.tacho-kasten.setzbar { cursor:pointer; border-radius:10px;
  transition:background .15s ease, box-shadow .15s ease }
.tacho-kasten.setzbar:hover, .tacho-kasten.setzbar:focus-visible {
  background:color-mix(in srgb, var(--akzent) 12%, transparent);
  box-shadow:0 0 0 1px color-mix(in srgb, var(--akzent) 45%, transparent);
  outline:none }
/* Der Hinweis erscheint erst beim Zeigen: dauerhaft sichtbar stuende an jedem
   der vierundzwanzig Tachos ein Wort, das nichts ueber die Messung sagt. */
.tacho-kasten.setzbar::after { content:'Grenze'; position:absolute;
  left:0; right:0; bottom:-2px; text-align:center; font-size:9px;
  color:var(--akzent); opacity:0; transition:opacity .15s ease;
  pointer-events:none }
.tacho-kasten.setzbar:hover::after,
.tacho-kasten.setzbar:focus-visible::after { opacity:1 }

dialog.grenze { border:1px solid var(--linie); border-radius:14px;
  background:var(--karte); color:var(--text); padding:20px 22px 18px;
  width:min(94vw, 400px); box-shadow:0 18px 60px rgba(0,0,0,.5) }
dialog.grenze::backdrop { background:rgba(0,0,0,.55) }
dialog.grenze h2 { margin:0 0 2px; font-size:16px }
dialog.grenze h2 code { font-family:ui-monospace,SFMono-Regular,Menlo,monospace }
.gr-wo { margin:0 0 12px; color:var(--gedaempft); font-size:12px }
.gr-schliessen { position:absolute; top:10px; right:12px; margin:0 }
.gr-schliessen button { background:none; border:none; color:var(--gedaempft);
  font-size:20px; line-height:1; cursor:pointer; padding:2px 6px }

/* Die Lage: Istwert und Spanne stehen im Formular, damit niemand eine Zahl
   ins Blaue tippt. Das ist der eigentliche Grund, warum der Dialog am Tacho
   haengt und nicht auf einer Einstellungsseite. */
.gr-lage { display:grid; grid-template-columns:auto 1fr; gap:2px 12px;
  margin:0 0 14px; padding:9px 11px; background:var(--karte2);
  border-radius:8px; font-size:12px }
.gr-lage dt { color:var(--gedaempft) }
.gr-lage dd { margin:0; font-variant-numeric:tabular-nums }

.gr-art { display:flex; gap:0; margin-bottom:10px }
.gr-art button { flex:1; padding:6px 8px; font-size:12px; cursor:pointer;
  background:var(--karte2); color:var(--gedaempft);
  border:1px solid var(--linie); border-right-width:0 }
.gr-art button:first-child { border-radius:7px 0 0 7px }
.gr-art button:last-child { border-radius:0 7px 7px 0; border-right-width:1px }
.gr-art button.an { background:var(--akzent); color:#0b0e14; font-weight:600;
  border-color:var(--akzent) }

.gr-zeile { display:flex; align-items:center; gap:9px; margin-bottom:9px }
.gr-zeile[hidden] { display:none }
.gr-wort { width:88px; font-size:12px; color:var(--gedaempft) }
.gr-zahl { flex:1; min-width:0; padding:7px 9px; border-radius:7px;
  border:1px solid var(--linie); background:var(--karte2); color:var(--text);
  font-size:15px; font-variant-numeric:tabular-nums }
.gr-zahl.gr-klein { font-size:13px }
.gr-einheit { width:38px; font-size:11px; color:var(--gedaempft) }

.gr-titel { font-size:10px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--leise); margin:14px 0 6px }
.gr-vorschlaege { display:flex; flex-wrap:wrap; gap:6px }
.gr-vorschlag { display:flex; flex-direction:column; align-items:flex-start;
  gap:1px; padding:6px 9px; border-radius:7px; cursor:pointer;
  background:var(--karte2); border:1px solid var(--linie); color:var(--text) }
.gr-vorschlag:hover { border-color:var(--akzent) }
.gr-vorschlag b { font-size:13px; font-variant-numeric:tabular-nums }
.gr-vorschlag span { font-size:10px; color:var(--leise) }

.gr-reichweite { display:flex; flex-direction:column; gap:5px; font-size:12px }
.gr-reichweite label { display:flex; align-items:center; gap:7px; cursor:pointer }

.gr-fuss { display:flex; gap:14px; margin-top:14px; padding-top:12px;
  border-top:1px solid var(--linie); flex-wrap:wrap }
.gr-fuss .gr-zeile { margin:0; flex:1 1 150px }
.gr-fuss .gr-wort { width:auto }
.gr-schwere { padding:6px 8px; border-radius:7px; border:1px solid var(--linie);
  background:var(--karte2); color:var(--text) }

.gr-hinweis { font-size:10.5px; color:var(--leise); margin:12px 0 0;
  line-height:1.4 }
.gr-meldung:empty { display:none }
.gr-meldung { margin-top:10px; font-size:12px; color:var(--gedaempft) }
.gr-meldung.fehler { color:var(--alarm) }

.gr-knoepfe { display:flex; gap:8px; justify-content:flex-end; margin-top:14px }
.gr-knoepfe button { padding:8px 15px; border-radius:8px; cursor:pointer;
  border:1px solid var(--linie); background:var(--karte2); color:var(--text) }
.gr-setzen { background:var(--akzent) !important; color:#0b0e14 !important;
  border-color:var(--akzent) !important; font-weight:600 }
.gr-loeschen { margin-right:auto; color:var(--alarm) !important }

/* Nachweisversand im Schwellendialog (nachweis#D3, D11). Gesperrt heisst
 * ausgegraut MIT sichtbarem Grund -- nicht weggelassen (O4). */
.gr-nachweis { margin-top:12px; padding-top:12px; border-top:1px solid var(--linie) }
.gr-nw-feld { display:flex; align-items:center; gap:8px; font-size:12px;
  cursor:pointer }
.gr-nachweis.gesperrt .gr-nw-feld { color:var(--leise); cursor:not-allowed }
.gr-nw-grund:empty, .gr-nw-warnung:empty { display:none }
.gr-nw-grund { margin-top:5px; font-size:11px; color:var(--leise);
  line-height:1.4 }
.gr-nw-liste { margin-top:9px }
.gr-nw-liste[hidden] { display:none }
.gr-nw-boxen { display:flex; flex-wrap:wrap; gap:5px 14px }
.gr-nw-boxen label { display:flex; align-items:center; gap:6px; font-size:12px;
  cursor:pointer }
.gr-nw-warnung { margin-top:8px; font-size:12px; color:var(--warn) }

/* --------------------------------------------------------- Schwellenmatrix */
.matrix { width:100%; border-collapse:collapse; font-size:12px }
.matrix th { text-align:left; font-weight:600; color:var(--gedaempft);
  font-size:11px; padding:6px 8px; border-bottom:1px solid var(--linie) }
.matrix td { padding:0; border-bottom:1px solid var(--linie) }
.matrix .q { font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  padding:6px 8px; color:var(--gedaempft) }
.zelle { width:100%; text-align:left; padding:7px 8px; cursor:pointer;
  background:none; border:none; color:var(--text); font:inherit;
  font-variant-numeric:tabular-nums; border-radius:6px }
.zelle:hover { background:color-mix(in srgb, var(--akzent) 14%, transparent) }
.zelle.leer { color:var(--leise) }
.zelle .art { font-size:10px; color:var(--gedaempft); display:block }
.zelle.aus { opacity:.45; text-decoration:line-through }
.matrix-fuss { font-size:11px; color:var(--leise); margin-top:8px }

/* ================================================================ Verwaltung
 *
 * Die erste Fassung stapelte alles untereinander: Eingabefelder ueber die
 * volle Breite -- vierzehnhundert Pixel fuer eine Portnummer --, Formulare
 * standen offen zwischen den Tabellen, und Bearbeiten gab es nicht.
 *
 * Drei Regeln dagegen, und sie gelten fuer jede Flaeche hier:
 *   1. Ein Feld ist so breit wie sein Inhalt. Ein Port ist kurz, eine Adresse
 *      lang, eine Notiz breit. Gleiche Breite fuer Ungleiches ist keine
 *      Ordnung, sondern deren Abwesenheit.
 *   2. Formulare stehen in einem Dialog, nicht in der Seite. Eine Seite, die
 *      immer alle Formulare zeigt, zwingt zum Lesen, was man gerade nicht tut.
 *   3. Jede Zeile ist bearbeitbar. Eine Liste, die nur anlegen und stilllegen
 *      kann, zwingt zum Neuanlegen fuer einen Tippfehler.
 */

/* ---------------------------------------------------------- Reiter */
.reiter { display:flex; gap:2px; padding:3px; background:var(--karte2);
  border:1px solid var(--linie); border-radius:9px; width:fit-content; margin-bottom:18px }
.reiter button { background:none; border:none; padding:7px 15px; border-radius:7px;
  color:var(--gedaempft); cursor:pointer; font-size:13px; white-space:nowrap }
.reiter button:hover { color:var(--text) }
.reiter button.aktiv { background:var(--karte); color:var(--text); font-weight:600;
  box-shadow:0 1px 3px rgba(0,0,0,.25) }
.reiter button .zahl { color:var(--leise); margin-left:6px; font-variant-numeric:tabular-nums }
.reiter button.aktiv .zahl { color:var(--akzent) }

/* ---------------------------------------------------------- Bereichskopf */
.bereich-kopf { display:flex; align-items:flex-start; gap:16px; margin-bottom:12px }
.bereich-kopf h2 { font-size:15px; margin:0 0 3px; font-weight:650 }
.bereich-kopf p { margin:0; color:var(--gedaempft); font-size:12.5px; max-width:70ch;
  line-height:1.55 }
.bereich-kopf .rechts { margin-left:auto; flex:none }

/* ---------------------------------------------------------- Tabelle */
table.verw { width:100%; border-collapse:separate; border-spacing:0;
  background:var(--karte); border:1px solid var(--linie); border-radius:10px;
  overflow:hidden; font-size:13px }
table.verw th { text-align:left; font-size:11.5px; font-weight:600; color:var(--gedaempft);
  padding:9px 14px; background:var(--karte2); border-bottom:1px solid var(--linie);
  white-space:nowrap; letter-spacing:.02em }
table.verw td { padding:10px 14px; border-bottom:1px solid var(--linie);
  vertical-align:middle }
table.verw tbody tr:last-child td { border-bottom:none }
table.verw tbody tr:hover { background:var(--karte2) }
table.verw td.tat { text-align:right; white-space:nowrap; width:1% }
table.verw td.tat .knopf { padding:4px 10px; font-size:12px; margin-left:6px }
table.verw .haupt { font-weight:600 }
table.verw .neben { color:var(--gedaempft); font-size:12px; margin-top:1px }
table.verw td.zahl { text-align:right; font-variant-numeric:tabular-nums }
.leerhinweis { padding:34px; text-align:center; color:var(--gedaempft);
  background:var(--karte); border:1px dashed var(--linie); border-radius:10px }

/* Marken fuer Rolle und Zustand -- Text, nicht nur Farbe. */
.marke { display:inline-block; padding:2px 8px; border-radius:11px; font-size:11.5px;
  font-weight:600; letter-spacing:.01em; white-space:nowrap }
.marke.gut     { background:color-mix(in srgb,var(--gut) 15%,transparent);   color:var(--gut) }
.marke.ruhe    { background:color-mix(in srgb,var(--leise) 22%,transparent); color:var(--gedaempft) }
.marke.warn    { background:color-mix(in srgb,var(--warn) 16%,transparent);  color:var(--warn) }
.marke.alarm   { background:color-mix(in srgb,var(--alarm) 14%,transparent); color:var(--alarm) }
/* sichtfeinschliff T5: Katalog liest sich -- Schluessel klein unter dem
   Klartext, Lueckenzeile mit Streifen, Pflichthinweis am Haken, gesperrte
   Vorlagenwahl erkennbar. */
.ps-schluessel { font-size:12px; opacity:.7 }
tr.ps-zeile.luecke td:first-child { border-left:3px solid var(--warn) }
.wz-pflichthinweis { margin-top:6px }
.f select:disabled { color:var(--gedaempft); background:var(--karte2) }
.marke.akzent  { background:color-mix(in srgb,var(--akzent) 15%,transparent);color:var(--akzent) }
/* Typmarke der Geraeteklasse an der Kennung in der Geraeteliste (G4). */
.typmarke { margin-left:7px; vertical-align:middle }

/* ---------------------------------------------------------- Dialog */
.schleier { position:fixed; inset:0; background:rgba(0,0,0,.55); z-index:100;
  display:grid; place-items:center; padding:22px; overflow:auto }
.dialog { background:var(--karte); border:1px solid var(--linie); border-radius:12px;
  width:100%; max-width:640px; box-shadow:0 20px 60px rgba(0,0,0,.45) }
.dialog header { padding:16px 20px; border-bottom:1px solid var(--linie);
  display:flex; align-items:baseline; gap:10px; background:none; position:static }
.dialog header h3 { margin:0; font-size:15px; font-weight:650 }
.dialog header .sub { color:var(--gedaempft); font-size:12px }
.dialog .rumpf { padding:18px 20px }
.dialog .fuss { padding:14px 20px; border-top:1px solid var(--linie);
  display:flex; gap:9px; justify-content:flex-end; align-items:center }
.dialog .fuss .links { margin-right:auto; color:var(--gedaempft); font-size:12px }

/* ---------------------------------------------------------- Formularraster
 * Zwoelf Spalten. Ein Feld belegt so viele, wie sein Inhalt braucht:
 * Port drei, Adresse neun, Notiz zwoelf. */
/* minmax(0,1fr) und NICHT 1fr. Eine Rasterspalte mit 1fr schrumpft nie unter
   die Inhaltsbreite ihres Kindes -- eine Auswahlliste mit langen Eintraegen
   drueckt damit die Nachbarspalte auf null. Genau das ist passiert: das
   E-Mail-Feld war zwanzig Pixel breit, waehrend daneben eine Mandantenauswahl
   stand. minmax(0,1fr) erlaubt das Schrumpfen, und dann gilt wieder die
   Spaltenzahl, die man hingeschrieben hat. */
.gitter { display:grid; grid-template-columns:repeat(12,minmax(0,1fr)); gap:14px 12px }
.f { display:flex; flex-direction:column; gap:5px; min-width:0 }
/* ALLE zwoelf, nicht nur die gerade gebrauchten. Es fehlten s7, s10 und s11 --
   ein Feld mit `spalten: 7` bekam dadurch keine Regel und belegte EINE Spalte
   statt sieben. Im Dialog stand ein E-Mail-Feld von zwanzig Pixeln neben einer
   Mandantenauswahl, und es sah aus wie ein Rasterproblem. Eine Klassenleiter,
   die Luecken hat, ist keine Leiter. */
.f.s1{grid-column:span 1}   .f.s2{grid-column:span 2}   .f.s3{grid-column:span 3}
.f.s4{grid-column:span 4}   .f.s5{grid-column:span 5}   .f.s6{grid-column:span 6}
.f.s7{grid-column:span 7}   .f.s8{grid-column:span 8}   .f.s9{grid-column:span 9}
.f.s10{grid-column:span 10} .f.s11{grid-column:span 11} .f.s12{grid-column:span 12}
.f label { font-size:11.5px; color:var(--gedaempft); font-weight:500 }
.f input, .f select, .f textarea { width:100%; min-width:0; padding:7px 10px;
  background:var(--bg); border:1px solid var(--linie); border-radius:7px; font-size:13px;
  text-overflow:ellipsis }
.f label { white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.f input:focus, .f select:focus, .f textarea:focus { outline:none; border-color:var(--akzent) }
.f input:disabled { color:var(--gedaempft); background:var(--karte2); cursor:not-allowed }
.f .tipp { font-size:11px; color:var(--leise); line-height:1.45 }
.f.schalter { flex-direction:row; align-items:center; gap:9px }
.f.schalter input { width:auto }
.f.schalter label { font-size:13px; color:var(--text) }
.dialog .fehler { margin:0 20px 14px }

/* Bestaetigung IN der Zeile statt als Browserdialog: ein window.confirm
   blockiert die Seite und ist mit der Tastatur schlecht bedienbar. */
.bestaetigen { display:inline-flex; align-items:center; gap:8px; font-size:12px;
  color:var(--warn) }

/* Sprachumschalter: zwei Kuerzel nebeneinander, kein Auswahlmenue. Bei zwei
   Sprachen kostet ein Menue einen Klick mehr und zeigt weniger -- man saehe
   nicht, welche Sprachen es ueberhaupt gibt. */
.sprachen { display:flex; gap:0; margin-right:12px }
.sprache { padding:4px 8px; font-size:11px; font-weight:600; cursor:pointer;
  background:var(--karte2); color:var(--gedaempft);
  border:1px solid var(--linie); border-right-width:0; letter-spacing:.04em }
.sprache:first-child { border-radius:6px 0 0 6px }
.sprache:last-child { border-radius:0 6px 6px 0; border-right-width:1px }
.sprache.an { background:var(--akzent); color:#0b0e14; border-color:var(--akzent);
  cursor:default }

/* Der Sprachumschalter auf dem Anmeldeschirm. Er baut keinen rahmen(), also
   braucht er seinen eigenen Platz -- ohne ihn sass ein englischer Benutzer
   vor „Mandant / E-Mail / Kennwort" fest. */
.anmelde-sprachen { display:flex; justify-content:center }

/* ---------------------------------------------------------------- Auftraege
 *
 * Spec: docs/vorhaben/2026-08-22-command-plane/spec.md
 *
 * Die wichtigste Aussage dieses Blocks ist der Unterschied zwischen einem
 * ABGESCHLOSSENEN Abbruch und einem LAUFENDEN. Wer eine Zeile ueberfliegt,
 * liest die Form vor dem Wort -- deshalb ist `cancelling` in Bewegung und
 * `cancelled` still. Ein Geraet, das noch auf safe_state_reached wartet, steht
 * moeglicherweise unter Spannung; das darf nicht aussehen wie erledigt.
 */
table.auftraege { width:100%; border-collapse:collapse }
table.auftraege th { text-align:left; font-size:12px; color:var(--gedaempft);
  font-weight:500; padding:6px 8px; border-bottom:1px solid var(--linie) }
table.auftraege td { padding:7px 8px; border-bottom:1px solid var(--linie);
  vertical-align:middle }
table.auftraege tbody tr { cursor:pointer }
table.auftraege tbody tr:hover { background:var(--karte2) }
table.auftraege tbody tr.gewaehlt { background:var(--karte2) }

.auftragszustand { display:inline-flex; align-items:center; gap:6px;
  font-size:12px; padding:2px 9px; border-radius:999px;
  border:1px solid var(--linie); color:var(--gedaempft); background:var(--karte2) }

/* Ein Punkt vor dem Wort. Er traegt die Farbe, das Wort bleibt lesbar. */
.auftragszustand::before { content:''; width:7px; height:7px; border-radius:50%;
  background:currentColor; flex:none }

.auftragszustand.laeuft { color:var(--akzent);
  border-color:color-mix(in srgb, var(--akzent) 40%, var(--linie)) }
.auftragszustand.z-succeeded { color:var(--gut);
  border-color:color-mix(in srgb, var(--gut) 40%, var(--linie)) }
.auftragszustand.z-failed, .auftragszustand.z-aborted {
  color:var(--alarm); border-color:color-mix(in srgb, var(--alarm) 40%, var(--linie)) }
.auftragszustand.z-expired { color:var(--warn);
  border-color:color-mix(in srgb, var(--warn) 40%, var(--linie)) }
/* cancelled ist still und grau: der Abbruch ist durch, das Geraet ist sicher. */
.auftragszustand.z-cancelled { color:var(--leise) }

/* cancelling und aborting sind NICHT still. Der Auftrag ist nicht zu Ende --
 * er wartet darauf, dass der Ausfuehrer safe_state_reached meldet. */
.auftragszustand.wartet-sicher { color:var(--warn);
  border-color:var(--warn); background:color-mix(in srgb, var(--warn) 10%, var(--karte2)) }
.auftragszustand.wartet-sicher::before { animation:pochen 1.1s ease-in-out infinite }
tr.wartet-sicher td { background:color-mix(in srgb, var(--warn) 6%, transparent) }

@keyframes pochen {
  0%, 100% { opacity:1; transform:scale(1) }
  50%      { opacity:.35; transform:scale(.7) }
}

/* Wer Bewegung abgestellt hat, bekommt den Unterschied trotzdem -- als Ring
 * statt als Puls. Die Aussage darf nicht an einer Systemeinstellung haengen. */
@media (prefers-reduced-motion: reduce) {
  .auftragszustand.wartet-sicher::before { animation:none;
    box-shadow:0 0 0 3px color-mix(in srgb, var(--warn) 35%, transparent) }
}

.protokollkasten { margin-top:18px; background:var(--karte);
  border:1px solid var(--linie); border-radius:10px; padding:14px 16px }
.protokollkasten h2 { font-size:14px; margin:0 0 10px; color:var(--gedaempft);
  font-weight:500 }
ol.auftragsprotokoll { list-style:none; margin:0; padding:0;
  max-height:320px; overflow-y:auto; font-family:ui-monospace, monospace;
  font-size:12px }
ol.auftragsprotokoll li { display:flex; gap:10px; padding:3px 0;
  border-bottom:1px solid color-mix(in srgb, var(--linie) 50%, transparent) }
ol.auftragsprotokoll .zeit { color:var(--leise); flex:none }
ol.auftragsprotokoll .art { color:var(--text) }
ol.auftragsprotokoll .schritt { color:var(--gedaempft) }
ol.auftragsprotokoll .kode { color:var(--alarm) }
ol.auftragsprotokoll li.stufe-warn .art { color:var(--warn) }
ol.auftragsprotokoll li.stufe-error .art { color:var(--alarm) }

/* ---------------------------------------------------------- CP-Tester
   Zu ansicht-cp.js. Alles auf .cp beziehungsweise .cp-* gescopt: dieser Block
   darf keine andere Ansicht verstellen. Der Leerzustand ist hier der REGELFALL
   und kein Fehlerbild -- er bekommt deshalb Platz und ruhige Farben, keine
   Warnfarbe. */
.cp h1 { margin-bottom:6px }
.cp-einordnung { color:var(--gedaempft); font-size:13px; max-width:80ch;
  margin:0 0 8px; line-height:1.5 }
.cp-nurlesen { color:var(--leise); font-size:12px; max-width:80ch; margin:0 0 16px }
.cp-warnung { background:color-mix(in srgb,var(--warn) 10%,transparent);
  border-left:3px solid var(--warn); color:var(--text); font-size:12.5px;
  padding:10px 14px; border-radius:0 7px 7px 0; margin:0 0 20px; max-width:92ch;
  line-height:1.5 }
.cp-abschnitt { margin:26px 0 }
.cp-geraet { margin:14px 0 18px; padding:14px 16px; background:var(--karte);
  border:1px solid var(--linie); border-radius:9px }
.cp-geraet .bereich-kopf { margin-bottom:10px }
.cp-geraet h3 { font-size:14px; margin:0 0 2px; font-weight:650 }
.cp-geraet h3 a { color:var(--text); text-decoration:none }
.cp-geraet h3 a:hover { color:var(--akzent) }
.cp-geraet .bereich-kopf p { margin:0; color:var(--gedaempft); font-size:12.5px }
.cp-geraet .leerhinweis { padding:22px }
.cp-fuss { color:var(--leise); font-size:11.5px; max-width:90ch; margin:14px 0 0;
  line-height:1.55 }

/* CP-Tester, Nachweisteil. "Noch nicht gemessen" und "nicht lesbar" tragen
   verschiedene Kanten: das eine ist ein gueltiger Zustand, das andere ein
   Ausfall. Gleiche Farbe fuer beides waere die Aussage, es sei dasselbe. */
.cp-ergebnisse { margin-top:16px; border-top:1px solid var(--linie); padding-top:12px }
.cp-ergebnisse-kopf { font-size:12px; font-weight:650; color:var(--gedaempft);
  text-transform:uppercase; letter-spacing:.05em; margin:0 0 10px }
.cp-ergebnis { margin:0 0 14px; padding:11px 13px; background:var(--karte2);
  border-radius:8px; border-left:3px solid var(--linie) }
.cp-ergebnis.u-pass  { border-left-color:var(--gut) }
.cp-ergebnis.u-fail  { border-left-color:var(--alarm) }
.cp-ergebnis.offen   { border-left-color:var(--leise); border-left-style:dashed }
.cp-ergebnis.unlesbar{ border-left-color:var(--warn) }
.cp-ergebnis .bereich-kopf { margin-bottom:8px }
.cp-ergebnis h4 { font-size:13px; margin:0 0 2px; font-weight:650 }
.cp-ergebnis .bereich-kopf p { margin:0; color:var(--gedaempft); font-size:12px }
.cp-urteil { display:flex; gap:6px; flex-wrap:wrap; margin:0 0 8px }
.cp-quelle { font-size:11.5px; color:var(--gedaempft); margin:8px 0 0;
  max-width:88ch; line-height:1.5 }

/* Grenzwert in fremder Einheit: nicht umgerechnet, und das steht dran. */
.warnfarbe { color:var(--warn) }

/* ---------------------------------------------------------------- Messplan
   Spec: docs/vorhaben/2026-08-23-messplan/spec-ENTWURF.md */

table.messplaene { width:100%; border-collapse:collapse }
table.messplaene th { text-align:left; font-size:12px; color:var(--gedaempft);
  font-weight:600; padding:7px 8px; border-bottom:1px solid var(--linie) }
table.messplaene td { padding:8px; border-bottom:1px solid var(--linie);
  font-size:13px; vertical-align:top }
table.messplaene td.tat { text-align:right; white-space:nowrap; width:1% }
table.messplaene td.tat .knopf { padding:4px 10px; font-size:12px }
table.messplaene .neben { color:var(--gedaempft); font-size:12px; margin-top:1px }

/* Abgeschaltet heisst SICHTBAR abgeschaltet: Schraffur plus Alarm-Marke,
   nicht bloss weniger Deckkraft -- ein halbdurchsichtiger Plan saehe aus wie
   einer, der noch laedt, und ein Bildschirm ist ein Beweismittel. */
table.messplaene tr.plan-aus td { background:repeating-linear-gradient(-45deg,
  transparent 0 8px, color-mix(in srgb, var(--warn) 7%, transparent) 8px 16px) }

/* Die Ausloesewarnung im Anlegedialog (messplan#D7): auffaellig und mit
   eigenem Haken -- eine Warnung, die man wegscrollen kann, ist keine. */
/* Gefuehrte Pruefung (gefuehrte-pruefung#D4): Kopf mit Fortschritt, dann
   Schritt-Karten in Reihenfolge; der erste offene Schritt ist "Jetzt". */
.pruefung-knoepfe { display:inline-flex; gap:8px; align-items:center }
.pf-kopf { display:flex; gap:18px; align-items:center; flex-wrap:wrap; margin-bottom:16px }
.pf-fortschritt { font-size:13px; color:var(--gedaempft); font-variant-numeric:tabular-nums }
.pf-balken { height:6px; width:180px; background:var(--karte2); border-radius:3px; overflow:hidden }
.pf-balken > div { height:100%; background:var(--akzent) }
.pf-schritt { display:flex; gap:14px; align-items:flex-start; background:var(--karte);
  border:1px solid var(--linie); border-radius:10px; padding:12px 14px; margin:8px 0 }
.pf-schritt .nr { font-family:ui-monospace,Menlo,monospace; color:var(--leise); min-width:1.6rem;
  padding-top:2px }
.pf-schritt .inhalt { flex:1; min-width:0 }
.pf-schritt .titel { font-weight:600 }
.pf-schritt .lage { font-size:12.5px; color:var(--gedaempft); margin-top:3px }
.pf-schritt.jetzt { border-color:var(--akzent); box-shadow:0 0 0 2px color-mix(in srgb, var(--akzent) 25%, transparent) }
.pf-schritt.jetzt .titel { color:var(--akzent) }
.pf-schritt.fertig { opacity:.7 }
.pf-schritt .rechts { margin-left:auto; flex:none; display:flex; gap:8px; align-items:center }
.pf-urteil { display:inline-block; padding:3px 10px; border-radius:999px; font-size:12.5px;
  font-weight:600; background:var(--karte2); color:var(--gedaempft) }
.pf-urteil.pass { color:var(--gut) } .pf-urteil.fail { color:var(--alarm) }
.pf-urteil.not_evaluable { color:var(--warn) }
table.pruefungen tbody tr { cursor:pointer }
.pf-werte { display:flex; gap:10px; font-variant-numeric:tabular-nums; font-size:13px }
.pf-wert { font-family:ui-monospace,Menlo,monospace }
.pf-urteil.gemessen { color:var(--gut) }

/* Wizard-Karten der Vorlage (vorlagen-wizard#D1): eine Karte je Baustein,
   Klarname zuerst, Parameter und Risiko-Zeile darunter, Abwahl am Fuss. */
/* Zeilenform der Karten (startfluss#D1): eine Zeile je Baustein, der Rumpf
   klappt erst mit "Details" auf. */
.wz-zeile { display:flex; gap:10px; align-items:center; flex-wrap:wrap }
.wz-zeile .wz-titel { flex:0 0 auto }
.wz-kurz { color:var(--gedaempft); font-size:12.5px; flex:1 1 auto }
.wz-details { background:none; border:1px solid var(--linie); color:var(--gedaempft);
  border-radius:6px; padding:3px 9px; font-size:12px; cursor:pointer; margin-left:auto }
.wz-details:hover { color:var(--text); border-color:var(--akzent) }
.wz-rumpf { margin-top:8px; padding-top:8px; border-top:1px dashed var(--linie) }
.wz-bestaetigung { padding:8px 12px }
.wz-bestaetigung label { display:flex; gap:8px; align-items:flex-start; font-size:13px }
.wz-karte { background:var(--karte); border:1px solid var(--linie); border-radius:10px;
  padding:10px 12px; margin:8px 0 }
.wz-karte.wz-aus { opacity:.45 }
.wz-titel { font-weight:600 }
.wz-titel .mono { margin-left:8px; font-size:12px; opacity:.7; font-weight:400 }
.wz-titel .marke { margin-left:8px }
.wz-satz { margin:6px 0 0; font-size:12.5px; color:var(--gedaempft); max-width:75ch;
  line-height:1.5 }
.wz-params { display:flex; gap:16px; flex-wrap:wrap; align-items:center; margin-top:8px;
  font-size:13px }
.wz-params label { display:flex; gap:6px; align-items:center }
.wz-feldname { color:var(--gedaempft); font-size:12px }
.wz-risiko { margin:8px 0 0; font-size:12.5px; color:var(--gedaempft);
  border-left:3px solid var(--linie); padding-left:8px }
.wz-risiko.warnt { color:var(--warn); border-left-color:var(--warn) }
.wz-dabei { display:flex; gap:6px; align-items:center; margin-top:10px; font-size:12.5px;
  color:var(--gedaempft) }
.wz-weg { color:var(--warn) }

.messplan-warnkasten { margin-top:14px; padding:12px 14px;
  border:1px solid var(--warn); border-radius:8px;
  background:color-mix(in srgb, var(--warn) 10%, transparent) }
.messplan-warnkasten p { margin:0 0 10px; font-size:12.5px; line-height:1.5 }
.messplan-warnkasten label { display:flex; align-items:center; gap:8px;
  font-size:13px; font-weight:600; cursor:pointer }

/* Klarname zuerst, kind_key mono klein daneben (prozeduren#D3) -- dieselbe
   Nebenrolle wie in table.verw und table.messplaene; die Regel loest den
   Inline-Stil ab, den ansicht-auftraege.js uebergangsweise trug (Task 4). */
table.auftraege .neben { color:var(--gedaempft); font-size:12px }

/* ------------------------------------------- Prozedur-Checkliste (pz-*)
   Spec: docs/vorhaben/2026-09-01-prozeduren/spec-ENTWURF.md (Task 6)
   Zu ansicht-pruefschritt.js, Quelle releases/DE. Alles auf pz- gescopt.
   Die Bestandsbilder sind PNG mit Transparenz und fuer die helle App
   gezeichnet -- Thumbnail und Grossansicht bekommen deshalb IMMER einen
   hellen Grund, sonst verschwindet eine schwarze Strichzeichnung im
   dunklen Thema und das Bild sieht aus wie kaputt. */
.pz-gruppe { font-size:12px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--gedaempft); font-weight:650; margin:20px 0 8px }
/* Nicht abhakbar heisst SICHTBAR anders gebaut: keine Karte, keine Knoepfe,
   nur eine ruhige Zeile mit Randstreifen -- Normzitate und Bestandszeilen
   des Deckblatts (functionId 18, prozeduren#D12). */
.pz-norm { margin:4px 0; padding:5px 10px; font-size:12px;
  color:var(--gedaempft); background:var(--karte);
  border-left:3px solid var(--linie); border-radius:0 6px 6px 0 }
.pz-punkt { display:flex; gap:12px; align-items:center; padding:9px 12px;
  background:var(--karte); border:1px solid var(--linie); border-radius:8px;
  margin-bottom:6px }
.pz-text { flex:1; min-width:0; font-size:13px; line-height:1.45 }
.pz-thumb { flex:none; width:90px; padding:0; overflow:hidden;
  border:1px solid var(--linie); border-radius:6px; background:#fff;
  cursor:zoom-in }
.pz-thumb:hover, .pz-thumb:focus-visible { border-color:var(--akzent);
  outline:none }
.pz-thumb img { display:block; width:100%; height:auto }
.pz-knoepfe { flex:none }
.pz-voll { position:fixed; inset:0; z-index:200; background:rgba(0,0,0,.82);
  display:flex; flex-direction:column; align-items:center;
  justify-content:center; gap:10px; padding:24px; cursor:zoom-out }
.pz-voll img { max-width:min(92vw, 900px); max-height:82vh;
  background:#fff; border-radius:8px }
.pz-voll-hinweis { margin:0; color:#e8eaf0; font-size:12px }

/* --------------------------------------- Alarmruhe: Kachelzeile und Gruppen */
/* Spec: docs/vorhaben/2026-09-01-alarmruhe/spec.md */
/* Drei Zusammenfassungskacheln nach dem .kacheln-Muster oben: dieselbe
   Karte, aber die Zahl gross ueber der Beschriftung -- die Zeile ist die
   Lagekarte, kein Messwert-Cockpit. */
.alarm-kacheln { display:grid; gap:12px; margin-bottom:14px;
  grid-template-columns:repeat(auto-fit,minmax(170px,1fr)) }
.alarm-kacheln .ak { background:var(--karte); border:1px solid var(--linie);
  border-radius:10px; padding:12px 14px; display:flex; flex-direction:column;
  align-items:center; gap:2px }
.alarm-kacheln .ak-wert { font-size:22px; font-variant-numeric:tabular-nums;
  letter-spacing:-.03em }
.alarm-kacheln .ak-name { font-size:11px; color:var(--gedaempft);
  text-transform:uppercase; letter-spacing:.06em; font-weight:600;
  text-align:center }
/* Geraetegruppen: natives details/summary (alarmruhe#D7), beim Laden
   eingeklappt -- die summary-Zeile ist die ganze Lagekarte je Geraet. */
details.alarm-gruppe { background:var(--karte); border:1px solid var(--linie);
  border-radius:10px; margin-bottom:8px }
details.alarm-gruppe > summary { cursor:pointer; padding:9px 14px;
  display:flex; gap:12px; align-items:baseline; flex-wrap:wrap }
/* display:flex nimmt der summary den nativen Aufklapp-Pfeil -- der eigene
   ersetzt ihn, sonst sieht die Zeile nicht bedienbar aus. */
details.alarm-gruppe > summary::before { content:'\25B8';
  color:var(--gedaempft); font-size:11px }
details.alarm-gruppe[open] > summary::before { content:'\25BE' }
details.alarm-gruppe[open] > summary { border-bottom:1px solid var(--linie) }
details.alarm-gruppe .ag-serial { font-weight:600;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace }
details.alarm-gruppe .ag-zaehler { color:var(--gedaempft); font-size:13px }
details.alarm-gruppe .ag-schwere { display:inline-flex; gap:5px;
  align-items:center; font-size:12px; margin-left:auto }
details.alarm-gruppe > p.hinweis { margin:8px 14px }
details.alarm-gruppe table { margin:0 }
/* Schweremarker als Farbpunkt; die Ordnung ist info < warn < alarm. */
.schwere-punkt { width:9px; height:9px; border-radius:50%;
  display:inline-block; background:var(--leise) }
.ag-schwere.schwere-info  .schwere-punkt { background:var(--akzent) }
.ag-schwere.schwere-warn  .schwere-punkt { background:var(--warn) }
.ag-schwere.schwere-alarm .schwere-punkt { background:var(--alarm) }
/* Schwellen-Matrizen je Geraet hinter details/summary (alarmruhe#D4):
   dieselbe Karte wie details.alarm-gruppe oben; die summary traegt die
   Seriennummer und den Fusssatz aus derselben Zaehlung wie .matrix-fuss. */
details.schwellen-gruppe { background:var(--karte); border:1px solid var(--linie);
  border-radius:10px; margin-bottom:8px }
details.schwellen-gruppe > summary { cursor:pointer; padding:9px 14px;
  display:flex; gap:12px; align-items:baseline; flex-wrap:wrap }
/* display:flex nimmt der summary den nativen Aufklapp-Pfeil -- der eigene
   ersetzt ihn (dasselbe Muster wie details.alarm-gruppe). */
details.schwellen-gruppe > summary::before { content:'\25B8';
  color:var(--gedaempft); font-size:11px }
details.schwellen-gruppe[open] > summary::before { content:'\25BE' }
details.schwellen-gruppe[open] > summary { border-bottom:1px solid var(--linie) }
details.schwellen-gruppe .sg-serial { font-weight:600;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace }
details.schwellen-gruppe .sg-luecken { color:var(--gedaempft); font-size:13px }
details.schwellen-gruppe > .matrix-block { margin:10px 14px }
