/* ── Logbuch ────────────────────────────────────────────────────────────────
   Das Diagnosewerkzeug auf dem Server. Es teilt die Farben mit der
   Bordansicht, damit es zum selben System gehoert — aber nicht deren Aufbau.
   Die Bordansicht ist ein Armaturenbrett: viele Kacheln, alles gleichzeitig im
   Blick, fuer den Griff im Vorbeigehen. Hier liest jemand, der etwas
   herausfinden will. Deshalb: eine Spalte, viel Ruhe, Text vor Zahl, und ganz
   oben der Zeitstrahl statt eines Messwerts.
   ------------------------------------------------------------------------- */

:root {
  --bg: #0b1120;
  --surface: #131c2e;
  --surface2: #1a2438;
  --border: #253046;
  --text: #e8edf6;
  --text2: #9aa8bf;
  --text3: #64748b;
  --accent: #22d3ee;
  --green: #34d399;
  --yellow: #fbbf24;
  --red: #f87171;
  --violet: #a78bfa;
  --blau: #60a5fa;
  --kopf-h: 58px;
  --schiene-b: 232px;
}

* { box-sizing: border-box; }

/* Das hidden-Attribut MUSS staerker sein als jede Layout-Regel. Ohne diese
   Zeile setzt schon ein `display: flex` in einer Klasse das Ausblenden
   stillschweigend ausser Kraft — die Abweisung lag dann ueber der ganzen
   Seite, obwohl sie versteckt sein sollte. */
[hidden] { display: none !important; }

body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  font-size: 14px; line-height: 1.5;
}

/* ── Kopfzeile ───────────────────────────────────────────────────────────── */
/* Sie sitzt jetzt IN der Inhaltsspalte, nicht mehr quer ueber die ganze Seite:
   die Schiene links reicht bis oben durch, wie in einem Programm. Und sie ist
   nicht mehr position:fixed, sondern klebt oben in ihrer Spalte — dadurch
   braucht der Body keinen Platzhalter mehr, und nichts verrutscht, wenn die
   Kopfzeile einmal hoeher wird. */
.kopf {
  position: sticky; top: 0; z-index: 30;
  min-height: var(--kopf-h);
  display: flex; align-items: center; gap: 16px;
  padding: 0 24px; flex: 0 0 auto;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.kopf-mitte {
  display: flex; align-items: center; gap: 9px;
  font-size: 13px; color: var(--text2); min-width: 0;
}
.zust-punkt {
  width: 9px; height: 9px; border-radius: 50%; background: var(--text3);
  flex: 0 0 auto; transition: background .3s;
}
.zust-punkt.an   { background: var(--green); }
.zust-punkt.weg  { background: var(--red); }
.kopf-rechts { display: flex; align-items: center; gap: 10px; margin-left: auto; }

/* ── Wandbetrieb ─────────────────────────────────────────────────────────── */
/* Die Knoepfe kommen aus wandbetrieb.js und bringen die Klassennamen der
   Bordansicht mit. Hier bekommen sie das Aussehen dieser Seite. */
.wand-knoepfe { display: flex; align-items: center; gap: 8px; }
.wand-knoepfe .icon-btn {
  background: none; border: 1px solid var(--border); border-radius: 8px;
  color: var(--text2); cursor: pointer; padding: 6px 8px;
  display: flex; align-items: center; transition: all .15s;
}
.wand-knoepfe .icon-btn:hover { background: var(--surface2); color: var(--accent);
  border-color: var(--accent); }
.wand-knopf.an { border-color: var(--accent); color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent); }
.wand-knopf.wartet { border-color: var(--yellow); color: var(--yellow); }

/* ── Nachtmodus ──────────────────────────────────────────────────────────── */
/* Dieselbe Rechnung wie in der Bordansicht: die Token drehen die Flaeche, der
   Filter am Wurzelelement faengt alles fest Kodierte — hier vor allem die
   Graphenfarben und die Seekarte. Der Filter MUSS an der Wurzel haengen: auf
   jedem anderen Element spannt er einen Bezugsrahmen fuer fest positionierte
   Kinder auf, und die klebende Kopfzeile wuerde mitscrollen. */
html.nachtmodus {
  --bg: #0b0704;
  --surface: #18100a;
  --surface2: #24170e;
  --border: #4f2a15;
  --text: #ffcfa8;
  --text2: #cf9463;
  --text3: #96603c;
  --accent: #ff9248;
  --violet: #e0955a;
  --blau: #d98a4e;
  filter: brightness(.8) sepia(.55) saturate(1.6) hue-rotate(-16deg);
}

/* Graphen bekommen eine staerkere Dosis.
   Der Unterschied ist inhaltlich: in einem Graphen sagt die Farbe, WELCHE Linie
   das ist — Violett, Cyan, Blau sind Namen, keine Bedeutung. Bei gruen/gelb/rot
   sagt die Farbe, WIE ES STEHT, und dieser Unterschied darf nachts nicht
   verschwinden. Deshalb bleibt der Seitenfilter mild, und die Leinwaende
   bekommen obendrauf, was die Skala kalt macht.
   Gemessen: der Seitenfilter allein senkt den Blauanteil der Seite um 82 % und
   laesst gruen/gelb/rot trotzdem unterscheidbar. */
html.nachtmodus canvas,
html.nachtmodus .ampel-spur svg { filter: sepia(.55) saturate(1.2); }

/* Die Seekarte faerbt der Seitenfilter mit — gewollt: eine weisse Karte mitten
   in der Nacht ist genau das, was der Nachtmodus verhindern soll. */

.wer { font-size: 12px; color: var(--text3); }
.knopf-schlicht {
  background: none; border: 1px solid var(--border); border-radius: 7px;
  color: var(--text2); padding: 6px 11px; font-size: 12px; font-family: inherit;
  cursor: pointer; text-decoration: none; transition: all .15s; white-space: nowrap;
}
.knopf-schlicht:hover { border-color: var(--text3); color: var(--text); }

/* ── Aufbau: ein Vollbild-Werkzeug ───────────────────────────────────────── */
/* Zwei Spalten ueber die ganze Flaeche: die Schiene links steht fest und rollt
   fuer sich, rechts liegen Kopfzeile und Inhalt uebereinander.
   Vorher stand hier ein 1260 px breites, zentriertes Blatt mit einer Kopfzeile
   quer darueber. Das las sich wie eine Webseite; hier arbeitet aber jemand, und
   auf einem breiten Bildschirm blieb links und rechts Flaeche liegen, waehrend
   die Graphen in der Mitte gequetscht standen.
   Das Dokument scrollt weiterhin als Ganzes — genau wie im Schwesterprojekt.
   Ein eigener Rollbereich fuer den Inhalt saehe gleich aus, braechte aber zwei
   Rollbalken, eine zweite Stelle fuer "nach oben" und Aerger mit den Canvas-
   Breiten. Die Schiene klebt stattdessen oben und bleibt damit stehen. */
.rahmen {
  display: grid; grid-template-columns: var(--schiene-b) minmax(0, 1fr);
  align-items: stretch; min-height: 100vh; min-height: 100dvh;
  /* Die Flaeche der Schiene gehoert der SPALTE, nicht dem Element.
     Das Element ist genau einen Bildschirm hoch und klebt oben — richtig so,
     denn es soll beim Rollen stehenbleiben. Traegt es aber auch die Farbe,
     endet die Flaeche auf einer langen Seite dort, wo der Bildschirm endet,
     und darunter steht die Spalte leer. Beim Rollen faellt das nicht auf
     (die Schiene wandert ja mit), auf einem Bild der ganzen Seite sofort.
     Deshalb malt der Rahmen die Spalte durchgehend aus, samt Trennlinie, und
     die Schiene selbst bleibt durchsichtig. */
  background:
    linear-gradient(to right,
      var(--surface) 0 calc(var(--schiene-b) - 1px),
      var(--border) calc(var(--schiene-b) - 1px) var(--schiene-b),
      transparent var(--schiene-b));
}

.schiene {
  position: sticky; top: 0;
  height: 100vh; height: 100dvh; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 2px;
  padding: 14px 10px max(14px, env(safe-area-inset-bottom)) 10px;
  z-index: 40;
}
/* Die Marke oben in der Schiene, wie der Name auf einem Programmfenster. */
.schiene-marke {
  display: flex; align-items: baseline; gap: 9px;
  padding: 6px 12px 16px; text-decoration: none; color: var(--accent);
  font-size: 17px; white-space: nowrap;
}
.schiene-marke .sm-zusatz {
  font-size: 10px; font-weight: 600; letter-spacing: .15em;
  text-transform: uppercase; color: var(--text3);
}
.schiene-marke:hover .sm-zusatz { color: var(--text2); }

/* Der Fuss wird nach unten gedrueckt, damit er auch bei kurzer Liste unten
   steht — und nicht in der Mitte in der Luft haengt. */
.schiene-fuss {
  margin-top: auto; padding-top: 14px;
  border-top: 1px solid var(--border);
}
.sf-weg {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: 9px;
  color: var(--text2); font-size: 13px; text-decoration: none;
  transition: background .15s, color .15s;
}
.sf-weg:hover { background: var(--surface2); color: var(--text); }

/* Der Griff fuer die Schiene taucht erst im Schmalbild auf. */
.schiene-schalter {
  display: none; flex: 0 0 auto;
  width: 38px; height: 38px; margin-left: -6px;
  align-items: center; justify-content: center;
  background: none; border: 1px solid var(--border); border-radius: 9px;
  color: var(--text2); cursor: pointer;
}
.schiene-schalter svg { width: 19px; height: 19px; }
.schiene-schleier { display: none; }

.haupt {
  display: flex; flex-direction: column; min-width: 0;
}

.sl-gruppe {
  font-size: 9.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text3); padding: 0 12px; margin: 16px 0 7px;
}
.sl-gruppe:first-child { margin-top: 0; }
.sl-knopf {
  display: flex; align-items: center; gap: 11px; text-align: left;
  background: none; border: none; border-radius: 9px;
  padding: 9px 12px; cursor: pointer; font-family: inherit;
  transition: background .15s, color .15s;
}
.sl-knopf:hover { background: var(--surface); }
.sl-knopf.an { background: var(--surface2); }
.sl-icon {
  flex: 0 0 18px; height: 18px; color: var(--text3);
  display: flex; align-items: center; justify-content: center;
}
.sl-icon svg { width: 18px; height: 18px; }
.sl-knopf.an .sl-icon { color: var(--accent); }
.sl-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sl-name { font-size: 13px; font-weight: 600; color: var(--text2); }
.sl-knopf.an .sl-name { color: var(--text); }
.sl-neben { font-size: 10px; color: var(--text3); line-height: 1.3; }

/* Zwei Spalten: links das Breite, rechts das Schmale. Untereinander
   beanspruchte die Anwesenheitsliste eine ganze Bildschirmbreite fuer drei
   Zeilen. */
