/* Energy Tracker v2.2 – Enterprise-Designsystem
   Shell: Sidebar (Desktop) / Bottom-Tabs (Mobil) · Inter für UI, IBM Plex Mono für Zahlen */

@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/static/fonts/inter-latin-400.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/static/fonts/inter-latin-500.woff2') format('woff2'); }
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/static/fonts/inter-latin-600.woff2') format('woff2'); }
@font-face { font-family: 'Manrope'; font-style: normal; font-weight: 800; font-display: swap;
  src: url('/static/fonts/manrope-latin-800.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-latin-400.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-latin-500.woff2') format('woff2'); }

:root {
  --bg:#0f1114; --side:#0b0d10;
  --s1:#161a20; --s2:#1d232b; --s3:#252c36;
  --border:rgba(255,255,255,0.06); --border2:rgba(255,255,255,0.13);
  --fg:#e7eaee; --fg2:#9aa3ad; --fg3:#8b95a1;   /* 5,6:1 auf der Karte – vorher 2,8:1 */
  --accent:#7BB0FF; --accent-ink:#0b1220;
  --accent-dim:rgba(123,176,255,.13);
  --brand:#1A2540;
  --ok:#57b18e; --warn:#d0a35c; --danger:#c97a7a;
  /* Schriftstufen – bewusst nur fünf. Vorher lagen neun Größen zwischen
     10,5 und 14 px auf einer Seite; das ergibt kein Raster, sondern Unruhe,
     und das untere Ende war zu klein zum Lesen. */
  --fs-xs:12px;    /* Hinweise, Marken, Abzeichen, Legenden */
  --fs-sm:13px;    /* Formularbeschriftungen, Knöpfe, Tabellen */
  --fs-md:14px;    /* Grundtext, Kennzahlzeilen */
  --fs-lg:15px;    /* Abschnittsüberschriften */
  --fs-xl:22px;    /* Seitentitel */
  --r:9px; --r-lg:13px;
  --mono:'IBM Plex Mono',ui-monospace,monospace;
  --sans:'Inter',system-ui,sans-serif;
  --sh:0 1px 2px rgba(0,0,0,.35), 0 4px 14px rgba(0,0,0,.18);
  /* Seitenleiste waechst um die linke Safe Area (iPhone quer mit mehr als
     860 px, z. B. Pro Max): sonst laege sie unter Notch bzw. Dynamic Island. */
  --sidebar-w:calc(216px + env(safe-area-inset-left,0px)); --bottomnav-h:56px;
  --logo-cut:var(--bg);
}
[data-theme="light"] {
  --bg:#f4f5f7; --side:#eceef2;
  --s1:#ffffff; --s2:#f1f2f5; --s3:#e7e9ee;
  --border:rgba(15,23,32,0.08); --border2:rgba(15,23,32,0.16);
  --fg:#1a1e24; --fg2:#5c6672; --fg3:#616a76;   /* 4,9:1 auch auf der Seitenflaeche */
  --accent:#2A4470; --accent-ink:#ffffff;
  --accent-dim:rgba(42,68,112,.10);
  --brand:#2A4470;
  --ok:#1e7355; --warn:#7a5a1f; --danger:#9c4444;   /* lesbar auf den getoenten Flaechen der Abzeichen */
  --sh:0 1px 2px rgba(15,23,32,.05), 0 3px 10px rgba(15,23,32,.04);
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none!important}
/* Tipp-Kasten von iOS einmal fuer alles aus – Rueckmeldung gibt :active
   (unten bei .chip). :hover steht durchweg in @media(hover:hover): iOS setzt
   :hover beim Antippen und haelt es, bis woanders getippt wird. */
html{-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}
html,body{background:var(--bg);color:var(--fg);font-family:var(--sans);font-size:14px;line-height:1.5;-webkit-font-smoothing:antialiased}
a{color:inherit;text-decoration:none}
button{font-family:inherit}
/* Überschriften gliedern die Seite für Screenreader (Rotor „Überschriften“).
   Größe und Gewicht kommen weiter aus den Klassen (.page-title, .sec-label …);
   ohne Klasse übernimmt die Überschrift die Schrift ihres Behälters. */
h1,h2,h3{font:inherit}
/* Nur für Screenreader: unsichtbar, aber im Baum (z. B. #staleLive) */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0}
:focus{outline:none}                     /* Mausklick: ruhig */
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
input:focus-visible,select:focus-visible,textarea:focus-visible{
  outline:2px solid var(--accent);outline-offset:2px}

/* ── Shell ── */
.shell{display:flex;min-height:100vh;min-height:100dvh}
.sidebar{position:fixed;top:0;bottom:0;left:0;width:var(--sidebar-w);z-index:110;
  background:var(--side);border-right:1px solid var(--border);
  display:flex;flex-direction:column;padding:18px 12px 14px;--logo-cut:var(--side);
  padding-left:calc(12px + env(safe-area-inset-left,0px))}
.content{flex:1;margin-left:var(--sidebar-w);display:flex;flex-direction:column;min-width:0}
main{flex:1;padding:26px 0 64px}
.wrap{max-width:1160px;margin:0 auto;padding:0 max(28px,env(safe-area-inset-right)) 0 28px;width:100%}

/* Sidebar: Marke */
.sb-brand{display:flex;align-items:center;gap:9px;padding:2px 10px 18px}
/* Bildmarke: Blitz wird in --logo-cut ausgestanzt (Muster wie hzprd),
   dadurch sitzt sie in hellem wie dunklem Thema automatisch bündig. */
.sb-mark{width:30px;height:30px;flex-shrink:0;display:block}
.sb-name{font-family:'Manrope',var(--sans);font-size:20px;font-weight:800;
  letter-spacing:-.035em;line-height:1.1;color:var(--fg)}
.sb-domain{font-size:var(--fs-xs);color:var(--fg3)}

/* Sidebar: Navigation */
.sb-nav{display:flex;flex-direction:column;gap:2px;margin-top:6px}
.sb-item{display:flex;align-items:center;gap:11px;padding:8px 10px;border-radius:var(--r);
  font-size:var(--fs-md);font-weight:500;color:var(--fg2);position:relative;transition:all .12s}
.sb-item svg{width:17px;height:17px;flex-shrink:0}
@media(hover:hover){.sb-item:hover{color:var(--fg);background:var(--s2)}}
/* Aktiv = aria-current (base.html): Optik und Ansage hängen am selben Merkmal */
.sb-item[aria-current="page"]{color:var(--fg);background:var(--accent-dim)}
.sb-item[aria-current="page"]::before{content:'';position:absolute;left:-12px;top:7px;bottom:7px;width:3px;
  border-radius:0 3px 3px 0;background:var(--accent)}

