/* Designsystem uhl-bernd (aus IPSView-Widgets uebernommen) */
:root {
  --bg:    #141414;
  --text:  #f2f2f2;
  --muted: #aaaaaa;
  --card:  rgba(35,35,35,0.65);
  --bord:  rgba(255,255,255,0.10);
  --r:     5px;

  --tx:  #FFD44D;   /* Gelb  - Hauptwert */
  --rx:  #a6e3a1;   /* Gruen - gut/an   */
  --avg: #7DD4FC;   /* Hellblau         */
  --cap: #FFA040;   /* Orange           */
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
/* overscroll-behavior:none schaltet das "Ziehen von oben = Seite neu laden" (Pull-to-
   Refresh) ab. In der installierten PWA loeste ein versehentliches Ueberziehen beim
   Blaettern eine KOMPLETTE Neuladung aus - und Chrome zeigt bei jedem Neustart der
   App im Standalone-Modus den Hinweis "Tippen, um die URL zu kopieren". Normales
   Scrollen bleibt unberuehrt. (11.08.2026) */
html, body { height: 100%; overscroll-behavior: none; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, "Segoe UI", Roboto, sans-serif;

}
.hidden { display: none !important; }

/* ---------- Status-Dots ---------- */
.dot { display:inline-block; width:10px; height:10px; border-radius:50%; flex-shrink:0; }
.s-up   { background:#2ecc71; box-shadow:0 0 5px 1px rgba(46,204,113,.6); }
.s-down { background:#e74c3c; }
/* v145: Verbindung wird geprueft (Rueckkehr in den Vordergrund, Zeitueberschreitung) - Bedienung gesperrt */
.s-wait { background:#f1c40f; animation:st-puls 1s ease-in-out infinite; }

/* ---------- Karten ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--bord);
  border-radius: var(--r);
  padding: 10px 12px;
}

/* ---------- Login ---------- */
.login-wrap { min-height:100vh; display:flex; align-items:center; justify-content:center; padding:16px; }
.login-card { width:100%; max-width:340px; display:flex; flex-direction:column; gap:10px; padding:22px 18px; }
.login-title { font-size:26px; font-weight:700; color:var(--tx); text-align:center; }
.login-sub   { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.08em; text-align:center; margin-bottom:6px; }
.login-card input {
  background: rgba(255,255,255,.06);
  border: 1px solid var(--bord);
  border-radius: var(--r);
  padding: 11px 12px;
  color: var(--text);
  font-size: 15px;
}
.login-card input:focus { outline:none; border-color: var(--tx); }
.login-err { color:#ff8a80; font-size:12px; text-align:center; min-height:16px; }
.login-err.login-hinweis { color: var(--tx); }   /* v143: naechster Schritt (2FA-Code), kein Fehler */

/* Nebenweg unter dem Passkey-Knopf ("Mit Passwort anmelden" bzw. "Stattdessen ein Passwort
   vergeben"). Sieht aus wie ein Link, ist aber ein <button>: ein <a href="#"> wuerde die
   Adresszeile veraendern - auf der Einlade-Seite steht dort das Token-Fragment. */
.login-oder { text-align:center; }
.login-oder button, .ein-link {
  background:none; border:none; padding:6px 2px; cursor:pointer;
  color:var(--muted); font-size:12px; text-decoration:underline; font-family:inherit;
}
.login-oder button:hover, .ein-link:hover { color:var(--text); }

/* ---------- Buttons ---------- */
.btn-primary {
  background: var(--tx); color:#1a1a1a; border:none; border-radius:var(--r);
  padding: 11px; font-size:15px; font-weight:700; cursor:pointer;
}
.btn-primary:active { filter: brightness(.85); }
.btn-ghost {
  background:none; border:1px solid var(--bord); border-radius:var(--r);
  color:var(--muted); padding:5px 10px; font-size:11px; cursor:pointer;
}

/* ---------- Fusszeile (frueher Kopfbereich) ----------
   Verbindungsanzeige, Benutzer und Abmelden stehen unten, damit der Inhalt
   ganz oben beginnt und nichts Platz wegnimmt. */
.fuss {
  display:flex; align-items:center; justify-content:center; gap:10px;
  padding:14px 14px calc(14px + env(safe-area-inset-bottom));
  margin-top:6px; border-top:1px solid var(--bord);
}
.head-user { font-size:11px; color:var(--muted); }
/* Fassung aus dem ?v=-Parameter der geladenen app.js - zeigt, was der Browser
   wirklich ausfuehrt, und macht Cache-Probleme sofort sichtbar. */
.app-version { font-size:10px; color:var(--muted); opacity:.6; }

/* ---------- Tabs (Seiten-Menue) ---------- */
.tabs {
  display:flex; gap:6px; max-width:900px; margin:0 auto;
  padding:calc(8px + env(safe-area-inset-top)) 10px 0;
}
.tabs button {
  flex:1; max-width:150px;
  background:rgba(255,255,255,.05); border:1px solid var(--bord); border-radius:var(--r);
  color:var(--muted); font-size:13px; font-weight:600; padding:9px 0; cursor:pointer;
}
.tabs button.active { background:var(--tx); border-color:var(--tx); color:#1a1a1a; font-weight:700; }
.page-empty { color:var(--muted); font-size:13px; text-align:center; padding:48px 0; }
.page-content { display:flex; flex-direction:column; gap:14px; }

/* Untermenue (Rubrik-Chips) */
.subtabs { display:flex; gap:6px; flex-wrap:wrap; }
.subtabs button {
  background:rgba(255,255,255,.05); border:1px solid var(--bord); border-radius:99px;
  color:var(--muted); font-size:11px; font-weight:600; padding:6px 13px; cursor:pointer;
}
.subtabs button.active { color:var(--tx); border-color:var(--tx); background:rgba(255,212,77,.08); }
/* Untermenue-Streifen sitzt ausserhalb #dashboard, UEBER dem Stoerungsbanner. Leer -> weg. */
#subtabs { max-width:900px; margin:0 auto; padding:0 10px; }
#subtabs:empty { display:none; }
#subtabs .subtabs { margin:10px 0 2px; }

/* Spannen-Anzeige (range-Kachel, z.B. PV-Prognose) */
.tile-range { font-size:11px; color:var(--muted); }

/* ---------- Mähroboter ---------- */
.worx-kopf { display:flex; align-items:center; gap:8px; }
.worx-name { font-size:14px; font-weight:600; flex:1; }
.worx-status { font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.06em; }
.worx-abzeichen { display:flex; gap:4px; }
.worx-badge { font-size:9px; font-weight:700; padding:2px 6px; border-radius:3px;
  background:rgba(255,160,64,.25); color:#FFA040; }
.worx-badge.bad { background:rgba(231,76,60,.25); color:#e74c3c; }

.worx-banner-bereich:empty { display:none; }
.worx-banner-bereich { display:flex; flex-direction:column; gap:6px; }
.worx-banner { font-size:11px; font-weight:600; text-align:center; padding:6px 8px; border-radius:var(--r); }
.worx-banner.fehler { background:rgba(120,20,20,.55); border:1px solid rgba(255,80,80,.4); color:#ff8a80; }
.worx-banner.warn   { background:rgba(255,212,77,.15); border:1px solid rgba(255,212,77,.4); color:var(--tx); }
.worx-banner.info   { background:rgba(125,212,252,.15); border:1px solid rgba(125,212,252,.4); color:var(--avg); }
.worx-banner.gut    { background:rgba(46,204,113,.15); border:1px solid rgba(46,204,113,.4); color:#2ecc71; }

.worx-akku { display:flex; align-items:center; gap:12px; }
.worx-akku-wert { font-size:30px; font-weight:700; line-height:1; min-width:78px; }
.worx-akku-rechts { flex:1; display:flex; flex-direction:column; gap:4px; }
.worx-spur { height:10px; background:rgba(255,255,255,.08); border-radius:99px; overflow:hidden; }
.worx-fuellung { height:100%; border-radius:99px; transition:width .4s ease; }
.worx-akku-info { display:flex; justify-content:space-between; font-size:10px; color:var(--muted); }
.worx-laedt { color:var(--avg); font-weight:600; }

.worx-karte-flaeche { width:100%; }
.worx-karte { display:block; width:100%; height:auto; border-radius:var(--r); }
.worx-karte-quelle { font-size:8px; fill:rgba(255,255,255,.55); }

.worx-reihe { display:grid; grid-template-columns:repeat(3, 1fr); gap:6px; }
.worx-knopf {
  background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:var(--r);
  color:var(--text); font-size:11px; font-weight:700; padding:11px 4px; cursor:pointer;
}
.worx-knopf:active:not(:disabled) { background:rgba(255,255,255,.14); }
.worx-knopf:disabled { opacity:.35; cursor:default; }
.worx-knopf.start { color:#2ecc71; border-color:rgba(46,204,113,.4); }
.worx-knopf.pause { color:#FFA040; border-color:rgba(255,160,64,.4); }
.worx-knopf.home  { color:var(--avg);  border-color:rgba(125,212,252,.4); }
.worx-knopf.zone  { color:var(--tx);   border-color:rgba(255,212,77,.35); }

/* Schnellzugriff: drei GEFUELLTE Knoepfe - klar unterscheidbar von allem anderen */
.worx-schnell { display:grid; grid-template-columns:repeat(3, 1fr); gap:8px; }
.worx-knopf.gross { padding:14px 6px; font-size:13px; border-radius:var(--r); }
.worx-knopf.start-voll { background:rgba(46,204,113,.85); border-color:transparent; color:#0c2417; }
.worx-knopf.start-voll:active:not(:disabled) { background:#2ecc71; }
.worx-knopf.pause-voll { background:rgba(255,160,64,.85); border-color:transparent; color:#2b1a05; }
.worx-knopf.pause-voll:active:not(:disabled) { background:#FFA040; }
.worx-knopf.home-voll  { background:rgba(125,212,252,.85); border-color:transparent; color:#0a2230; }
.worx-knopf.home-voll:active:not(:disabled) { background:#7DD4FC; }
.worx-knopf.zone-voll  { background:var(--tx); border-color:transparent; color:#1a1a1a; width:100%; }
.worx-knopf.zone-voll:disabled { background:rgba(255,212,77,.25); color:rgba(26,26,26,.6); opacity:1; }

/* Mähauftrag: Zonen-Chips mit sichtbarer Auswahl */
.worx-auftrag { display:flex; flex-direction:column; gap:8px; }
.worx-hinweis { font-size:10px; color:var(--muted); }
.worx-chips { display:flex; gap:6px; flex-wrap:wrap; }
.worx-chip {
  background:rgba(255,255,255,.05); border:1px solid var(--bord); border-radius:99px;
  color:var(--text); font-size:12px; font-weight:600; padding:8px 16px; cursor:pointer;
}
.worx-chip.aktiv {
  background:rgba(255,212,77,.18); border-color:var(--tx); color:var(--tx);
}
.worx-chip.aktiv::before { content:'✓ '; }
.worx-chip.alle { color:var(--muted); }

.worx-reihe.zweier { display:grid; grid-template-columns:1fr 1fr; gap:6px; }

/* Schnitthöhen je Zone */
.worx-hoehen { display:flex; flex-direction:column; gap:6px; }
.worx-hoehen-liste { display:flex; flex-direction:column; gap:2px; }
.worx-hoehen-zeile {
  display:flex; justify-content:space-between; font-size:12px; padding:4px 0;
  border-bottom:1px solid rgba(255,255,255,.05);
}
.worx-hoehen-zeile:last-of-type { border-bottom:none; }
.worx-hoehen-wert { font-weight:700; min-width:64px; text-align:center; }
.worx-hoehe-regler { display:flex; align-items:center; gap:6px; }
.worx-hoehe-regler button {
  width:30px; height:26px; background:rgba(255,255,255,.08); border:1px solid var(--bord);
  border-radius:var(--r); color:var(--text); font-size:16px; line-height:1; cursor:pointer;
}
.worx-hoehe-regler button:disabled { opacity:.35; cursor:default; }

.worx-option {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  background:rgba(255,255,255,.04); border:1px solid var(--bord);
  border-radius:var(--r); padding:7px 10px; font-size:12px;
}
.worx-schalter {
  background:rgba(255,255,255,.08); border:1px solid var(--bord); border-radius:99px;
  color:var(--muted); font-size:10px; font-weight:700; padding:4px 14px; cursor:pointer; min-width:56px;
}
.worx-schalter.an { background:rgba(255,212,77,.2); border-color:var(--tx); color:var(--tx); }

.worx-fuss-gitter { display:grid; grid-template-columns:repeat(3, 1fr); gap:8px 6px; text-align:center; }
.worx-fuss-zelle .v { font-size:12px; font-weight:700; }
.worx-fuss-zelle .l { font-size:9px; color:var(--muted); text-transform:uppercase; letter-spacing:.05em; margin-top:2px; }
.worx-fuss-meta { font-size:9px; color:var(--muted); text-align:center;
  border-top:1px solid var(--bord); margin-top:8px; padding-top:6px; }

.worx-frage { position:fixed; inset:0; z-index:110; background:rgba(0,0,0,.75);
  display:flex; align-items:center; justify-content:center; padding:16px; }
.worx-frage-box { background:#232323; border:1px solid var(--bord); border-radius:var(--r);
  padding:16px; max-width:320px; width:100%; display:flex; flex-direction:column; gap:12px; }
.worx-frage-text { font-size:14px; font-weight:600; text-align:center; }
.worx-frage-knoepfe { display:grid; grid-template-columns:1fr 1fr; gap:8px; }

/* ---------- Bewässerung ----------
   Nutzt bewusst die Bausteine des Maeher-Panels (Knoepfe, Chips, Regler, Banner);
   hier stehen nur die Ergaenzungen fuer die Kreis-Zeilen und die Klappkarte. */
.bew-kreis {
  display:grid; grid-template-columns:auto auto 1fr auto auto; align-items:center; gap:8px;
  padding:5px 0; border-bottom:1px solid rgba(255,255,255,.05);
}
.bew-kreis:last-of-type { border-bottom:none; }
.bew-kreis .worx-schalter { min-width:46px; padding:4px 8px; }
.bew-ventil { width:8px; height:8px; }
.bew-kreis-name { font-size:12px; font-weight:600; }
.bew-kreis-name.aus { color:var(--muted); font-weight:400; }
.bew-kreis .worx-hoehen-wert { min-width:52px; font-size:12px; }
.bew-kreis .worx-knopf { padding:6px 10px; font-size:11px; }
.bew-auswahl { font-size:11px; text-align:center; min-width:120px; }

/* Klappkarte fuer Sensoren und Schwellwerte */
.bew-details { padding:0; }
.bew-details > summary {
  cursor:pointer; padding:10px 12px; font-size:12px; font-weight:600;
  list-style:none; display:flex; align-items:center; gap:6px;
}
.bew-details > summary::-webkit-details-marker { display:none; }
.bew-details > summary::before { content:'›'; font-size:16px; line-height:1; transition:transform .15s; }
.bew-details[open] > summary::before { transform:rotate(90deg); }
.bew-details > .worx-option, .bew-details > .bew-gruppe { margin:0 12px 6px; }
.bew-details > .bew-gruppe { margin-top:10px; }
.bew-details > .worx-chips { margin:2px 12px 12px; }

/* Berechnung im Detail: Stufen je Kriterium, die geltende ist eingefaerbt */
.bew-vorschau { margin:0 12px 8px; display:flex; flex-direction:column; gap:4px; }
.bew-stufen { margin:0 12px 12px; }
.bew-krit-kopf {
  display:flex; justify-content:space-between; align-items:baseline; gap:8px;
  font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.05em;
  color:var(--muted); margin:10px 0 3px; padding-top:6px; border-top:1px solid var(--bord);
}
.bew-krit-kopf span:last-child { color:var(--text); font-size:12px; letter-spacing:0; }
.bew-stufe {
  display:flex; justify-content:space-between; gap:10px; font-size:11px; color:var(--muted);
  padding:3px 6px; border-radius:3px;
}
.bew-stufe.aktiv { font-weight:700; background:rgba(255,255,255,.05); }
.bew-stufe.aktiv.f-schlecht { color:#ff8a80; }
.bew-stufe.aktiv.f-mittel   { color:var(--cap); }
.bew-stufe.aktiv.f-kuehl    { color:var(--avg); }
.bew-stufe.aktiv.f-gut      { color:var(--rx); }
.bew-stufe.aktiv::before { content:'◂ '; }
.bew-stufe.ergebnis {
  margin-top:8px; padding-top:7px; border-top:2px solid rgba(255,255,255,.2);
  color:var(--text); font-weight:700; font-size:12px;
}
.bew-stufe.ergebnis .bew-stufe-wirkung { color:var(--tx); font-size:14px; }

/* Historie: eine Saeule je Tag */
/* Historie: eine Zeile je Tag, waagerechter Balken (Laenge = Dauer), heute oben.
   Waagerecht statt senkrecht, weil bei 14 Tagen senkrechte Saeulen zu schmal wuerden
   und daneben kein Platz fuer Datum + heute/gestern bliebe. */
.bew-balken { display:flex; flex-direction:column; gap:5px; margin:8px 12px 12px; }
.bew-zeile { display:grid; grid-template-columns:60px 1fr 66px; align-items:center; gap:8px; }
.bew-zeile-tag { display:flex; flex-direction:column; line-height:1.15; }
.bew-zeile-rel { font-size:11px; color:var(--text); font-weight:600; }
.bew-zeile.aktuell .bew-zeile-rel { color:var(--tx); }
.bew-zeile-datum { font-size:9px; color:var(--muted); }
.bew-zeile-track { height:14px; background:rgba(255,255,255,.06); border-radius:99px; overflow:hidden; }
.bew-zeile-fill { height:100%; border-radius:99px; background:var(--rx); transition:width .3s; }
.bew-zeile.t-abbruch   .bew-zeile-fill { background:var(--cap); }
.bew-zeile.t-aussetzen .bew-zeile-fill { background:var(--avg); }
.bew-zeile-wert { font-size:11px; color:var(--muted); text-align:right; white-space:nowrap; }
.bew-zeile.t-lauf      .bew-zeile-wert { color:var(--text); }
.bew-zeile.t-abbruch   .bew-zeile-wert { color:var(--cap); }
.bew-zeile.t-aussetzen .bew-zeile-wert { color:var(--avg); }

/* Statistik */
.bew-stat { margin:0 12px 12px; }
.bew-stat .worx-fuss-gitter { margin-bottom:4px; }

/* ---------- Stoerungsbanner (config.banner) ----------
   Nimmt die Alarmfarbe der Klingel (#ff6b5e) auf, damit "Stoerung" in der App ueberall
   gleich aussieht. Steht ausserhalb von #dashboard und hat darum eigene Abstaende.
   Schmale EINZEILIGE Zeilen (Vorgabe Bernd 13.08.2026), klickbar -> fuehren zur Rubrik. */
.banner-wrap { padding-top:8px; padding-bottom:0; gap:6px; }
.stoerzeile {
  display:flex; align-items:center; gap:8px; width:100%;
  padding:7px 10px; border-radius:var(--r);
  border:1px solid rgba(255,107,94,.5); background:rgba(255,107,94,.10);
  color:#ff6b5e; text-align:left; font:inherit; cursor:pointer;
}
.stoerzeile:not(button) { cursor:default; }
.st-zeichen {
  flex:0 0 auto; width:17px; height:17px; border-radius:50%;
  background:#ff6b5e; color:#1a1a1a; font-weight:900; font-size:12px; line-height:17px;
  text-align:center; animation:st-puls 1.6s ease-in-out infinite;
}
@keyframes st-puls { 50% { opacity:.45; } }
@media (prefers-reduced-motion: reduce) { .st-zeichen { animation:none; } }
.st-titel {
  flex:1 1 auto; min-width:0; font-size:12.5px; font-weight:600; color:#ff6b5e;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.st-seit { flex:0 0 auto; font-size:10px; color:var(--muted); white-space:nowrap; }
.st-pfeil { flex:0 0 auto; font-size:16px; color:rgba(255,107,94,.7); line-height:1; }

/* ---------- Störungsmanagement ---------- */
.sm-wrap { display:flex; flex-direction:column; gap:12px; }
.sm-kopf { display:flex; align-items:center; gap:14px; border-color:rgba(255,160,64,.45); background:rgba(255,160,64,.08); }
.sm-kopf.ok { border-color:rgba(46,204,113,.45); background:rgba(46,204,113,.08); }
.sm-kopf.kritisch { border-color:rgba(231,76,60,.6); background:rgba(231,76,60,.10); }
.sm-zahl { font-size:34px; font-weight:800; color:var(--cap); line-height:1; min-width:42px; text-align:center; }
.sm-kopf.ok .sm-zahl { color:var(--rx); }
.sm-kopf.kritisch .sm-zahl { color:#ff6b5e; }
.sm-kopf-txt { font-size:14px; color:var(--text); }
.sm-liste { display:flex; flex-direction:column; gap:4px; }
.sm-ok { color:var(--rx); font-size:14px; font-weight:600; padding:10px 2px; }
.sm-gruppe { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; margin-top:8px; }
.sm-zeile { font-size:13px; padding:8px 10px; border-radius:var(--r); border-left:3px solid; background:rgba(255,255,255,.03); }
.sm-zeile.warnung { border-color:var(--cap); color:var(--text); }
.sm-zeile.kritisch { border-color:#ff6b5e; color:#ff8a80; font-weight:600; }
.sm-schwelle { display:flex; flex-direction:column; gap:6px; }
.sm-schwelle .reg-row { display:grid; grid-template-columns:32px 1fr 32px; align-items:center; gap:6px; max-width:200px; }
.sm-schwelle .reg-row button {
  height:32px; background:rgba(255,255,255,.08); border:1px solid var(--bord);
  border-radius:var(--r); color:var(--text); font-size:18px; line-height:1; cursor:pointer;
}
.sm-schwelle .reg-row button:disabled { opacity:.3; cursor:default; }

/* ---------- KI-Reiter (v146) ---------- */
.ki-wrap, .ki-inhalt { display:flex; flex-direction:column; gap:10px; }
.ki-kopf { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.ki-titel { font-size:14px; font-weight:700; color:var(--text); }
.ki-klein { font-size:12px; padding:6px 12px; }
.ki-meldung { display:flex; flex-direction:column; gap:8px; border-color:rgba(125,212,252,.35); }
.ki-meld-text { font-size:14px; line-height:1.4; white-space:pre-wrap; overflow-wrap:anywhere; }
.ki-info { font-size:11px; color:var(--muted); padding:0 2px; overflow-wrap:anywhere; }
.ki-warn { font-size:13px; color:#ff8a80; padding:8px 10px; border-radius:var(--r); background:rgba(231,76,60,.10); }
.ki-hinweis { font-size:13px; color:var(--avg); padding:8px 10px; border-radius:var(--r); background:rgba(125,212,252,.08); }
.ki-zwischen { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; margin:6px 2px -2px; }
.ki-leer { font-size:13px; color:var(--muted); }
.ki-gruppe { padding:0; overflow:hidden; }
.ki-gruppe-kopf { width:100%; display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:12px 14px; background:none; border:none; color:inherit; cursor:pointer; text-align:left; font:inherit; }
.ki-gruppe-kopf::after { content:'▸'; color:var(--muted); font-size:12px; margin-left:4px; }
.ki-gruppe.offen .ki-gruppe-kopf::after { content:'▾'; }
.ki-anzahl { margin-left:auto; font-size:12px; font-weight:700; color:var(--tx); background:rgba(255,212,77,.12);
  border-radius:99px; padding:2px 9px; }
.ki-liste { display:none; flex-direction:column; gap:6px; padding:0 10px 12px; }
.ki-gruppe.offen .ki-liste { display:flex; }
.ki-punkt { border-left:3px solid var(--bord); background:rgba(255,255,255,.03); border-radius:var(--r); }
.ki-punkt-kopf { width:100%; display:flex; align-items:flex-start; justify-content:space-between; gap:8px;
  padding:9px 10px; background:none; border:none; color:inherit; cursor:pointer; text-align:left; font:inherit; }
.ki-punkt-kopf:disabled { cursor:default; }
.ki-punkt-titel { font-size:13px; font-weight:600; line-height:1.35; overflow-wrap:anywhere; }
.ki-badge { flex-shrink:0; font-size:10px; font-weight:700; color:#0c2417; background:var(--avg); border-radius:99px; padding:2px 7px; }
.ki-punkt-koerper { display:none; flex-direction:column; gap:8px; padding:0 10px 10px; }
.ki-punkt.offen { border-left-color:var(--tx); }
.ki-punkt.offen .ki-punkt-koerper { display:flex; }
.ki-punkt-text { font-size:13px; color:var(--muted); line-height:1.45; overflow-wrap:anywhere; }
.ki-notiz { width:100%; min-height:56px; resize:vertical; background:rgba(0,0,0,.25); color:var(--text);
  border:1px solid var(--bord); border-radius:var(--r); padding:8px; font:inherit; font-size:14px; }
.ki-knoepfe { display:flex; gap:8px; flex-wrap:wrap; }
.ki-knoepfe button:disabled { opacity:.5; }
.ki-termin { display:grid; grid-template-columns:minmax(90px, 32%) 1fr; gap:8px; font-size:13px; padding:7px 10px;
  border-radius:var(--r); background:rgba(255,255,255,.03); }
.ki-termin-wann { font-weight:600; color:var(--tx); overflow-wrap:anywhere; }
.ki-termin-was { color:var(--text); line-height:1.4; overflow-wrap:anywhere; }
.ki-termin.ueberfaellig { background:rgba(231,76,60,.10); }
.ki-termin.ueberfaellig .ki-termin-wann { color:#ff8a80; }
.ki-lauf-erg { flex-shrink:0; font-size:11px; font-weight:700; }
.ki-lauf-erg.gut { color:var(--rx); }
.ki-lauf-erg.schlecht { color:#ff8a80; }
.ki-lauf-erg.neutral { color:var(--muted); }
.ki-lauf-zeit { font-size:11px; color:var(--muted); padding:0 10px 9px; margin-top:-4px; }
.ki-bericht { font-size:12px; color:var(--text); white-space:pre-wrap; overflow-wrap:anywhere; line-height:1.45;
  max-height:340px; overflow:auto; background:rgba(0,0,0,.2); border-radius:var(--r); padding:8px; }
.ki-einst-zeile { display:flex; align-items:center; justify-content:space-between; gap:12px; }
.ki-einst-info { font-size:12px; color:var(--muted); margin-top:3px; line-height:1.4; }
.ki-meld-liste { display:flex; flex-direction:column; gap:6px; overflow:auto; }
.ki-meld-zeile { font-size:13px; line-height:1.4; padding:8px 10px; border-radius:var(--r); background:rgba(255,255,255,.04); overflow-wrap:anywhere; }
.ki-meld-wann { font-size:11px; color:var(--muted); margin-bottom:3px; }

/* ---------- HomeConnect (zwei Geraetekarten) ---------- */
.hc-wrap { display:flex; flex-direction:column; gap:14px; }
.hc-card { display:flex; flex-direction:column; gap:12px; }
.hc-kopf { display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.hc-name { font-size:15px; font-weight:700; }
.hc-tuer { font-size:11px; color:var(--muted); white-space:nowrap; }
.hc-tuer.offen { color:var(--cap); font-weight:600; }
/* Faecher-Temperaturen nebeneinander */
.hc-temps { display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.hc-temp { background:rgba(255,255,255,.04); border-radius:var(--r); padding:10px 12px; }
.hc-temp-wert { font-size:26px; font-weight:700; color:var(--tx); line-height:1; }
.hc-grad { font-size:13px; color:var(--muted); font-weight:400; }
.hc-temp-lbl { font-size:11px; color:var(--muted); margin-top:4px; }
/* Super-Funktion (SuperKuehlen / SuperGefrieren) */
.hc-super { border:1px solid var(--bord); border-radius:var(--r); padding:10px 12px; display:flex; flex-direction:column; gap:9px; }
.hc-super-kopf { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.hc-super-lbl { font-size:14px; font-weight:600; }
.hc-toggle { min-width:66px; height:34px; border-radius:99px; border:1px solid var(--bord);
  background:rgba(255,255,255,.06); color:var(--muted); font-size:13px; font-weight:700; cursor:pointer; }
.hc-toggle.an { background:var(--rx); border-color:var(--rx); color:#0c2417; }
.hc-auto { display:flex; align-items:center; justify-content:space-between; gap:8px 12px; flex-wrap:wrap; }
.hc-auto-toggle { background:none; border:1px solid var(--bord); border-radius:99px; color:var(--muted);
  font-size:11px; padding:6px 12px; cursor:pointer; white-space:nowrap; }
.hc-auto-toggle.an { color:var(--tx); border-color:var(--tx); background:rgba(255,212,77,.08); }
.hc-zeit { font-size:12px; color:var(--text); display:flex; align-items:center; gap:5px; }
.hc-super.auto-aus .hc-zeit { opacity:.4; }
.hc-stepper { display:inline-flex; align-items:center; gap:4px; }
.hc-stepper button { width:26px; height:26px; border-radius:var(--r); border:1px solid var(--bord);
  background:rgba(255,255,255,.08); color:var(--text); font-size:16px; line-height:1; cursor:pointer; }
.hc-stepper button:disabled { opacity:.3; cursor:default; }
.hc-stepper-wert { min-width:16px; text-align:center; font-weight:700; font-size:14px; }
/* Backofen */
.hc-ofen-status { font-size:20px; font-weight:700; color:var(--tx); }
.hc-card.hc-laeuft .hc-ofen-status { color:var(--rx); }
.hc-ofen-zeile { font-size:14px; }
.hc-ofen-soll { color:var(--muted); }
.hc-ofen-rest { font-size:12px; color:var(--muted); }
.hc-ofen-rest:empty { display:none; }

/* ---------- Klingel / Tuerstation ---------- */
.db-card { display:flex; flex-direction:column; gap:8px; }
.db-card.ringing { border-color:rgba(231,76,60,.6); box-shadow:0 0 0 1px rgba(231,76,60,.25); }
.db-head { display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.db-status { font-size:12px; color:var(--muted); }
.db-status.alarm { color:#ff6b5e; font-weight:700; animation:db-blink 1s step-start infinite; }
@keyframes db-blink { 50% { opacity:.35; } }
@media (prefers-reduced-motion: reduce) { .db-status.alarm { animation:none; } }

/* Klingelbild-Rahmen. Zwei Dinge sind hier absichtlich so:
   - aspect-ratio 704/466: Die Kamera speichert 704x576, 1:1 angezeigt wirkt das Bild zu
     hoch (PAL, nicht-quadratische Pixel). Die Hoehe ist darum gestaucht. Flacher/hoeher
     stellen = NUR die zweite Zahl aendern, sonst nichts.
   - width in Prozent: Eine reine max-width in Pixeln greift am Handy nicht, weil der
     Bildschirm ohnehin schmaler ist. */
.db-frame {
  position:relative; width:76%; max-width:366px; margin:0 auto;
  aspect-ratio:704/466;
  background:#0d0d0d; min-height:60px; cursor:zoom-in;
  border:1px solid var(--bord); border-radius:var(--r); overflow:hidden;
  display:flex; align-items:center; justify-content:center; touch-action:pan-y;
}
.db-frame img { width:100%; height:100%; object-fit:fill; display:block; user-select:none; }

/* Vollbild beim Antippen - so darf die Kachel klein bleiben, ohne Details zu verlieren */
.db-voll {
  position:fixed; inset:0; z-index:100; background:rgba(0,0,0,.94);
  display:flex; align-items:center; justify-content:center; flex-direction:column;
  gap:10px; padding:12px; cursor:zoom-out;
}
/* Vollbild mit demselben gestauchten Verhältnis, sonst sähe es dort anders aus */
.db-voll img { max-width:100%; max-height:82vh; aspect-ratio:704/466; object-fit:fill; border-radius:var(--r); }
.db-voll .db-voll-txt { color:var(--muted); font-size:12px; text-align:center; }
.db-empty { position:absolute; color:var(--muted); font-size:12px; }
.db-nav {
  position:absolute; top:50%; transform:translateY(-50%);
  width:34px; height:52px; border:none; border-radius:var(--r);
  background:rgba(0,0,0,.45); color:#fff; font-size:26px; line-height:1; cursor:pointer;
}
.db-nav:active { background:rgba(0,0,0,.7); }
.db-nav.prev { left:6px; }
.db-nav.next { right:6px; }
.db-caption { font-size:11px; color:var(--muted); text-align:center; }
.db-dots { display:flex; gap:6px; justify-content:center; }
.db-dot {
  width:8px; height:8px; padding:0; border-radius:50%; cursor:pointer;
  background:rgba(255,255,255,.18); border:none;
}
.db-dot.active { background:var(--tx); }

.db-hist-title { font-size:9px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; margin-top:2px; }
.db-hist { display:flex; flex-direction:column; }
.db-hist-row {
  display:flex; justify-content:space-between; gap:10px;
  font-size:11px; padding:2px 0; border-bottom:1px solid rgba(255,255,255,.05);
}
.db-hist-row:last-child { border-bottom:none; }
.db-hist-row.muted { color:var(--muted); }
.db-hist-rel { color:var(--muted); }

/* Türöffner ganz oben, mittig - ohne Scrollen erreichbar */
.db-open-top { display:flex; justify-content:center; }
.db-open-top .db-btn {
  flex:0 1 auto; min-width:220px; max-width:340px;
  padding:14px 22px; font-size:15px;
}

.db-actions { display:flex; gap:8px; }
.db-btn {
  flex:1; background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:var(--r);
  color:var(--text); font-size:13px; font-weight:600; padding:11px 8px; cursor:pointer;
}
.db-btn:active { background:rgba(255,255,255,.12); }
.db-btn:disabled { opacity:.5; cursor:default; }
.db-btn.aktiv { background:rgba(166,227,161,.14); border-color:rgba(166,227,161,.45); color:var(--rx); }
.db-open { background:rgba(255,212,77,.12); border-color:rgba(255,212,77,.4); color:var(--tx); }
.db-open.armed { background:rgba(231,76,60,.22); border-color:rgba(231,76,60,.65); color:#ff8a80; }

/* Szenen-Zeile: Anfahren (3/4) + Speichern (1/4).
   Der Knopf IST hier die Karte - darum kein zweiter Rahmen um die Kachel.
   WICHTIG `.tile.tile-scene` statt `.tile-scene`: `.tile` setzt weiter unten
   `min-height:74px`. Bei gleicher Spezifitaet gewinnt die spaetere Regel - die Zeile
   war dadurch 74 px hoch und der Knopf schwamm in 34 px Leerraum, was wie ein
   grosser Abstand zwischen den Szenen aussah. Die zwei Klassen erzwingen den Vorrang
   unabhaengig von der Reihenfolge im Stylesheet. */
.tile.tile-scene { padding:0; border:none; background:none; min-height:0; }
.sc-row { display:grid; grid-template-columns:3fr 1fr; gap:6px; }
.sc-row.ohne-speichern { grid-template-columns:1fr; }
/* Etwas flacher als die Rollladen-Knoepfe (11 statt 14 px), damit die vier Szenen
   zusammen mit dem Raster ohne Scrollen auf den Bildschirm passen. Bei ~40 px
   Gesamthoehe bleiben sie bequem tippbar. */
.sc-go {
  background:rgba(255,212,77,.12); border:1px solid rgba(255,212,77,.4);
  border-radius:var(--r); color:var(--tx); font-size:13px; font-weight:700;
  padding:11px 8px; cursor:pointer;
}
.sc-go:active:not(:disabled) { background:rgba(255,212,77,.28); }
.sc-save {
  background:rgba(255,255,255,.06); border:1px solid var(--bord);
  border-radius:var(--r); color:var(--muted); font-size:11px; font-weight:700;
  padding:11px 2px; cursor:pointer;
}
.sc-save:active:not(:disabled) { background:rgba(255,255,255,.14); }
/* zweiter Schritt - rot wie beim Tueroeffner, damit die Bedeutung gleich gelesen wird */
.sc-save.armed { background:rgba(231,76,60,.22); border-color:rgba(231,76,60,.65); color:#ff8a80; }
.sc-go:disabled, .sc-save:disabled { opacity:.5; cursor:default; }

/* Untergruppe innerhalb einer Rubrik - knapp gehalten, siehe .sc-go */
.section-title.unter { margin:6px 2px 2px; }
.gruppe-hinweis { font-size:10px; color:var(--muted); margin:0 2px 4px; }

/* Hoch/Runter-Kachel.
   Raster statt Flexbox: Bei `flex:1` wird der Knopf mit dem laengsten Text
   („▼ Runter") breiter als „■ Stop", weil min-width:auto greift. Mit gleich
   grossen Spalten sind alle Knoepfe exakt gleich breit - auch zu zweit,
   wenn `stop` in der Konfiguration fehlt. */
.tile-updown .ud-row {
  display:grid; grid-auto-flow:column; grid-auto-columns:1fr; gap:6px; flex:1;
}
.tile-updown .ud-row button {
  background:rgba(255,212,77,.12); border:1px solid rgba(255,212,77,.4);
  border-radius:var(--r); color:var(--tx); font-size:13px; font-weight:700;
  padding:14px 4px; cursor:pointer;
}
.tile-updown .ud-row button:active { background:rgba(255,212,77,.28); }

/* ---------- Dashboard ---------- */
.wrap { padding: 10px; display:flex; flex-direction:column; gap:14px; max-width:900px; margin:0 auto; }
.section-title {
  font-size:10px; color:var(--muted); text-transform:uppercase;
  letter-spacing:.08em; margin: 4px 2px 6px;
}
.grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap:8px; }
/* layout:"liste" in devices.json -> alle Kacheln untereinander (z.B. Jalousie-Szenen).
   Enger als das Raster, damit Rollläden und Szenen zusammen auf eine Seite passen. */
.grid.liste { grid-template-columns: 1fr; gap:15px; }
/* wide:true -> zwei Spalten breit. Nur im Raster: in einer Liste gibt es nur eine
   Spalte, dort wuerde span 2 eine zweite Spalte erzwingen. */
.grid:not(.liste) > .tile-wide { grid-column: span 2; }
/* htmlbox (IPS-HTML im abgeschotteten Rahmen): immer die ganze Zeile. Die Box bringt eigene
   Karten mit, darum ohne Innenabstand und ohne zweiten Kartenhintergrund. */
.grid > .tile-htmlbox { grid-column: 1 / -1; padding: 0; background: none; border: 0; min-height: 0; }
.htmlbox-frame { display:block; width:100%; height:320px; border:0; background:transparent; color-scheme:dark; }

/* ---------- Kacheln ---------- */
.tile { display:flex; flex-direction:column; gap:6px; min-height:74px; }
.tile-lbl { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; }
.tile-val { font-size:22px; font-weight:700; color:var(--tx); word-break:break-word; }
.tile-val.text { font-size:14px; color:var(--text); font-weight:600; }
.tile-unit { font-size:12px; color:var(--muted); font-weight:400; margin-left:3px; }

/* Switch */
.tile-switch { user-select:none; }
.tile-switch .tile-val { font-size:15px; color:var(--muted); }
.tile-switch.on { border-color: rgba(166,227,161,.45); }
.tile-switch.on .tile-val { color: var(--rx); }
/* `soll` in devices.json: weicht der Zustand vom bevorzugten ab, faellt die Kachel auf */
.tile-switch.abweichend { border-color:rgba(255,160,64,.6); background:rgba(255,160,64,.07); }
.tile-switch.abweichend .tile-val { color:var(--cap); }
.tile-switch.abweichend .tile-lbl::after { content:' ⚠'; color:var(--cap); }
.sw-row { display:flex; align-items:center; justify-content:space-between; }
.sw-track {
  width:40px; height:22px; border-radius:99px; background:rgba(255,255,255,.10);
  position:relative; transition:background .15s; cursor:pointer; flex-shrink:0;
}
/* Trefferflaeche des Schalters vergroessern, ohne die Optik zu aendern - die Kachel
   selbst schaltet ja nicht mehr mit. */
.sw-track::after { content:''; position:absolute; inset:-11px -10px; border-radius:99px; }
.tile-switch.on .sw-track { background:rgba(166,227,161,.35); }
.sw-knob {
  position:absolute; top:2px; left:2px; width:18px; height:18px; border-radius:50%;
  background:#888; transition:left .15s, background .15s;
}
.tile-switch.on .sw-knob { left:20px; background:var(--rx); }

/* v145 (Fallstrick 18): Befehl unterwegs -> Kachel zeigt "sendet …", weitere Tipps werden abgewiesen.
   Steht NACH der abweichend-Regel, damit es das ⚠ waehrend des Sendens ersetzt. */
.tile.sendet .tile-lbl::after { content:' · sendet …'; color:var(--cap); text-transform:none; letter-spacing:0; }
.tile.sendet .sw-track, .tile.sendet button, .tile.sendet input { animation:st-puls 1s ease-in-out infinite; }
/* Verbindung wird geprueft: Bedienung sichtbar gesperrt. Erst nach 0,5 s abdunkeln - bei normaler
   Verbindung ist die Pruefung nach ~0,2 s durch und es soll nicht flackern. */
.tile { transition:opacity .15s; }
body.verb-unsicher .tile { opacity:.5; transition-delay:.5s; }
@media (prefers-reduced-motion: reduce) { .s-wait, .tile.sendet .sw-track, .tile.sendet button, .tile.sendet input { animation:none; } }

/* Aktuelle Leistung in einer Schalt-Kachel (Steckdosen mit Messung) */
.plug-watt { font-size:12px; font-weight:700; color:var(--muted); text-align:right; }
.plug-watt.aktiv { color:var(--avg); }

/* Maschinen-Fertigmeldung an der Plug-Kachel: Abzeichen + Fuss (Melder-Knopf + Leistung) + Popup */
.masch-badge {
  align-self:flex-start; font:inherit; font-size:11px; font-weight:700; margin-top:2px;
  padding:3px 9px; border-radius:999px; border:1px solid transparent; cursor:default;
}
.masch-badge.laeuft { background:rgba(125,212,252,.16); border-color:rgba(125,212,252,.4); color:var(--avg); }
.masch-badge.fertig { background:rgba(46,204,113,.18); border-color:rgba(46,204,113,.5); color:#2ecc71; cursor:pointer; animation:st-puls 1.6s ease-in-out infinite; }
.masch-fuss { display:flex; flex-wrap:nowrap; align-items:center; gap:8px; margin-top:auto; padding-top:6px; }
.masch-fuss .plug-watt { margin:0 0 0 auto; font-size:13px; flex:0 0 auto; }   /* Leistung rechts, bleibt in der Zeile */
/* Knopf schmal halten: Zahnrad oben, kleine Schrift darunter - dann rutscht die Leistung nicht */
.masch-zahn {
  display:inline-flex; flex-direction:column; align-items:center; gap:1px; padding:5px 9px;
  background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:8px;
  color:var(--muted); cursor:pointer; font:inherit; font-size:9.5px; font-weight:600;
  line-height:1.15; white-space:nowrap; flex:0 0 auto;
}
.masch-zahn svg { flex:0 0 auto; }
.masch-zahn:hover, .masch-zahn:focus-visible { color:var(--text); background:rgba(255,255,255,.1); }
.masch-overlay {
  position:fixed; inset:0; z-index:50; display:flex; align-items:center; justify-content:center;
  background:rgba(0,0,0,.7); padding:16px;
}
.masch-card {
  width:100%; max-width:340px; display:flex; flex-direction:column; gap:12px;
  background:#2e2e33; border:1px solid rgba(255,255,255,.2); box-shadow:0 14px 44px rgba(0,0,0,.65);
  /* Das Fassaden-Popup bringt acht Regler mit (640 px) und passt damit auf ein 812-px-Handy,
     auf ein 667er aber nicht mehr. Ohne diese zwei Zeilen waere der untere Teil samt
     "Glashöhe" schlicht abgeschnitten - und NICHT erreichbar, weil die Karte nicht scrollt. */
  max-height:calc(100vh - 32px); overflow-y:auto;
}
.zahn-zeile { display:flex; justify-content:center; margin-top:10px; }
.popup-liste { gap:8px; }
/* Kennlinie Fussbodenheizung im Zahnrad-Popup (v148) */
.kl-wrap { margin:4px 0 12px; }
/* v151: Kopf + Diagramm kleben oben in der scrollenden Popup-Karte (.masch-card: padding 10px 12px, gap 12px).
   Negativer Rand + gleiche Hintergrundfarbe, damit beim Scrollen nichts durchscheint. */
.popup-fest { position:sticky; top:-10px; z-index:2; margin:-10px -12px 0; padding:10px 12px 6px;
  background:#2e2e33; border-bottom:1px solid rgba(255,255,255,.12); display:flex; flex-direction:column; gap:12px; }
.popup-fest .kl-wrap { margin:0; }
.kl-legende { margin-top:0; }
.kl-svg { width:100%; height:auto; display:block; }
.kl-gitter { stroke:rgba(255,255,255,.08); stroke-width:1; }
.kl-achse { fill:var(--muted); font-size:9px; }
.kl-jetzt-linie { stroke:var(--tx); stroke-width:1; stroke-dasharray:3 3; opacity:.7; }
.kl-jetzt { fill:var(--tx); stroke:#141414; stroke-width:1.5; }
.kl-text { font-size:12px; color:var(--muted); line-height:1.4; margin-top:4px; }
/* v150: Heizkurve oben, Ventil unten, beide ueber der Aussentemperatur */
.kl-titel { fill:var(--text); font-size:10px; font-weight:600; }
.kl-hk { fill:none; stroke:#e74c3c; stroke-width:2.5; stroke-linejoin:round; }
.kl-hk-eingestellt { stroke-width:1.5; stroke-dasharray:6 4; opacity:.5; }
.kl-hoch { stroke-dasharray:2 4; opacity:.7; }
.kl-eckpunkt { stroke:var(--muted); stroke-width:1; stroke-dasharray:3 3; opacity:.7; }
.kl-eck-text { fill:var(--muted); font-size:8.5px; }
.kl-ventil { fill:none; stroke:var(--avg); stroke-width:2.5; stroke-linejoin:round; }

/* Rubrik als EINE aufgeraeumte Karte (Klimaanlage): kompakte Zeilen statt vieler Kacheln */
.karte { display:flex; flex-direction:column; gap:11px; padding:14px; }
.karte-titel { font-size:15px; font-weight:700; color:var(--tx); }
.karte-unter { font-size:10px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted);
  margin-top:4px; padding-top:11px; border-top:1px solid var(--bord); }
.karte-reihe { display:flex; align-items:center; justify-content:space-between; gap:12px; min-height:28px; }
.karte-lbl { font-size:13px; color:var(--text); }
.karte-wert { font-size:14px; font-weight:600; color:var(--tx); text-align:right; }
.karte-reihe.an .sw-track { background:rgba(166,227,161,.35); }
.karte-reihe.an .sw-knob { left:20px; background:var(--rx); }
.karte-reihe.auswahl { flex-direction:column; align-items:stretch; gap:7px; }
.karte-btns { display:grid; gap:4px; }
.karte-opt { min-width:0; padding:9px 2px; font:inherit; font-size:12px; line-height:1.1;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
  background:rgba(255,255,255,.05); border:1px solid var(--bord); border-radius:var(--r);
  color:var(--muted); cursor:pointer; }
.karte-opt.an { background:var(--tx); border-color:var(--tx); color:#1a1a1a; font-weight:700; }
.karte .karte-reg { gap:6px; }
.karte .karte-reg .masch-reg-lbl { color:var(--text); font-size:13px; }
.masch-kopf { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.masch-titel { font-size:15px; font-weight:700; color:var(--tx); }
.masch-hint { font-size:11px; color:var(--muted); line-height:1.5; }
.masch-reg { display:flex; flex-direction:column; gap:6px; }
.masch-reg-lbl { font-size:12px; color:var(--muted); }
.masch-reg .reg-row { display:grid; grid-template-columns:44px 1fr 44px; align-items:center; gap:8px; }
.masch-reg .reg-row button {
  height:38px; background:rgba(255,255,255,.08); border:1px solid var(--bord);
  border-radius:8px; color:var(--tx); font-size:20px; line-height:1; cursor:pointer;
}
.masch-reg .reg-row button:disabled { opacity:.3; cursor:default; }
.masch-reg .reg-val { text-align:center; font-size:18px; font-weight:700; color:var(--tx); }

/* Fusszeilen-Knoepfe sind nur 33x27 px gross - das ist am Handy zu wenig. Trefferflaeche
   auf rund 45x43 px vergroessern, ohne die Optik zu aendern (gleicher Kniff wie .sw-track). */
.btn-zahnrad { position:relative; }
.btn-zahnrad::after { content:''; position:absolute; inset:-8px -6px; }

/* Aktualisieren-Knopf in der Fusszeile: dreht sich, solange geholt wird */
@keyframes fr-dreh { to { transform: rotate(360deg); } }
#btn-frisch.dreht svg { animation: fr-dreh .8s linear infinite; }
#btn-frisch:disabled { opacity:.6; cursor:default; }

/* ---------- Beschattung: ein Widget je Fassade (seit v63) ----------
   Vorher hatte jede Fassade 13 Einzelkacheln. Jetzt: Kopf mit Zahnrad, Zielposition als
   Zahl + Balken, Begruendung im Klartext, darunter die drei meistbenutzten Bedienelemente.
   Der Rest liegt im Popup und nutzt die .masch-*-Klassen oben mit. */
.tile-fassade { gap:9px; }
.fas-kopf { display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
.fas-titel { min-width:0; }
.fas-hinweis { font-size:11px; color:var(--muted); line-height:1.4; margin-top:3px; }
.fas-zahn {
  display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px;
  background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:8px;
  color:var(--muted); cursor:pointer; flex:0 0 auto;
}
.fas-zahn:hover, .fas-zahn:focus-visible { color:var(--text); background:rgba(255,255,255,.1); }
.fas-stand { display:flex; align-items:center; gap:12px; }
.fas-zahl { font-size:22px; font-weight:700; color:var(--tx); flex:0 0 auto; min-width:58px; }
.fas-bar { flex:1 1 auto; height:8px; border-radius:99px; background:rgba(255,255,255,.08); overflow:hidden; }
.fas-bar i { display:block; height:100%; width:0; border-radius:99px; background:var(--tx); transition:width .3s ease; }
/* 0 % = offen: das ist der Normalzustand und soll nicht wie ein Messwert leuchten. */
.fas-stand.offen .fas-zahl { color:var(--muted); }
.fas-stand.offen .fas-bar i { background:rgba(255,255,255,.22); }
.fas-grund { font-size:12px; color:var(--muted); line-height:1.45; }
.fas-sperre {
  align-self:flex-start; font-size:11px; font-weight:600; line-height:1.3;
  color:var(--cap); background:rgba(255,160,64,.14); border:1px solid rgba(255,160,64,.4);
  border-radius:999px; padding:4px 10px;
}
.fas-bedienung { display:flex; flex-direction:column; gap:9px; border-top:1px solid var(--bord); padding-top:10px; }
.fas-reihe { display:flex; align-items:center; justify-content:space-between; gap:10px; }
.fas-reihe-lbl { font-size:12px; color:var(--muted); min-width:0; }
.fas-reihe.an .sw-track { background:rgba(166,227,161,.35); }
.fas-reihe.an .sw-knob { left:20px; background:var(--rx); }
/* Feste Breite statt 1fr: sonst dehnt der Regler die Zeile und die Beschriftung bricht um.
   34+74+34 plus zwei Abstaende = 154 px, bei 375 px Viewport bleiben ~110 px fuers Label. */
.fas-reihe-reg .masch-reg { flex:0 0 auto; }
.fas-reihe-reg .masch-reg .reg-row { grid-template-columns:34px 74px 34px; gap:6px; }
.fas-reihe-reg .masch-reg .reg-row button { height:32px; font-size:18px; }
.fas-reihe-reg .masch-reg .reg-val { font-size:16px; }
/* Automatik aus: Zielposition und Begruendung sind dann bedeutungslos - sichtbar
   zuruecknehmen, aber NICHT ausblenden (sonst springt die Kachelhoehe beim Schalten). */
.tile-fassade.automatik-aus .fas-stand,
.tile-fassade.automatik-aus .fas-grund { opacity:.45; }

/* Werte-Kachel: mehrere Anzeigen in einer Zeile statt vier Einzelkacheln */
.tile-werte .werte-row { display:flex; flex-wrap:wrap; gap:10px 18px; margin-top:6px; }
.werte-zelle { min-width:0; }
.werte-lbl { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; }
.werte-val { font-size:17px; font-weight:700; color:var(--tx); white-space:nowrap; }

/* Dimmstreifen in einer Schalt-Kachel (dimmbare Leuchten) */
.dim-zeile { display:flex; align-items:center; gap:6px; }
/* `flex:1 1 0` mit `min-width:0` ist Pflicht: Ein input[type=range] bringt eine
   intrinsische Mindestbreite (~129 px) mit und schrumpft sonst nicht - der Prozentwert
   wurde dadurch aus der Kachel heraus und hinter die naechste geschoben. */
.dim-zeile input[type=range] {
  flex:1 1 0; min-width:0; appearance:none; -webkit-appearance:none; height:6px;
  border-radius:99px; background:rgba(255,255,255,.10); outline:none; cursor:pointer;
}
.dim-zeile input[type=range]::-webkit-slider-thumb {
  -webkit-appearance:none; width:16px; height:16px; border-radius:50%;
  background:var(--tx); border:2px solid #1a1a1a; box-shadow:0 0 5px 2px rgba(255,212,77,.45);
}
.dim-zeile input[type=range]::-moz-range-thumb {
  width:14px; height:14px; border-radius:50%; background:var(--tx); border:2px solid #1a1a1a;
}
.dim-wert { font-size:11px; color:var(--muted); flex:0 0 auto; text-align:right; white-space:nowrap; }
/* Sicherheitsnetz: nichts darf aus einer Kachel herausragen */
.tile { overflow:hidden; }
.tile-switch.on .dim-wert { color:var(--tx); }

/* Rollladen / Dimmer */
.tile-shutter input[type=range] {
  width:100%; appearance:none; -webkit-appearance:none; height:8px; border-radius:99px;
  background: rgba(255,255,255,.08); outline:none;
}
.tile-shutter input[type=range]::-webkit-slider-thumb {
  -webkit-appearance:none; width:20px; height:20px; border-radius:50%;
  background:var(--tx); border:2px solid #fff;
  box-shadow:0 0 6px 3px rgba(255,212,77,.5); cursor:pointer;
}
.tile-shutter input[type=range]::-moz-range-thumb {
  width:18px; height:18px; border-radius:50%;
  background:var(--tx); border:2px solid #fff; cursor:pointer;
}
/* 5 px mehr Luft als der Kachel-Abstand (6 px): Der Regler-Knopf hat einen Glow-Rand,
   der sonst fast auf den Voreinstellungs-Tasten sitzt. */
.preset-row { display:flex; gap:6px; margin-top:10px; }
.preset-row button {
  flex:1; background:rgba(255,255,255,.06); border:1px solid var(--bord);
  border-radius:var(--r); color:var(--muted); font-size:11px; padding:5px 0; cursor:pointer;
}
.preset-row button:active { color:var(--tx); border-color:var(--tx); }

/* Zahlenregler (Schwellen, Maße, Zeiten) */
.tile-regler .reg-row { display:grid; grid-template-columns:32px 1fr 32px; align-items:center; gap:6px; }
.tile-regler .reg-row button {
  height:32px; background:rgba(255,255,255,.08); border:1px solid var(--bord);
  border-radius:var(--r); color:var(--text); font-size:18px; line-height:1; cursor:pointer;
}
.tile-regler .reg-row button:active:not(:disabled) { background:rgba(255,255,255,.16); }
.tile-regler .reg-row button:disabled { opacity:.3; cursor:default; }
/* min-width:0 - sonst sprengt eine lange Zahl das Raster statt sich einzupassen */
.reg-val { font-size:17px; text-align:center; min-width:0; white-space:nowrap; }

/* Auswahl (Betriebsart, Luefterstufe, Luftrichtung) - genau eine Taste ist aktiv.
   flex:1 1 0 + min-width:0, damit sich auch sieben Tasten die Kachelbreite teilen. */
.tile-auswahl .aus-row { display:flex; gap:4px; }
/* flex-basis:auto (nicht 0): "Schwenken" braucht mehr Platz als "3" - bei starr gleich
   breiten Tasten passen sieben Optionen nicht. Der Rest wird gleichmaessig verteilt. */
.tile-auswahl .aus-row button {
  flex:1 1 auto; min-width:0; height:32px; padding:0 6px;
  background:rgba(255,255,255,.08); border:1px solid var(--bord);
  border-radius:var(--r); color:var(--muted);
  font-size:12px; line-height:1; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; cursor:pointer;
}
.tile-auswahl .aus-row button:active { background:rgba(255,255,255,.16); }
.tile-auswahl .aus-row button.an {
  background:rgba(255,212,77,.16); border-color:rgba(255,212,77,.5);
  color:var(--tx); font-weight:600;
}

/* Skript-Button */
.tile-script { align-items:stretch; justify-content:center; }
.tile-script button {
  background:rgba(255,212,77,.12); border:1px solid rgba(255,212,77,.4);
  border-radius:var(--r); color:var(--tx); font-size:13px; font-weight:700;
  padding:14px 8px; cursor:pointer;
}
.tile-script button:active { background:rgba(255,212,77,.28); }
/* scharfgeschalteter Bestaetigungs-Button (button mit confirm:true, z.B. Garagentor) */
.tile-script button.armed { background:rgba(231,76,60,.22); border-color:rgba(231,76,60,.65); color:#ff8a80; }

/* Toast */
.toast {
  position:fixed; bottom:20px; left:50%; transform:translateX(-50%);
  background:rgba(120,20,20,.9); border:1px solid rgba(255,80,80,.4);
  color:#ff8a80; font-size:12px; padding:8px 14px; border-radius:var(--r); z-index:50;
}
.toast.ok { background:rgba(20,80,30,.9); border-color:rgba(46,204,113,.4); color:var(--rx); }

/* ---------- Energie-Panel: Flussdiagramm ---------- */
/* Knapper Innenabstand: das Diagramm bringt seine Raender selbst mit (viewBox),
   die Karte soll darum nichts zusaetzlich wegnehmen. */
.en-flow-card { padding: 2px 2px 0; }
.en-flow { width:100%; max-width:460px; display:block; margin:0 auto; }
.en-edge { fill:none; stroke-width:2; stroke-linecap:round; }
.en-base { stroke:rgba(255,255,255,.08); }
/* Das Strichmuster wandert immer in Pfadrichtung; die Richtung des Flusses steckt im
   Pfad selbst (siehe `edge()` in app.js), nicht in `animation-direction`. */
.en-anim { stroke-dasharray:5 7; animation:en-dash 1.05s linear infinite; }
@keyframes en-dash { to { stroke-dashoffset:-24; } }
@media (prefers-reduced-motion: reduce) { .en-anim { animation:none; } }
/* Pfeilspitze auf der Leitungsmitte - zeigt die Richtung auch ohne Animation */
.en-pfeil { stroke:#141414; stroke-width:.8; }
.en-hub  { fill:rgba(255,255,255,.25); }
.en-node { fill:rgba(255,255,255,.03); stroke-width:2; }
.en-icon { stroke:rgba(242,242,242,.85); stroke-width:1.8; fill:none; stroke-linecap:round; stroke-linejoin:round; }
.en-lbl  { font-size:9px; letter-spacing:.06em; text-transform:uppercase; fill:var(--muted); }
.en-val  { font-size:14px; font-weight:700; fill:var(--text); }
/* Werte der Balkonkraftwerke - kleiner, damit sie in die Ecken passen */
.en-val-klein { font-size:11.5px; font-weight:700; fill:var(--text); }
.en-soc  { font-size:11px; font-weight:700; fill:var(--rx); }
.en-batt-fill { fill:rgba(166,227,161,.5); }

/* ---------- Energie-Panel: Verlaufschart ---------- */
.en-chart-card { display:flex; flex-direction:column; gap:8px; }

/* ---------- Heizung: Anlagenschema (ab v51) ----------
   Nachbau des TA-Schemas im Hochformat. Rohre werden je nach Temperatur eingefaerbt
   (heizFarbe() in app.js); laeuft eine Pumpe, wandert zusaetzlich das Strichmuster -
   dieselbe Idee wie beim Energiefluss: die Richtung steckt in der Geometrie. */
.hz-card { padding:10px 8px; }
/* eigene Zeichenebene: Aenderungen im Schaltbild zwingen nicht die ganze Seite zum Neuzeichnen */
.hz-svg { display:block; width:100%; height:auto; will-change:transform; contain:layout paint; }
.hz-kopf { display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:4px; }
.hz-voll-btn {
  background:none; border:1px solid var(--bord); border-radius:var(--r);
  color:var(--muted); padding:2px 8px; font-size:13px; line-height:1.3; cursor:pointer; flex-shrink:0;
}
.hz-voll-btn:hover { color:var(--text); border-color:var(--tx); }

/* Vollbild: Das Schema ist im Original 1280 px breit. In der Kachel ist es auf rund 340 px
   gestaucht - eine Uebersicht, in der Farben und Bewegung den Zustand zeigen, aber keine
   Zahl lesbar ist. Hier bleibt es in ORIGINALGROESSE und laesst sich schieben; nur so sind
   die Werte am Handy zu lesen. Das SVG wird VERSCHOBEN, nicht kopiert. */
.hz-voll { position:fixed; inset:0; z-index:100; background:#0d0d0d; display:flex; flex-direction:column; }
.hz-voll-leiste {
  display:flex; align-items:center; justify-content:space-between; gap:10px; flex-shrink:0;
  padding:calc(8px + env(safe-area-inset-top)) 12px 8px; border-bottom:1px solid var(--bord);
}
.hz-voll-hinweis { font-size:11px; color:var(--muted); }
.hz-voll-buehne {
  flex:1 1 auto; overflow:auto; -webkit-overflow-scrolling:touch;
  padding:8px calc(8px + env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) calc(8px + env(safe-area-inset-left));
}
.hz-voll-buehne .hz-svg { width:1280px; max-width:none; height:auto; }

/* Schriftgroessen gelten in der 1280er viewBox des Originals */
/* Dunkler Rand um jede Schrift im Schaltbild: wo Text eine Leitung kreuzt, bleibt er lesbar (v122) */
.hz-svg text   { paint-order:stroke fill; stroke:#161616; stroke-width:5px; stroke-linejoin:round; }
.hz-lbl        { font-size:17px; fill:var(--muted); letter-spacing:.02em; }
.hz-wert       { font-size:19px; font-weight:700; fill:var(--text); }
.hz-wert.an    { fill:var(--rx); }
.hz-klein      { font-size:15px; fill:var(--muted); }
.hz-weiss      { font-size:19px; font-weight:700; fill:#fff; }
.hz-weiss-klein{ font-size:15px; fill:rgba(255,255,255,.85); }
.hz-status     { font-size:22px; font-weight:700; fill:var(--rx); }
.hz-status.aus { fill:var(--muted); }
.hz-betriebsart{ font-size:22px; font-weight:700; fill:var(--text); }

.hz-rohr { stroke-width:9; stroke-linecap:round; stroke-linejoin:round; opacity:.8; }
/* Fliesst etwas, wandert das Strichmuster - sonst steht die Leitung still */
.hz-rohr.fliesst { opacity:1; stroke-dasharray:22 16; animation:hz-fluss 1.1s linear infinite; }
@keyframes hz-fluss { to { stroke-dashoffset:-76; } }

/* Fuehler: gruener Punkt wie im Original-Schema der TA */
.hz-fuehler { fill:#2ecc71; stroke:#141414; stroke-width:2; }

.hz-sonne   { fill:var(--tx); opacity:.9; }
.hz-strahl  { stroke:var(--tx); stroke-width:4; stroke-linecap:round; opacity:.7; }
.hz-wolke   { fill:rgba(255,255,255,.18); }
.hz-koll    { fill:rgba(125,212,252,.16); stroke:#7DD4FC; stroke-width:5; stroke-linejoin:round; }
.hz-speicher{ stroke:var(--bord); stroke-width:3; }
.hz-fuss    { fill:rgba(255,255,255,.16); }
.hz-fuss-linie { stroke:var(--muted); stroke-width:7; stroke-linecap:round; fill:none; }
.hz-kessel  { fill:#2a2a2a; stroke:var(--bord); stroke-width:3; }
.hz-kessel-deckel { fill:#3a3a3a; }
.hz-kessel-tuer { fill:#f2f2f2; }
.hz-flamme  { fill:#FF6B35; }
.hz-rad-q   { fill:rgba(255,255,255,.16); rx:4; }
.hz-wp      { fill:#242424; stroke:var(--bord); stroke-width:3; }
.hz-luefter { fill:none; stroke:var(--muted); stroke-width:5; }
.hz-luefter.dreht { stroke:var(--rx); }
.hz-fl      { fill:var(--muted); }
.hz-fluegel.dreht { animation:hz-dreh 1.1s linear infinite; }
.wp-laeuft .hz-fl { fill:var(--rx); }
.hz-rippe   { fill:rgba(255,255,255,.30); }
.hz-rad     { fill:rgba(255,255,255,.20); }

.hz-p-kreis { fill:#1c1c1c; stroke:var(--muted); stroke-width:4; }
.hz-p-drei  { fill:var(--muted); }
.hz-pumpe.an .hz-p-kreis { stroke:var(--rx); }
.hz-pumpe.an .hz-p-drei  { fill:var(--rx); animation:hz-dreh 1.1s linear infinite; }
@keyframes hz-dreh { to { transform:rotate(360deg); } }

.hz-v-drei    { fill:#1c1c1c; stroke:var(--muted); stroke-width:4; }
.hz-v-stange  { stroke:var(--muted); stroke-width:4; fill:none; stroke-linecap:round; }
.hz-v-antrieb { fill:#1c1c1c; stroke:var(--muted); stroke-width:4; }
.hz-ventil.an .hz-v-drei,
.hz-ventil.an .hz-v-antrieb { fill:rgba(166,227,161,.25); stroke:var(--rx); }
.hz-ventil.an .hz-v-stange  { stroke:var(--rx); }
/* Umschaltventil (v119): offene Wege blau gefuellt wie die Ruecklaufleitung, geschlossener Eingang dunkel */
.hz-uv-port        { fill:#1c1c1c; stroke:var(--muted); stroke-width:3; stroke-linejoin:round; }
.hz-uv-port.offen  { fill:#4a9fe0; stroke:#4a9fe0; }
.hz-uv-antrieb     { fill:#1c1c1c; stroke:var(--muted); stroke-width:3; }
.hz-uv.ww .hz-uv-antrieb { stroke:var(--tx); }
.hz-modus          { font-size:19px; font-weight:700; fill:var(--text); }
.hz-modus.ww       { fill:var(--tx); }
/* Werte im Schaltbild antippbar (v124): gepunktet unterstrichen, oeffnen den Verlauf */
.hz-klick { cursor:pointer; text-decoration:underline dotted rgba(255,255,255,.45); text-underline-offset:4px; }
.hz-klick:hover { fill:var(--tx); }
.masch-card.wert-verlauf { max-width:560px; }
/* ueber der Vollbildansicht des Schaltbilds (.hz-voll, z-index 100) */
.wert-verlauf-overlay { z-index:110; }
.masch-card.wert-verlauf .en-chart-card { margin:0; background:transparent; border:0; padding:0; }
/* Handventile (v124): Stellung nach Sommer/Winter */
.hz-ventil.offen .hz-v-drei { fill:#e74c3c; stroke:#e74c3c; }
.hz-ventil.zu .hz-v-drei    { fill:#1c1c1c; stroke:#ff8a80; }
.hz-vst.offen { fill:var(--rx); }
.hz-vst.zu    { fill:#ff8a80; }
/* Handventil passt nicht zur Sommer-/Winterstellung (v138) */
.hz-ventil.warn .hz-v-drei { stroke:#FFD44D; stroke-width:3; }
.hz-vst.warn  { fill:#FFD44D; font-weight:700; }
/* Fenster „Handventil eintragen" (v138) */
.hv-karte  { display:flex; flex-direction:column; gap:10px; max-width:360px; }
.hv-info   { font-size:13px; color:var(--muted); line-height:1.45; }
.hv-knoepfe { justify-content:stretch; }
.hv-knoepfe button { flex:1 1 0; font-size:16px; padding:10px 0; }
.hv-verlauf { align-self:flex-start; }
/* Klartext-Zeile „So läuft die Heizung gerade" (v138) */
.hz-k-gesamt { font-size:13px; font-weight:700; color:var(--text); line-height:1.4; padding:6px 10px; border-radius:6px; background:rgba(255,255,255,.05); }
/* Mischer (v123): oben Pufferwasser rot, links Ruecklauf blau - Deckkraft = geschaetzter Anteil */
.hz-mi-port           { stroke:var(--muted); stroke-width:3; stroke-linejoin:round; }
.hz-mi-port.puffer    { fill:#e74c3c; }
.hz-mi-port.ruecklauf { fill:#4a9fe0; }
.hz-mi-port.aus       { fill:#1c1c1c; }
.hz-uv-antrieb.auf    { stroke:#e74c3c; }
.hz-uv-antrieb.zu     { stroke:#4a9fe0; }
/* nicht aktiver Pufferanschluss des Umschaltventils */
.hz-rohr.ruht      { opacity:.35; }

/* Bewegung abschalten, wenn das System es wuenscht - die Farben bleiben aussagekraeftig */
@media (prefers-reduced-motion: reduce) {
  .hz-rohr.fliesst, .hz-pumpe.an .hz-p-drei, .hz-luefter.dreht { animation:none; }
}

/* Werteliste unter dem Schaltbild */
/* Arbeitszahl-Karte in der Rubrik Heizung (seit v115, ersetzt die IPS-HTML-Box) */
.az-card { display:flex; flex-direction:column; gap:6px; }
.az-kopf { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; }
.az-sub  { font-size:11px; color:var(--muted); margin-top:2px; }
.az-kpi  { text-align:right; }
.az-kv   { font-size:30px; font-weight:700; line-height:1; font-variant-numeric:tabular-nums; }
.az-kl   { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; margin-top:3px; }
.az-svg  { display:block; width:100%; height:auto; }
.az-hit  { fill:transparent; cursor:pointer; }
.az-bar  { fill:var(--muted); opacity:.55; }
.az-balken.gut .az-bar      { fill:var(--rx); opacity:.85; }
.az-balken.mittel .az-bar   { fill:var(--cap); opacity:.85; }
.az-balken.schlecht .az-bar { fill:#ff8a80; opacity:.85; }
.az-balken.aktiv .az-bar    { opacity:1; stroke:var(--text); stroke-width:1.5; }
.az-balken:focus-visible { outline:none; }
.az-balken:focus-visible .az-bar { stroke:var(--tx); stroke-width:2; }
.az-achse   { font-size:10px; fill:var(--muted); }
.az-achse.laufend { fill:var(--tx); }
.az-grenze  { stroke:var(--rx); stroke-width:1; stroke-dasharray:4 4; opacity:.5; }
.az-null    { stroke:var(--bord); stroke-width:1; }
.az-detail  { font-size:12px; color:var(--muted); min-height:32px; line-height:1.4; font-variant-numeric:tabular-nums; }
.az-detail b { color:var(--text); }
.az-kv.gut, .az-detail b.gut { color:var(--rx); }
.az-kv.mittel, .az-detail b.mittel { color:var(--cap); }
.az-kv.schlecht, .az-detail b.schlecht { color:#ff8a80; }

/* Einstellungen Waermepumpe (v127): Heizkurven-Grafik + Werte */
.hz-einst { display:flex; flex-direction:column; gap:6px; }
.hz-kurve-svg { display:block; width:100%; height:auto; }
.hk-gitter { stroke:var(--bord); stroke-width:1; }
.hk-achse  { font-size:10px; fill:var(--muted); font-variant-numeric:tabular-nums; }
.hk-aus    { fill:rgba(255,255,255,.04); }
.hk-grenze { stroke:var(--tx); stroke-width:1.2; stroke-dasharray:4 3; opacity:.8; }
.hk-linie  { stroke-width:2.5; stroke-linecap:round; }
.hk-mk     { stroke:#e74c3c; }
.hk-hk     { stroke:#FFA040; stroke-dasharray:6 4; }
.hk-punkt  { fill:#fff; stroke:#e74c3c; stroke-width:2; }
.hk-punkt-hk { stroke:#FFA040; }
.hk-legende { flex-direction:column; flex-wrap:nowrap; }
.hk-l-info { color:var(--text); }
.hk-l-info::before { display:none !important; }
/* Zeitdiagramm in der Einstellungs-Karte (v135): ohne zweiten Kartenrahmen */
.hz-einst-verlauf { background:none; border:0; box-shadow:none; padding:0; margin:8px 0 0; }

/* „So läuft die Heizung gerade" (v128): je Kreis ein Block mit Farbkante wie die Kurven */
.hz-kreise { display:flex; flex-direction:column; gap:10px; }
.hz-kreis  { padding:2px 0 2px 10px; border-left:3px solid var(--bord); }
.hz-k-hk   { border-left-color:#FFA040; }
.hz-k-mk   { border-left-color:#e74c3c; }
.hz-k-kopf { display:flex; align-items:baseline; justify-content:space-between; gap:8px; }
.hz-k-name { font-size:14px; font-weight:700; color:var(--text); }
.hz-k-tag  { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; white-space:nowrap; }
.hz-k-status { font-size:12px; color:var(--muted); margin:2px 0 3px; line-height:1.35; }
.hz-k-status.an { color:var(--rx); font-weight:700; }
/* Umschaltventil-Schaltzeiten (v129) */
.uv-liste  { max-height:80vh; display:flex; flex-direction:column; gap:6px; }
.uv-info   { font-size:12px; color:var(--muted); }
.uv-info b { color:var(--text); }
.uv-sum    { font-size:11px; color:var(--muted); }
.uv-zeilen { overflow-y:auto; min-height:0; font-variant-numeric:tabular-nums; }
.hz-k-info { font-size:11px; color:var(--muted); line-height:1.4; margin-top:4px; opacity:.85; }
.hk-legende { display:flex; flex-wrap:wrap; gap:4px 14px; font-size:11px; color:var(--muted); margin-top:2px; }
.hk-legende span::before { content:''; display:inline-block; width:14px; height:3px; margin-right:5px; vertical-align:middle; border-radius:2px; }
.hk-l-mk::before  { background:#e74c3c; }
.hk-l-hk::before  { background:repeating-linear-gradient(90deg,#FFA040 0 5px,transparent 5px 8px); }
.hk-l-pkt::before { width:8px !important; height:8px !important; border-radius:50% !important; background:#fff; border:2px solid #e74c3c; }
.hz-zeile-klick { cursor:pointer; }
.hz-zeile-klick .hz-z-wert { text-decoration:underline dotted rgba(255,255,255,.45); text-underline-offset:3px; }
.hz-zeile-klick:focus-visible { outline:2px solid var(--tx); outline-offset:2px; }

.hz-gruppe { display:flex; flex-direction:column; gap:0; }
.hz-zeile {
  display:flex; align-items:baseline; gap:10px; padding:5px 0;
  border-bottom:1px solid rgba(255,255,255,.05);
}
.hz-zeile:last-child { border-bottom:none; }
.hz-z-lbl  { flex:1 1 auto; min-width:0; font-size:12px; color:var(--muted); }
.hz-z-wert { font-size:12px; font-weight:700; color:var(--text); text-align:right; white-space:nowrap; }
.hz-z-wert.an { color:var(--rx); }

/* ---------- Speedtest-Kopf (ab v50): drei grosse Werte + Infozeile in derselben Karte ---------- */
.st-kopf { display:flex; flex-direction:column; gap:8px; padding-bottom:4px; border-bottom:1px solid var(--bord); }
.st-gross { display:flex; gap:8px; text-align:center; }
.st-big { flex:1 1 0; min-width:0; }
.st-big-wert { font-size:19px; font-weight:700; color:var(--tx); line-height:1.2; }
.st-big-lbl { font-size:9px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); margin-top:2px; }
.st-klein { display:flex; flex-wrap:wrap; gap:4px 12px; }
.st-info { font-size:11px; color:var(--muted); }
.st-info:first-child { color:var(--text); }

/* Zeitsteuerung: Stufen mittig, Pfeile aussen zum Blaettern durch Tage/Stunden/Wochen */
.zeit-wrap { display:flex; flex-direction:column; gap:4px; }
.zeit-leiste { display:flex; align-items:center; justify-content:center; gap:8px; }
.zeit-pfeil {
  width:34px; height:30px; flex-shrink:0;
  background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:var(--r);
  color:var(--text); font-size:20px; line-height:1; cursor:pointer;
}
.zeit-pfeil:active { background:rgba(255,255,255,.14); }
.zeit-pfeil:disabled { opacity:.3; cursor:default; }
.zeit-titel { font-size:11px; color:var(--muted); text-align:center; }
.en-chart-head { display:flex; align-items:center; justify-content:space-between; gap:8px; flex-wrap:wrap; }
.en-chart-title { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.08em; }
.en-range-row { display:flex; gap:6px; }
/* Prognose-Tagessummen (Heute/Morgen/…) als kompakte Zeile ueber dem Chart */
.en-tage { display:flex; gap:6px; margin:6px 0 2px; flex-wrap:wrap; }
.en-tag { flex:1 1 0; min-width:56px; background:rgba(255,255,255,.04); border-radius:var(--r); padding:6px 4px; text-align:center; }
.en-tag.heute { background:rgba(255,212,77,.10); border:1px solid rgba(255,212,77,.35); }
.en-tag-lbl { font-size:9px; color:var(--muted); text-transform:uppercase; letter-spacing:.05em; }
.en-tag-wert { font-size:14px; font-weight:700; color:var(--tx); margin-top:2px; }
.en-tag.heute .en-tag-wert { color:var(--tx); }
/* Verbraucher-Balkenliste */
.vb-card { display:flex; flex-direction:column; gap:8px; }
.vb-liste { display:flex; flex-direction:column; gap:5px; }
.vb-zeile { display:grid; grid-template-columns:104px 1fr 62px; align-items:center; gap:8px; }
.vb-lbl { font-size:12px; color:var(--text); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.vb-spur { height:12px; background:rgba(255,255,255,.06); border-radius:99px; overflow:hidden; }
.vb-fill { height:100%; border-radius:99px; background:var(--cap); min-width:2px; transition:width .4s ease; }
.vb-wert { font-size:12px; font-weight:600; color:var(--text); text-align:right; white-space:nowrap; }
.vb-zeile.aus .vb-lbl, .vb-zeile.aus .vb-wert { color:var(--muted); }
.vb-zeile.aus .vb-fill { background:rgba(255,255,255,.12); }
.en-range-row button {
  background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:var(--r);
  color:var(--muted); font-size:11px; padding:4px 10px; cursor:pointer;
}
.en-range-row button.active { color:var(--tx); border-color:var(--tx); }
/* Umbrechend: bei fuenf Reihen (Plugs) passt eine Zeile nicht mehr. */
.en-legend { display:flex; gap:6px 14px; align-items:center; flex-wrap:wrap; }
/* Die Eintraege sind Knoepfe: Antippen blendet die Kurve aus und wieder ein. */
.en-legend .item {
  display:flex; gap:6px; align-items:center; font-size:11px; color:var(--muted);
  background:none; border:none; padding:2px 0; cursor:pointer; font-family:inherit;
}
.en-legend .item.aus { opacity:.4; }
.en-legend .item.aus span:last-child { text-decoration:line-through; }
.en-legend .key { width:14px; height:2px; border-radius:1px; display:inline-block; }
.en-legend .key.dotted, .en-tip .t-key.dotted { background:none !important; height:0; border-top:2px dotted; border-radius:0; }
/* HINWEIS (18.08.2026): frueher stand hier `touch-action:none`, damit jede Beruehrung sofort
   Werte zeigt. Das machte vertikales Scrollen ueber einem Diagramm unmoeglich. Jetzt `pan-y`:
   der Browser scrollt vertikal, waagerechtes Wischen/Tippen zeigt Werte. Die Gebaerden-
   Erkennung sitzt in zeigerBedienung() (app.js) - erst wenn dort die Richtung als waagerecht
   erkannt ist, wird der Finger per Pointer Capture gehalten. NICHT wieder auf `none` stellen,
   sonst ist das Scrollen erneut tot. Alter Grund fuers `none` (jetzt entschaerft):
   Mit `pan-y` behaelt der Browser das senkrechte Scrollen - sobald er die Fingerbewegung
   als Scrollen deutet, feuert er `pointercancel`, und die Werte-Einblendung verschwand
   sofort wieder. Im Diagramm laesst sich dadurch nicht scrollen; daneben (Zeitleiste,
   Legende, Kartenrand) schon. */
.en-plot { position:relative; width:100%; transition:opacity .2s; touch-action:pan-y; }
/* overflow:visible: Endpunkt-Marker und Peaks sitzen konstruktiv nah am Rand (Ring r=4+2px).
   Damit kann sie das SVG selbst dann nicht klemmen, wenn ein Punkt genau auf der Kante liegt. */
.en-plot svg { display:block; width:100%; height:auto; touch-action:pan-y; overflow:visible; }
.en-grid-line { stroke:rgba(255,255,255,.07); stroke-width:1; }
/* Nulllinie - nur sichtbar, wenn der Netzverlauf negativ wird (Einspeisung darunter) */
.en-zero-line { stroke:rgba(255,255,255,.22); stroke-width:1; }
.en-tick { font-size:10px; fill:var(--muted); }
.en-series { fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
.en-cross { stroke:rgba(255,255,255,.25); stroke-width:1; }
.en-empty { color:var(--muted); font-size:12px; text-align:center; padding:24px 0; }
.en-tip {
  position:absolute; z-index:5; background:rgba(28,28,28,.95); border:1px solid var(--bord);
  border-radius:var(--r); padding:7px 10px; font-size:11px; pointer-events:none; min-width:140px;
}
.en-tip .t-time { color:var(--muted); margin-bottom:4px; }
.en-tip .t-row { display:flex; align-items:center; gap:6px; margin-top:2px; }
.en-tip .t-key { width:12px; height:2px; border-radius:1px; flex-shrink:0; }
.en-tip .t-lbl { color:var(--muted); }
.en-tip .t-val { font-weight:700; color:var(--text); margin-left:auto; padding-left:10px; }

/* ---------- Zahnrad in der Fusszeile + Einstellmenue (ab v33) ----------
   Ein Overlay fuer alles, was nicht in eine Kachel gehoert. Bisher nur die
   Benachrichtigungen - die Schalter sassen frueher verteilt in den Klingel-Panels. */
.btn-zahnrad {
  background:none; border:1px solid var(--bord); border-radius:var(--r);
  color:var(--muted); padding:4px 7px; cursor:pointer; line-height:0;
  display:inline-flex; align-items:center;
}
.btn-zahnrad:hover { color:var(--text); }

.einst-wrap {
  position:fixed; inset:0; z-index:60; display:flex; align-items:center;
  justify-content:center; padding:16px;
  background:rgba(0,0,0,.6); backdrop-filter:blur(2px);
}
.einst-card {
  width:100%; max-width:460px; max-height:80vh; display:flex; flex-direction:column;
  background:#1c1c1c; border:1px solid var(--bord); border-radius:var(--r);
  box-shadow:0 10px 40px rgba(0,0,0,.5);
}
.einst-kopf {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:12px 14px; border-bottom:1px solid var(--bord);
}
.einst-titel { font-size:13px; font-weight:700; color:var(--text); }
.einst-inhalt { overflow-y:auto; padding:12px 14px calc(14px + env(safe-area-inset-bottom)); }

.einst-block + .einst-block { margin-top:18px; }
.einst-h {
  font-size:10px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted);
  margin-bottom:8px;
}
.einst-zeile {
  display:flex; align-items:center; gap:10px; padding:9px 0;
  border-bottom:1px solid rgba(255,255,255,.05);
}
.einst-zeile:last-of-type { border-bottom:none; }
.einst-label { flex:1 1 auto; min-width:0; font-size:13px; color:var(--text); }
.einst-probe {
  background:none; border:1px solid var(--bord); border-radius:var(--r);
  color:var(--muted); padding:3px 8px; font-size:10px; cursor:pointer; flex-shrink:0;
}
.einst-probe:hover { color:var(--text); }
.einst-probe[hidden] { display:none; }

/* Der Schalter ist hier ein <button> (fokussierbar, role=switch). Buttons bringen eine
   eigene Border und ein eigenes Widget-Aussehen mit; die Border verschiebt die
   Padding-Box - und damit den absolut gesetzten .sw-knob, der dann versetzt sitzt.
   Der globale Reset in Zeile 16 deckt nur margin/padding ab, nicht border/appearance.
   Darum hier hart zuruecksetzen. */
.einst-sw {
  appearance:none; -webkit-appearance:none;
  border:0; margin:0; padding:0; font:inherit; color:inherit;
  display:block; width:40px; height:22px; flex-shrink:0;
}
/* Eigener Zustand statt .tile-switch.on - die Zeile ist keine Kachel */
.einst-sw.an { background:rgba(166,227,161,.35); }
.einst-sw.an .sw-knob { left:20px; background:var(--rx); }
.einst-sw:disabled { opacity:.5; }

.einst-hinweis, .einst-fuss, .einst-lade { font-size:11px; color:var(--muted); line-height:1.5; }
.einst-fuss { margin-top:10px; padding-top:10px; border-top:1px solid var(--bord); }

/* ---------- Einlöse-Seite /einladung (ab v48) ---------- */
.ein-gruss   { font-size:14px; color:var(--text); text-align:center; line-height:1.5; }
.ein-gruss b { color:var(--tx); }
.ein-hinweis { font-size:11px; color:var(--muted); line-height:1.5; text-align:center; }
.ein-zeig    { font-size:11px; color:var(--muted); display:flex; align-items:center; gap:7px; cursor:pointer; }
.ein-zeig input { width:15px; height:15px; accent-color:var(--tx); }
/* Der Benutzername steht fest (der Admin legt ihn beim Einladen fest) - sichtbar, damit
   der Eingeladene ihn liest und der Passwortspeicher ihn mitsichert, aber nicht änderbar. */
#ein-user { text-align:center; color:var(--tx); font-weight:700; cursor:default; }

/* ---------- Benutzerverwaltung im Einstellmenue (ab v48, nur für Admins) ---------- */
.einst-inp {
  background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:var(--r);
  padding:9px 10px; color:var(--text); font-size:14px; width:100%;
}
.einst-inp:focus { outline:none; border-color:var(--tx); }
.einst-btn {
  background:none; border:1px solid var(--bord); border-radius:var(--r);
  color:var(--text); padding:7px 12px; font-size:12px; cursor:pointer;
}
.einst-btn:hover:not(:disabled) { border-color:var(--tx); }
.einst-btn:disabled { opacity:.5; cursor:default; }
.einst-btn.haupt { background:var(--tx); color:#1a1a1a; border-color:var(--tx); font-weight:700; }
.einst-btn.warn  { color:#ff8a80; }
.einst-reihe { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
.einst-reihe.eng { gap:6px; }

.einst-nutzer {
  display:flex; align-items:center; gap:10px; padding:10px 0;
  border-bottom:1px solid rgba(255,255,255,.05);
}
.einst-nutzer:last-of-type { border-bottom:none; }
.einst-nname { font-size:13px; color:var(--text); }
.einst-klein { font-size:10px; color:var(--muted); margin-top:2px; }
.einst-klein.wartet { color:var(--cap); }

/* Freigabe-Ansicht: Rubriken je Seite, aufklappbar bis zur einzelnen Kachel */
.einst-seite {
  font-size:10px; text-transform:uppercase; letter-spacing:.06em; color:var(--tx);
  margin:14px 0 4px;
}
.frei-auf {
  background:none; border:0; color:var(--muted); font-size:11px; cursor:pointer;
  padding:2px 6px; flex-shrink:0; width:22px; text-align:center;
}
.frei-auf.offen { color:var(--text); }
.frei-kacheln { padding:0 0 6px 22px; border-bottom:1px solid rgba(255,255,255,.05); }
.frei-kacheln .einst-zeile { padding:6px 0; border-bottom:none; }
.frei-kacheln .einst-label { font-size:12px; color:var(--muted); }
/* Dritter Zustand: einzelne Kacheln der Rubrik sind frei, aber nicht alle */
.einst-sw.teil { background:rgba(255,160,64,.30); }
.einst-sw.teil .sw-knob { left:10px; background:var(--cap); }

/* Der erzeugte Link wird EINMAL angezeigt - er muss vollständig lesbar und markierbar sein */
.einst-link {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size:11px; color:var(--text); background:rgba(255,255,255,.06);
  border:1px solid var(--bord); border-radius:var(--r); padding:8px 10px;
  word-break:break-all; user-select:all; line-height:1.5;
}
.einst-warn { font-size:11px; color:var(--cap); line-height:1.5; }

/* ---------- Wochenplan-Editor ---------- */
.wp-back { position: fixed; inset: 0; background: rgba(0,0,0,.72); z-index: 300; display: flex; align-items: flex-start; justify-content: center; overflow-y: auto; padding: 14px; }
.wp-box { background: #232323; color: var(--text); border: 1px solid var(--bord); border-radius: 16px; width: 100%; max-width: 560px; margin: auto; padding: 14px; box-shadow: 0 12px 40px rgba(0,0,0,.6); }
.wp-kopf { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.wp-titel { font-weight: 600; font-size: 1.05rem; }
.wp-laedt { padding: 28px 4px; text-align: center; opacity: .7; }   /* v144: sofort sichtbar, bis der Plan da ist */
.wp-x { background: none; border: none; color: inherit; font-size: 1.7rem; line-height: 1; cursor: pointer; padding: 0 6px; }
.wp-kopier { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.wp-btn-klein { background: var(--bg); color: inherit; border: 1px solid var(--bord); border-radius: 8px; padding: 5px 9px; font-size: .78rem; cursor: pointer; transition: background .12s, color .12s, border-color .12s, transform .08s; }
.wp-btn-klein:active { transform: scale(.94); }
.wp-btn-klein.flash { background: #E8A33D; color: #1a1a1a; border-color: #E8A33D; }
.wp-tag { border-top: 1px solid var(--bord); padding: 9px 0; }
.wp-tag-name { font-weight: 600; font-size: .9rem; margin-bottom: 6px; }
.wp-bar { position: relative; height: 14px; border-radius: 7px; background: #3465A4; overflow: hidden; margin-bottom: 7px; }
.wp-seg { position: absolute; top: 0; bottom: 0; }
.wp-seg.k { background: #E8A33D; }
.wp-seg.a { background: #3465A4; }
.wp-punkte { display: flex; flex-direction: column; gap: 6px; }
.wp-punkt { display: flex; align-items: center; gap: 7px; }
.wp-zeit { background: var(--bg); color: inherit; border: 1px solid var(--bord); border-radius: 7px; padding: 5px 6px; font-size: .92rem; }
.wp-lvl { flex: 1; border: none; border-radius: 7px; padding: 7px 8px; font-size: .85rem; cursor: pointer; color: #1a1a1a; font-weight: 600; }
.wp-lvl.k { background: #E8A33D; }
.wp-lvl.a { background: #7FA8E0; }
.wp-del { background: none; border: 1px solid var(--bord); color: inherit; border-radius: 7px; width: 32px; height: 32px; font-size: 1.15rem; cursor: pointer; flex: none; }
.wp-del:disabled { opacity: .3; cursor: default; }
.wp-add { align-self: flex-start; background: none; border: 1px dashed var(--bord); color: inherit; border-radius: 7px; padding: 5px 10px; font-size: .82rem; cursor: pointer; margin-top: 2px; }
.wp-fuss { margin-top: 14px; }
.wp-speichern { width: 100%; background: #2f7d4f; color: #fff; border: none; border-radius: 10px; padding: 12px; font-size: 1rem; font-weight: 600; cursor: pointer; }
.wp-speichern:disabled { opacity: .6; }

/* Wochenplan-Editor: Temperaturen + Aktiv-Schalter (Speichern-Knopf oben) */
.wp-speichern { margin-top: 2px; }
.wp-temps { display: flex; flex-direction: column; gap: 8px; margin: 12px 0 4px; }
.wp-temp { display: flex; align-items: center; gap: 10px; }
.wp-temp-lbl { flex: 1; font-size: .92rem; }
.wp-step { width: 38px; height: 38px; border-radius: 9px; border: 1px solid var(--bord); background: var(--bg); color: inherit; font-size: 1.3rem; line-height: 1; cursor: pointer; flex: none; }
.wp-temp-val { min-width: 76px; text-align: center; font-variant-numeric: tabular-nums; font-weight: 600; }
.wp-aktiv { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 0; border-top: 1px solid var(--bord); border-bottom: 1px solid var(--bord); margin: 10px 0; font-size: .95rem; }
.wp-aktiv .sw-track { flex: none; }
.wp-aktiv.an .sw-track { background: rgba(166,227,161,.35); }
.wp-aktiv.an .sw-knob { left: 20px; background: var(--rx); }

/* ---------- Schaltuhr-Editor (Einstell-Popup) ---------- */
.schaltuhr { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--bord); display: flex; flex-direction: column; gap: 10px; }
.su-info { color: var(--muted, #9a9a9a); font-size: .85rem; }
.su-kopf { display: flex; align-items: center; justify-content: space-between; }
.su-titel { font-weight: 600; }
.su-save { background: #E8A33D; color: #1a1a1a; border: none; border-radius: 8px; padding: 6px 14px; font-weight: 600; cursor: pointer; }
.su-save:disabled { opacity: .5; }
.su-aktiv { display: flex; align-items: center; justify-content: space-between; }
.su-toggle { background: var(--bg); color: var(--text); border: 1px solid var(--bord); border-radius: 20px; padding: 4px 14px; cursor: pointer; min-width: 56px; transition: background .12s, color .12s; }
.su-toggle.an { background: #E8A33D; color: #1a1a1a; border-color: #E8A33D; }
.su-toggle.su-klein { padding: 3px 10px; font-size: .78rem; min-width: 48px; }
.su-liste { display: flex; flex-direction: column; gap: 8px; }
.su-liste.su-aus { opacity: .45; pointer-events: none; }
.su-zeile { display: flex; align-items: center; gap: 8px; }
.su-zeit { background: var(--bg); color: var(--text); border: 1px solid var(--bord); border-radius: 8px; padding: 6px 8px; font-size: 1rem; color-scheme: dark; }
.su-ea { flex: 0 0 auto; border: 1px solid var(--bord); border-radius: 8px; padding: 5px 14px; cursor: pointer; min-width: 56px; transition: background .12s, color .12s; }
.su-ea.ein { background: #2e7d32; color: #fff; border-color: #2e7d32; }
.su-ea.aus { background: var(--bg); color: var(--muted, #9a9a9a); }
.su-del { margin-left: auto; background: transparent; color: var(--muted, #9a9a9a); border: 1px solid var(--bord); border-radius: 8px; width: 30px; height: 30px; font-size: 1.1rem; line-height: 1; cursor: pointer; }
.su-del:hover { color: #e57373; border-color: #e57373; }
.su-add { background: transparent; color: var(--text); border: 1px dashed var(--bord); border-radius: 8px; padding: 8px; cursor: pointer; }
.su-add:hover { border-color: #E8A33D; color: #E8A33D; }

/* ---------- Kleine Info-Texte rechts neben dem Zahnrad (nur Anzeige) ---------- */
.tile-infos { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; gap: 1px; text-align: right; }
.tile-info { font-size: .72rem; line-height: 1.25; color: var(--muted, #9a9a9a); white-space: nowrap; }

/* ---------- Kameras (Schnappschuss-Bilder) ---------- */
.kam-grid { display: flex; flex-direction: column; gap: 12px; }
.kam-card { position: relative; border-radius: 12px; overflow: hidden; background: #000; border: 1px solid var(--bord); cursor: pointer; }
.kam-bild { display: block; width: 100%; height: auto; min-height: 40px; }
.kam-lbl { position: absolute; left: 8px; bottom: 8px; padding: 2px 9px; border-radius: 8px; background: rgba(0,0,0,.55); color: #fff; font-size: .8rem; }

/* ---------- Dimmbare Leuchte in einer Karten-Zeile (Schalter oben, Dimmstreifen darunter) ---------- */
.karte-reihe-dim { flex-direction: column; align-items: stretch; gap: 6px; }
.karte-reihe-oben { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* Klima-Verlauf: Liste der letzten Ereignisse im Zahnrad-Popup. Eigene Bahn mit Scroll,
   damit lange Verlaeufe das Popup nicht sprengen. */
.verlauf { margin-top:10px; max-height:50vh; overflow-y:auto; }
.verlauf-tag { font-size:11px; color:var(--muted); text-transform:uppercase; letter-spacing:.04em;
  margin:10px 0 4px; padding-bottom:3px; border-bottom:1px solid rgba(255,255,255,.08); }
.verlauf-tag:first-child { margin-top:0; }
.verlauf-zeile { display:flex; align-items:baseline; gap:8px; padding:4px 0; font-size:13px; line-height:1.35; }
.verlauf-punkt { flex:0 0 auto; width:7px; height:7px; border-radius:50%; margin-top:5px; align-self:flex-start; }
.verlauf-punkt.gruen { background:#4ac97e; }
.verlauf-punkt.grau  { background:rgba(255,255,255,.28); }
.verlauf-punkt.gelb  { background:#ffd44d; }
.verlauf-punkt.rot   { background:#ff5f56; }
.verlauf-uhr { flex:0 0 auto; color:var(--muted); font-variant-numeric:tabular-nums; }
.verlauf-txt { flex:1 1 auto; min-width:0; }
.verlauf-leer { font-size:13px; color:var(--muted); padding:6px 0; }

/* ---------- Waldeck v4: dichtere Gruppen-Layouts (siehe baueGruppenInhalt in app.js) ---------- */
/* kompakt: kleine Kacheln, drei nebeneinander am Handy, auf breiten Schirmen mehr */
.grid.kompakt { grid-template-columns:repeat(auto-fill, minmax(110px, 1fr)); gap:6px; }
.grid.kompakt .tile { min-height:0; padding:7px 8px; gap:3px; }
.grid.kompakt .tile-lbl { font-size:9px; line-height:1.2; }
.grid.kompakt .tile-val { font-size:17px; }
.grid.kompakt .tile-val.text, .grid.kompakt .tile-switch .tile-val { font-size:13px; }
/* zeilen: eine Karte, ein Wert je Zeile. 40 px hoch, damit Schalter bequem tippbar bleiben */
.zk { padding:0 12px; }
/* Trennlinie OBEN statt unten: sonst bliebe unter der letzten sichtbaren Zeile eine Linie stehen,
   wenn die Zeilen darunter per verstecktWenn ausgeblendet sind (Schranke). */
.zk-z { display:flex; align-items:center; justify-content:space-between; gap:10px; min-height:40px; font-size:14px; }
.zk-z + .zk-z { border-top:1px solid var(--bord); }
.zk-l { color:var(--text); min-width:0; padding:6px 0; }
.zk-r { display:flex; align-items:center; gap:10px; flex-shrink:0; }
.zk-w { font-weight:600; color:var(--text); white-space:nowrap; }
.zk-w.zahl { font-weight:700; color:var(--tx); font-size:16px; }
.zk-w small { font-size:11px; color:var(--muted); font-weight:400; margin-left:3px; }
.zk-w.gut { color:var(--rx); }
.zk-w.aus { color:var(--muted); }
.zk-watt { font-size:12px; font-weight:700; color:var(--muted); }
.zk-watt.aktiv { color:var(--avg); }
.zk-z.an .sw-track, .lt-sw.an .sw-track { background:rgba(166,227,161,.35); }
.zk-z.an .sw-knob, .lt-sw.an .sw-knob { left:20px; background:var(--rx); }
.zk + .grid, .grid + .zk, .zk + .zk { margin-top:8px; }
/* tabelle: paarweise Werte (Logiken Bedingung/Freigabe, Energierechner kWh/Kosten) */
.zk-tab { padding:2px 12px; overflow-x:auto; }
.lt { width:100%; border-collapse:collapse; font-size:13px; }
.lt th { font-size:10px; color:var(--muted); text-transform:uppercase; letter-spacing:.06em; font-weight:400;
         text-align:right; padding:7px 0 5px 10px; }
.lt td { padding:9px 0 9px 10px; border-top:1px solid var(--bord); text-align:right; white-space:nowrap; }
.lt td:first-child { text-align:left; color:var(--text); padding-left:0; white-space:normal; }
.lt .zk-w.zahl { font-size:14px; }
.lt-sw .sw-track { display:inline-block; vertical-align:middle; }
/* "sendet …" und Verbindungspruefung wie bei den Kacheln */
.zk-z.sendet .zk-l::after, .lt-sw.sendet::before { content:'sendet … '; color:var(--cap); font-size:11px; }
.zk-z.sendet .sw-track, .lt-sw.sendet .sw-track { animation:st-puls 1s ease-in-out infinite; }
body.verb-unsicher .zk, body.verb-unsicher .zk-tab { opacity:.5; transition:opacity .15s .5s; }
/* htmlbox maxZeilen: Knopf zum Aufklappen unter der gekuerzten Tabelle */
.htmlbox-mehr { display:block; width:100%; margin-top:6px; padding:9px; font:inherit; font-size:13px;
                background:rgba(255,255,255,.06); border:1px solid var(--bord); border-radius:var(--r);
                color:var(--muted); cursor:pointer; }
.htmlbox-mehr[hidden] { display:none; }
.zk-w.stoer { color:#ff8a80; }
/* v6: Wert mit Diagramm - antippbar, kleines Verlaufszeichen */
.hat-verlauf { cursor:pointer; }
.tile.hat-verlauf .tile-lbl::after, .zk-z.hat-verlauf .zk-l::after { content:' ⌁'; color:var(--avg); }
td.hat-verlauf .zk-w { text-decoration:underline dotted rgba(125,212,252,.5); text-underline-offset:3px; }
/* v6: Tabellenzeile mit Popup (LAN-Standorte) */
tr.lt-popup { cursor:pointer; }
tr.lt-popup td:first-child::after { content:' ›'; color:var(--muted); }
tr.lt-popup:active td { background:rgba(255,255,255,.04); }
/* v6: Popups mit vielen Geraeten (LAN Haus: 18) - dichter, wie die Rubriken seit v4 */
.popup-liste.grid.liste { gap:6px; }
.popup-liste .tile { min-height:0; padding:8px 10px; gap:2px; }
.popup-liste .tile-werte .werte-row { gap:4px 14px; margin-top:2px; }
.popup-liste .werte-val { font-size:14px; }
.popup-liste .werte-lbl { font-size:9px; }
/* v7: Ereignis-Kachel (Zeitschaltung / Wochenplan) */
.tile-ereignis .ereignis-fuss { display:flex; align-items:center; flex-wrap:wrap; gap:6px; font-size:13px; color:var(--muted); }
.ereignis-zeit, .ep-punkt input, .ep-punkt select { background:rgba(0,0,0,.3); color:var(--text); border:1px solid var(--bord);
  border-radius:var(--r); padding:5px 6px; font:inherit; font-size:14px; color-scheme:dark; }
.ereignis-heute { flex-basis:100%; font-size:12px; }
.ep-liste { display:flex; flex-direction:column; gap:8px; max-height:60vh; overflow-y:auto; }
.ep-tag { border:1px solid var(--bord); border-radius:var(--r); padding:6px 8px; display:flex; flex-direction:column; gap:5px; }
.ep-tagkopf { display:flex; justify-content:space-between; align-items:center; font-size:13px; font-weight:700; color:var(--tx); }
.ep-punkt { display:grid; grid-template-columns:auto 1fr auto; gap:6px; align-items:center; }
.ep-klein { font-size:12px; padding:4px 8px; }
.ep-fuss { display:flex; justify-content:flex-end; margin-top:8px; }
/* v7: Live-Bild */
.kam-card { position:relative; }
.kam-live { position:absolute; top:8px; right:8px; background:rgba(0,0,0,.6); color:#fff; border:1px solid rgba(255,255,255,.35);
  border-radius:99px; padding:5px 10px; font-size:12px; font-weight:700; cursor:pointer; }
.kam-live-bild { width:100%; border-radius:var(--r); background:#000; min-height:180px; }
/* v7: Tagesbalken */
.tw-wahl { display:flex; gap:6px; margin-bottom:8px; }
.tw-wahl .aktiv { border-color:var(--tx); color:var(--tx); }
.tw-flaeche { position:relative; }
.tw-svg { width:100%; height:180px; display:block; }
.tw-svg rect { fill:var(--tx); opacity:.85; }
.tw-achse { display:flex; font-size:10px; color:var(--muted); }
.tw-achse span { flex:1; text-align:center; overflow:hidden; white-space:nowrap; }
.tw-max { font-size:10px; color:var(--muted); }
.tw-knopf { margin:6px 0 4px; }
.bestand-knoepfe { display:flex; flex-wrap:wrap; gap:6px; }

/* =====================================================================================
   Waldeck v9: IPSView-Ansicht (ipsv.js) - Holzhintergrund, Kopf, Menü und Seiten wie IPSView
   ===================================================================================== */
@font-face { font-family: 'Material Symbols Outlined'; font-style: normal; font-weight: 400; font-display: block; src: url(/ms.woff2) format('woff2'); }
.ipsv-sym { font-family: 'Material Symbols Outlined'; font-weight: normal; font-style: normal; line-height: 1; letter-spacing: normal;
  text-transform: none; white-space: nowrap; direction: ltr; -webkit-font-feature-settings: 'liga'; font-feature-settings: 'liga';
  display: inline-flex; align-items: center; justify-content: center; color: #bdbdbd; font-variation-settings: 'FILL' 0; }
.ipsv-sym.an { color: #3fe857; font-variation-settings: 'FILL' 1; }
.ipsv-sym.gut { color: #3fe857; font-variation-settings: 'FILL' 1; }

body.ipsv-an { background: #111 url(/ipsv/164414602.png) center top / cover fixed; }
body.ipsv-an #tabs, body.ipsv-an #subtabs { display: none !important; }
body.ipsv-an #dashboard { max-width: none; padding: 6px 6px 16px; }
body.ipsv-an .fuss { background: rgba(0,0,0,.55); }

.ipsv-kopf { position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 10px; padding: 8px 10px calc(8px) 6px;
  padding-top: max(8px, env(safe-area-inset-top)); background: linear-gradient(rgba(20,20,20,.92), rgba(20,20,20,.78));
  border-bottom: 1px solid rgba(188,188,188,.25); font-family: Roboto, 'Segoe UI', Arial, sans-serif; color: #fff; }
.ipsv-menu-knopf { background: rgba(86,86,86,.5); border: 0; border-radius: 6px; width: 44px; height: 40px; cursor: pointer; }
.ipsv-menu-knopf .ipsv-sym { font-size: 28px; color: #fff; }
.ipsv-kopf-mitte { flex: 1; min-width: 0; }
.ipsv-titel { font-size: 20px; color: #3fe857; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ipsv-datum { font-size: 12px; color: #bcbcbc; }
.ipsv-kopf-rechts { display: flex; align-items: center; gap: 8px; }
.ipsv-temp { font-size: 18px; }
.ipsv-wetter { width: 34px; height: 34px; object-fit: contain; }
.ipsv-uhr { font-size: 18px; font-weight: 700; min-width: 46px; text-align: right; }

.ipsv-menu-back { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.55); }
.ipsv-menu { position: absolute; left: 0; top: 0; bottom: 0; width: min(330px, 86vw); overflow-y: auto; padding: 10px 8px 24px;
  padding-top: max(10px, env(safe-area-inset-top)); background: #111 url(/ipsv/164414602.png) left top / cover;
  box-shadow: 4px 0 18px rgba(0,0,0,.6); font-family: Roboto, 'Segoe UI', Arial, sans-serif; }
.ipsv-menu-e { display: flex; align-items: center; gap: 14px; width: 100%; margin: 0 0 6px; padding: 8px 12px; min-height: 58px;
  border: 0; border-radius: 6px; color: #fff; font-size: 17px; text-align: left; cursor: pointer;
  background: linear-gradient(rgba(86,86,86,.5), rgba(54,54,54,.5)); position: relative; }
.ipsv-menu-e::after { content: ''; position: absolute; left: 40%; right: 14px; bottom: 6px; height: 2px; background: rgba(188,188,188,.8); border-radius: 1px; }
.ipsv-menu-e.aktiv { box-shadow: inset 4px 0 0 #3fe857; }
.ipsv-menu-e.aktiv .m-text { color: #3fe857; }
.ipsv-menu-e .m-sym { font-size: 32px; width: 40px; }
.ipsv-menu-e .m-text { flex: 1; }
.ipsv-menu-e .m-pfeil { font-size: 26px; }
.ipsv-menu-e.kind { min-height: 50px; padding-left: 28px; font-size: 16px; }
.ipsv-menu-e.kind .m-sym { font-size: 26px; width: 32px; }
.ipsv-menu-unter { display: none; }
.ipsv-menu-unter.offen { display: block; }
.ipsv-menu-fuss { margin-top: 14px; display: flex; justify-content: center; }

.ipsv-huelle { overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; }
.ipsv-flaeche { position: relative; margin: 0 auto; }
.ipsv-seite { position: absolute; left: 0; top: 0; transform-origin: 0 0; font-family: Roboto, 'Segoe UI', Arial, sans-serif; color: #fff; }
.ipsv-el { position: absolute; box-sizing: border-box; overflow: hidden; line-height: 1.15; color: #fff; }
.ipsv-el .ipsv-t { white-space: pre-wrap; overflow-wrap: anywhere; max-width: 100%; }
.ipsv-el.ipsv-weg { display: none !important; }
.ipsv-klick { cursor: pointer; }
.ipsv-klick:active { filter: brightness(1.25); }
.ipsv-img { width: 100%; height: 100%; object-fit: contain; display: block; pointer-events: none; }
.ipsv-el > .ipsv-sym { width: 100%; height: 100%; }
.ipsv-ToggleImage > .ipsv-sym, .ipsv-Image > .ipsv-sym, .ipsv-DetailImage > .ipsv-sym, .ipsv-RangeImage > .ipsv-sym,
.ipsv-ImageButton > .ipsv-sym, .ipsv-AssociationImage > .ipsv-sym, .ipsv-ValueImage > .ipsv-sym, .ipsv-ContinuousImage > .ipsv-sym { font-size: var(--sym, 1em); }
.ipsv-ToggleButton, .ipsv-Button, .ipsv-AssociationButton, .ipsv-DetailButton { border-radius: 6px; }
.ipsv-ToggleButton, .ipsv-Button { background: rgb(66,66,66); }
.ipsv-ToggleButton.an { background: linear-gradient(rgba(10,190,10,.67), rgb(10,110,10)); }
.ipsv-AssociationButton .ipsv-t { font-weight: 700; }
.ipsv-nurlesen { cursor: default; }
.ipsv-fluss { width: 100%; height: 100%; overflow: visible; display: block; }
.ipsv-fluss-punkte { stroke-dasharray: 2 26; animation: ipsv-fluss 1.4s linear infinite; }
.ipsv-fluss-punkte.rueck { animation-direction: reverse; }
@keyframes ipsv-fluss { to { stroke-dashoffset: -28; } }
.ipsv-ProgressbarVertical, .ipsv-Slider { background: rgba(255,255,255,.12); border-radius: 6px; display: flex; align-items: flex-end; }
.ipsv-voll { background: linear-gradient(rgba(10,190,10,.8), rgb(10,110,10)); border-radius: 6px; }
.ipsv-Slider { background: transparent; overflow: visible; }
.ipsv-spur { position: absolute; left: 6px; right: 6px; top: 50%; height: 12px; margin-top: -6px; border-radius: 6px; background: rgb(105,105,105); }
.ipsv-spur .ipsv-voll { position: absolute; left: 0; top: 0; background: rgb(10,190,10); }
.ipsv-knopf { position: absolute; top: 50%; width: 26px; height: 26px; margin: -13px 0 0 -13px; border-radius: 50%; background: #fafafa; border: 2px solid #000; box-sizing: border-box; }
.ipsv-gauge { width: 100%; height: 100%; }
.ipsv-gauge .g-grund { fill: none; stroke: rgba(255,255,255,.18); stroke-width: 8; stroke-linecap: round; }
.ipsv-gauge .g-wert { fill: none; stroke: #3fe857; stroke-width: 8; stroke-linecap: round; }
.ipsv-gauge text { fill: #fff; font-size: 13px; }
.ipsv-html { width: 100%; height: 100%; border: 0; display: block; background: transparent; }
.ipsv-medium { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 4px; background: #111; }
.ipsv-live { position: absolute; right: 8px; bottom: 8px; font-size: 20px; padding: 6px 14px; border-radius: 8px; border: 0;
  background: rgba(0,0,0,.6); color: #fff; cursor: pointer; }
.ipsv-chart { width: 100%; height: 100%; overflow: hidden; }
.ipsv-chart .en-chart-card { margin: 0; background: rgba(0,0,0,.25); height: 100%; box-sizing: border-box; }
.ipsv-ereignis { margin: 0; height: 100%; box-sizing: border-box; background: rgba(0,0,0,.25); font-size: 22px; }
.ipsv-leer { display: none; }

.ipsv-pop-back { align-items: flex-start; padding-top: max(12px, env(safe-area-inset-top)); overflow-y: auto; }
.ipsv-pop { margin: 0 auto 24px; max-width: calc(100vw - 16px); background: #111 url(/ipsv/164414602.png) center / cover;
  border: 1px solid rgba(127,127,127,.6); border-radius: 10px; padding: 8px; box-shadow: 0 10px 40px rgba(0,0,0,.7); }
.ipsv-pop-kopf { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 2px 4px 8px; color: #3fe857;
  font-size: 18px; font-family: Roboto, 'Segoe UI', Arial, sans-serif; }
.ipsv-pop-zu { background: rgba(86,86,86,.6); border: 0; border-radius: 6px; width: 38px; height: 34px; cursor: pointer; }
.ipsv-pop-zu .ipsv-sym { font-size: 24px; color: #fff; }
.ipsv-wahl .ipsv-wahl-knopf { display: block; width: 100%; margin: 6px 0; padding: 12px; border-radius: 6px; border: 1px solid #555;
  background: #333; color: #fff; font-size: 16px; }
.ipsv-wahl .ipsv-wahl-knopf.aktiv { background: linear-gradient(rgba(10,190,10,.67), rgb(10,110,10)); }
.ansicht-wahl { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 8px 0; }
.ansicht-wahl .aktiv { border-color: #3fe857; color: #3fe857; }