.raster {
  display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); gap: 20px;
  align-items: start;
}
.raster-breit, .raster-schmal { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
@media (max-width: 1000px) { .raster { grid-template-columns: 1fr; } }

main {
  min-width: 0; flex: 1 1 auto;
  padding: 24px 28px 64px;
  display: flex; flex-direction: column; gap: 20px;
}
.seite { display: flex; flex-direction: column; gap: 20px; }
.seiten-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 2px;
}
.seiten-kopf h1 {
  margin: 0; font-size: 21px; font-weight: 700; letter-spacing: -.01em;
}

/* ── Schmalbild: die Schiene faehrt ueber den Inhalt ─────────────────────── */
/* Vorher wurde sie hier zu einer Reiterleiste quer oben. Das ging, kostete aber
   dauerhaft Hoehe — auf einem Telefon im Querformat blieb fuer den Inhalt kaum
   etwas uebrig — und die Gruppenueberschriften mussten weg, womit die Ordnung
   verlorenging, die sie ueberhaupt erst rechtfertigt.
   Jetzt liegt sie daneben und kommt auf Griff herein. Die Ordnung bleibt, die
   Hoehe bleibt dem Inhalt. */
@media (max-width: 900px) {
  .rahmen { grid-template-columns: 1fr; background: none; }
  .schiene {
    background: var(--surface); border-right: 1px solid var(--border);
    position: fixed; top: 0; left: 0; bottom: 0;
    width: min(280px, 84vw); height: 100dvh;
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: 0 0 40px rgba(0, 0, 0, .5);
  }
  html.schiene-offen .schiene { transform: none; }
  .schiene-schalter { display: flex; }
  .schiene-schleier {
    display: block; position: fixed; inset: 0; z-index: 35;
    background: rgba(3, 7, 18, .6);
    opacity: 0; pointer-events: none; transition: opacity .22s;
  }
  html.schiene-offen .schiene-schleier { opacity: 1; pointer-events: auto; }
  /* Solange sie offen liegt, soll der Inhalt darunter nicht mitrollen. */
  html.schiene-offen body { overflow: hidden; }
  main { padding: 16px 15px 54px; }
  .kopf { padding: 0 15px; gap: 10px; }
  /* Eine Zeile bleibt eine Zeile. Der Zustandssatz ist der einzige Text hier,
     der wirklich gebraucht wird — er darf kuerzen, aber nicht umbrechen und
     die Kopfzeile doppelt so hoch machen. */
  .kopf-mitte { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}
@media (max-width: 620px) {
  /* Wer angemeldet ist, steht in der Schiene ohnehin nicht — aber auf einem
     Telefon nimmt der Name den Platz weg, den der Zustandssatz braucht.
     Abmelden bleibt: das ist eine Handlung, kein Schmuck. */
  .wer { display: none; }
}
.tafel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 18px 20px 20px;
}
.tafel-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 16px;
}
.tafel-kopf h2 {
  margin: 0; font-size: 12px; font-weight: 700; letter-spacing: .11em;
  text-transform: uppercase; color: var(--text2);
}
.hinweis { font-size: 11px; color: var(--text3); }

/* ── Verfügbarkeitsstreifen ──────────────────────────────────────────────── */
/* Ein durchgehender Balken statt vieler Balken: Ausfaelle sind Loecher in
   einer Linie, und genau so sollen sie aussehen. */
.zeitwahl { display: flex; gap: 4px; }
.zw-knopf {
  background: none; border: 1px solid var(--border); border-radius: 6px;
  color: var(--text3); padding: 4px 9px; font-size: 11px; font-family: inherit;
  cursor: pointer; transition: all .15s;
}
.zw-knopf:hover { color: var(--text2); }
.zw-knopf.an { color: var(--bg); background: var(--accent); border-color: var(--accent); }

.streifen {
  position: relative; height: 46px; border-radius: 8px; overflow: hidden;
  background: var(--surface2); display: flex;
}
.st-teil { height: 100%; position: relative; transition: filter .15s; }
.st-teil:hover { filter: brightness(1.35); }
.st-teil.an        { background: var(--green); }
.st-teil.funkloch  { background: var(--yellow); }
.st-teil.stromlos  { background: var(--red); }
.st-teil.neustart  { background: var(--violet); }
.st-teil.dienst    { background: var(--blau); }
.st-teil.erststart,
.st-teil.unbekannt { background: var(--text3); }
.st-teil.leer      { background: var(--surface2); }

.streifen-achse {
  display: flex; justify-content: space-between;
  margin-top: 6px; font-size: 10px; color: var(--text3);
}
.legende {
  display: flex; flex-wrap: wrap; gap: 14px; margin-top: 14px;
  padding-top: 13px; border-top: 1px solid var(--border);
  font-size: 11px; color: var(--text2);
}
.lg { display: flex; align-items: center; gap: 6px; }
.lg-farbe { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.lg-farbe.an { background: var(--green); }
.lg-farbe.funkloch { background: var(--yellow); }
.lg-farbe.stromlos { background: var(--red); }
.lg-farbe.neustart { background: var(--violet); }
.lg-farbe.dienst { background: var(--blau); }
.lg-farbe.unbekannt { background: var(--text3); }

/* ── Kennzahlen ──────────────────────────────────────────────────────────── */
.zahlen {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px;
}
.zahl {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 15px 17px;
  display: grid; grid-template-columns: auto 1fr; gap: 0 13px; align-items: center;
}
.zahl-icon {
  grid-row: 1 / 4; width: 38px; height: 38px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface2); color: var(--text3);
}
.zahl-icon svg { width: 19px; height: 19px; }
.zahl.gut .zahl-icon { background: color-mix(in srgb, var(--green) 15%, transparent); color: var(--green); }
.zahl.mau .zahl-icon { background: color-mix(in srgb, var(--yellow) 15%, transparent); color: var(--yellow); }
.zahl-wert {
  font-size: 25px; font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums; color: var(--text);
}
.zahl-wert.gut { color: var(--green); }
.zahl-wert.mau { color: var(--yellow); }
.zahl-lbl {
  font-size: 10px; font-weight: 600; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text3); margin-top: 6px;
}
.zahl-neben { font-size: 11px; color: var(--text2); margin-top: 3px; }

/* ── Listen: Ausfälle und Ereignisse ─────────────────────────────────────── */
.liste { display: flex; flex-direction: column; }
.zeile {
  display: grid; grid-template-columns: 132px 1fr auto; gap: 14px;
  align-items: baseline; padding: 11px 0; border-top: 1px solid var(--border);
}
.zeile:first-child { border-top: none; padding-top: 0; }
.z-zeit {
  font-size: 11px; color: var(--text3); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.z-text { font-size: 13px; color: var(--text); min-width: 0; }
.z-neben { font-size: 11px; color: var(--text2); margin-top: 2px; }
.z-dauer {
  font-size: 11px; font-weight: 600; white-space: nowrap;
  font-variant-numeric: tabular-nums; color: var(--text2);
}
.z-marke {
  display: inline-block; font-size: 9px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; padding: 2px 7px; border-radius: 4px; margin-right: 8px;
  vertical-align: 1px;
}
.z-marke.funkloch { background: color-mix(in srgb, var(--yellow) 22%, transparent); color: var(--yellow); }
.z-marke.stromlos { background: color-mix(in srgb, var(--red) 22%, transparent); color: var(--red); }
.z-marke.neustart { background: color-mix(in srgb, var(--violet) 22%, transparent); color: var(--violet); }
.z-marke.dienst   { background: color-mix(in srgb, var(--blau) 22%, transparent); color: var(--blau); }
.z-marke.erststart,
.z-marke.unbekannt { background: color-mix(in srgb, var(--text3) 25%, transparent); color: var(--text2); }
.leerlauf { padding: 22px 0; text-align: center; color: var(--text3); font-size: 13px; }

/* ── Konten ──────────────────────────────────────────────────────────────── */
.konten { display: flex; flex-direction: column; }
.konto {
  display: grid; grid-template-columns: 1fr auto auto; gap: 14px;
  align-items: center; padding: 12px 0; border-top: 1px solid var(--border);
}
.konto:first-child { border-top: none; padding-top: 0; }
.k-name { font-size: 14px; font-weight: 600; }
.k-name.gesperrt { color: var(--text3); text-decoration: line-through; }
.k-rolle { font-size: 11px; color: var(--text2); margin-top: 2px; }
.k-darf { font-size: 10px; color: var(--text3); margin-top: 3px; }
.k-tat { display: flex; gap: 6px; }
.knopf {
  background: var(--accent); border: none; border-radius: 7px; color: var(--bg);
  padding: 7px 13px; font-size: 12px; font-weight: 600; font-family: inherit;
  cursor: pointer; text-decoration: none; display: inline-block; transition: opacity .15s;
}
.knopf:hover { opacity: .9; }
.knopf.stumm { background: none; border: 1px solid var(--border); color: var(--text2); }
.knopf.stumm:hover { border-color: var(--text3); color: var(--text); }
.knopf.warn { background: none; border: 1px solid color-mix(in srgb, var(--red) 45%, transparent); color: var(--red); }
.knopf:disabled { opacity: .45; cursor: default; }

/* ── Fernwartung ─────────────────────────────────────────────────────────── */
.wartung { display: flex; flex-direction: column; gap: 13px; }
.w-zeile {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 12px 0; border-top: 1px solid var(--border);
}
.w-zeile:first-child { border-top: none; padding-top: 0; }
.w-text { font-size: 13px; }
.w-neben { font-size: 11px; color: var(--text2); margin-top: 3px; max-width: 62ch; }

/* ── Sperre und Popup ────────────────────────────────────────────────────── */
.sperre {
  position: fixed; inset: 0; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: var(--bg); z-index: 300;
}
.sperre-karte {
  max-width: 420px; text-align: center;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 14px; padding: 30px 28px;
}
.sperre-titel { font-size: 17px; font-weight: 700; margin-bottom: 10px; }
.sperre-karte p { color: var(--text2); font-size: 13px; margin: 0 0 20px; }

.pop {
  position: fixed; inset: 0; z-index: 350;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: blur(5px); -webkit-backdrop-filter: blur(5px);
}
.pop.hidden { display: none; }
.pop-karte {
  width: min(400px, 100%); background: var(--surface);
  border: 1px solid var(--border); border-radius: 14px; padding: 22px;
  box-shadow: 0 20px 60px rgba(0,0,0,.5);
}
.pop-titel { font-size: 15px; font-weight: 700; margin-bottom: 15px; }
.pop-feld { display: flex; flex-direction: column; gap: 5px; margin-bottom: 13px; }
.pop-feld span {
  font-size: 10px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text3);
}
.pop-feld input, .pop-feld select {
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  padding: 10px 11px; color: var(--text); font-size: 15px; font-family: inherit;
}
.pop-feld input:focus, .pop-feld select:focus { outline: none; border-color: var(--accent); }
.pop-fehler {
  font-size: 12px; color: var(--red); margin-bottom: 12px;
  background: color-mix(in srgb, var(--red) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--red) 32%, transparent);
  border-radius: 7px; padding: 8px 10px;
}
.pop-fehler.hidden { display: none; }
.pop-tat { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }

/* ── Anmeldung (dieselbe Gestalt wie in der Bordansicht) ─────────────────── */
.anmeldung {
  position: fixed; inset: 0; z-index: 400;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: var(--bg);
}
.anmeldung.hidden { display: none; }
.anm-karte {
  width: min(360px, 100%); background: var(--surface);
  border: 1px solid var(--border); border-radius: 16px; padding: 26px 24px 22px;
  display: flex; flex-direction: column; gap: 14px;
}
.anm-marke {
  font-size: 19px; font-weight: 700; letter-spacing: .18em;
  color: var(--accent); text-transform: uppercase; text-align: center;
}
.anm-marke span {
  display: block; font-size: 10px; font-weight: 500; letter-spacing: .16em;
  color: var(--text3); margin-top: 4px;
}
/* Der Schriftzug ist selbst ein span und wuerde sonst die Regel darueber
   erben — also klein, grau und unter sich selbst. Er traegt hier die
   Akzentfarbe und steht mittig, wie es der Marke zusteht. */
.anm-marke .marke-mave {
  display: block; margin: 0 auto 2px; color: var(--accent);
  height: 2.1em; font-size: inherit; letter-spacing: normal;
}
.anm-wohin {
  text-align: center; font-size: 12px; color: var(--text2);
  margin: -6px 0 4px; padding-bottom: 12px; border-bottom: 1px solid var(--border);
}
.anm-feld { display: flex; flex-direction: column; gap: 5px; }
.anm-feld span {
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text3);
}
.anm-feld input {
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px;
  padding: 11px 12px; color: var(--text); font-size: 15px; font-family: inherit;
}
.anm-feld input:focus { outline: none; border-color: var(--accent); }
.anm-fehler {
  font-size: 12px; color: var(--red);
  background: color-mix(in srgb, var(--red) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--red) 35%, transparent);
  border-radius: 8px; padding: 8px 10px;
}
.anm-fehler.hidden { display: none; }
.anm-knopf {
  margin-top: 4px; padding: 12px; border: none; border-radius: 9px;
  background: var(--accent); color: var(--bg);
  font-size: 14px; font-weight: 700; font-family: inherit; cursor: pointer;
}
.anm-knopf:disabled { opacity: .55; cursor: default; }

@media (max-width: 680px) {
  .kopf { padding: 0 13px; gap: 9px; }
  .kopf-mitte { font-size: 12px; }
  main { padding: 16px 13px 50px; gap: 15px; }
  .zeile { grid-template-columns: 1fr auto; }
  .z-zeit { grid-column: 1 / -1; }
  .konto { grid-template-columns: 1fr; gap: 9px; }
}

/* ── Messwerte ──────────────────────────────────────────────────────────────
   Mehrere Graphen UNTEREINANDER mit gemeinsamer Zeitachse — nicht nebeneinander
   in Kacheln. Das ist der ganze Unterschied zur Bordansicht: dort will man
   einen Wert im Vorbeigehen ablesen, hier will man sehen, dass die Spannung
   einbricht, WAEHREND der Strom steigt. Zusammenhaenge liest man nur an einer
   gemeinsamen Achse ab. */

.werkzeug { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.reihen-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-bottom: 12px;
}
.gw-knopf {
  background: none; border: 1px solid var(--border); border-radius: 6px;
  color: var(--text3); padding: 4px 9px; font-size: 11px; font-family: inherit;
  cursor: pointer; transition: all .15s; display: flex; align-items: center; gap: 5px;
}
.gw-knopf:hover { color: var(--text2); }
.gw-knopf.an { color: var(--text); border-color: var(--text3); }
.gw-punkt { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }

/* Die Kategorien stehen ueber allem und sind groesser als die Graphenknoepfe:
   sie sind die erste Wahl, die anderen die zweite. Auf dem Telefon rollen sie
   seitlich, statt umzubrechen. */
.mess-kategorien { margin-bottom: 12px; overflow-x: auto; scrollbar-width: none; }
.mess-kategorien::-webkit-scrollbar { display: none; }
.mess-kategorien .zw-knopf { font-size: 12.5px; padding: 6px 13px; white-space: nowrap; }

.reihen { display: flex; flex-direction: column; gap: 2px; position: relative; }
.reihe {
  position: relative; border-top: 1px solid var(--border);
  padding: 9px 0 4px;
}
.reihe:first-child { border-top: none; }
.reihe-kopf {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 4px;
}
.reihe-name {
  font-size: 11px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text2);
}
.reihe-jetzt {
  font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text);
  display: flex; gap: 12px; flex-wrap: wrap;
}
.rj-wert { display: flex; align-items: center; gap: 5px; }
.rj-punkt { width: 7px; height: 7px; border-radius: 2px; }
.rj-zahl { font-weight: 600; }
.rj-einheit { color: var(--text3); font-size: 10px; }
.reihe-bild { position: relative; height: 88px; }
.reihe-bild canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.reihe-spanne {
  position: absolute; right: 2px; top: 0; font-size: 9px; color: var(--text3);
  font-variant-numeric: tabular-nums; pointer-events: none;
}
.reihe-spanne.unten { top: auto; bottom: 0; }
.reihe-spanne.links { right: auto; left: 2px; }

/* Ein Graph je Kategorie — er darf hoch sein. */
.reihe-bild.gross { height: 300px; }
@media (max-width: 600px) { .reihe-bild.gross { height: 220px; } }
/* Mehrere Skalen rechts: die Zahlen stehen untereinander, jede in ihrer Farbe. */
.reihe-spanne > span { display: block; text-align: right; }
.reihe-spanne.links > span { text-align: left; }
.mess-tafel { padding-bottom: 14px; }
.zustand-feld { position: relative; margin-top: 6px; }
.zustandsleiste { display: block; width: 100%; }
/* Der Name eines Balkens, ueber dem Balken. Ein Element und kein gemalter
   Text, damit er einen Hinweis tragen kann. */
.zustand-name { position: absolute; left: 0; height: 12px; line-height: 12px;
                padding: 0 4px; font-size: 9px; color: var(--text);
                background: rgba(15,23,42,.72); border-radius: 0 3px 3px 0;
                cursor: help; white-space: nowrap; }