/* Sidebar: Fuß */
.sb-foot{margin-top:auto;padding:12px 10px 0;border-top:1px solid var(--border);
  display:flex;flex-direction:column;gap:8px}
.sb-status{display:flex;align-items:center;gap:7px;font-size:var(--fs-xs);color:var(--fg2)}
.sb-meta{display:flex;align-items:center;justify-content:space-between;gap:8px}
.kw-tag{font-size:var(--fs-xs);color:var(--fg3);border:1px solid var(--border);padding:1px 7px;border-radius:5px}
.ver-tag{font-size:var(--fs-xs);color:var(--fg3)}

.theme-btn{padding:4px 9px;border-radius:6px;border:1px solid var(--border);background:none;
  color:var(--fg3);cursor:pointer;font-size:var(--fs-md);line-height:1;transition:color .12s}
@media(hover:hover){.theme-btn:hover{color:var(--fg)}}

/* Mobile Topbar */
.mtop{display:none;position:sticky;top:0;z-index:100;background:var(--bg);
  border-bottom:1px solid var(--border);align-items:center;gap:10px;
  padding:10px 16px;padding-top:calc(10px + env(safe-area-inset-top));
  padding-left:max(16px,env(safe-area-inset-left));padding-right:max(16px,env(safe-area-inset-right))}
.mtop .sb-mark{width:26px;height:26px}
.mtop .sb-name{font-size:18px}
.mtop-brand{display:flex;align-items:center;gap:10px}
.mtop .theme-btn{margin-left:auto}

/* Bottom-Tabs (Mobil) */
.bottomnav{display:none}

@media(max-width:860px){
  .sidebar{display:none}
  .content{margin-left:0}
  .mtop{display:flex}
  .bottomnav{position:fixed;bottom:0;left:0;right:0;z-index:100;display:flex;
    background:var(--s1);border-top:1px solid var(--border);
    padding-bottom:env(safe-area-inset-bottom);
    padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}
  .bn{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:3px;height:var(--bottomnav-h);color:var(--fg3);font-size:11px;font-weight:500;
    letter-spacing:.02em;position:relative}
  .bn svg{width:21px;height:21px}
  /* Aktiver Reiter: Farbe, halbfett und ein Balken oben. Die Farbe allein hob
     sich nur mit 1,4:1 (dunkel) bzw. 1,8:1 (hell) von den anderen ab. */
  .bn[aria-current="page"]{color:var(--accent);font-weight:600}
  .bn[aria-current="page"]::before{content:'';position:absolute;top:0;left:30%;right:30%;
    height:2px;border-radius:0 0 2px 2px;background:var(--accent)}
  main{padding:18px 0 calc(var(--bottomnav-h) + env(safe-area-inset-bottom) + 24px)}
  /* Quer (iPhone 15: 852 px) liegen links oder rechts Notch bzw. Dynamic
     Island – der Inhalt haelt mindestens die Safe Area Abstand. */
  .wrap{padding:0 max(16px,env(safe-area-inset-right)) 0 max(16px,env(safe-area-inset-left))}
}

/* ── Seitenkopf ── */
.page-hd{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin-bottom:22px}
.page-title{font-size:var(--fs-xl);font-weight:600;letter-spacing:-.02em}
.page-sub{font-size:var(--fs-sm);color:var(--fg3);display:flex;align-items:center;gap:7px}

/* Sprungmarken im Seitenkopf */
html{scroll-behavior:smooth}
.jumpnav{flex-wrap:wrap;gap:0}
.jumpnav a{color:var(--fg3);padding:3px 9px;border-radius:99px;border:1px solid transparent;
  transition:all .12s}
@media(hover:hover){.jumpnav a:hover{color:var(--accent);border-color:var(--border2);background:var(--s2)}}
.jumpnav a:not(:last-child)::after{content:'';display:inline-block}
/* Marke sitzt auf der KARTE, nicht auf der Überschrift: sonst schiebt der
   Browser die Überschrift bündig an die Oberkante, Kartenrand und Innenabstand
   liegen außerhalb – es wirkt, als wäre man mitten im Text gelandet.
   Am Handy klebt der Kopf (.mtop) darüber, seine Höhe kommt dazu. Sie ist
   nicht fest: In der Homescreen-App wächst er um die Safe Area (47–62 px).
   app.js misst ihn und setzt --mtop-h; bis dahin gilt die Formel des Kopfs
   (10 + 26 + 10 px + Linie + Safe Area). Auf dem Desktop ist er aus: 0. */
[id^="sec-"]{scroll-margin-top:calc(var(--mtop-h,0px) + 20px)}
@media(max-width:860px){:root{--mtop-h:calc(47px + env(safe-area-inset-top,0px))}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

/* ── Sektionen / Karten ── */
.sec{margin-top:26px}
.sec-gap{margin-top:12px}
.sec-label{font-size:var(--fs-lg);font-weight:600;color:var(--fg);letter-spacing:-.01em;
  margin-bottom:13px;display:flex;align-items:center;gap:10px}
.sec-label::after{display:none}
.row-between{justify-content:space-between}
.sec-note{font-size:var(--fs-xs);font-weight:400;color:var(--fg3);letter-spacing:0}
/* Weiterführender Link rechts in der Abschnittszeile („Mehr in der Analyse“).
   Textlink statt Knopf, damit die Zeile nicht höher wird. Die Tippfläche
   wächst unsichtbar auf 44 px, nur senkrecht wie bei .jumpnav. */
.mehr-link{position:relative;margin-left:auto;display:inline-flex;align-items:center;gap:1px;
  font-size:var(--fs-sm);font-weight:500;color:var(--accent);letter-spacing:0;white-space:nowrap}
.mehr-link svg{width:14px;height:14px;flex-shrink:0}
.mehr-link::after{content:'';position:absolute;left:0;right:0;top:50%;
  transform:translateY(-50%);height:44px}
@media(hover:hover){.mehr-link:hover{text-decoration:underline;text-underline-offset:2px}}

.card{background:var(--s1);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:18px 20px;box-shadow:var(--sh)}
.table-card{padding:0;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch}
/* Breite Tabellen MUESSEN im eigenen Rahmen scrollen. Mit overflow:hidden war
   am Handy die Spalte „Widerrufen" schlicht unerreichbar (28.09.2026 gemessen:
   Tabelle 727 px in einem 301 px breiten Kasten, Knopf bei 658 px). */

.grid{display:grid;gap:12px}
.g2{grid-template-columns:1fr 1fr}
@media(max-width:860px){.g2{grid-template-columns:1fr}}
.col-stack{display:flex;flex-direction:column;gap:12px}
.col-stack .card{flex-shrink:0}

/* ── KPI ── */
.kpi-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:12px}
@media(max-width:1000px){.kpi-row{grid-template-columns:1fr 1fr}}
@media(max-width:380px){.kpi-row{gap:8px}}
/* Unter 340 px (iPhone mit Anzeigezoom: 320 px, Textzoom 200 %: 188 px)
   reicht die halbe Breite nicht für einen fünfstelligen Zählerstand –
   overflow:hidden schnitt die letzten Ziffern ohne jedes Zeichen ab. */