/* Das Hinweisfeld zu einem Wert. */
.tw-name, .zustand-name { cursor: help; }
.mess-tipp { position: fixed; z-index: 1000; max-width: 300px; pointer-events: none;
             background: var(--surface2, #263348); color: var(--text);
             border: 1px solid var(--border); border-radius: 8px;
             padding: 8px 10px; font-size: 12px; line-height: 1.45;
             box-shadow: 0 10px 28px rgba(0,0,0,.45); }
.mess-tipp b { display: block; font-size: 10.5px; font-weight: 600; letter-spacing: .05em;
               text-transform: uppercase; color: var(--text3); margin-bottom: 3px; }

/* Die Schalter ueber der Tafel: eine Reihe, und jeder traegt seinen Wert.
   Der Schalter IST die Legende — Name, Farbe und Zahl an einer Stelle. */
.tafel-werte { margin-bottom: 10px; }
/* EINE Zeile. Passt sie nicht, teilt die Seite die Kategorie auf zwei
   Graphen; passt es auch dann nicht (Telefon), rollt die Zeile seitlich,
   statt umzubrechen. */
.tw-zeile { display: flex; flex-wrap: nowrap; gap: 5px; overflow-x: auto;
            scrollbar-width: thin; padding-bottom: 2px; }
.tw-knopf { gap: 6px; white-space: nowrap; flex: none; }
/* Feste Breite (gesetzt im Code: laengster Text im Zeitraum), rechtsbuendig
   und mit gleich breiten Ziffern — beim Fahren durch den Graphen springt
   dadurch nichts. */
.tw-knopf .tw-wert { display: inline-block; text-align: right;
                     font-weight: 700; font-variant-numeric: tabular-nums;
                     color: var(--text); }
/* Nur die FARBE wechselt, nicht die Schriftstaerke: die feste Breite steht in
   Zeichenbreiten (ch), und die sind fett breiter als duenn — der Knopf wurde
   beim Ausschalten vier Pixel breiter. */
.tw-knopf:not(.an) .tw-wert { color: var(--text3); }

.faden {
  position: absolute; top: 0; bottom: 0; width: 1px;
  background: color-mix(in srgb, var(--accent) 60%, transparent);
  pointer-events: none; display: none; z-index: 5;
}
.faden.an { display: block; }
.faden-zeit {
  position: absolute; top: -19px; transform: translateX(-50%);
  background: var(--accent); color: var(--bg);
  font-size: 10px; font-weight: 700; padding: 2px 6px; border-radius: 4px;
  white-space: nowrap;
}
.zeitachse {
  display: flex; justify-content: space-between;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
  font-size: 10px; color: var(--text3);
}
.mess-leer { padding: 40px 0; text-align: center; color: var(--text3); font-size: 13px; }
/* Waehrend geladen wird, bleiben die alten Graphen stehen und werden blass.
   Sie gehoeren zum vorigen Zeitraum — sie wegzuwerfen hiesse, bei jedem
   Umschalten eine leere Seite zu zeigen. Nicht anfassbar, damit niemand in
   ein Bild hineinzielt, das gleich ein anderes ist. */
.reihen.mess-blass { opacity: .4; pointer-events: none;
                     transition: opacity .12s ease-out; }

.knopf.mehr { margin-top: 12px; width: 100%; }

.pop-hinweis {
  font-size: 11px; line-height: 1.45; color: var(--text2);
  background: var(--bg); border-radius: 8px; padding: 9px 11px; margin-bottom: 12px;
}
.pop-feld input:disabled, .pop-feld select:disabled { opacity: .5; }

/* ── Änderungen ─────────────────────────────────────────────────────────────
   Was sich geändert hat, in der Sprache des Eigners — nicht die Begründung für
   Entwickler, die in derselben Commit-Nachricht steht. */
.aenderungen { display: flex; flex-direction: column; }
.ae-stand {
  display: grid; grid-template-columns: 1fr auto; gap: 12px;
  padding: 14px 0; border-top: 1px solid var(--border);
}
.ae-stand:first-child { border-top: none; padding-top: 0; }
.ae-stand.jetzt { }
.ae-titel { font-size: 14px; font-weight: 600; line-height: 1.35; }
.ae-kopf { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.ae-marke {
  font-size: 9px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 4px;
  background: color-mix(in srgb, var(--green) 20%, transparent); color: var(--green);
}
.ae-marke.neu {
  background: color-mix(in srgb, var(--accent) 20%, transparent); color: var(--accent);
}
.ae-zeit { font-size: 11px; color: var(--text3); font-variant-numeric: tabular-nums; }
.ae-hash {
  font-size: 10px; color: var(--text3);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.ae-punkte { margin: 7px 0 0; padding-left: 17px; }
.ae-punkte li { font-size: 12px; color: var(--text2); line-height: 1.55; margin-bottom: 2px; }
.ae-ohne { font-size: 11px; color: var(--text3); margin-top: 5px; font-style: italic; }
.ae-tat { display: flex; align-items: flex-start; }

/* ── Mitschnitt ─────────────────────────────────────────────────────────────
   Zum Nachsehen, nicht zum Zuschauen: dichte Zeilen, feste Spalten, damit sich
   beim Überfliegen ein Muster zeigt. */
.ms-wahl, .ms-suche {
  background: var(--surface); border: 1px solid var(--border); border-radius: 7px;
  color: var(--text2); padding: 6px 10px; font-size: 12px; font-family: inherit;
}
.ms-wahl:focus, .ms-suche:focus { outline: none; border-color: var(--accent); color: var(--text); }
.ms-suche { min-width: 160px; }

.mitschnitt { display: flex; flex-direction: column; font-size: 12px; }
.ms-zeile {
  display: grid; grid-template-columns: 74px 88px 1fr; gap: 12px;
  padding: 7px 0; border-top: 1px solid var(--border); align-items: baseline;
}
.ms-zeile:first-child { border-top: none; }
.ms-zeit {
  color: var(--text3); font-variant-numeric: tabular-nums; white-space: nowrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
}
.ms-quelle {
  font-size: 10px; font-weight: 600; color: var(--text2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ms-text { color: var(--text); line-height: 1.45; word-break: break-word; }
.ms-zeile.fehler .ms-text { color: var(--red); }
.ms-zeile.warnung .ms-text { color: var(--yellow); }
.ms-daten {
  font-size: 10px; color: var(--text3); margin-top: 3px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
@media (max-width: 700px) {
  .ms-zeile { grid-template-columns: 1fr; gap: 2px; }
  .ms-quelle { color: var(--text3); }
}

.ae-version {
  font-size: 12px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.ae-bereich {
  font-size: 9px; font-weight: 600; letter-spacing: .05em;
  padding: 2px 6px; border-radius: 4px;
  background: var(--surface2); color: var(--text3);
}
.ae-bereich.logbuch { background: color-mix(in srgb, var(--violet) 18%, transparent); color: var(--violet); }
.ae-bereich.bordansicht { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }
.ae-bereich.server { background: color-mix(in srgb, var(--blau) 16%, transparent); color: var(--blau); }

.wahl-zeile { display: flex; gap: 16px; flex-wrap: wrap; padding: 4px 0; }
.wahl { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text2); cursor: pointer; }
.wahl input { accent-color: var(--accent); }
.pop-feld.hidden { display: none; }
.link-kasten {
  background: var(--bg); border: 1px solid var(--border); border-radius: 8px;
  padding: 11px 12px; font-size: 12px; word-break: break-all;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--accent);
  user-select: all;
}

.konto-weitere {
  display: flex; gap: 7px; flex-wrap: wrap;
  margin: 4px 0 14px; padding-top: 13px; border-top: 1px solid var(--border);
}
.konto-weitere .knopf { font-size: 11px; padding: 6px 10px; }

/* ── Der Schriftzug "Mave" ──────────────────────────────────────────────────
   Siehe style.css: ein Pfad als Maske, keine Schriftdatei. Hier eine Spur
   kleiner, weil die Kopfzeile des Logbuchs flacher ist als die der
   Bordansicht. */
.marke-mave { font-style: italic; text-transform: none; letter-spacing: .02em; }
.marke .marke-mave { color: var(--accent); }
@supports ((-webkit-mask-image: url(#a)) or (mask-image: url(#a))) {
  .marke-mave {
    display: inline-block; vertical-align: -.5em;
    height: 1.9em; aspect-ratio: 2.469 / 1;
    background: currentColor;
    -webkit-mask: url(/static/marke-mave.svg) no-repeat center / contain;
            mask: url(/static/marke-mave.svg) no-repeat center / contain;
    text-indent: -9999px; overflow: hidden; white-space: nowrap;
  }
}

/* ── Dashboard ("Überblick") ────────────────────────────────────────────────
   Ein Zwoelferraster in drei Zeilen: die Ampeln ueber die ganze Breite, danach
   zweimal 7+5. Zwoelf, weil sich damit Drittel, Viertel und Sechstel sauber
   legen lassen; 7+5 statt 6+6, weil Karte und Wetter mehr Platz brauchen als
   eine Liste mit vier Zeilen.

   Der Ueberblick fuellt GENAU einen Bildschirm — man soll draufschauen und
   fertig sein, nicht scrollen muessen, um zu wissen, wie es dem Boot geht. Wer
   stoebern will, geht auf Messwerte oder Mitschnitt; dafuer sind sie da.

   Die Hoehe kommt aus --ueberblick-h, das diagnose.js an der echten Hoehe von
   Kopfzeile und Innenabstand fuehrt (die Kopfzeile bricht auf schmalen
   Schirmen um, eine feste Zahl waere dort falsch).
   Unter 620 px Hoehe wird nicht weiter gequetscht, dann darf es rollen: lieber
   scrollen als fuenf Karten, in denen nichts mehr zu lesen ist. */
.seite[data-seite="ueberblick"] {
  height: var(--ueberblick-h, auto);
  min-height: 0;
}
/* Die feste Hoehe gilt NUR, solange das Raster zweispaltig ist. Sobald die
   Karten untereinander stehen, sind es fuenf Reihen statt drei — die passen
   nicht mehr auf einen Bildschirm, und der Versuch, sie hineinzuzwingen,
   quetscht die mittleren auf null. Dann wird gerollt, und das ist richtig so:
   lieber rollen als fuenf Karten, in denen nichts mehr zu lesen ist. */
@media (max-height: 620px), (max-width: 1180px) {
  .seite[data-seite="ueberblick"] { height: auto; }
}

.db {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 14px; align-items: stretch;
}
/* Im Ueberblick fuellt das Raster die verbleibende Hoehe. Die Ampeln richten
   sich nach ihrem Inhalt, die beiden anderen Zeilen teilen sich den Rest.
   min-height:0 auf den Karten ist Pflicht, sonst wachsen sie ueber ihren Platz
   hinaus statt ihren Inhalt zu kuerzen — die klassische Falle bei Rastern mit
   fester Hoehe. */
.seite[data-seite="ueberblick"] .db {
  flex: 1 1 auto; min-height: 0;
  grid-template-rows: auto minmax(0, 1fr) minmax(0, 1fr);
}
.seite[data-seite="ueberblick"] .db-karte {
  min-height: 0; overflow: hidden;
  padding: 14px 16px 15px;
}
@media (max-height: 620px), (max-width: 1180px) {
  .seite[data-seite="ueberblick"] .db { grid-template-rows: none; }
  .seite[data-seite="ueberblick"] .db-karte { overflow: visible; }
}
.db-karte { display: flex; flex-direction: column; min-width: 0; }
.db-karte .tafel-kopf { margin-bottom: 12px; }
/* Die Ampeln bringen ihre eigenen Trennlinien mit und brauchen deshalb keinen
   Innenabstand der Karte — sonst haetten sie einen Rahmen im Rahmen. */
.seite[data-seite="ueberblick"] #kAmpeln { padding: 0; border: none; background: none; }

.sp12 { grid-column: span 12; }
.sp7 { grid-column: span 7; }
.sp5 { grid-column: span 5; }

/* Zwei Stufen, nicht fuenf. Bei 1180 wird aus 7+5 ein 12+12; darunter steht
   ohnehin alles untereinander. Mehr Stufen sehen im Entwurf klug aus und
   fuehren im Betrieb dazu, dass niemand mehr weiss, warum eine Karte gerade so
   breit ist. */
@media (max-width: 1180px) {
  .sp7, .sp5 { grid-column: 1 / -1; }
}
@media (max-width: 760px) {
  .db { gap: 12px; }
  .sp12, .sp7, .sp5 { grid-column: 1 / -1; }
}

/* Der Balken ganz oben, wenn der ganze Schnappschuss alt ist. */
.db-warnung {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 15px; border-radius: 12px;
  background: color-mix(in srgb, var(--yellow) 12%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--yellow) 38%, transparent);
  font-size: 12.5px; color: var(--text);
}
.db-warnung.schwer {
  background: color-mix(in srgb, var(--red) 12%, var(--surface));
  border-color: color-mix(in srgb, var(--red) 38%, transparent);
}
.dbw-mark {
  font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  background: var(--yellow); color: #1b1405; border-radius: 5px;
  padding: 2px 7px; flex: 0 0 auto;
}
.db-warnung.schwer .dbw-mark { background: var(--red); color: #240b0b; }

/* ── Farbe als Zustand ──────────────────────────────────────────────────── */
/* Ein Punkt und vier Farbklassen, ueberall dieselben. Wer einmal gelernt hat,
   was Gelb heisst, muss es in der naechsten Karte nicht neu lernen. */
.punkt {
  width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto;
  background: var(--text3);
}
.punkt.gut  { background: var(--green);  box-shadow: 0 0 0 3px color-mix(in srgb, var(--green) 20%, transparent); }
.punkt.warn { background: var(--yellow); box-shadow: 0 0 0 3px color-mix(in srgb, var(--yellow) 20%, transparent); }
.punkt.rot  { background: var(--red);    box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 22%, transparent); }
.w-gut { color: var(--green); }
.w-warn { color: var(--yellow); }
.w-rot { color: var(--red); }
.w-ruhe { color: var(--text2); }

/* ── Zeile 1: die Ampeln ────────────────────────────────────────────────── */
/* Farbe vor Zahl. Aus zwei Metern soll erkennbar sein, ob etwas nicht stimmt;
   die Zahl steht daneben, fuer den zweiten Blick. */
.ampeln {
  display: grid; grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1px; background: var(--border);
  border: 1px solid var(--border); border-radius: 11px; overflow: hidden;
}
/* SECHS Ampeln, seit „Software" dazugekommen ist. Vorher stand hier fest die
   Fünf — und die sechste Kachel stand allein in einer zweiten Reihe, neben
   vier leeren Zellen, die aussahen wie Kacheln, in denen etwas fehlt.
   Sechs geht dafür in jeder Stufe glatt auf (6, 3, 2), und die Sonderregel
   „die letzte nimmt den Rest der Reihe mit" wird nicht mehr gebraucht. */
@media (max-width: 1400px) { .ampeln { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 700px)  { .ampeln { grid-template-columns: repeat(2, 1fr); } }
.ampel {
  background: var(--surface2); padding: 10px 13px 11px;
  display: flex; flex-direction: column; gap: 3px; min-width: 0;
  position: relative; overflow: hidden;
}
/* Der Verlauf der letzten 24 Stunden als Flaeche HINTER dem Text — dieselbe
   Sprache wie in der Statusleiste der Bordansicht: nach unten durchsichtig
   auslaufend, in der Zustandsfarbe des Feldes. Er beantwortet nebenbei "war
   das schon laenger so?", ohne dass ein Diagramm Platz kostet.
   Die Wartung bekommt keinen: ein Wartungsplan hat keinen Tagesverlauf, und
   eine Flaeche, die nur Dekoration waere, ist hier fehl am Platz. */
/* Die Fläche nimmt die GANZE Kachel ein. Das ist keine Kosmetik: die Oberkante
   des Feldes ist das Maximum der Skala — hundert Prozent Ladestand berühren
   den oberen Rand. Sie weiter unten beginnen zu lassen hiesse, die Skala zu
   stauchen, und der Blick von zwei Metern verlöre seinen Bezugspunkt.
   Der Text darüber wird deshalb nicht durch Weglassen der Fläche lesbar
   gemacht, sondern durch einen Hof in der Farbe des Untergrunds (siehe
   .ampel-name). */
.ampel-spur { position: absolute; inset: 0; pointer-events: none; }
.ampel-spur svg { display: block; width: 100%; height: 100%; }
.ampel > *:not(.ampel-spur) { position: relative; }
.ampel-kopf { display: flex; align-items: center; gap: 7px; }
.ampel-name {
  font-size: 10px; font-weight: 700; letter-spacing: .09em;
  /* --text3 ergab selbst auf blankem Grund nur 3,26:1 und lag damit schon
     ohne Fläche unter dem, was für kleinen Text nötig ist. */
  text-transform: uppercase; color: var(--text2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  /* Ein Hof in der Farbe des Untergrunds. Er schiebt die Verlaufsfläche in den
     zwei Pixeln um jeden Buchstaben herum beiseite und stellt dort den
     Kontrast des blanken Grundes wieder her — ohne die Fläche selbst
     anzutasten. Wo keine Fläche liegt, ist er unsichtbar, weil er dieselbe
     Farbe hat wie das, worauf er liegt. */
  text-shadow: 0 0 3px var(--surface2), 0 0 3px var(--surface2),
               0 0 6px var(--surface2);
}
.ampel-wert {
  font-size: 17px; font-weight: 700; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.ampel-wert small { font-size: 10.5px; font-weight: 600; color: var(--text2); margin-left: 2px; }
.ampel-neben {
  font-size: 11px; color: var(--text2);
  text-shadow: 0 0 3px var(--surface2), 0 0 3px var(--surface2),
               0 0 6px var(--surface2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Zeile 2 links: Ort und Wetter ──────────────────────────────────────── */
.ort {
  display: grid; grid-template-columns: minmax(0, 1fr) 172px; gap: 13px;
  flex: 1 1 auto; min-height: 0;
}
@media (max-width: 760px) { .ort { grid-template-columns: 1fr; } }
.kartenfeld {
  position: relative; border-radius: 10px; overflow: hidden;
  border: 1px solid var(--border); background: var(--surface2);
  min-height: 150px;
}
/* Leaflet setzt seine Kacheln absolut; ohne eigene Hoehe faellt das Feld auf
   null zusammen und die Karte bleibt unsichtbar. Im Ueberblick kommt die Hoehe
   aus dem Raster, auf schmalen Schirmen braucht es eine feste. */
@media (max-height: 620px), (max-width: 1180px) { .kartenfeld { height: 240px; } }
@media (max-width: 760px) { .kartenfeld { height: 210px; } }
.karten-warte {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 12px; color: var(--text3); text-align: center; padding: 0 14px;
}
.ort-daten { display: flex; flex-direction: column; gap: 9px; min-width: 0; }
.koord {
  font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-size: 12.5px; font-variant-numeric: tabular-nums; line-height: 1.5;
  color: var(--text);
}
.koord span { color: var(--text3); font-family: inherit; }
.wetter {
  border-top: 1px solid var(--border); padding-top: 9px;
  display: flex; flex-direction: column; gap: 6px;
}
.wetter-haupt { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.wetter-grad { font-size: 24px; font-weight: 700; font-variant-numeric: tabular-nums; }
.wetter-wort { font-size: 12px; color: var(--text2); }
.wetter-zeile {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 11.5px; color: var(--text2); font-variant-numeric: tabular-nums;
}
.wetter-zeile b { color: var(--text); font-weight: 600; }
.wetter-quelle { font-size: 9.5px; color: var(--text3); letter-spacing: .03em; }

/* ── Zeile 2 rechts: Strom ──────────────────────────────────────────────── */
.quellen {
  display: flex; flex-direction: column; gap: 1px;
  flex: 1 1 auto; min-height: 0; justify-content: space-between;
}
.quelle {
  display: grid; grid-template-columns: 3px minmax(0, 1fr) auto;
  align-items: center; gap: 9px; padding: 7px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  font-size: 13px;
}
.quelle:last-child { border-bottom: 0; }
.q-strich { width: 3px; height: 17px; border-radius: 2px; background: var(--border); }
.q-strich.an { background: var(--green); }
.q-strich.raus { background: var(--blau); }
.q-name { color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.q-wert { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.q-wert small { font-size: 10.5px; font-weight: 600; color: var(--text3); margin-left: 2px; }
.q-aus { color: var(--text3); font-weight: 600; }
.bilanz {
  margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border);
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; color: var(--text2);
}
.bilanz b { font-size: 15px; font-variant-numeric: tabular-nums; color: var(--text); }

/* ── Zeile 3 links: Heizung ─────────────────────────────────────────────── */
.heiz { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 760px) { .heiz { grid-template-columns: repeat(2, 1fr); } }
.kennzahl { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.k-name {
  font-size: 9.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--text3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.k-wert {
  font-size: 19px; font-weight: 700; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.k-wert small { font-size: 10.5px; font-weight: 600; color: var(--text2); margin-left: 2px; }
.raeume {
  margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 7px;
  overflow-y: auto; overscroll-behavior: contain; min-height: 0;
}
.raum {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center; gap: 10px; font-size: 12.5px;
}
.raum-name { color: var(--text2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.raum-ist { font-weight: 700; font-variant-numeric: tabular-nums; }
.raum-soll { font-size: 11.5px; color: var(--text3); font-variant-numeric: tabular-nums; }
.heiz-hinweis {
  margin-top: auto; padding-top: 11px; font-size: 11.5px; color: var(--yellow);
  display: flex; align-items: center; gap: 7px;
}
.heiz-hinweis.still { color: var(--text3); }

/* ── Zeile 3 rechts: Geräte ─────────────────────────────────────────────── */
.geraete {
  display: flex; flex-direction: column; gap: 1px;
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
}
.geraet {
  display: grid; grid-template-columns: 9px minmax(0, 1fr) auto;
  align-items: center; gap: 10px; padding: 8px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}
.geraet:last-child { border-bottom: 0; }
.g-name { font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.g-neben { display: block; font-size: 10.5px; color: var(--text3); }
.g-zeit { font-size: 11px; color: var(--text3); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── Innenleben der übrigen Karten ──────────────────────────────────────── */
/* Bleibt fuer die Positionsseite: dort steht der Satz oben, die Zahl darunter. */
.dk-kopf {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px;
}
.dk-kopf h2 {
  margin: 0; font-size: 11px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text3);
}
.dk-frische {
  margin-left: auto; font-size: 10.5px; color: var(--text3); white-space: nowrap;
  display: flex; align-items: center; gap: 6px;
}
.dk-punkt { width: 7px; height: 7px; border-radius: 50%; background: var(--green); flex: 0 0 auto; }
.dk-punkt.alt { background: var(--yellow); }
.dk-punkt.aus { background: var(--text3); }
.dk-satz { font-size: 15px; font-weight: 600; line-height: 1.35; }
.dk-satz.leer { color: var(--text2); font-weight: 500; }
.dk-neben { font-size: 12px; color: var(--text2); }

/* Die Belegzeile: Name links, Wert rechts. Immer dasselbe Muster, damit das
   Auge an derselben Stelle sucht. */
.dk-liste { margin-top: auto; padding-top: 14px; display: flex; flex-direction: column; }
.dk-zeile {
  display: flex; align-items: baseline; gap: 10px;
  padding: 6px 0; border-top: 1px solid var(--border);
  font-size: 12.5px;
}
.dk-zeile:first-child { border-top: none; }
.dk-name { color: var(--text2); }
.dk-wert { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }
.dk-wert.still { color: var(--text3); font-weight: 500; }
.dk-wert.gut { color: var(--green); }
.dk-wert.mau { color: var(--yellow); }
.dk-wert.schlecht { color: var(--red); }
.dk-grund { font-size: 11.5px; color: var(--text3); margin-top: -2px; padding-bottom: 6px; }

/* ── Einstellungen ──────────────────────────────────────────────────────── */
/* Eine Wahl je Zeile, die Begruendung gleich daneben. Ein Auswahlfeld waere
   kuerzer und wuerde verschweigen, WARUM man das eine oder das andere nimmt —
   und genau daran haengt hier alles: welches Modell ueber der Ostsee taugt,
   weiss man nicht aus dem Namen. */
.es-text {
  margin: 0 0 16px; font-size: 13px; line-height: 1.6; color: var(--text2);
  max-width: 62ch;
}
.es-wahl { display: flex; flex-direction: column; gap: 1px; }
.es-zeile {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px;
  align-items: start; padding: 11px 12px; border-radius: 9px;
  border: 1px solid transparent; cursor: pointer;
}
.es-zeile:hover { background: var(--surface2); }
.es-zeile.an { background: var(--surface2); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
.es-zeile input { accent-color: var(--accent); margin-top: 2px; }
.es-zeile b { font-size: 13.5px; font-weight: 600; }
.es-neben { display: block; font-size: 11.5px; color: var(--text3); margin-top: 2px; }
.es-zeile input:disabled { cursor: default; }
.es-zeile:has(input:disabled) { cursor: default; opacity: .7; }

/* ── Zeitleiste der Messwerte ───────────────────────────────────────────── */
/* Zwei Pfeile, zwei Felder, ein Rueckweg ins Jetzt. Bewusst KEIN Ziehbalken
   ueber dem Graphen: der laesst sich mit der Maus fein bedienen und mit dem
   Daumen gar nicht, und diese Seite wird auch auf dem Telefon geoeffnet. */
/* Der Bereichsschieber. Zwei Griffe auf einer Spur, die den gesamten
   vorhandenen Verlauf zeigt; das Band dazwischen ist der gezeigte Ausschnitt.
   Er ist das GROBE Werkzeug — hinziehen, wo es ungefaehr war —, die Felder
   darunter das genaue. Beide zusammen, weil beides vorkommt. */
.zl-schiene { margin: 2px 0 14px; }
.zls-spur {
  position: relative; height: 30px; border-radius: 8px;
  background: var(--surface2); border: 1px solid var(--border);
  /* Der Griff soll auch am aeussersten Rand noch ganz auf der Spur liegen. */
  margin: 0 11px;
  touch-action: none;      /* sonst scrollt das Telefon, statt zu ziehen */
}
.zls-band {
  position: absolute; top: -1px; bottom: -1px;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 8px; cursor: grab;
}
.zls-band:active { cursor: grabbing; }
.zls-griff {
  position: absolute; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px;
  border-radius: 50%; border: 2px solid var(--bg);
  background: var(--accent); padding: 0; cursor: ew-resize;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  /* Der sichtbare Punkt ist 22 px; die Flaeche zum Anfassen ist groesser —
     mit dem Daumen trifft man 22 px nicht zuverlaessig. */
  outline-offset: 4px;
}
.zls-griff::before {
  content: ''; position: absolute; inset: -9px; border-radius: 50%;
}
.zls-griff:focus-visible { outline: 2px solid var(--text); }
.zls-marken {
  display: flex; justify-content: space-between; margin: 5px 12px 0;
  font-size: 10.5px; color: var(--text3); font-variant-numeric: tabular-nums;
}

.zeitleiste {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.zl-pfeil {
  background: none; border: 1px solid var(--border); border-radius: 7px;
  color: var(--text2); font-family: inherit; font-size: 15px; line-height: 1;
  padding: 7px 11px; cursor: pointer;
}
.zl-pfeil:hover { border-color: var(--text3); color: var(--text); }
.zl-navi { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.zl-feld {
  display: flex; align-items: center; gap: 7px;
  font-size: 11px; color: var(--text3); min-width: 0;
}
.zl-feld input { min-width: 0; }
.zl-feld input {
  background: var(--surface2); border: 1px solid var(--border); border-radius: 7px;
  color: var(--text); font-family: inherit; font-size: 12.5px;
  padding: 6px 9px; font-variant-numeric: tabular-nums;
  /* Chrome faerbt das Kalendersymbol schwarz — auf dunklem Grund unsichtbar. */
  color-scheme: dark;
}
.zl-feld input:focus { outline: none; border-color: var(--accent); }
.zl-hinweis { font-size: 11px; color: var(--text3); margin-left: auto; }
@media (max-width: 700px) {
  /* Schmal teilen sich die beiden Datumsfelder eine Zeile; die Knoepfe stehen
     darueber. Zwei Zeilen statt fuenf. */
  .zl-feld { flex: 1 1 46%; }
  .zl-feld > span { display: none; }      /* das Format sagt schon, was gemeint ist */
  .zl-hinweis { margin-left: 0; flex: 1 1 100%; }
}

/* ── Aufbau: die Nachschlageseite ───────────────────────────────────────── */
/* Zum LESEN gebaut, nicht zum Ablesen. Deshalb Fliesstext in Lesebreite statt
   Kacheln, und die Zahlen in Tabellenform mit ihrer Quelle daneben: wer nicht
   glaubt, was dasteht, soll nachsehen koennen, ohne zu suchen. */
.aufbau { display: flex; flex-direction: column; gap: 16px; }
.au-text {
  margin: 0 0 14px; font-size: 13.5px; line-height: 1.65; color: var(--text2);
  max-width: 74ch;
}
.au-text b { color: var(--text); font-weight: 600; }
.au-gruppe {
  margin: 24px 0 10px; font-size: 10.5px; font-weight: 700; letter-spacing: .11em;
  text-transform: uppercase; color: var(--accent);
}
.au-gruppe:first-of-type { margin-top: 4px; }

/* Die drei Namen. Der eigene bekommt eine Kante — man soll auf einen Blick
   sehen, wo man gerade steht, ohne die Adresszeile zu lesen. */
.au-namen { display: flex; flex-direction: column; gap: 1px; }
.au-name {
  padding: 13px 15px; border-radius: 10px; background: var(--surface2);
  border-left: 3px solid transparent;
}
.au-name.hier { border-left-color: var(--accent); }
.au-name-kopf { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.au-name code {
  font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-size: 13px; color: var(--text); font-weight: 600;
}
.au-rolle { font-size: 11px; color: var(--text3); }
.au-marke {
  font-size: 9.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 5px; padding: 1px 6px; margin-left: auto;
}
.au-name p {
  margin: 7px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--text2);
  max-width: 74ch;
}

.au-flaechen { display: flex; flex-direction: column; gap: 1px; }
.au-flaeche { padding: 13px 0; border-top: 1px solid var(--border); }
.au-flaeche:first-child { border-top: none; padding-top: 0; }
.au-flaeche-kopf { display: flex; align-items: baseline; gap: 11px; }
.au-flaeche-kopf b { font-size: 14px; }
.au-flaeche-kopf code {
  font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-size: 11.5px; color: var(--text3);
}
.au-flaeche p {
  margin: 6px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--text2);
  max-width: 74ch;
}

/* Der Weg der Daten als Kette. Vier Stufen, drei Pfeile — im Schmalbild
   untereinander, dann drehen sich die Pfeile mit. */
.au-weg {
  display: flex; align-items: stretch; gap: 10px; margin-bottom: 16px;
  flex-wrap: wrap;
}
.au-stufe {
  flex: 1 1 150px; min-width: 0; padding: 12px 14px;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 10px;
  display: flex; flex-direction: column; gap: 4px;
}
.au-stufe b { font-size: 13px; }
.au-stufe span { font-size: 11.5px; color: var(--text3); line-height: 1.45; }
.au-pfeil {
  flex: 0 0 auto; align-self: center; width: 14px; height: 14px;
  border-right: 2px solid var(--border); border-top: 2px solid var(--border);
  transform: rotate(45deg);
}
@media (max-width: 720px) {
  .au-weg { flex-direction: column; }
  .au-pfeil { transform: rotate(135deg); }
}

/* Die Takte. Drei Spalten: was, wie oft, woher die Zahl stammt. */
.au-takte { display: flex; flex-direction: column; }
.au-takt {
  /* Die Quellenspalte bekommt, was sie braucht — abgeschnitten waere sie
     wertlos: sie steht da, damit man nachschlagen kann, ohne zu suchen.
     Nachgeben muss die Beschreibung, die notfalls umbricht. */
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline; gap: 14px; padding: 8px 0;
  border-top: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
  font-size: 12.5px;
}
.au-takt:first-child { border-top: none; }
.au-was { color: var(--text); min-width: 0; }
.au-neben { display: block; font-size: 11px; color: var(--text3); margin-top: 1px; }
.au-wert {
  font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap;
  color: var(--text);
}
.au-quelle {
  font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-size: 10.5px; color: var(--text3); text-align: right; white-space: nowrap;
}
/* Schmal faellt die Quellenspalte weg — sie ist Beleg, nicht Inhalt, und
   zwaenge den Rest sonst in zwei Zeichen Breite. */
@media (max-width: 720px) {
  .au-takt { grid-template-columns: minmax(0, 1fr) auto; }
  .au-quelle { display: none; }
}

/* ── Alarme seit dem letzten Blick ──────────────────────────────────────── */
/* Ueber allem, weil ein uebersehener Alarm der teuerste Fehler dieser
   Oberflaeche waere. Deshalb auch kein stiller Streifen am Rand, sondern etwas,
   das man wegklicken MUSS — und dabei liest, was war. */
.alarmvorhang {
  /* Ueber ALLEM heisst auch: ueber der Karte. Leaflet legt seine Ebenen auf
     z-index 200 bis 700 und stand mit einer kleineren Zahl mitten im Vorhang.
     1200 liegt darueber und unter nichts, was es hier sonst gaebe. */
  position: fixed; inset: 0; z-index: 1200;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(3px);
  display: grid; place-items: center; padding: 24px;
}
.alarmkasten {
  width: min(620px, 100%); max-height: min(74vh, 640px);
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 16px; overflow: hidden;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
  /* Die rote Kante links statt eines roten Kastens: der Vorhang soll auffallen
     und nicht anschreien. Wer nachts aufsteht und aufs Handy schaut, hat genug
     Schreck ohne eine leuchtend rote Flaeche. */
  border-left: 3px solid var(--red);
}
.ak-kopf {
  display: flex; align-items: baseline; gap: 12px;
  padding: 17px 20px 13px; border-bottom: 1px solid var(--border);
}
.ak-kopf h2 { margin: 0; font-size: 15px; font-weight: 700; color: var(--text); }
.ak-zahl { margin-left: auto; font-size: 11.5px; color: var(--text3); white-space: nowrap; }
.ak-liste { overflow-y: auto; overscroll-behavior: contain; padding: 4px 20px; }
.ak-eintrag {
  display: grid; grid-template-columns: 9px minmax(0, 1fr) auto;
  gap: 11px; align-items: start; padding: 12px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 60%, transparent);
}
.ak-eintrag:last-child { border-bottom: 0; }
.ak-eintrag .punkt { margin-top: 4px; }
.ak-name { font-size: 13.5px; font-weight: 600; }
.ak-neben { font-size: 11.5px; color: var(--text3); margin-top: 2px; line-height: 1.45; }
.ak-marken { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 5px; }
.ak-marke {
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  border-radius: 5px; padding: 2px 7px;
  border: 1px solid var(--border); color: var(--text3);
}
/* Quittiert und vorbei sind zwei verschiedene Aussagen, und beide muessen
   dastehen: ein Alarm kann von selbst gegangen sein, ohne dass ihn je jemand
   gesehen hat — genau das will man wissen. */
.ak-marke.quittiert {
  border-color: color-mix(in srgb, var(--green) 45%, transparent); color: var(--green);
}
.ak-marke.offen {
  border-color: color-mix(in srgb, var(--yellow) 45%, transparent); color: var(--yellow);
}
.ak-marke.weg { border-color: var(--border); color: var(--text2); }
.ak-zeit { font-size: 11px; color: var(--text3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ak-fuss {
  display: flex; align-items: center; gap: 14px;
  padding: 13px 20px 15px; border-top: 1px solid var(--border);
}
.ak-hinweis { font-size: 11.5px; color: var(--text3); }
.ak-fuss .knopf { margin-left: auto; }

/* ── Position ───────────────────────────────────────────────────────────────
   Karte gross, Zahlen daneben. Umgekehrt waere es falsch: die Frage lautet
   "wo liegt das Boot", und die beantwortet die Karte, nicht die Koordinate. */
.pos-raster {
  display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px;
  align-items: stretch;
}
@media (max-width: 1080px) { .pos-raster { grid-template-columns: 1fr; } }

.pos-tafel { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.karte {
  /* Eine Karte braucht Hoehe. Zu wenig davon, und man sieht nur die eigene
     Umgebung im Umkreis von zweihundert Metern. */
  height: clamp(360px, 62vh, 680px); width: 100%;
  background: var(--surface2);
  display: flex; align-items: center; justify-content: center;
}
.karte-warte { font-size: 13px; color: var(--text3); }
.karte-fuss {
  padding: 11px 18px; border-top: 1px solid var(--border);
  font-size: 12px; color: var(--text3);
  display: flex; gap: 18px; flex-wrap: wrap;
}
.karte-fuss b { color: var(--text2); font-variant-numeric: tabular-nums; }

/* Die Grundkarte ist hell, die Oberflaeche dunkel. Ein wenig heruntergedimmt
   stoert sie das Auge nicht mehr — die Seezeichen darueber bleiben unberuehrt,
   sonst waeren sie nicht mehr zu lesen, und genau die braucht man hier. */
.karte-grund { filter: brightness(.78) saturate(.82) contrast(1.05); }
/* Die Karte bleibt in ihrer eigenen Ebene.
   Leaflet vergibt INTERN z-index 200 bis 1000 — Kartenebenen 200-700, die
   Bedienelemente (Zoom, Herkunftsangabe) 800-1000. Ohne eigenen Stapelkontext
   messen sich diese Zahlen mit denen der Seite, und die Karte legt sich vor
   alles, was kleiner ist: die Kopfzeile (30), die Seitenschiene (40) und ihren
   Schleier (35). In der mobilen Ansicht heisst das, die Karte liegt vor dem
   ausgefahrenen Menue — vom Eigner am 07.09.2026 gemeldet.
   Der Alarmvorhang war schon einmal derselbe Fall und wurde einzeln auf 1200
   gehoben. Das ist Flickschusterei: dann muss JEDES Bedienelement Leaflet
   ueberbieten, und das naechste, das dazukommt, faellt wieder hinein.
   `isolation: isolate` macht aus dem Kartenfeld einen eigenen Stapelkontext.
   Innen aendert sich nichts — Ebenen, Bedienelemente und Sprechblasen liegen
   weiter richtig zueinander —, nach aussen zaehlt nur noch das Feld selbst,
   und das ordnet sich wie jeder andere Kasten ein.

   NACHGEMESSEN und NICHT nachgestellt: in Chromium bei 390 px liegen auf allen
   neun Seiten Schiene UND Schleier vorn, auch OHNE diese Regel (elementFromPoint
   an vier Punkten je Seite, dazu die Gegenprobe mit herausgenommener Regel).
   Irgendetwas im Bestand kapselt die Karte dort also schon. Die Regel bleibt
   trotzdem, und zwar nicht auf Verdacht: sie macht den Fall UNMOEGLICH, statt
   ihn von einer Eigenschaft abhaengen zu lassen, die niemand aufgeschrieben hat
   und die beim naechsten Umbau verschwindet. Woran es auf dem Geraet des
   Eigners wirklich lag, ist damit NICHT geklaert — Verdacht Safari/iPadOS. */
.leaflet-container {
  background: var(--surface2); font: inherit;
  isolation: isolate; z-index: 0;
}
.leaflet-control-attribution {
  background: rgba(11, 17, 32, .78) !important; color: var(--text3) !important;
  font-size: 10.5px !important;
}
.leaflet-control-attribution a { color: var(--text2) !important; }
.leaflet-bar a {
  background: var(--surface) !important; color: var(--text) !important;
  border-color: var(--border) !important;
}
.leaflet-bar a:hover { background: var(--surface2) !important; }

/* Die Koordinate selbst: gross genug zum Ablesen und Weitersagen. */
.pos-koord {
  font-family: var(--mono, ui-monospace, "SF Mono", Menlo, Consolas, monospace);
  font-size: 15px; font-weight: 600; line-height: 1.5;
  font-variant-numeric: tabular-nums;
}
.pos-kopieren {
  margin-top: 10px; align-self: flex-start;
  background: none; border: 1px solid var(--border); border-radius: 7px;
  color: var(--text2); padding: 6px 11px; font-size: 12px; font-family: inherit;
  cursor: pointer;
}
.pos-kopieren:hover { border-color: var(--text3); color: var(--text); }

/* ── KI-Zugang ──────────────────────────────────────────────────────────────
   Er steht auf derselben Seite wie das Wettermodell und benutzt dieselbe
   Tafel — nur die Knopfzeile darunter ist neu. */
.es-tat { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
.es-tat .hinweis { margin: 0; }

/* ── Die Flotte ──────────────────────────────────────────────────────────────
   Eine Zeile je Bordgerät, in der Fernwartung ganz oben. Die Zeile ist ein
   Knopf: aus der Ferne will man von "läuft alles" mit einem Griff auf "was
   genau läuft da" kommen, ohne eine zweite Seite zu suchen.

   Die Ampel ist ein Streifen und kein Punkt. Ein Punkt wäre bei den drei
   Zuständen dieser Liste zu wenig Fläche, um ihn im Vorbeigehen zu lesen —
   und Farbe ist hier die einzige Auszeichnung, weil daneben schon Text steht. */
.flotte { display: flex; flex-direction: column; }

.fl-zeile {
  display: grid; grid-template-columns: 5px 1fr auto; gap: 14px;
  align-items: center; width: 100%; text-align: left;
  padding: 12px 0; border: none; border-top: 1px solid var(--border);
  background: none; color: inherit; font-family: inherit; cursor: pointer;
}
.fl-zeile:first-child { border-top: none; padding-top: 0; }
.fl-zeile:hover .fl-name { color: var(--accent); }

.fl-ampel { align-self: stretch; min-height: 30px; border-radius: 2px; }
.fl-ampel.gruen { background: var(--green); }
.fl-ampel.gelb  { background: var(--yellow); }
.fl-ampel.rot   { background: var(--red); }

.fl-namen { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.fl-name { font-size: 13px; font-weight: 600; transition: color .15s; }
.fl-nr {
  font-size: 11px; color: var(--text3); font-weight: 400; margin-left: 6px;
}
.fl-schluessel {
  font-size: 11px; color: var(--text2);
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.fl-stand { display: flex; flex-direction: column; gap: 3px; text-align: right; }
.fl-fassung {
  font-size: 13px; font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}
.fl-neben { font-size: 11px; color: var(--text2); }
.fl-hinweis {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
  font-size: 11px; color: var(--text2); max-width: 62ch;
}

/* ── Ein Gerät im Popup ────────────────────────────────────────────────────
   Fünf Blöcke in fester Reihenfolge: was läuft, was verfügbar wäre, was an
   Bord lief, was es gibt, was gemeldet ist. Die Reihenfolge ändert sich nie —
   eine Oberfläche, die ihre Anordnung wechselt, muss man jedes Mal neu lesen. */
.fl-detail { max-height: 62vh; overflow-y: auto; margin: 4px 0 2px; }

.fl-block { padding: 12px 0; border-top: 1px solid var(--border); }
.fl-block:first-child { border-top: none; padding-top: 4px; }
.fl-block-kopf {
  font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text2); margin-bottom: 7px;
}
.fl-gross {
  font-size: 20px; font-weight: 600; margin-bottom: 4px;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}
.fl-gross.neu { color: var(--yellow); }

.fl-liste { list-style: none; margin: 0; padding: 0; }
.fl-liste li {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 12px; padding: 5px 0; border-top: 1px solid var(--border);
}
.fl-liste li:first-child { border-top: none; }
.fl-liste a { color: var(--accent); text-decoration: none; }
.fl-zeit { font-size: 11px; color: var(--text3); }
.fl-leer { color: var(--text3); }

/* Die Markierung, an der VS Code erkennt, was Claude abarbeiten soll. Sie ist
   ein GitHub-Label und kein eigener Zustand — deshalb sieht sie hier aus wie
   ein Schalter und nicht wie ein Arbeitsablauf. */
/* Drei feste Spalten: Nummer, Titel, Schalter. Mit `flex-wrap` sprang der
   Schalter bei laengeren Titeln in die naechste Zeile und stand mal rechts,
   mal darunter — eine Liste, deren Knoepfe wandern, liest sich zweimal. */
.fl-liste li.fl-issue {
  display: grid; grid-template-columns: auto 1fr auto; gap: 8px;
  align-items: center; flex-wrap: nowrap;
}
.fl-issue-titel { min-width: 0; overflow-wrap: anywhere; }
/* Die Knöpfe einer Ticketzeile sind EIN Rasterfeld, nicht drei. Das Raster
   hat drei Spalten (Nummer, Titel, Rest) und wird auch von der Störungsliste
   benutzt — als „Ändern" und „Wegräumen" dazukamen, standen fünf Kinder in
   drei Spalten, und die Zeile lief auseinander. */
.fl-issue-tat { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }

.fl-marke {
  border: 1px solid var(--border); border-radius: 6px;
  background: none; color: var(--text2); padding: 3px 9px; font-size: 11px;
  font-family: inherit; cursor: pointer; white-space: nowrap; transition: all .15s;
}
.fl-marke:hover { border-color: var(--text3); color: var(--text); }
.fl-marke.an { border-color: var(--violet); color: var(--violet); }

.fl-eingabe {
  width: 100%; box-sizing: border-box; margin: 8px 0 0;
  background: var(--surface2); border: 1px solid var(--border); border-radius: 7px;
  color: var(--text); padding: 8px 11px; font-size: 13px; font-family: inherit;
}
.fl-eingabe:focus { outline: none; border-color: var(--accent); }
.fl-haken {
  display: flex; align-items: center; gap: 8px; margin-top: 10px;
  font-size: 12px; color: var(--text2); cursor: pointer;
}
.fl-fehler { margin-top: 10px; font-size: 12px; color: var(--red); }

/* Die zwei Knoepfe zum Aufspielen. Der zweite ist gesperrt und bleibt es —
   siehe die Begruendung in diagnose.js. Er steht trotzdem da, weil ein Knopf,
   den es nicht gibt, keine Frage beantwortet: so sieht man, dass es den
   Schritt gibt und warum er hier nicht geht. */
.fl-tat { display: flex; gap: 10px; align-items: center; margin-bottom: 8px; }

/* Ein gesperrter Knopf darf nicht aussehen wie ein Hauptknopf. Nur die
   Deckkraft zu senken reicht dafuer nicht: das Akzentblau bleibt auch bei
   40 Prozent blau und liest sich weiter als "hier klicken". Er verliert
   deshalb die Farbe ganz. */
.fl-vollbild .knopf[disabled],
.fl-vb-tafel .knopf[disabled],
.fl-tat .knopf[disabled] {
  background: none; border: 1px solid var(--border); color: var(--text3);
  cursor: not-allowed; opacity: 1;
}

/* Die Fassung steht rechts, darunter was mit ihr los ist. Ein Update faerbt
   nur die Nebenzeile — die Zahl selbst soll nicht blinken. */
.fl-neben.neu { color: var(--yellow); }

/* Der Hinweis in der Wartungstafel stand zentriert mit viel Luft darum, weil
   die Tafel sonst fast leer ist. Er gehoert an den Text, ueber den er etwas
   sagt, nicht in die Mitte einer leeren Flaeche. */
.wartung .leerlauf {
  padding: 12px 0 0; text-align: left; border-top: 1px solid var(--border);
  margin-top: 12px;
}

/* ── Alle Bordgeräte ─────────────────────────────────────────────────────── */
/* Nach Kategorie gruppiert wie in der Bordansicht: 29 Geräte am Stück sind
   eine Wand, dieselben 29 in acht Gruppen sind eine Liste. */
.fl-gruppe {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text3); padding: 16px 0 6px; border-top: 1px solid var(--border);
  margin-top: 8px;
}
.fl-gruppe:first-child { border-top: none; margin-top: 0; padding-top: 0; }
.fl-gruppe + .fl-zeile { border-top: none; }

/* Grau ist ein eigener Zustand und kein fehlender: "stumm" heisst, dass kein
   Melder verbaut ist, und "unbekannt", dass der Bus schweigt. Beides ist kein
   Fehler und darf nicht rot sein. */
.fl-ampel.grau { background: var(--border); }

/* ── Ein Gerät im Vollbild ───────────────────────────────────────────────── */
/* Vollbild statt Popup: hier stehen Laufzeitwerte, Fassungen, Verlauf und
   Meldungen untereinander. In ein Popup passt das nicht, und man will beim
   Lesen nicht scrollen, während die Liste dahinter durchscheint. */
body.fl-offen .seite[data-seite="wartung"] > .tafel,
body.fl-offen .seite[data-seite="wartung"] > .seiten-kopf { display: none; }

.fl-vollbild { display: flex; flex-direction: column; gap: 16px; }

.fl-zurueck {
  background: none; border: none; color: var(--text2); font-family: inherit;
  font-size: 12px; cursor: pointer; padding: 0 0 12px;
}
.fl-zurueck::before { content: '‹ '; }
.fl-zurueck:hover { color: var(--text); }

.fl-vb-titel { display: flex; align-items: center; gap: 12px; }
.fl-vb-titel .fl-ampel { width: 5px; height: 26px; flex: none; }
.fl-vb-titel h1 { margin: 0; font-size: 22px; }
.fl-vb-status { font-size: 12px; color: var(--text2); }
.fl-vb-notiz { margin: 8px 0 0; font-size: 13px; color: var(--text2); max-width: 68ch; }

.fl-vb-tafel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; padding: 18px 20px;
}

/* Laufzeitwerte: Zahl gross, Bezeichnung klein darunter. Das ist die Anordnung,
   in der man sie im Vorbeigehen liest — umgekehrt liest man erst das Wort. */
.fl-werte { display: flex; flex-wrap: wrap; gap: 22px 34px; }
.fl-wert-v {
  font-size: 19px; font-variant-numeric: tabular-nums;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}
.fl-wert-l {
  font-size: 11px; color: var(--text2); text-transform: uppercase;
  letter-spacing: .06em; margin-top: 3px;
}

.fl-vb-fassungen { display: flex; flex-wrap: wrap; gap: 16px 48px; margin-bottom: 4px; }
.fl-vb-fassungen .fl-wert-l { margin: 0 0 4px; }
.fl-vb-fassungen .knopf { margin-top: 8px; }

/* Stammdaten als zwei Spalten: Bezeichnung links, Wert rechts. Untereinander
   in einer Zeile waere es eine Textwueste. */
.fl-stamm {
  display: grid; grid-template-columns: auto 1fr; gap: 7px 18px;
  font-size: 12px; align-items: baseline;
}
.fl-stamm-l { color: var(--text2); }
.fl-stamm-v { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; }

/* Die Art der Meldung: was kaputt ist, was besser sein koennte, was anders
   werden soll. Drei reichen — mehr Auswahl heisst nur laenger ueberlegen. */
.fl-arten { display: flex; gap: 16px; margin: 10px 0 4px; }
.fl-art {
  display: flex; align-items: center; gap: 6px; font-size: 12px;
  color: var(--text2); cursor: pointer;
}

/* Kein Wert, nur ein Zustand: dann steht rechts EINE kleine Zeile und keine
   grosse leere darueber. Sie sitzt auf der Hoehe des Namens, nicht der
   Unterzeile — sonst haengt sie in der Luft. */
.fl-nurstatus { font-size: 12px; color: var(--text2); }
.fl-zeile:has(.fl-nurstatus) .fl-stand { justify-content: center; }

/* ── Drei Anzeigen je Zeile ──────────────────────────────────────────────── */
/* Am Bus, Software, Meldungen — die drei Fragen, mit denen man auf die Seite
   kommt, nebeneinander statt in drei Klicks. Feste Breite, damit die Spalten
   über alle Zeilen fluchten; ohne das tanzen sie mit der Textlänge. */
.fl-zeile .fl-stand { flex-direction: row; gap: 20px; align-items: stretch; }
.fl-anz {
  display: flex; flex-direction: column; justify-content: center;
  min-width: 74px; text-align: right;
}
.fl-anz b {
  font-size: 13px; font-weight: 600; color: var(--text2);
  font-variant-numeric: tabular-nums;
}
.fl-anz i {
  font-style: normal; font-size: 10px; color: var(--text3);
  text-transform: uppercase; letter-spacing: .05em; margin-top: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fl-anz.gut b  { color: var(--green); }
.fl-anz.warn b { color: var(--yellow); }
.fl-anz.rot b  { color: var(--red); }

@media (max-width: 900px) {
  /* Auf schmalem Bild bleibt die Software-Anzeige — sie ist die, wegen der man
     hier ist. Die anderen beiden stehen ohnehin schon als Ampel und in der
     Detailansicht. */
  .fl-anz:first-child, .fl-anz:last-child { display: none; }
}

/* ── Alle Fassungen ──────────────────────────────────────────────────────── */
.fl-fassung-zeile { border-top: 1px solid var(--border); }
.fl-fassung-zeile:first-child { border-top: none; }
.fl-f-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 3px 0;
}
.fl-f-auf {
  display: flex; align-items: baseline; gap: 9px; flex: 1; min-width: 0;
  background: none; border: none; color: inherit; font-family: inherit;
  font-size: 12px; text-align: left; cursor: pointer; padding: 7px 0;
}
.fl-f-auf::before { content: '▸'; color: var(--text3); font-size: 10px; }
.fl-f-auf b {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-variant-numeric: tabular-nums;
}
.fl-f-laeuft {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--green); border: 1px solid var(--green); border-radius: 3px;
  padding: 1px 5px;
}
.fl-f-tat { display: flex; gap: 7px; flex: none; }
.fl-f-tat .knopf-schlicht[disabled] { opacity: .35; cursor: not-allowed; }
.fl-f-aend { padding: 0 0 10px 18px; }

/* Der Knopf, hinter dem ein Gerät im Bootloader landen kann. Er sieht nicht aus
   wie der Hauptweg — der Hauptweg ist Abbrechen. */
.knopf-schlicht.warnung { border-color: var(--red); color: var(--red); }
.knopf-schlicht.warnung:hover { background: var(--red); color: var(--bg); }
.fl-warnung {
  font-size: 13px; line-height: 1.5; color: var(--text);
  border-left: 3px solid var(--red); padding: 2px 0 2px 12px; margin: 10px 0;
}

/* Die Pruefsumme unter der Fassung. Wer ein Abbild herunterlaedt und spaeter
   von Hand ueber USB aufspielt, hat sonst keine Moeglichkeit mehr zu pruefen,
   ob unterwegs etwas passiert ist — ueber den Bus faengt die CRC im Geraet das
   ab, ueber das Kabel niemand. */
.fl-f-summe {
  font-size: 10px; color: var(--text3); padding: 0 0 7px 18px;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  overflow-wrap: anywhere;
}

/* Stoerungen, die das GERAET meldet — nicht zu verwechseln mit Tickets, die ein
   Mensch anlegt. Deshalb eigene Spalte und eigene Farbe. */
.fl-stoer {
  font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
  border: 1px solid currentColor; border-radius: 3px; padding: 1px 5px;
  color: var(--text3); white-space: nowrap;
}
.fl-stoer.stoerung { color: var(--red); }
.fl-stoer.warnung  { color: var(--yellow); }

/* Der Hinweis waehrend einer Uebertragung steht VOR der Liste und nicht
   darunter: er erklaert, was man gleich sehen wird, nicht was man gesehen hat. */
.fl-hinweis.warnung {
  border: 1px solid var(--yellow); border-radius: 8px; color: var(--text2);
  padding: 10px 12px; margin: 0 0 14px; border-top: 1px solid var(--yellow);
}

/* Die Fassungsliste waechst mit jedem Etikett; bei 40 Fassungen schob sie alles
   darunter (Stammdaten, Meldungen) aus dem Bild. Sie bekommt deshalb einen
   eigenen Bereich mit Rollbalken statt unbegrenzter Hoehe. Die Hoehe ist an den
   Bildschirm gebunden, nicht fest: auf dem Kartentisch-Tablet passt weniger als
   am Laptop. */
.fl-fassungen {
  max-height: min(52vh, 560px);
  overflow-y: auto;
  overscroll-behavior: contain;          /* am Ende nicht die ganze Seite mitziehen */
  padding-right: 4px;                    /* der Balken soll nicht auf dem Text liegen */
}

/* Der Aktualisieren-Knopf steht in derselben Reihe wie „läuft" und
   „verfügbar" — dort, wo die Frage entsteht, ob es etwas Neues gibt. Er
   erscheint nur, wenn es das gibt; ein dauerhaft gesperrter Knopf ist eine
   Einladung, ihn zu übersehen, wenn er es einmal nicht ist. */
.fl-akt { display: flex; align-items: center; }
.fl-gut { color: var(--green); }
/* Platz fuer Stand und sechs Protokollzeilen vorab: der Dialog springt nicht, waehrend der Ablauf laeuft. */
.fl-stoker-stand { min-height: 14em; }

/* ── Aenderungsnotizen (CHANGELOG.md) ──────────────────────────────────── */
.fl-notiz { margin: 6px 0 10px; }
.fl-notiz-kopf { font-size: 12px; font-weight: 700; letter-spacing: .04em;
  color: var(--text2); margin-bottom: 2px; font-variant-numeric: tabular-nums; }
.fl-notiz .fl-liste li { color: var(--text); line-height: 1.4; }
.fl-technisch { margin-top: 8px; }
.fl-technisch summary { cursor: pointer; font-size: 12px; color: var(--text3);
  user-select: none; }
.fl-technisch[open] summary { margin-bottom: 4px; }
.fl-technisch .fl-liste li { font-size: 12px; color: var(--text3); }
.fl-technisch .fl-liste li b { font-weight: 500; }