@media(max-width:340px){.kpi-row{grid-template-columns:1fr}}
.kpi{background:var(--s1);border:1px solid var(--border);border-radius:var(--r-lg);
  padding:14px 16px;box-shadow:var(--sh);position:relative;overflow:hidden}
.kpi-label{font-size:var(--fs-sm);font-weight:500;color:var(--fg2);margin-bottom:7px}
/* Fließend kleiner unter 375 px, darüber unverändert 27/33 px */
.kpi-value{font-size:clamp(21px,7.2vw,27px);font-weight:600;line-height:1.1;letter-spacing:-.025em;font-feature-settings:'tnum' 1}
.kpi-unit{font-size:var(--fs-md);color:var(--fg3);margin-left:5px;font-weight:400;letter-spacing:0}
.kpi-sub{font-size:var(--fs-sm);color:var(--fg3);margin-top:6px}
@keyframes fadeUp{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}
.kpi{animation:fadeUp .22s ease both}
.kpi:nth-child(1){animation-delay:.03s}.kpi:nth-child(2){animation-delay:.06s}
.kpi:nth-child(3){animation-delay:.09s}.kpi:nth-child(4){animation-delay:.12s}
@media(prefers-reduced-motion:reduce){.kpi{animation:none}}

/* ── Live-Status ── */
.live-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--ok);flex-shrink:0;
  box-shadow:0 0 0 0 rgba(87,177,142,.4);animation:dpulse 2.2s ease-in-out infinite}
.live-dot.stale{background:var(--fg3);animation:none;box-shadow:none}
@keyframes dpulse{0%,100%{box-shadow:0 0 0 0 rgba(87,177,142,.4)}55%{box-shadow:0 0 0 5px rgba(87,177,142,0)}}
/* „Bewegung reduzieren“: Punkt steht still, grün heißt weiter „live“ */
@media(prefers-reduced-motion:reduce){.live-dot{animation:none}}

.stale-banner{display:flex;align-items:center;gap:8px;justify-content:center;
  background:rgba(208,163,92,.09);border-bottom:1px solid rgba(208,163,92,.25);
  color:var(--warn);font-size:var(--fs-sm);padding:7px max(16px,env(safe-area-inset-right)) 7px 16px;text-align:center}
/* Links grenzt am Handy der Bildschirmrand an, auf dem Desktop die Seitenleiste */
@media(max-width:860px){.stale-banner{padding-left:max(16px,env(safe-area-inset-left))}}
/* Weg zur Anmeldung nach einem 401. Das Banner ist nur gut 30 px hoch, die
   Trefferfläche wächst unsichtbar auf 44 px. */
.stale-banner a{position:relative;color:inherit;font-weight:600;white-space:nowrap;
  text-decoration:underline;text-underline-offset:2px}
.stale-banner a::after{content:'';position:absolute;left:-8px;right:-8px;top:50%;
  transform:translateY(-50%);height:44px}

/* ── KV-Zeilen ── */
.kv{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:6.5px 0;border-bottom:1px solid var(--border)}
.kv:last-child{border-bottom:none}
.kv .k{font-size:var(--fs-md);color:var(--fg2)}
.kv .v{font-size:var(--fs-md);font-weight:500;text-align:right;font-feature-settings:'tnum' 1}
/* Erlaeuterung unter einem Wert: volle Zeilenbreite, rechtsbuendig unter dem Wert –
   so bricht sie am Handy nicht in eine schmale Spalte */
.kv{flex-wrap:wrap}
.kv-sub{flex-basis:100%;text-align:right;font-size:var(--fs-xs);color:var(--fg3);
  margin-top:-3px;font-feature-settings:'tnum' 1}
.badge{white-space:nowrap}

.badge{display:inline-flex;align-items:center;font-size:var(--fs-xs);font-weight:600;
  padding:3px 9px;border-radius:6px;font-feature-settings:'tnum' 1}
.badge.ok{background:rgba(87,177,142,.13);color:var(--ok)}
.badge.danger{background:rgba(201,122,122,.13);color:var(--danger)}
.badge.neu{background:var(--s2);color:var(--fg2)}
.badge.warnung{background:rgba(208,163,92,.14);color:var(--warn)}

/* ── Buttons / Controls ── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:6px 13px;min-height:33px;
  border-radius:var(--r);font-size:var(--fs-sm);font-weight:500;border:1px solid var(--border);
  background:var(--s2);color:var(--fg2);cursor:pointer;transition:all .12s;white-space:nowrap}
@media(hover:hover){.btn:hover{color:var(--fg);border-color:var(--border2);background:var(--s3)}}
.btn.active{color:var(--fg);background:var(--s1);border-color:var(--border2)}
.btn.primary{background:var(--accent);border-color:var(--accent);color:var(--accent-ink);font-weight:600}
@media(hover:hover){.btn.primary:hover{filter:brightness(1.08)}}
.btn.warn-btn{color:var(--warn)}
/* Gesperrt nur, solange eine Anfrage läuft (app.js, aktion) */
.btn:disabled{opacity:.55;cursor:progress}
.btnrow{display:flex;gap:7px;flex-wrap:wrap}

.ftabs{display:inline-flex;background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:3px;gap:2px}
.ftabs .btn{padding:4px 11px;min-height:27px;font-size:var(--fs-sm);border:none;background:none;border-radius:6px;font-weight:500}
.ftabs .btn.active{background:var(--s1);color:var(--fg);box-shadow:0 1px 3px rgba(0,0,0,.25)}
@media(hover:hover){.ftabs .btn:hover:not(.active){background:transparent;color:var(--fg)}}
[data-theme="light"] .ftabs .btn.active{box-shadow:0 1px 3px rgba(15,23,32,.12)}
/* Schmale Handys (320 px mit Anzeigezoom): inline-flex bricht nicht um und
   schrumpft nicht – die Leiste „Tag … Jahr“ schob die ganze Seite seitlich
   heraus. Hier füllt sie die Kartenbreite, die Knöpfe teilen sich den Platz
   nach Textlänge. Umbrechen nur als Notnagel bei starkem Textzoom. */
@media(max-width:380px){
  .ftabs{display:flex;flex-wrap:wrap;width:100%}
  .ftabs .btn{flex:1 1 auto;min-width:0;padding-left:2px;padding-right:2px}
}

.presets{display:inline-flex;gap:5px;flex-wrap:wrap}
.chip{padding:4px 12px;min-height:27px;border-radius:99px;font-size:var(--fs-sm);font-weight:500;
  border:1px solid var(--border);background:none;color:var(--fg2);cursor:pointer;transition:all .12s}
@media(hover:hover){.chip:hover{color:var(--fg);border-color:var(--border2)}}
.chip.active{color:var(--accent);border-color:var(--accent);background:var(--accent-dim)}
/* Am Handy füllen die Zeitraum-Chips die Kartenbreite und teilen sich den
   Platz nach Textlänge, wie .ftabs darüber. Mit ausgeschriebenen Namen
   („30 Tage“ statt „30 T“) passten sie mit 12 px Rand nicht in eine Zeile,
   „Alles“ stand dann allein in der zweiten (gemessen bei 375 px: 361 px
   Bedarf, 301 px Platz). Mit 4 px passen sie ab 360 px; darunter bricht die
   Reihe als Notnagel um. */
@media(max-width:719px){
  .presets{display:flex;width:100%}
  .chip{flex:1 1 auto;padding-left:4px;padding-right:4px}
}
/* Rückmeldung beim Drücken – am Finger gibt es kein Hover, und den grauen
   Tipp-Kasten von iOS schaltet html{} ab. */
.btn:active,.chip:active,.bn:active,.jumpnav a:active,.klapp-kopf:active,.theme-btn:active,.mehr-link:active{opacity:.7}

.inline-check{display:inline-flex;flex-direction:row;align-items:center;gap:6px;margin:0;
  font-size:var(--fs-sm);color:var(--fg2);white-space:nowrap}
.inline-check input[type=checkbox]{width:13px;height:13px;accent-color:var(--accent)}

/* ── Chart ── */
.chart-wrap{position:relative;height:280px;width:100%}
.h290{height:290px}.h240{height:240px}.h220{height:220px}.h180{height:180px}
@media(max-width:860px){.chart-wrap{height:230px}.h290{height:250px}.h240{height:210px}.h220{height:200px}.h180{height:150px}}
.chart-tb{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.stats-bar{font-size:var(--fs-sm);color:var(--fg3);min-height:18px;margin-bottom:7px;font-feature-settings:'tnum' 1}
/* Abruf gescheitert: Hinweis deckt die Leinwand ab (charts.js, leinwandHinweis),
   damit kein altes Diagramm unter der neu gewählten Schaltfläche steht. */
.lade-hinweis{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:12px;text-align:center;font-size:var(--fs-sm);color:var(--fg3);background:var(--s1)}

/* ── Tabellen ── */
.tbl{width:100%;border-collapse:collapse}
.tbl thead tr{border-bottom:1px solid var(--border)}
.tbl th{font-size:var(--fs-xs);font-weight:600;color:var(--fg3);text-align:left;padding:11px 14px 9px}
.tbl td{padding:8px 14px;border-bottom:1px solid var(--border);font-size:var(--fs-sm)}
.tbl tr:last-child td{border-bottom:none}
@media(hover:hover){.tbl tbody tr:hover td{background:var(--s2)}}
/* Tagesabschlüsse: Die Herkunft des Werts ist am Handy verzichtbar, dort
   bleiben Zeitpunkt und Stand nebeneinander. */
@media(max-width:719px){.tbl-quelle{display:none}}
.mono{font-size:inherit;font-feature-settings:'tnum' 1}
.dim{color:var(--fg3)}
.ua-cell{max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fs-xs)}
.empty{font-size:var(--fs-sm);color:var(--fg3);padding:12px 0;text-align:center}

/* ── Formulare ── */
label{display:flex;flex-direction:column;gap:5px;font-size:var(--fs-sm);font-weight:500;color:var(--fg2);margin-bottom:8px}
/* NICHT nach type auswählen: Felder ohne type-Attribut (wie die Tasmota-Pfade)
   werden davon nicht erfasst und fallen auf die Browser-Voreinstellung zurück –
   13,3 px in fremder Schrift neben 14-px-Nachbarn. */
input:not([type=file]):not([type=checkbox]):not([type=radio]){
  background:var(--bg);border:1px solid var(--border);
  color:var(--fg);border-radius:var(--r);padding:7px 10px;font-size:var(--fs-md);font-family:inherit;
  width:100%;transition:border-color .12s;min-height:36px;font-weight:400}
input:focus{border-color:var(--accent)}
input[type=file]{color:var(--fg2);font-size:var(--fs-sm);padding:4px 0;font-weight:400}
select{background:var(--bg);border:1px solid var(--border);color:var(--fg);border-radius:var(--r);
  padding:5px 9px;font-size:var(--fs-sm);cursor:pointer;min-height:29px}
.hint{font-size:var(--fs-xs);color:var(--fg3);margin-bottom:9px;line-height:1.55;font-weight:400}
.import-form{display:flex;flex-direction:column;gap:9px}
.file-label{font-size:var(--fs-xs);color:var(--fg3);font-weight:400}

.flash{padding:10px 14px;border-radius:var(--r);font-size:var(--fs-sm);margin-bottom:14px}
.flash.ok{background:rgba(87,177,142,.09);border:1px solid rgba(87,177,142,.22);color:var(--ok)}
.flash.err{background:rgba(201,122,122,.09);border:1px solid rgba(201,122,122,.22);color:var(--danger)}

/* ── Demo-Zugaenge ── */
.demo-neu{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap}
.demo-neu label{display:flex;flex-direction:column;gap:5px;font-size:var(--fs-xs);color:var(--fg2)}
.demo-neu input{min-width:220px}
.demo-neu .btn{white-space:nowrap}
@media(max-width:560px){.demo-neu label,.demo-neu input,.demo-neu select,.demo-neu .btn{width:100%}}
/* Gekürzter Link (/r/abcd…) in einer Zeile – vorher brach die volle URL in
   der schmalen Spalte auf viele Zeilen um, jede Zeile war rund 217 px hoch. */
#demoTbl .keycode{width:auto;min-width:0;font-size:var(--fs-xs);white-space:nowrap}
.warn-text{color:var(--warn)}
.ta-r{text-align:right}

.keyrow{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap}
.keyrow label{flex:1;min-width:210px;display:flex;flex-direction:column;gap:5px;
  font-size:var(--fs-xs);color:var(--fg2)}
.keycode{display:block;flex:1;min-width:200px;font-family:var(--mono);font-size:var(--fs-xs);line-height:1.65;
  background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:10px 12px;
  color:var(--accent);white-space:normal;word-break:break-all;cursor:pointer;transition:all .12s;
  -webkit-user-select:all;user-select:all}
/* Kopierfelder sind Knöpfe (kopieren, nicht öffnen): Breite und Ausrichtung
   wie zuvor beim Link */
button.keycode{width:100%;text-align:left}
@media(hover:hover){.keycode:hover{border-color:var(--accent);background:var(--accent-dim)}}
.keycode:active{transform:scale(.995)}

code{font-family:var(--mono);font-size:.95em;background:var(--s2);padding:1.5px 6px;border-radius:4px;color:var(--fg2)}

/* ── Grundlast ── */
.baseload-value{font-size:34px;font-weight:600;letter-spacing:-.025em;line-height:1.1;margin:2px 0 6px;font-feature-settings:'tnum' 1}
.baseload-value .kpi-unit{font-size:var(--fs-md)}
.baseload-cost{font-size:var(--fs-sm);color:var(--fg2);margin-bottom:9px}
.baseload-cost b{color:var(--warn);font-weight:600;font-feature-settings:'tnum' 1}

/* ── Klappkarten ──
   Kopfzeile ist der Schalter. Die Karte startet zu; der Inhalt wird erst
   gezeichnet, wenn sie aufgeht – sonst rechnet die Seite fuer nichts. */
.klapp-zeile{margin-bottom:0}
.klapp.auf .klapp-zeile{margin-bottom:13px}
/* Mit Auswahl daneben (Jahres-Heatmap) steckt der Knopf in einem eigenen h2 –
   sonst stünde „Jahr: 2026 2025“ im Namen der Überschrift. Das h2 übernimmt
   dann den Platz, den vorher der Knopf in der Zeile hatte. display:flex,
   damit der Knopf (flex:1) es ausfüllt – als Block bliebe er so schmal wie
   sein Text, und Tipp- und Hover-Fläche endeten am Titel. */
.klapp-h{flex:1;min-width:0;display:flex}
.klapp-kopf{display:flex;align-items:center;gap:9px;flex:1;min-width:0;
  background:none;border:0;padding:0;margin:0;cursor:pointer;text-align:left;
  font:inherit;color:inherit;letter-spacing:inherit}
@media(hover:hover){.klapp-kopf:hover{color:var(--accent)}}
.klapp-kopf:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:4px}
.klapp-pfeil{width:15px;height:15px;flex:0 0 15px;color:var(--fg3);
  transition:transform .18s ease,color .18s ease}
.klapp.auf .klapp-pfeil{transform:rotate(90deg);color:var(--accent)}
@media(hover:hover){.klapp-kopf:hover .klapp-pfeil{color:var(--accent)}}
.klapp-titel{white-space:nowrap}
.klapp-hinweis{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Am Handy zaehlt jeder Millimeter: Zusatz weg, Titel bleibt einzeilig */
@media(max-width:719px){.klapp-hinweis{display:none}}
/* Gesperrt wird per disabled (charts.js, klappkarten) – so gilt es auch für
   Tastatur und VoiceOver. Hier nur die Optik dazu. */
.klapp:not(.auf) .inline-check{opacity:.45}
.klapp-korpus{animation:klappAuf .18s ease}
@keyframes klappAuf{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.klapp-korpus{animation:none}.klapp-pfeil{transition:none}}

/* ── Heatmap ── */
.heatmap-scroll{overflow-x:auto;padding-bottom:6px}
.heatmap{min-width:740px}
/* Hochkant-Fassung (Monate x Tage) passt in die Breite – kein Mindestmass */
@media(max-width:719px){.heatmap{min-width:0}}
.heatmap svg{display:block}
.hm-cell{rx:2px}
.hm-l0{fill:var(--s2)}
.hm-l1{fill:rgba(123,176,255,.25)}
.hm-l2{fill:rgba(123,176,255,.45)}
.hm-l3{fill:rgba(123,176,255,.68)}
.hm-l4{fill:rgba(123,176,255,.78)}
.hm-l5{fill:rgba(123,176,255,.95)}
[data-theme="light"] .hm-l1{fill:rgba(42,68,112,.22)}
[data-theme="light"] .hm-l2{fill:rgba(42,68,112,.40)}
[data-theme="light"] .hm-l3{fill:rgba(42,68,112,.62)}
[data-theme="light"] .hm-l4{fill:rgba(42,68,112,.74)}
[data-theme="light"] .hm-l5{fill:rgba(42,68,112,.92)}
/* 11 px wie die Diagrammachsen – 10 px war die kleinste Schrift der App */
.hm-label{fill:var(--fg3);font-family:var(--mono);font-size:11px}
/* Kästchen lassen sich antippen, der Wert steht dann in .hm-wert. cursor
   auch, damit iOS den Tipp überhaupt als Klick meldet. Die Auswahl erkennt
   man am Rahmen, nicht nur an der Farbe. */
.hm-cell{cursor:pointer}
.hm-cell.hm-wahl{stroke:var(--fg);stroke-width:2px}
/* Ein Tabstopp je Raster, Pfeiltasten wandern (charts.js rasterAblesen).
   Fokusrahmen nach innen: Der Scrollkasten schneidet alles außen ab.
   manipulation: schnelles Antippen zoomt am iPhone nicht die Seite. */
.raster{touch-action:manipulation}
.raster:focus-visible{outline-offset:-2px}
/* Ablesezeile über der Legende, je eine eigene Zeile: So springt nichts,
   wenn der Text beim Antippen kürzer oder länger wird. */
.heatmap-fuss{margin-top:8px}
.hm-wert{font-size:var(--fs-sm);color:var(--fg);font-feature-settings:'tnum' 1}
.hm-wert.leer{color:var(--fg3)}
.heatmap-legend{display:flex;flex-wrap:wrap;align-items:center;gap:4px 10px;margin-top:4px;
  font-size:var(--fs-xs);color:var(--fg3);justify-content:flex-end;font-feature-settings:'tnum' 1}
.heatmap-legend .lg{width:11px;height:11px;border-radius:2px;display:inline-block}
.lg-stufe{display:inline-flex;align-items:center;gap:4px;white-space:nowrap}
/* Legende – dieselben Stufen wie die Kacheln, theme-abhaengig.
   hm-lg0 = „keine Daten“ wie .hm-l0 */
.hm-lg0{background:var(--s2)}
.hm-lg1{background:rgba(123,176,255,.25)} .hm-lg2{background:rgba(123,176,255,.45)}
.hm-lg3{background:rgba(123,176,255,.68)} .hm-lg4{background:rgba(123,176,255,.78)}
.hm-lg5{background:rgba(123,176,255,.95)}
[data-theme="light"] .hm-lg1{background:rgba(42,68,112,.22)}
[data-theme="light"] .hm-lg2{background:rgba(42,68,112,.40)}
[data-theme="light"] .hm-lg3{background:rgba(42,68,112,.62)}
[data-theme="light"] .hm-lg4{background:rgba(42,68,112,.74)}
[data-theme="light"] .hm-lg5{background:rgba(42,68,112,.92)}
/* Hochkant steht das Raster links – die Skala gehoert darunter, nicht ins Leere */
@media(max-width:719px){.heatmap-legend{justify-content:flex-start}}

/* ── Events ── */
.ev-list{display:flex;flex-direction:column}
.ev-row{display:flex;align-items:baseline;gap:14px;padding:7px 0;border-bottom:1px solid var(--border);font-size:var(--fs-sm)}
.ev-row:last-child{border-bottom:none}
.ev-ts{font-size:var(--fs-sm);color:var(--fg3);white-space:nowrap;font-feature-settings:'tnum' 1}
.ev-delta{font-weight:600;min-width:78px;text-align:right;font-feature-settings:'tnum' 1}
.ev-delta.up{color:var(--danger)}
.ev-delta.down{color:var(--ok)}
.ev-bar{flex:1;height:4px;border-radius:2px;background:var(--s2);position:relative;overflow:hidden}
.ev-bar i{position:absolute;top:0;bottom:0;border-radius:2px}
.ev-bar .up{background:rgba(201,122,122,.55)}
.ev-bar .down{background:rgba(87,177,142,.55)}
.pair-dur{font-size:var(--fs-sm);color:var(--fg3);min-width:74px;font-feature-settings:'tnum' 1}
.pair-cost{font-weight:600;min-width:62px;text-align:right;font-feature-settings:'tnum' 1}
@media(max-width:520px){.pair-dur{display:none}.ev-bar{display:none}}

/* Wiederkehrende Verbraucher */
.grp-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-bottom:14px}
.grp{background:var(--s2);border:1px solid var(--border);border-radius:var(--r);padding:9px 11px}
.grp-w{font-size:15px;font-weight:600;letter-spacing:-.02em;font-feature-settings:'tnum' 1}
.grp-c{font-size:var(--fs-xs);color:var(--fg3);margin-top:2px}
.grp-e{font-size:var(--fs-md);font-weight:600;color:var(--warn);margin-top:4px;font-feature-settings:'tnum' 1}

/* ── Kein Zugriff ── */
.denied-wrap{display:flex;align-items:center;justify-content:center;min-height:100vh;min-height:100dvh;padding:24px}
.denied-card{max-width:340px;text-align:center;padding:30px 26px}
/* ── Anmeldung ── */
.anmelde-karte{width:100%;max-width:330px;padding:30px 26px;display:flex;flex-direction:column;
  align-items:center;gap:0}
.anmelde-marke{font-family:'Manrope',var(--sans);font-weight:800;letter-spacing:-.9px;font-size:23px;
  margin:10px 0 20px;color:var(--fg)}
.anmelde-feld{display:flex;flex-direction:column;gap:6px;width:100%;font-size:var(--fs-xs);color:var(--fg2)}
.anmelde-feld input{width:100%;text-align:center;letter-spacing:.06em;font-family:var(--mono)}
.anmelde-knopf{width:100%;margin-top:14px;justify-content:center}
.anmelde-fuss{margin:16px 0 0;text-align:center}
.anmelde-fuss + .anmelde-fuss{margin-top:6px}
.anmelde-karte .flash{width:100%;margin-bottom:14px}

/* ── Toast ── */
#notif{position:fixed;bottom:20px;right:max(20px,env(safe-area-inset-right));z-index:999;background:var(--s1);border:1px solid var(--border2);
  border-radius:var(--r);padding:10px 15px;font-size:var(--fs-sm);box-shadow:var(--sh);
  opacity:0;transform:translateY(5px);transition:all .2s;pointer-events:none;max-width:calc(100vw - 40px)}
#notif.show{opacity:1;transform:translateY(0)}
/* Ohne Hochgleiten, nur Einblenden */
@media(prefers-reduced-motion:reduce){#notif{transform:none}}
@media(max-width:860px){#notif{bottom:calc(var(--bottomnav-h) + env(safe-area-inset-bottom) + 14px);
  left:max(18px,env(safe-area-inset-left));right:max(18px,env(safe-area-inset-right));text-align:center}}

/* ── Pull-to-Refresh (Muster hzprd) ──────────────────────────────────────
   Aufbau bewusst 1:1: Position UND Deckkraft der Münze hängen an EINER
   Variablen, die das JS setzt. Schreibt das JS bei jedem touchmove stattdessen
   einen Inline-transform, sitzt der drehende Pfeil in einem Elternteil mit
   ständig wechselndem Transform – und iOS zeichnet die Animation nicht neu.
   KEIN will-change: das zwingt Kopf und Inhalt in eigene Zeichenebenen, in
   deren Nachbarschaft iOS die Drehung ebenfalls verschluckt. */
.ptr-ind{position:fixed;top:env(safe-area-inset-top,0px);left:50%;z-index:60;
  transform:translate(-50%,calc(var(--ptr,0px) - 40px));
  opacity:calc(var(--ptr,0px) / 43px);
  width:32px;height:32px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--s1);border:1px solid var(--border2);color:var(--fg2);
  box-shadow:0 2px 8px rgba(0,0,0,.18);pointer-events:none;
  /* Farbe NICHT mit in diesen Übergang: --ptr-t wechselt mitten in der Geste,
     dabei wird die transition-Eigenschaft neu gelesen und der laufende
     Farbwechsel bleibt am Startwert hängen – die Münze blieb grau, obwohl
     .ptr-spin die Markenfarbe setzt (nachgemessen 12.08.). Der Wechsel an der
     Schwelle ist ohnehin ein Schaltpunkt, kein Verlauf. */
  transition:transform var(--ptr-t,0s) cubic-bezier(.22,1,.36,1),
             opacity var(--ptr-t,0s) cubic-bezier(.22,1,.36,1)}
.ptr-ind svg{display:block;width:16px;height:16px}
/* Auslösepunkt: die Marke tritt schon hier auf, damit der Wechsel ins Laden
   kein Farbsprung ist, sondern nur der Moment, in dem sich das Rad dreht. */
.ptr-ind.ptr-bereit{color:var(--accent)}
/* Laden: nur das ICON dreht, die Münze steht still – ein drehender Kreis mit
   Kante sähe aus wie ein Rad, das sich löst. Keine opacity-Regel hier: die
   Deckkraft hängt am Zugweg, sonst bliebe die Münze voll sichtbar, WÄHREND
   sie nach oben zurückfährt. */
.ptr-ind.ptr-spin{color:var(--accent)}
.ptr-ind.ptr-spin svg{animation:ptr-rot .6s linear infinite}
@keyframes ptr-rot{to{transform:rotate(360deg)}}
/* „Bewegung reduzieren“: kein Drehen, die Markenfarbe zeigt das Laden.
   (Vorher stand hier animation-duration:.6s – derselbe Wert wie oben, ohne
   Wirkung.) Das JS startet unter dieser Einstellung ebenfalls kein animate(). */
@media(prefers-reduced-motion:reduce){.ptr-ind.ptr-spin svg{animation:none}}

/* Kopf und Inhalt folgen der Geste gedämpft – dieselbe Variable wie die Münze.
   Die Bottom-Leiste liegt bewusst außerhalb und bleibt stehen. */
.ptr-shift{transform:translateY(var(--ptr,0px));
  transition:transform var(--ptr-t,0s) cubic-bezier(.22,1,.36,1)}
/* Der freigelegte Streifen trägt den SEITEN-Hintergrund, nicht die Kopffarbe:
   sonst wirkt es, als würde der Kopf in die Höhe gezogen. */
.ptr-feld{position:fixed;top:0;left:0;right:0;height:0;background:var(--bg);
  z-index:15;pointer-events:none}
.ptr-feld[data-an]{height:calc(env(safe-area-inset-top,0px) + var(--ptr,0px))}

/* Diagramme: waagerecht wischen soll den Wert abgreifen, nicht die Seite
   scrollen. pan-y lässt senkrechtes Scrollen unberührt.
   Dazu iOS die Langdruck-Reflexe abgewöhnen: Ohne callout/user-select
   erschienen beim Halten Lupe bzw. Auswahl – genau auf der Geste, die dem
   Werte-Abgreifen gehört (11.08.2026). */
.chart-wrap canvas{touch-action:pan-y;
  -webkit-touch-callout:none;-webkit-user-select:none;user-select:none}

::-webkit-scrollbar{width:5px;height:5px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border2);border-radius:3px}

/* ── Tippflaechen (Handy) ───────────────────────────────────────────────────
   44x44 px ist das Mass fuer den Finger. Wo das Element selbst wachsen darf,
   waechst es; wo das die Anordnung verschoebe (Kopfzeile, Sprungleiste),
   erweitert eine unsichtbare ::after/::before-Flaeche NUR SENKRECHT – waagerecht
   wuerden sich benachbarte Knoepfe sonst gegenseitig ueberlappen. */
@media(max-width:719px){
  .btn{min-height:44px}
  /* 16 px Schrift: Bei weniger vergroessert iOS die Seite, sobald ein Feld den
     Fokus bekommt, und sie bleibt vergroessert. NICHT ueber maximum-scale=1
     loesen – das sperrt unter Android auch das gewollte Zoomen. */
  input:not([type=file]):not([type=checkbox]):not([type=radio]),select{min-height:44px;font-size:16px}
  .file-label input[type=file]{min-height:44px}

  /* Kopfzeile: Marke und Themenschalter duerfen nicht groesser werden */
  .mtop-brand{position:relative}
  .mtop-brand::after{content:'';position:absolute;left:0;right:0;top:50%;
    transform:translateY(-50%);height:44px}
  .theme-btn{position:relative}
  .theme-btn::after{content:'';position:absolute;inset:-12px -10px}

  /* Sprungleiste: ::after ist dort schon der Abstandhalter, also ::before */
  .jumpnav a{position:relative}
  .jumpnav a::before{content:'';position:absolute;left:0;right:0;top:50%;
    transform:translateY(-50%);height:44px}

  /* Segmentierte Schalter und Chips: die Reihe soll ihre Hoehe behalten,
     deshalb nur die Trefferflaeche wachsen lassen – und NUR senkrecht,
     sonst greifen die Nachbarn ineinander. */
  .ftabs .btn,.chip{position:relative;min-height:34px}
  .ftabs .btn::after,.chip::after{content:'';position:absolute;left:0;right:0;top:50%;
    transform:translateY(-50%);height:44px}
  .inline-check{min-height:44px}
  /* Klappkopf: volle Kartenbreite, daneben sitzt aber die Jahresauswahl –
     deshalb wieder nur senkrecht erweitern. */
  .klapp-kopf{position:relative}
  .klapp-kopf::after{content:'';position:absolute;left:0;right:0;top:50%;
    transform:translateY(-50%);height:44px}
  .inline-check input[type=checkbox]{width:18px;height:18px}
}

/* ── Nachbesserungen nach der Gegenprüfung (28.09.2026) ── */
.kpi-veraltet .kpi-value{opacity:.45}
/* Umbrochener Wert bleibt rechtsbündig über seiner Unterzeile (320 px) */
.kv .v{margin-left:auto}
/* iOS zoomt bei Feldschrift unter 16 px – auch quer (720–932 px), dort greift
   der Handy-Block nicht. Grobzeiger = Finger, also Touch-Geräte jeder Breite. */
@media(pointer:coarse){
  input:not([type=file]):not([type=checkbox]):not([type=radio]),select,textarea{font-size:16px}
}
@media(max-width:719px){
  /* Sprungleiste: die 44-px-Trefferflächen reichen über die 27 px hohen Pillen
     hinaus; ohne Reihenabstand überlappten sie zwischen umbrochenen Reihen. */
  .jumpnav{row-gap:17px}
  /* Zeitraum-Chips gleich breit; bricht die Reihe um, wird „Alles" nicht mehr
     über die ganze Karte gezogen. */
  .presets{display:grid;grid-template-columns:repeat(auto-fit,minmax(58px,1fr));gap:5px}
}
@media(max-width:719px){
  /* Kopierknöpfe der Gast-Links (seit A11Y-11 echte Knöpfe) lagen bei 42 px */
  #demoTbl .keycode{min-height:44px}
}
@media(max-width:380px){
  /* Kopf der Jahres-Heatmap: bei 320 px lief der Titel über „Jahr:“ */
  .jahr-wort{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
    clip:rect(0,0,0,0);white-space:nowrap;border:0}
}

/* ── Verlauf: Tag oder Woche (Übersicht, 05.10.2026) ──
   Oben Tag/Woche und Blättern, darunter die Kurve, vier Kennzahlen und
   „Mehr Zahlen“ zum Aufklappen. Am Handy rutscht das Blättern in eine eigene
   Zeile, das Datumsfeld füllt sie. */
#sec-tag .sec-label{flex-wrap:wrap;row-gap:2px}
.vl-tb{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-bottom:10px}
.tag-nav{display:flex;align-items:center;gap:8px;flex:1 1 240px}
.tag-pfeil{width:36px;padding:0;flex:0 0 auto}
/* Am Anfang oder bei heute: Pfeil steht, ist aber nicht bedienbar */
.tag-pfeil:disabled{opacity:.35;cursor:default}
.tag-datum{flex:0 1 190px;min-width:0;margin:0;flex-direction:row}
.tag-datum input{min-height:33px;padding:4px 9px;font-feature-settings:'tnum' 1}
#tagWahl{color-scheme:dark}
[data-theme="light"] #tagWahl{color-scheme:light}
@media(max-width:719px){
  /* Zeile 1: Tag/Woche und ggf. „Heute“, Zeile 2: Blättern über die volle Breite */
  .vl-tb .ftabs{flex:1 1 auto;width:auto}
  .tag-nav{flex:1 1 100%}
  .tag-pfeil{width:44px}
  .tag-datum{flex:1 1 auto}
  .tag-datum input{min-height:44px}
}
.vl-legende{display:flex;align-items:center;flex-wrap:wrap;gap:6px 8px;margin-top:6px;
  font-size:var(--fs-xs);color:var(--fg3)}
.vl-l-jetzt,.vl-l-vorher{display:inline-block;width:16px;height:0;border-top:2px solid var(--accent)}
.vl-l-vorher{border-top:2px dashed var(--fg3);margin-left:6px}
.vl-kz{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-top:12px}
@media(max-width:719px){.vl-kz{grid-template-columns:1fr 1fr}}
.vl-k{background:var(--s2);border-radius:var(--r);padding:10px 12px;min-width:0}
.vl-k-l{font-size:var(--fs-xs);font-weight:500;color:var(--fg2);margin-bottom:3px}
.vl-k-v{font-size:20px;font-weight:600;line-height:1.2;letter-spacing:-.02em;font-feature-settings:'tnum' 1;white-space:nowrap}
.vl-k-v.weniger{color:var(--ok)}
.vl-k-v.mehr{color:var(--warn)}
.vl-k-u{font-size:var(--fs-sm);font-weight:400;color:var(--fg3);margin-left:4px;letter-spacing:0}
.vl-k-s{font-size:var(--fs-xs);color:var(--fg3);margin-top:3px;line-height:1.4}
.vl-mehr{display:flex;align-items:center;gap:8px;min-height:44px;margin-top:6px;padding:0;
  background:none;border:0;font:inherit;font-size:var(--fs-sm);font-weight:500;color:var(--fg2);cursor:pointer}
.vl-mehr.auf .klapp-pfeil{transform:rotate(90deg);color:var(--accent)}
@media(hover:hover){.vl-mehr:hover,.vl-mehr:hover .klapp-pfeil{color:var(--accent)}}
.vl-mehr:active{opacity:.7}
.vl-mehr-korpus{border-top:1px solid var(--border);padding-top:12px;animation:klappAuf .18s ease}
@media(prefers-reduced-motion:reduce){.vl-mehr-korpus{animation:none}}
.vl-block+.vl-block{margin-top:16px}
.vl-block-t{font-size:var(--fs-sm);font-weight:500;color:var(--fg2);margin-bottom:8px}
/* Tageszeiten: vier Abschnitte, getrennt durch eine Fuge in Kartenfarbe */
.vl-teile{display:flex;gap:2px;height:10px;border-radius:5px;overflow:hidden;background:var(--s1)}
.vl-teile i,.vl-sw{background:var(--accent)}
.vl-t0{opacity:.3}.vl-t1{opacity:.55}.vl-t2{opacity:.78}.vl-t3{opacity:1}
.vl-teile-leg{list-style:none;display:grid;grid-template-columns:repeat(4,1fr);gap:6px 12px;margin-top:8px;
  font-size:var(--fs-sm);color:var(--fg2)}
.vl-teile-leg li{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.vl-teile-leg b{font-weight:600;color:var(--fg);font-feature-settings:'tnum' 1}
.vl-sw{display:inline-block;width:10px;height:10px;border-radius:2px;flex:0 0 10px}
@media(max-width:719px){
  .vl-teile-leg{grid-template-columns:1fr}
  .vl-teile-leg b{margin-left:auto}
}
/* Tage der Woche: ganze Zeile ist der Knopf zum Tagesverlauf */
.vl-tage{display:flex;flex-direction:column}
.vl-tag{display:grid;grid-template-columns:86px 1fr auto;align-items:center;gap:10px;min-height:40px;
  padding:4px 0;background:none;border:0;border-bottom:1px solid var(--border);
  font:inherit;font-size:var(--fs-sm);color:var(--fg);text-align:left;cursor:pointer}
.vl-tag:last-child{border-bottom:0}
@media(max-width:719px){.vl-tag{min-height:44px}}
@media(hover:hover){.vl-tag:hover .vl-tag-n{color:var(--accent)}}
.vl-tag:active{opacity:.7}
.vl-tag-n{white-space:nowrap}
.vl-tag-b{height:6px;border-radius:3px;background:var(--s2);overflow:hidden}
.vl-tag-b i{display:block;height:100%;border-radius:3px;background:var(--accent);opacity:.75}
.vl-tag-w{font-feature-settings:'tnum' 1;white-space:nowrap;text-align:right;color:var(--fg2)}
.vl-tag.hoch .vl-tag-w{font-weight:600;color:var(--fg)}
/* Verweis unter dem Verbrauchsdiagramm auf den Verlauf des gewählten Balkens */
.tag-verweis{font-size:var(--fs-sm);color:var(--fg3);margin-top:8px;min-height:20px}
.tag-verweis a{position:relative;color:var(--accent);font-weight:500}
.tag-verweis a::after{content:'';position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:44px}
@media(hover:hover){.tag-verweis a:hover{text-decoration:underline;text-underline-offset:2px}}
.nw{white-space:nowrap}
/* Formular, das nur einen Knopf trägt (Abmelden per POST): ordnet sich in
   die Knopfreihe ein, als stünde der Knopf allein dort. */
.form-zeile{display:contents}
