/* Ohne Framework. Die Oberfläche hat vier Seiten; was hier fehlt, muss
   nicht gepflegt werden.

   JavaScript kommt aus /static, nicht aus dem Dokument - die CSP steht
   auf script-src 'self' ohne unsafe-inline. Jedes Skript ergänzt nur;
   ohne JavaScript bleibt jede Seite bedienbar.

   Aufbau: Farbwerte als Variablen (hell und dunkel), dann Grundlagen,
   dann die Bausteine in der Reihenfolge, in der sie auf der Seite
   erscheinen. */

[hidden] { display: none !important; }

:root {
  --grund: #f3f4f6;
  --flaeche: #ffffff;
  --flaeche-2: #f8f9fb;
  --rand: #e3e6eb;
  --rand-stark: #c9ced6;
  --text: #17191d;
  --text-2: #4b5563;
  --leise: #7a8290;
  --akzent: #2563eb;
  --akzent-hell: #dbe7ff;
  --akzent-text: #1d4ed8;
  --gut: #15803d;
  --gut-hell: #dcfce7;
  --warn: #b45309;
  --schlecht: #b91c1c;
  --schlecht-hell: #fee2e2;
  --schatten: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .08);
  --radius: 10px;

  /* Farbplätze für mehrere Linien in einem Diagramm.
     Acht geprüfte Plätze in fester Reihenfolge - die Reihenfolge ist
     die Sicherung, nicht die Zierde: Sie ist so gewählt, dass auch
     benachbarte Plätze bei Farbfehlsichtigkeit auseinanderzuhalten
     sind. Gegen diese Fläche (#ffffff) nachgerechnet: schlechtestes
     Nachbarpaar 9,1 Delta E bei Protanopie, 19,6 bei normalem Sehen.
     Wer eine Farbe austauscht, rechnet neu nach.
     Drei davon (k3, k4, k5) liegen unter 3:1 Kontrast zur hellen
     Fläche. Deshalb steht in der Legende zu jeder Linie ihr Wert -
     die Farbe allein trägt die Zuordnung nicht. */
  --k1: #2a78d6;
  --k2: #eb6834;
  --k3: #1baf7a;
  --k4: #eda100;
  --k5: #e87ba4;
  --k6: #008300;
  --k7: #4a3aa7;
  --k8: #e34948;
  --radius-klein: 6px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --grund: #0f1115;
    --flaeche: #171a20;
    --flaeche-2: #1d2128;
    --rand: #2a2f38;
    --rand-stark: #3b414d;
    --text: #e8eaee;
    --text-2: #b4bac4;
    --leise: #7f8794;
    --akzent: #5b9bff;
    --akzent-hell: #16264a;
    --akzent-text: #8ab4ff;
    --gut: #4ade80;
    --gut-hell: #10281a;
    --warn: #f59e0b;
    --schlecht: #f87171;
    --schlecht-hell: #3a1515;
    --schatten: 0 1px 2px rgba(0, 0, 0, .4);

    /* Dieselben acht Farbtöne, für die dunkle Fläche neu gestuft -
       keine andere Palette und keine automatische Umkehrung. Gegen
       #171a20 nachgerechnet: alle acht über 3:1, schlechtestes
       Nachbarpaar 8,4 Delta E bei Protanopie. */
    --k1: #3987e5;
    --k2: #d95926;
    --k3: #199e70;
    --k4: #c98500;
    --k5: #d55181;
    --k6: #008300;
    --k7: #9085e9;
    --k8: #e66767;
  }

  /* Der Pfeil im Auswahlfeld ist ein Hintergrundbild und kann keine
     CSS-Variable benutzen - deshalb hier noch einmal, heller. */
  select { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%237f8794' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
}

/* ---------- Grundlagen ---------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--grund);
  color: var(--text);
  font: 15px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

body.mittig {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: 1.5rem 1rem;
}

a { color: var(--akzent-text); }

h1 { font-size: 1.5rem; line-height: 1.25; margin: 0; letter-spacing: -.01em; }
h2 { font-size: 1.05rem; margin: 0 0 .6rem; }
h3 { font-size: .9rem; margin: 0; font-weight: 600; }

code, pre {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: .88em;
}
code {
  background: var(--flaeche-2);
  border: 1px solid var(--rand);
  padding: .05em .4em;
  border-radius: 4px;
  white-space: nowrap;
}
pre {
  background: var(--flaeche-2);
  border: 1px solid var(--rand);
  border-radius: var(--radius-klein);
  padding: .75rem .9rem;
  overflow-x: auto;
  line-height: 1.5;
}
pre code { background: none; border: 0; padding: 0; }

.hinweis { color: var(--text-2); font-size: .88rem; margin: .4rem 0; }
.leise-text { color: var(--leise); font-weight: 400; }
.kleinabstand { margin-top: 1.2rem; }
.mittig-text { text-align: center; }

.visuell-versteckt {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* ---------- Kopfleiste ---------- */

.kopfleiste {
  background: var(--flaeche);
  border-bottom: 1px solid var(--rand);
  position: sticky; top: 0; z-index: 10;
}
.kopfleiste-innen {
  max-width: 76rem;
  margin: 0 auto;
  padding: 0 1.25rem;
  min-height: 3.4rem;
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.marke {
  display: inline-flex; align-items: center; gap: .5rem;
  font-weight: 700; letter-spacing: .02em;
  color: var(--text); text-decoration: none;
}
.marke-zeichen { width: 1.4rem; height: 1.4rem; color: var(--akzent); }
.marke.gross { justify-content: center; font-size: 1.3rem; margin-bottom: 1.2rem; }
.marke.gross .marke-zeichen { width: 1.9rem; height: 1.9rem; }

.hauptnav { display: flex; gap: .25rem; align-self: stretch; }
.hauptnav a {
  display: inline-flex; align-items: center;
  padding: 0 .75rem;
  color: var(--text-2); text-decoration: none; font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.hauptnav a:hover { color: var(--text); }
.hauptnav a.aktiv { color: var(--akzent-text); border-bottom-color: var(--akzent); }

.kopf-rechts { margin-left: auto; display: flex; align-items: center; gap: .9rem; }
.wer { font-size: .9rem; color: var(--text-2); display: inline-flex; align-items: center; gap: .4rem; }

@media (max-width: 40rem) {
  .kopfleiste-innen { flex-wrap: wrap; gap: .3rem .9rem; padding-block: .5rem; }
  .hauptnav { order: 3; flex: 1 0 100%; }
  .hauptnav a { padding: .35rem .6rem .45rem; }
  .wer { display: none; }
}

/* ---------- Seite ---------- */

main {
  max-width: 76rem;
  margin: 0 auto;
  padding: 1.6rem 1.25rem 4rem;
}

.seitenkopf {
  display: flex; flex-wrap: wrap; gap: .8rem 1.5rem;
  align-items: flex-end; justify-content: space-between;
  margin-bottom: 1.1rem;
}
.untertitel { margin: .25rem 0 0; color: var(--text-2); font-size: .92rem; }

.karte {
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: 1.15rem 1.3rem;
  margin-bottom: 1.2rem;
}

.zweispaltig {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: 1.2rem;
}
.zweispaltig .karte { margin: 0; }

/* Leerer Zustand */
.leer {
  text-align: center;
  padding: 3rem 1.5rem;
  background: var(--flaeche);
  border: 1px dashed var(--rand-stark);
  border-radius: var(--radius);
  color: var(--text-2);
}
.leer svg { width: 2.6rem; height: 2.6rem; color: var(--leise); }
.leer h2 { margin-top: .6rem; color: var(--text); }
.leer pre { text-align: left; display: inline-block; margin-top: .5rem; }

/* ---------- Formulare ---------- */

label { display: block; margin-bottom: .95rem; font-size: .88rem; color: var(--text-2); font-weight: 500; }
label small { font-weight: 400; }

input:not([type=checkbox]):not([type=radio]), select, textarea {
  display: block; width: 100%;
  margin-top: .3rem;
  padding: .55rem .7rem;
  font: inherit; color: var(--text);
  /* Gemeinsame Mindesthöhe, damit ein <select> genauso hoch ist wie ein
     <input> daneben. Über line-height geht es nicht: Bei einem <select>
     in Standard-Darstellung bleibt die wirkungslos, die Höhe ergibt
     sich aus Schrift, Innenabstand und Rahmen. Die Rechnung bildet
     genau das nach - 1,55 ist die Zeilenhöhe des Fließtexts, 1,1rem die
     Summe der senkrechten Innenabstände, 2px die Rahmen. */
  line-height: 1.55;
  min-height: calc(1.55em + 1.1rem + 2px);
  background: var(--flaeche);
  border: 1px solid var(--rand-stark);
  border-radius: var(--radius-klein);
  transition: border-color .12s, box-shadow .12s;
}
input:focus, select:focus, button:focus-visible, a:focus-visible, summary:focus-visible {
  outline: none;
  border-color: var(--akzent);
  box-shadow: 0 0 0 3px var(--akzent-hell);
}
/* Eigene Darstellung statt der des Browsers.
   Safari behandelt ein <select> in Standard-Darstellung als
   Systemelement: Es ignoriert die senkrechten Innenabstaende, und das
   Feld bleibt niedriger als ein <input> daneben - unabhaengig davon,
   was hier steht. Mit appearance: none ist es eine gewoehnliche Box und
   folgt denselben Regeln wie die uebrigen Felder.
   Der Pfeil kommt als Hintergrundbild, weil die Vorgabe damit entfaellt. */
select {
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  padding-right: 2rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23646d78' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right .65rem center;
  background-size: .7rem;
}
select::-ms-expand { display: none; }

small { display: block; margin-top: .3rem; color: var(--leise); font-size: .8rem; line-height: 1.45; }

dl.werte { display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1rem; margin: .6rem 0 .9rem; }
dl.werte dt { color: var(--leise); font-size: .88rem; }
dl.werte dd { margin: 0; }

.raster { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 0 1.4rem; }
.raster .knoepfe { grid-column: 1 / -1; }

.knoepfe { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; margin-top: .3rem; }
.knoepfe small { margin: 0; }

/* ---------- Knöpfe ---------- */

button, a.knopf {
  font: inherit; font-weight: 500;
  padding: .5rem .95rem;
  border: 1px solid var(--rand-stark);
  border-radius: var(--radius-klein);
  background: var(--flaeche);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex; align-items: center; gap: .4rem;
  line-height: 1.2;
  transition: background .12s, border-color .12s;
}
button:hover, a.knopf:hover { border-color: var(--akzent); background: var(--flaeche-2); }

button.haupt { background: var(--akzent); border-color: var(--akzent); color: #fff; }
button.haupt:hover { filter: brightness(1.08); }
button.breit { width: 100%; justify-content: center; }
button.klein, a.knopf.klein { padding: .3rem .65rem; font-size: .85rem; }
button.leise { border-color: transparent; background: none; color: var(--text-2); }
button.leise:hover { color: var(--text); background: var(--flaeche-2); }
button.gefahr { border-color: var(--schlecht); color: var(--schlecht); }
button.gefahr:hover { background: var(--schlecht-hell); }

form.inline { display: inline-flex; gap: .4rem; align-items: center; margin: 0; }
form.inline select, form.inline input { width: auto; margin: 0; }

/* Rollen- und Zustandsmarken */
.rolle {
  font-size: .72rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase;
  padding: .12em .5em; border-radius: 999px;
  background: var(--flaeche-2); border: 1px solid var(--rand); color: var(--text-2);
}
.rolle.admin { background: var(--akzent-hell); border-color: transparent; color: var(--akzent-text); }
.rolle.aus { background: var(--schlecht-hell); border-color: transparent; color: var(--schlecht); }

/* Meldungen */
.meldung {
  padding: .7rem 1rem; border-radius: var(--radius-klein);
  margin-bottom: 1.1rem; border: 1px solid; font-size: .93rem;
}
.meldung.fehler { background: var(--schlecht-hell); border-color: transparent; color: var(--schlecht); }
.meldung.gut { background: var(--gut-hell); border-color: transparent; color: var(--gut); }
.meldung.hinweisbox { background: var(--flaeche); border-color: var(--rand); color: var(--text-2); }
.meldung.hinweisbox a { margin-right: .3rem; }

/* Knopfleiste unter einem Passwortfeld, von passwort.js eingefügt */
.pw-leiste { display: flex; gap: .35rem; margin-top: .35rem; }

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

.anmeldung { width: min(22rem, 100%); }
.anmeldung .karte { margin-bottom: .9rem; }
.anmeldung h1 { font-size: 1.2rem; margin-bottom: 1rem; }

/* ---------- Daten: Leiste ---------- */

.leiste {
  display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-start;
  margin-bottom: 1.4rem;

  /* Eine Höhe für alles in der Leiste. Zeitraum, Ausklapp und Export
     sind verschiedene Elemente - Anker, summary, Knopf - und kämen
     sonst auf drei verschiedene Höhen. */
  --leistenhoehe: 2.3rem;
}
.segmente a, .ausklapp > summary, .export a.knopf {
  min-height: var(--leistenhoehe);
  display: inline-flex;
  align-items: center;
}

.segmente {
  display: inline-flex;
  max-width: 100%;
  background: var(--flaeche);
  border: 1px solid var(--rand-stark);
  border-radius: var(--radius-klein);
  overflow-x: auto;
  scrollbar-width: none;
}
.segmente::-webkit-scrollbar { display: none; }
.segmente a {
  padding: .45rem .85rem;
  white-space: nowrap;
  color: var(--text-2); text-decoration: none; font-size: .9rem; font-weight: 500;
  border-right: 1px solid var(--rand);
}
.segmente a:last-child { border-right: 0; }
.segmente a:hover { background: var(--flaeche-2); color: var(--text); }
.segmente a.aktiv { background: var(--akzent); color: #fff; }

/* Seitenwechsler der Auswertung. Bricht auf schmalen Bildschirmen um,
   statt seitlich zu scrollen. */
.seitenwahl { display: flex; flex-wrap: wrap; gap: .5rem; margin: 1rem 0; }
.seitenwahl a {
  padding: .45rem .8rem;
  background: var(--flaeche); border: 1px solid var(--rand); border-radius: var(--radius-klein);
  color: var(--text-2); text-decoration: none; font-size: .9rem; font-weight: 500;
}
.seitenwahl a:hover { border-color: var(--rand-stark); color: var(--text); }
.seitenwahl a[aria-current] { border-color: var(--akzent); color: var(--akzent-text); }

.ausklapp {
  background: var(--flaeche);
  border: 1px solid var(--rand-stark);
  border-radius: var(--radius-klein);
}
.ausklapp > summary {
  list-style: none;
  cursor: pointer;
  padding: .45rem .85rem;
  font-size: .9rem; font-weight: 500; color: var(--text-2);
  display: inline-flex; align-items: center; gap: .45rem;
  user-select: none;
}
.ausklapp > summary::-webkit-details-marker { display: none; }
.ausklapp > summary::before {
  content: ""; width: .45rem; height: .45rem;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(-45deg) translateY(-1px); transition: transform .15s;
}
.ausklapp[open] > summary::before { transform: rotate(45deg) translateY(-2px); }
.ausklapp[open] > summary { color: var(--text); border-bottom: 1px solid var(--rand); }
.ausklapp[open] { flex: 1 0 100%; }
.ausklapp-inhalt { padding: .9rem 1rem 1rem; }

.zaehler {
  font-size: .75rem; font-weight: 600;
  padding: .1em .55em; border-radius: 999px;
  background: var(--akzent); color: #fff;
}
.punkt { width: .5rem; height: .5rem; border-radius: 50%; background: var(--akzent); display: inline-block; }

.zeitform { display: flex; flex-wrap: wrap; gap: .8rem 1rem; align-items: flex-end; }
.zeitform label { margin: 0; min-width: 12rem; }
.zeitform small { flex: 1 0 100%; margin: 0; }

.filterform fieldset { border: 0; padding: 0; margin: 0 0 1rem; }
.filterform legend { font-size: .88rem; font-weight: 600; color: var(--text-2); margin-bottom: .45rem; padding: 0; }
.filterform legend small { display: inline; margin-left: .4rem; font-weight: 400; }

.kaestchen { display: flex; flex-wrap: wrap; gap: .4rem; }
.kaestchen.dicht { max-height: 14rem; overflow-y: auto; padding: .1rem; }
.kasten {
  display: inline-flex; align-items: center; gap: .4rem;
  margin: 0; padding: .3rem .65rem .3rem .5rem;
  font-size: .85rem; font-weight: 500; color: var(--text);
  background: var(--flaeche-2); border: 1px solid var(--rand);
  border-radius: 999px; cursor: pointer;
  transition: border-color .12s, background .12s;
}
.kasten:hover { border-color: var(--akzent); }
.kasten input { margin: 0; accent-color: var(--akzent); width: .95rem; height: .95rem; }
.kasten:has(input:checked) { background: var(--akzent-hell); border-color: var(--akzent); color: var(--akzent-text); }

/* Auswahlfeld und Knopf auf gleiche Höhe. Die doppelte Klasse ist
   nötig, weil "form.inline" sonst mit seinem align-items: center
   gewinnt - gleiche Spezifität, aber dort steht es später. */
.zugangwahl.inline { align-items: stretch; }
.zugangwahl select { min-width: 9rem; padding-block: .4rem; min-height: 0; }
.zugangwahl button { padding-block: 0; }

/* Suche in der Leiste.
   Aufgebaut wie die Segmente daneben: Der Rahmen sitzt am Behälter, das
   Eingabefeld darin ist randlos und durchsichtig. Das ist kein Umweg,
   sondern der einzige Weg zu gleicher Höhe - ein <input> rechnet seinen
   eigenen Rahmen in die Mindesthöhe ein (box-sizing: border-box), die
   Segmente ihren nicht, weil er am Container hängt. Mit gleichem
   min-height bliebe das Feld 2 px flacher.

   Die dreifache Klasse ist nötig, nicht Zierde: Die allgemeine Regel
   für Eingabefelder steht mit
   input:not([type=checkbox]):not([type=radio]) bei (0,2,1) und schlüge
   zwei Klassen. Ihr margin-top, ihr Innenabstand und ihre Mindesthöhe
   setzten das Feld sonst tiefer und höher als alles daneben.

   Das Kreuz ist ein Link auf die Adresse ohne Suche - es holt zurück,
   was der Server wegen der Suche weggelassen hat. Sein Platz bleibt
   auch ohne Suche frei, sonst spränge die Textbreite beim Tippen. */
.leiste .suchform {
  position: relative;
  display: inline-flex; align-items: center;
  min-height: var(--leistenhoehe);
  background: var(--flaeche);
  border: 1px solid var(--rand-stark);
  border-radius: var(--radius-klein);
  transition: border-color .12s, box-shadow .12s;
}
.leiste .suchform:focus-within { border-color: var(--akzent); box-shadow: 0 0 0 3px var(--akzent-hell); }
.leiste .suchform .suche {
  display: block; width: 15rem; max-width: 100%;
  height: var(--leistenhoehe); min-height: 0;
  margin: 0; padding: 0 2rem 0 .85rem;
  font: inherit; font-size: .9rem; line-height: 1.55;
  color: var(--text); background: none;
  border: 0; border-radius: inherit;
}
/* Der Ring gehört an den Behälter, nicht an das Feld darin. */
.leiste .suchform .suche:focus { outline: none; border-color: transparent; box-shadow: none; }
.leiste .suchform .suche::placeholder { color: var(--leise); }
.leiste .suchform .suche::-webkit-search-cancel-button { display: none; }
.suche-weg {
  position: absolute; right: .3rem; top: 50%; transform: translateY(-50%);
  width: 1.4rem; height: 1.4rem; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px; color: var(--text-2); text-decoration: none; font-size: 1.05rem; line-height: 1;
}
.suche-weg:hover { background: var(--akzent-hell); color: var(--akzent-text); }
@media (max-width: 40rem) {
  .leiste .suchform { flex: 1 0 100%; }
  .leiste .suchform .suche { width: 100%; }
}

/* Export ganz rechts in der Leiste, in derselben Grösse wie Zeitraum und
   Filter; die Knöpfe tragen dieselben Parameter wie die Anzeige. */
.export { margin-left: auto; display: inline-flex; gap: .4rem; }
.export a.knopf {
  padding: .45rem .85rem; font-size: .9rem; font-weight: 500;
  color: var(--text-2); border-color: var(--rand-stark);
}
.export a.knopf:hover { color: var(--text); }
.export a.knopf svg { width: 1rem; height: 1rem; }
@media (max-width: 40rem) { .export { margin-left: 0; } }

/* ---------- Daten: Geräte und Kacheln ---------- */

/* ---------- Eigener Bereich und Auf-/Zuklappen ---------- */

/* Der eigene Bereich steht auch leer da: Ohne ihn gäbe es kein Ziel,
   auf das man die erste Kachel ziehen könnte. */
.eigener-bereich { margin-bottom: 1.8rem; }
.eigener-bereich > .kacheln { min-height: 3rem; border-radius: var(--radius); }
.eigener-bereich[data-leer] > .kacheln {
  border: 1px dashed var(--rand-stark);
}
.bereich-hinweis { margin: .5rem 0 0; font-size: .82rem; color: var(--leise); }
.eigener-bereich:not([data-leer]) .bereich-hinweis { display: none; }

/* Das Ablagefeld hebt sich erst hervor, wenn wirklich etwas darüber
   schwebt, das es annimmt - eine Fläche, die beim Ziehen immer
   aufleuchtet, sagt nichts. */
.kacheln.ziel {
  outline: 2px dashed var(--akzent);
  outline-offset: 3px;
  background: var(--akzent-hell);
}
.kachel.wird-gezogen, .kombi-karte.wird-gezogen { opacity: .4; }

/* Verschoben wird an der Überschrift, vergrössert am Griff in der Ecke.
   Zwei Gesten auf derselben Fläche gehen nicht auf: Solange die ganze
   Kachel ziehbar war, übernahm Drag & Drop jeden Zug, der nicht genau
   den Griff traf. Die Hand am Zeiger sagt, wo die eine aufhört und die
   andere anfängt. */
.zieh-kopf { cursor: grab; }
.zieh-kopf:active, body.zieht-kachel .zieh-kopf { cursor: grabbing; }

/* Beim Überfahren der Kachel hebt sich der Anfasser leicht ab - sonst
   müsste man ihn raten. */
.kachel:hover > .zieh-kopf, .kombi-karte:hover > .zieh-kopf {
  text-decoration-color: var(--rand-stark);
}
.zieh-kopf:hover {
  border-radius: var(--radius-klein);
  box-shadow: 0 0 0 .25rem var(--flaeche-2);
  background: var(--flaeche-2);
}

/* Das Exportformular. Aufgebaut wie das Zeitraum-Formular darüber:
   Felder und Knöpfe sind direkte Flex-Kinder und sitzen damit auf
   derselben Grundlinie. In einem Behälter mit eigenem Abstand sassen
   die Knöpfe tiefer als die Felder daneben. */
.exportform { display: flex; flex-wrap: wrap; align-items: flex-end; gap: .8rem 1rem; }
.exportform > label {
  display: flex; flex-direction: column; gap: .25rem;
  margin: 0; font-size: .85rem; color: var(--text-2);
}
.exportform > select, .exportform > label select { min-width: 14rem; }
.exportform > small { flex: 1 0 100%; margin: 0; }

/* Die Auswahl nimmt eine eigene Zeile: Bei achtzig Messgrößen bliebe
   neben den Feldern nichts übrig. */
.export-wahl { flex: 1 0 100%; border: 0; padding: 0; margin: .2rem 0 0; }
.export-wahl legend {
  font-size: .88rem; font-weight: 600; color: var(--text-2);
  margin-bottom: .45rem; padding: 0;
}
.export-wahl legend small { display: inline; margin-left: .4rem; font-weight: 400; }
.export-wahl .kaestchen { max-height: 11rem; overflow-y: auto; }
.summary-symbol { width: .9rem; height: .9rem; vertical-align: -.1rem; margin-right: .2rem; }

/* ---------- Das freie Raster des eigenen Bereichs ----------

   Zwölf feste Spalten und eine feste Zeilenhöhe, statt des fliessenden
   auto-fill-Rasters der Gerätegruppen. Der Unterschied ist der ganze
   Zweck: Ein fliessendes Raster füllt Lücken von selbst auf und streckt
   jede Zeile auf die Höhe ihres grössten Elements. Beides nimmt einem
   die Anordnung aus der Hand - ein Stück wandert, weil daneben eines
   wuchs, und eine Kachel wird hoch, weil ein Diagramm neben ihr hoch
   ist.

   Die Anordnung tragen Klassen und kein style-Attribut: Die
   Content-Security-Policy lässt kein eingebettetes CSS zu. Sie stehen
   schon im gelieferten Dokument, damit das erste Bild stimmt. */
.kacheln.frei {
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: 2rem;
  align-items: stretch;
}
.frei > .kachel, .frei > .kombi-karte {
  min-height: 0; min-width: 0; overflow: hidden;
}

/* Im festen Raster gibt die Zelle die Höhe vor, und der Inhalt muss
   sich darin einrichten. Ohne Ansage verteilt Flexbox das Schrumpfen
   gleichmässig - und Überschrift und Gerätename tragen overflow:hidden,
   ihre automatische Mindesthöhe ist damit null. Sie verschwanden
   lautlos, ohne dass etwas fehlte: Sie standen im Dokument, nur eben
   null Bildpunkte hoch. Nachgeben soll die Kurve, nicht die
   Beschriftung. */
.frei > .kachel > h3,
.frei > .kachel > .kachel-geraet,
.frei > .kachel > .wert,
.frei > .kachel > .kurve-achse,
.frei > .kachel > .kachel-fuss,
.frei > .kachel > .kachel-zeit { flex: none; }
.frei > .kachel > .kurve-rahmen { flex: 1 1 auto; min-height: 1.5rem; }

/* Wird die Zelle zu knapp für alles, fällt das Beiwerk weg statt
   angeschnitten zu werden.
   Eine halb abgeschnittene Zeile sieht aus wie ein Fehler; eine Kachel
   ohne Zeitstempel sieht aus wie eine Entscheidung. Die Reihenfolge
   geht von aussen nach innen: zuerst der Zeitpunkt, dann die Spanne,
   dann die Zeitachse, zuletzt der Gerätename. Überschrift, Wert und
   Kurve bleiben immer - ohne sie wäre es keine Kachel mehr.
   Gemessen wird an der Kachel selbst, nicht am Fenster: Wie hoch sie
   ist, entscheidet ihre Zelle. */
.frei > .kachel { container-type: size; container-name: kachel; }
@container kachel (max-height: 12.5rem) { .kachel-zeit { display: none; } }
@container kachel (max-height: 10.5rem) { .kachel-fuss { display: none; } }
@container kachel (max-height: 8.5rem)  { .kurve-achse { display: none; } }
@container kachel (max-height: 6.5rem)  { .kachel-geraet { display: none; } }

/* Dasselbe am Diagramm: Kopf und Legende bleiben, die Zeichenfläche
   gibt nach. */
.frei > .kombi-karte > .kombi-kopf,
.frei > .kombi-karte > .kombi-legende { flex: none; }
.frei > .kombi-karte { display: flex; flex-direction: column; }

/* Die Zeichenfläche nimmt, was Kopf und Legende übrig lassen; kombi.js
   rechnet die viewBox darauf um. Gestreckt zöge das Bild seine
   Beschriftung mit in die Länge, deshalb wird es neu eingeteilt und
   nicht skaliert. */
.kombi-flaeche { flex: 1 1 auto; min-height: 0; display: flex; }
.frei > .kombi-karte .kombi { flex: none; align-self: flex-start; }

/* Auf schmalen Anzeigen trägt das Raster keine zwölf Spalten. Dann
   steht alles untereinander, in der Reihenfolge des Dokuments - eine
   Anordnung, die auf ein Zwölftel Bildschirmbreite zielt, wäre dort
   nicht zu gebrauchen. */
@media (max-width: 52rem) {
  .kacheln.frei { grid-template-columns: 1fr; grid-auto-rows: auto; }
  .frei > .kachel, .frei > .kombi-karte {
    grid-column: 1 / -1 !important; grid-row: auto !important;
  }
  /* container-type: size lässt den Inhalt bei der Höhe aussen vor -
     im festen Raster egal, weil die Zelle sie vorgibt. Hier aber ist
     die Zeile auto hoch, und die Kachel schrumpfte auf ihr Padding:
     vom Titel blieb eine halbe Zeile. Ohne Zelle keine Enge, also
     auch keine Abfrage darauf. */
  .frei > .kachel { container-type: normal; min-height: 9.4rem; }
}

/* Spalte, Zeile, Breite und Höhe - eine Regel je Wert. */
.frei > .x-0 { grid-column-start: 1; } .frei > .x-1 { grid-column-start: 2; } .frei > .x-2 { grid-column-start: 3; } .frei > .x-3 { grid-column-start: 4; } .frei > .x-4 { grid-column-start: 5; } .frei > .x-5 { grid-column-start: 6; } .frei > .x-6 { grid-column-start: 7; } .frei > .x-7 { grid-column-start: 8; } .frei > .x-8 { grid-column-start: 9; } .frei > .x-9 { grid-column-start: 10; } .frei > .x-10 { grid-column-start: 11; } .frei > .x-11 { grid-column-start: 12; }
.frei > .b-1 { grid-column-end: span 1; } .frei > .b-2 { grid-column-end: span 2; } .frei > .b-3 { grid-column-end: span 3; } .frei > .b-4 { grid-column-end: span 4; } .frei > .b-5 { grid-column-end: span 5; } .frei > .b-6 { grid-column-end: span 6; } .frei > .b-7 { grid-column-end: span 7; } .frei > .b-8 { grid-column-end: span 8; } .frei > .b-9 { grid-column-end: span 9; } .frei > .b-10 { grid-column-end: span 10; } .frei > .b-11 { grid-column-end: span 11; } .frei > .b-12 { grid-column-end: span 12; }
.frei > .y-0 { grid-row-start: 1; } .frei > .y-1 { grid-row-start: 2; } .frei > .y-2 { grid-row-start: 3; } .frei > .y-3 { grid-row-start: 4; } .frei > .y-4 { grid-row-start: 5; } .frei > .y-5 { grid-row-start: 6; } .frei > .y-6 { grid-row-start: 7; } .frei > .y-7 { grid-row-start: 8; } .frei > .y-8 { grid-row-start: 9; } .frei > .y-9 { grid-row-start: 10; }
.frei > .y-10 { grid-row-start: 11; } .frei > .y-11 { grid-row-start: 12; } .frei > .y-12 { grid-row-start: 13; } .frei > .y-13 { grid-row-start: 14; } .frei > .y-14 { grid-row-start: 15; } .frei > .y-15 { grid-row-start: 16; } .frei > .y-16 { grid-row-start: 17; } .frei > .y-17 { grid-row-start: 18; } .frei > .y-18 { grid-row-start: 19; } .frei > .y-19 { grid-row-start: 20; }
.frei > .y-20 { grid-row-start: 21; } .frei > .y-21 { grid-row-start: 22; } .frei > .y-22 { grid-row-start: 23; } .frei > .y-23 { grid-row-start: 24; } .frei > .y-24 { grid-row-start: 25; } .frei > .y-25 { grid-row-start: 26; } .frei > .y-26 { grid-row-start: 27; } .frei > .y-27 { grid-row-start: 28; } .frei > .y-28 { grid-row-start: 29; } .frei > .y-29 { grid-row-start: 30; }
.frei > .y-30 { grid-row-start: 31; } .frei > .y-31 { grid-row-start: 32; } .frei > .y-32 { grid-row-start: 33; } .frei > .y-33 { grid-row-start: 34; } .frei > .y-34 { grid-row-start: 35; } .frei > .y-35 { grid-row-start: 36; } .frei > .y-36 { grid-row-start: 37; } .frei > .y-37 { grid-row-start: 38; } .frei > .y-38 { grid-row-start: 39; } .frei > .y-39 { grid-row-start: 40; }
.frei > .y-40 { grid-row-start: 41; } .frei > .y-41 { grid-row-start: 42; } .frei > .y-42 { grid-row-start: 43; } .frei > .y-43 { grid-row-start: 44; } .frei > .y-44 { grid-row-start: 45; } .frei > .y-45 { grid-row-start: 46; } .frei > .y-46 { grid-row-start: 47; } .frei > .y-47 { grid-row-start: 48; } .frei > .y-48 { grid-row-start: 49; } .frei > .y-49 { grid-row-start: 50; }
.frei > .y-50 { grid-row-start: 51; } .frei > .y-51 { grid-row-start: 52; } .frei > .y-52 { grid-row-start: 53; } .frei > .y-53 { grid-row-start: 54; } .frei > .y-54 { grid-row-start: 55; } .frei > .y-55 { grid-row-start: 56; } .frei > .y-56 { grid-row-start: 57; } .frei > .y-57 { grid-row-start: 58; } .frei > .y-58 { grid-row-start: 59; } .frei > .y-59 { grid-row-start: 60; }
.frei > .h-1 { grid-row-end: span 1; } .frei > .h-2 { grid-row-end: span 2; } .frei > .h-3 { grid-row-end: span 3; } .frei > .h-4 { grid-row-end: span 4; } .frei > .h-5 { grid-row-end: span 5; } .frei > .h-6 { grid-row-end: span 6; } .frei > .h-7 { grid-row-end: span 7; } .frei > .h-8 { grid-row-end: span 8; } .frei > .h-9 { grid-row-end: span 9; } .frei > .h-10 { grid-row-end: span 10; }
.frei > .h-11 { grid-row-end: span 11; } .frei > .h-12 { grid-row-end: span 12; } .frei > .h-13 { grid-row-end: span 13; } .frei > .h-14 { grid-row-end: span 14; } .frei > .h-15 { grid-row-end: span 15; } .frei > .h-16 { grid-row-end: span 16; } .frei > .h-17 { grid-row-end: span 17; } .frei > .h-18 { grid-row-end: span 18; } .frei > .h-19 { grid-row-end: span 19; } .frei > .h-20 { grid-row-end: span 20; }
.frei > .h-21 { grid-row-end: span 21; } .frei > .h-22 { grid-row-end: span 22; } .frei > .h-23 { grid-row-end: span 23; } .frei > .h-24 { grid-row-end: span 24; } .frei > .h-25 { grid-row-end: span 25; } .frei > .h-26 { grid-row-end: span 26; } .frei > .h-27 { grid-row-end: span 27; } .frei > .h-28 { grid-row-end: span 28; } .frei > .h-29 { grid-row-end: span 29; } .frei > .h-30 { grid-row-end: span 30; }
.frei > .h-31 { grid-row-end: span 31; } .frei > .h-32 { grid-row-end: span 32; } .frei > .h-33 { grid-row-end: span 33; } .frei > .h-34 { grid-row-end: span 34; } .frei > .h-35 { grid-row-end: span 35; } .frei > .h-36 { grid-row-end: span 36; } .frei > .h-37 { grid-row-end: span 37; } .frei > .h-38 { grid-row-end: span 38; } .frei > .h-39 { grid-row-end: span 39; } .frei > .h-40 { grid-row-end: span 40; }

/* Der Gerätename ist der Schalter. Ein Knopf, kein Link: Er führt
   nirgendwohin, er klappt zu. */
.geraet-schalter {
  display: inline-flex; align-items: center; gap: .5rem;
  /* Rundum derselbe Innenabstand, und der negative Rand links holt den
     Text wieder auf die Fluchtlinie der Spalte. Vorher war links null
     und rechts .3rem - die Fokusmarkierung folgt dem Innenabstand und
     sass damit schief um den Knopf. */
  margin: 0 0 0 -.45rem; padding: .15rem .45rem;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 1.05rem; font-weight: 600; color: var(--text);
  border-radius: var(--radius-klein);
}
.geraet-schalter:hover { color: var(--akzent-text); }
.geraet-schalter svg { width: 1.15rem; height: 1.15rem; color: var(--leise); }
.geraet-schalter code { font-size: .95em; background: none; border: 0; padding: 0; }
.pfeil-zu {
  width: .45rem; height: .45rem;
  border-right: 1.8px solid currentColor; border-bottom: 1.8px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform .15s;
}
.geraet-schalter[aria-expanded="false"] .pfeil-zu { transform: rotate(-45deg); }
.geraet[data-zu] > .kacheln { display: none; }

.geraet { margin-bottom: 1.8rem; }
.geraet-kopf {
  display: flex; flex-wrap: wrap; gap: .3rem 1rem;
  align-items: baseline; justify-content: space-between;
  margin-bottom: .7rem;
}
.geraet-kopf h2 { display: inline-flex; align-items: center; gap: .5rem; margin: 0; font-size: 1.05rem; }
.geraet-kopf h2 svg { width: 1.15rem; height: 1.15rem; color: var(--leise); }
.geraet-kopf h2 code { font-size: .95em; background: none; border: 0; padding: 0; }
.geraet-meta { display: flex; flex-wrap: wrap; gap: .3rem .9rem; align-items: baseline; font-size: .85rem; color: var(--leise); }

/* Gerät löschen: unscheinbar im Kopf, ausgeklappt eine rote Zone unter
   dem Kopf über die volle Breite. */
.geraet-loeschen > summary { list-style: none; cursor: pointer; color: var(--leise); }
.geraet-loeschen > summary::-webkit-details-marker { display: none; }
.geraet-loeschen > summary:hover { color: var(--schlecht); }
.geraet-loeschen[open] > summary { color: var(--schlecht); }
.geraet-loeschen[open] { flex: 1 0 100%; }
.geraet-loeschen form {
  margin: .5rem 0 .2rem; padding: .8rem 1rem;
  border: 1px solid var(--schlecht); border-radius: var(--radius-klein);
  background: var(--schlecht-hell); color: var(--text);
  display: flex; flex-wrap: wrap; gap: .6rem 1.2rem; align-items: center;
}
.geraet-loeschen form p { margin: 0; flex: 1 1 24rem; font-size: .88rem; }

.kacheln {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  gap: .8rem;
}

.kachel {
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: .85rem .95rem .7rem;
  display: flex; flex-direction: column;
  min-height: 9.4rem;
}
.kachel h3 {
  color: var(--text-2); font-size: .82rem; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Das Gerät an der Kachel. In der Gerätegruppe steht es schon in der
   Überschrift darüber - dort wäre es Wiederholung; im eigenen Bereich
   ist es das Einzige, was die Kachel noch zuordnet. */
.kachel-geraet {
  margin: .1rem 0 0; font-size: .74rem; color: var(--leise);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.geraet .kachel-geraet { display: none; }

.wert { display: flex; align-items: baseline; gap: .3rem; margin: .25rem 0 .2rem; }
.zahl { font-size: 1.7rem; font-weight: 600; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.einheit { color: var(--leise); font-size: .95rem; }
/* Beide Richtungen gleich gefärbt: ob ein steigender Strom gut oder
   schlecht ist, weiss die Oberfläche nicht. */
.pfeil { margin-left: auto; font-size: 1rem; color: var(--text-2); }

/* Der Rahmen um die Kurve nimmt den freien Platz der Kachel (flex: 1).
   Das ist der Grund, warum alle Kacheln einer Zeile gleich aussehen:
   Rasterzellen strecken sich auf die Zeilenhöhe, und wer die höchste
   Kachel höher zieht, zieht die ganze Zeile mit - ohne flex: 1 behielten
   die übrigen Kurven ihre 3,2 rem und darunter stünde Leerraum.
   Der Griff setzt deshalb die MINDESThöhe, nicht die Höhe: Er bestimmt,
   wie hoch die Zeile wird; verteilt wird sie hier.
   overflow hidden, damit ein zu hohes SVG nicht heraushängt; das SVG
   füllt den Rahmen, weil preserveAspectRatio auf none steht. */
.kurve-rahmen {
  position: relative;
  flex: 1 1 auto;
  min-height: 3.2rem;
  margin: .2rem 0 .1rem;
  overflow: hidden;
}
.kachel .kurve {
  display: block; width: 100%; height: 100%;
  overflow: visible; cursor: crosshair; touch-action: none;
}

/* Größe ändern: ein Griff unten rechts, von kachel.js eingesetzt.
   Ziehen nach rechts nimmt weitere Rasterspalten, nach unten macht die
   Kurve höher; die Werte setzt das Skript über die CSSOM. Sichtbar nur
   beim Überfahren, bei Fokus und wenn die Kachel vergrößert ist -
   sonst wäre der Zustand nur beim Überfahren zu sehen. */
/* Jede Karte ist ihr eigener Bezugspunkt - auch ausserhalb des
   Rasters. Fehlt er, sucht sich der Griff den nächsten positionierten
   Vorfahren und landet irgendwo auf der Seite. Sichtbar wäre das nicht
   einmal, denn er steht auf opacity 0; anklickbar bleibt er trotzdem
   und schluckt dann die Klicks auf alles, was darunter liegt. */
.kachel, .kombi-karte { position: relative; }
.griff {
  position: absolute; right: .2rem; bottom: .2rem;
  width: 1.25rem; height: 1.25rem; margin: 0; padding: 0;
  border: 0; border-radius: 4px; background: none;
  color: var(--rand-stark); cursor: nwse-resize; touch-action: none;
  opacity: 0; transition: opacity .15s, color .15s;
}
.griff::before {
  content: ""; position: absolute; right: 4px; bottom: 4px;
  width: 9px; height: 9px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
}
.kachel:hover .griff, .griff:focus-visible, .kachel.gross .griff { opacity: 1; }
.kacheln > .kombi-karte:hover .griff, .kacheln > .kombi-karte.gross .griff { opacity: 1; }
.griff:hover, .kachel.zieht .griff, .kachel.gross .griff { color: var(--akzent-text); }
.kombi-karte.zieht .griff, .kacheln > .kombi-karte.gross .griff { color: var(--akzent-text); }
.griff:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }
.kachel.zieht, .kombi-karte.zieht { user-select: none; box-shadow: 0 0 0 2px var(--akzent-hell), var(--schatten); }
/* Der Weg zurück: ein Kreuz oben rechts am Stück im eigenen Bereich.
   Es liegt über dem Inhalt und erscheint erst beim Überfahren - eine
   Kachel, an der dauerhaft ein Kreuz klebt, liest sich unruhig. */
/* ---------- Die Symbolknöpfe an einer Karte ----------

   Kreuz, Zurücklegen und Vergleichs-Schalter sehen gleich aus: dieselbe
   Fläche, dasselbe Symbolmaß, mittig darin, derselbe Abstand zum Rand.
   Vorher hatte jeder seine eigenen Zahlen, und an jeder Kartenart sass
   er anders - das fiel als Unruhe auf, bevor man sagen konnte, woran es
   liegt. */
.stueck-weg, .karte-weg, .vergleich-schalter {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; flex: none;
  padding: 0; margin: 0; border: 0;
  border-radius: var(--radius-klein);
  background: none; color: var(--leise); cursor: pointer;
  /* Gedämpft sichtbar, nicht unsichtbar. Ein Knopf, den man erst beim
     Überfahren findet, ist für den, der ihn sucht, gar nicht da -
     genau das war er nach dem Vereinheitlichen. */
  opacity: .45; transition: opacity .15s, color .15s, background .15s;
}
.stueck-weg > svg, .karte-weg > svg, .vergleich-schalter > svg {
  width: 1rem; height: 1rem; display: block;
}

/* An der Kachel absolut gesetzt, beide auf derselben Höhe. Das Kreuz
   ganz aussen, der Vergleichs-Schalter genau eine Knopfbreite davor -
   vorher lagen sie übereinander, und wer den einen treffen wollte,
   erwischte den anderen. */
.kachel > .stueck-weg, .kachel > .vergleich-schalter {
  position: absolute; top: .4rem; right: .4rem;
}
.frei > .kachel > .vergleich-schalter { right: 2.3rem; }
.frei > .kachel > h3 { padding-right: 4.4rem; }
.kachel:not(.frei > .kachel) > h3 { padding-right: 2.4rem; }

/* Am Diagramm stehen sie im Kopf, in einer Gruppe rechts. */
.kopf-knoepfe { display: flex; align-items: center; gap: .3rem; margin-left: auto; }
.kombi-kopf { justify-content: flex-start; }
.kombi-kopf .stueck-weg, .kombi-kopf .karte-weg { position: static; }

.kachel:hover .stueck-weg, .kachel:hover .vergleich-schalter,
.kombi-karte:hover .stueck-weg, .kombi-karte:hover .karte-weg,
.stueck-weg:focus-visible, .karte-weg:focus-visible,
.vergleich-schalter:focus-visible { opacity: 1; }
.vergleich-schalter.an { opacity: 1; color: var(--akzent-text); background: var(--akzent-hell); }
.vergleich-schalter:hover { color: var(--akzent-text); background: var(--flaeche-2); }
.stueck-weg:hover, .karte-weg:hover { color: var(--schlecht); background: var(--schlecht-hell); }
.stueck-weg:focus-visible, .karte-weg:focus-visible, .vergleich-schalter:focus-visible {
  outline: 2px solid var(--akzent); outline-offset: 1px;
}

/* Ausserhalb des Rasters hat ein Diagramm keine eigene Größe. Der
   Griff wird deshalb nicht bloss versteckt, sondern ausgeblendet:
   opacity 0 liesse ihn weiter Klicks annehmen. Wandert die Karte ins
   Raster, greift die Regel nicht mehr, und er ist wieder da. */
.vergleich > .kombi-karte > .griff { display: none; }

/* Der Griff sitzt in der Ecke - die Legende darf nicht darunter
   laufen. */
.kacheln > .kombi-karte .kombi-legende { padding-right: 1.4rem; }
.kachel.gross .zahl { font-size: 2rem; }
.kachel h3 { padding-right: 2rem; }

/* Mauszeiger auf der Kurve: senkrechte Linie im SVG, Punkt und Schild
   als HTML darüber (das SVG ist verzerrt, ein Kreis darin wäre eine
   Ellipse). Beides von kurve.js gesetzt. */
.kurve-marke { stroke: var(--text-2); stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; pointer-events: none; }
.kurve-punkt {
  position: fixed; z-index: 30; pointer-events: none;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--akzent); border: 2px solid var(--flaeche);
  box-shadow: 0 0 0 1px var(--akzent);
  transform: translate(-50%, -50%);
}
.kurve-schild {
  position: fixed; z-index: 31; pointer-events: none;
  padding: .3rem .55rem; border-radius: var(--radius-klein);
  background: var(--text); color: var(--grund);
  font-size: .8rem; font-variant-numeric: tabular-nums; white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
}
.kurve-linie {
  fill: none; stroke: var(--akzent); stroke-width: 1.6;
  stroke-linejoin: round; stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.kurve-netz { stroke: var(--rand); stroke-width: 1; vector-effect: non-scaling-stroke; }

/* Die Wertachse der Kachel liegt als HTML ÜBER der Kurve, nicht im
   SVG: Das SVG ist mit preserveAspectRatio="none" verzerrt, Text darin
   würde mitgestreckt. Sie zeigt nur runde Werte innerhalb der Spanne;
   die Spanne selbst steht in der Fusszeile.

   Der Hintergrund ist die Kachelfläche, damit die Zahl auch dort
   lesbar bleibt, wo die Kurve darunter durchläuft. Klicks gehen
   hindurch - darunter liegt das Fadenkreuz. */
.kurve-werte {
  position: absolute; inset: 0;
  pointer-events: none;
  font-size: .68rem; font-variant-numeric: tabular-nums;
  color: var(--leise);
}
.kurve-werte span {
  position: absolute; left: 0;
  transform: translateY(50%);
  padding: 0 .2rem;
  background: var(--flaeche);
  border-radius: 2px;
  white-space: nowrap;
}

/* Die Zwischenstufe der Zeitachse ist versteckt, bis kurve.js sie
   einblendet. Ohne Skript bleibt es bei der groben Stufe - die passt
   auch auf die schmalste Kachel. */
.kurve-achse .fein { display: none; }
.kurve-achse.dicht .fein { display: block; }

/* Zeitachse unter der Kurve.
   Als HTML, nicht im SVG: Das SVG ist mit preserveAspectRatio="none"
   verzerrt, Text darin würde mitgestreckt.
   Die Position kommt über eine Klasse je Rasterspalte - ein
   style-Attribut verbietet die Content-Security-Policy. */
.kurve-achse {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  margin: .1rem 0 .15rem;
  font-size: .7rem;
  color: var(--leise);
  font-variant-numeric: tabular-nums;
}
.kurve-achse span { grid-row: 1; justify-self: center; white-space: nowrap; }
.kurve-achse span.links { justify-self: start; }
.kurve-achse span.rechts { justify-self: end; }
.kurve-achse .p0 { grid-column: 1; }
.kurve-achse .p1 { grid-column: 2; }
.kurve-achse .p2 { grid-column: 3; }
.kurve-achse .p3 { grid-column: 4; }
.kurve-achse .p4 { grid-column: 5; }
.kurve-achse .p5 { grid-column: 6; }
.kurve-achse .p6 { grid-column: 7; }
.kurve-achse .p7 { grid-column: 8; }
.kurve-achse .p8 { grid-column: 9; }
.kurve-achse .p9 { grid-column: 10; }
.kurve-achse .p10 { grid-column: 11; }
.kurve-achse .p11 { grid-column: 12; }
.kurve-achse .p12 { grid-column: 13; }
.kurve-achse .p13 { grid-column: 14; }
.kurve-achse .p14 { grid-column: 15; }
.kurve-achse .p15 { grid-column: 16; }
.kurve-achse .p16 { grid-column: 17; }
.kurve-achse .p17 { grid-column: 18; }
.kurve-achse .p18 { grid-column: 19; }
.kurve-achse .p19 { grid-column: 20; }

.kachel-fuss {
  display: flex; justify-content: space-between;
  margin: 0; font-size: .74rem; color: var(--leise); font-variant-numeric: tabular-nums;
}
.kachel-fuss.einzel { justify-content: flex-start; margin-top: auto; }
.kachel-zeit { margin: .35rem 0 0; font-size: .74rem; color: var(--leise); }

/* ---------- Zugänge ---------- */

.anlegen { margin-bottom: 1.2rem; }
.anlegen > summary { padding: .7rem 1rem; font-size: .95rem; }

.zugangsliste { display: flex; flex-direction: column; gap: .7rem; }

.zugang {
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
}
.zugang.gesperrt .zugang-name code { text-decoration: line-through; color: var(--leise); }

.zugang-kopf {
  display: flex; flex-wrap: wrap; gap: .4rem 1.2rem;
  align-items: center; justify-content: space-between;
  padding: .85rem 1.1rem;
}
.zugang-name { display: flex; flex-wrap: wrap; align-items: center; gap: .55rem; }
.zugang-name > code { font-size: 1rem; font-weight: 600; }
.notiz { color: var(--leise); font-size: .88rem; }
.zugang-meta { display: flex; flex-wrap: wrap; gap: .3rem 1.2rem; font-size: .85rem; color: var(--leise); }

.zugang-aktionen > summary {
  list-style: none; cursor: pointer; user-select: none;
  padding: .55rem 1.1rem;
  border-top: 1px solid var(--rand);
  font-size: .88rem; font-weight: 500; color: var(--akzent-text);
}
.zugang-aktionen > summary::-webkit-details-marker { display: none; }
.zugang-aktionen[open] > summary { color: var(--text-2); }

.aktionen-inhalt {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1rem 1.6rem;
  padding: .4rem 1.1rem 1.1rem;
  background: var(--flaeche-2);
  border-top: 1px solid var(--rand);
  border-radius: 0 0 var(--radius) var(--radius);
}
.aktion label { margin-bottom: .5rem; }
.aktion-titel { display: block; font-size: .88rem; font-weight: 500; color: var(--text-2); margin-bottom: .45rem; }
.aktion small { margin-top: .4rem; }
/* Kästchen und Text in einer Zeile, auf Höhe des Knopfs daneben. */
.aktion .haken { display: inline-flex; align-items: center; gap: .4rem; margin: 0; font-weight: 400; color: var(--text); cursor: pointer; }

.gefahrzone > summary { cursor: pointer; font-size: .88rem; font-weight: 500; color: var(--schlecht); list-style: none; }
.gefahrzone > summary::-webkit-details-marker { display: none; }
.gefahrzone form { margin-top: .5rem; padding: .7rem .8rem; border: 1px solid var(--schlecht); border-radius: var(--radius-klein); }
.gefahrzone .hinweis { margin-top: 0; }


/* ---------- Daten: mehrere Reihen in einem Diagramm ---------- */

/* Die Farbplätze. Ein Element bekommt die Klasse k1..k8 und setzt damit
   --serie; Linie, Legendenpunkt und Treffermarkierung lesen dieselbe
   Variable. So steht jede Farbe genau einmal im Stylesheet. */
.k1 { --serie: var(--k1); }
.k2 { --serie: var(--k2); }
.k3 { --serie: var(--k3); }
.k4 { --serie: var(--k4); }
.k5 { --serie: var(--k5); }
.k6 { --serie: var(--k6); }
.k7 { --serie: var(--k7); }
.k8 { --serie: var(--k8); }


.kombi-karte {
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: .8rem .95rem .75rem;
  min-width: 0;
}
.kombi-kopf { display: flex; align-items: baseline; gap: .6rem; justify-content: space-between; }
.kombi-kopf h3 {
  margin: 0; font-size: .95rem; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.kombi-einheit { color: var(--leise); font-size: .85rem; flex: none; }

/* Dieses SVG ist NICHT verzerrt: Es trägt Text. width:100% mit
   height:auto hält Bild und viewBox im selben Seitenverhältnis - nur so
   bleiben die Beschriftungen unverzerrt und das Skript kann mit einem
   Maßstab rechnen. */
.kombi {
  display: block; width: 100%; height: auto;
  margin: .45rem 0 .1rem;
  cursor: crosshair; touch-action: none;
}
.kombi-netz line { stroke: var(--rand); stroke-width: 1; }
.kombi-beschriftung text {
  fill: var(--leise); font-size: 11px;
  font-variant-numeric: tabular-nums;
}
/* Die Schriftgröße steht in viewBox-Einheiten und schrumpft mit dem
   Bild. Auf schmalen Anzeigen wird sie deshalb grösser angesetzt - das
   gleicht den kleineren Maßstab aus, statt die Beschriftung
   unleserlich werden zu lassen. */
@media (max-width: 62rem) {
  .kombi-beschriftung text { font-size: 14px; }
}
@media (max-width: 42rem) {
  .kombi-beschriftung text { font-size: 20px; }
}
.kombi-linie {
  fill: none; stroke: var(--serie); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round;
}

/* Mauszeiger im Diagramm: senkrechte Linie und je Reihe ein Punkt.
   Beides liegt im SVG - anders als bei der Kachelkurve geht das hier,
   weil nichts verzerrt wird und ein Kreis ein Kreis bleibt. */
.kombi-marke { stroke: var(--text-2); stroke-width: 1; stroke-dasharray: 3 3; pointer-events: none; }
.kombi-treffer { fill: var(--serie); stroke: var(--flaeche); stroke-width: 2; pointer-events: none; }

.kombi-schild {
  position: fixed; z-index: 31; pointer-events: none;
  padding: .4rem .55rem; border-radius: var(--radius-klein);
  background: var(--text); color: var(--grund);
  font-size: .78rem; font-variant-numeric: tabular-nums;
  box-shadow: 0 2px 8px rgba(0,0,0,.25);
  max-width: 22rem;
}
.kombi-schild .zeit { display: block; margin-bottom: .25rem; opacity: .75; }
.kombi-schild table { border-collapse: collapse; }
.kombi-schild td { padding: .05rem .2rem; white-space: nowrap; }
.kombi-schild td:first-child { padding-left: 0; }
.kombi-schild td:last-child { padding-right: 0; text-align: right; font-weight: 600; }
.kombi-schild .punkt {
  display: inline-block; width: .5rem; height: .5rem; border-radius: 50%;
  background: var(--serie);
}

/* Legende. Zu jeder Linie der aktuelle Wert: Drei Farben der Palette
   liegen im hellen Erscheinungsbild unter 3:1 Kontrast zur Fläche, und
   dann muss eine sichtbare Beschriftung die Zuordnung tragen. */
.kombi-legende {
  list-style: none; margin: .35rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .25rem 1rem;
  font-size: .78rem;
}
.kombi-legende li { display: inline-flex; align-items: center; gap: .35rem; min-width: 0; }
.kombi-punkt { width: .55rem; height: .55rem; border-radius: 50%; background: var(--serie); flex: none; }
.kombi-name { color: var(--text-2); max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kombi-wert { font-weight: 600; font-variant-numeric: tabular-nums; }
.kombi-hinweis { color: var(--leise); }
.kombi-rest { margin: .55rem 0 0; font-size: .78rem; color: var(--text-2); }
.kombi-rest code { margin-right: .3rem; }
.kombi-rest small { display: block; margin-top: .2rem; }

/* ---------- Daten: freie Auswahl ---------- */

/* Die Sektion bleibt auch leer stehen: Sie ist das Ziel, wenn jemand
   ein herausgezogenes Diagramm zurücklegen will. */
.vergleich { margin-bottom: 1.8rem; }
.vergleich.ziel {
  outline: 2px dashed var(--akzent);
  outline-offset: 3px;
  background: var(--akzent-hell);
  border-radius: var(--radius);
}
.vergleich-leer {
  margin: 0; padding: 1rem;
  border: 1px dashed var(--rand-stark); border-radius: var(--radius);
  font-size: .82rem; color: var(--leise);
}
.vergleich-kopf {
  display: flex; flex-wrap: wrap; gap: .3rem 1rem;
  align-items: baseline; justify-content: space-between;
  margin-bottom: .7rem;
}
.vergleich-kopf h2 { margin: 0; font-size: 1.05rem; }
.vergleich > .kombi-karte + .kombi-karte { margin-top: 1rem; }

/* Der Schalter oben rechts. Er bleibt sichtbar, sobald die Reihe im
   Vergleich steht - sonst wäre der Zustand nur beim Überfahren zu
   sehen. */
/* Maße und Position stehen bei den Symbolknöpfen weiter oben. */
.vergleich-schalter { text-decoration: none; }
.vergleich-schalter:focus { opacity: 1; }

/* Ziehen im Diagramm wählt einen Zeitraum. Der Rahmen liegt im SVG und
   wird beim Loslassen in von/bis umgerechnet - die Seite lädt dann mit
   diesem Zeitraum neu, und er steht danach in der Adresszeile. */
.kombi-zieher { fill: var(--akzent); opacity: .16; pointer-events: none; }

/* Aus dem Vergleich nehmen: am Kopf das ganze Diagramm, in der Legende
   die einzelne Reihe. Beides bleibt blass, bis man hinfährt - sonst
   zöge das Kreuz mehr Aufmerksamkeit auf sich als die Kurve. */
/* Maße, Farben und Einblenden stehen bei den Symbolknöpfen weiter
   oben - hier nur, was den Link vom Knopf unterscheidet. */
.karte-weg { text-decoration: none; }

.linie-weg {
  margin-left: .35rem; display: inline-flex; align-items: center; justify-content: center;
  width: 1.15rem; height: 1.15rem; border-radius: 999px;
  color: var(--leise); text-decoration: none; font-size: 1rem; line-height: 1;
  opacity: 0; transition: opacity .12s, color .12s, background .12s;
}
.kombi-legende li:hover .linie-weg, .linie-weg:focus-visible { opacity: 1; }
.linie-weg:hover { color: var(--schlecht); background: var(--schlecht-hell); }
/* Eine ausgeblendete Reihe behält ihr Kreuz - gerade sie will man oft
   ganz loswerden. */
.kombi-legende li.aus .linie-weg { opacity: .6; text-decoration: none; }

/* Legende zum Schalten. Erst wenn das Skript läuft, wird sie anklickbar
   - ohne JavaScript sähe ein Zeigefinger über etwas, das nichts tut,
   nach einem Fehler aus. */
.kombi-legende.schaltbar li { cursor: pointer; border-radius: var(--radius-klein); padding: .1rem .25rem; }
.kombi-legende.schaltbar li:hover { background: var(--flaeche-2); }
.kombi-legende.schaltbar li:focus-visible { outline: 2px solid var(--akzent); outline-offset: 1px; }
/* Ausgeblendet: der Punkt wird hohl, der Text tritt zurück. Nicht
   allein über die Deckkraft - bei acht Einträgen ist "etwas blasser"
   nicht zu erkennen. */
.kombi-legende li.aus .kombi-punkt { background: none; box-shadow: inset 0 0 0 1.5px var(--rand-stark); }
.kombi-legende li.aus .kombi-name,
.kombi-legende li.aus .kombi-wert,

/* ---------- Übersicht ----------
   Ein Gerät wie auf dem Zählerdisplay: oben grosse Kacheln für das, was
   gerade fliesst und bisher geflossen ist, darunter je Art eine Karte
   mit allen Messgrößen. Keine Kurven - dafür gibt es die Auswertung. */

.ueb-kopf { align-items: center; }
.ueb-marke {
  margin: 0 0 .15rem; font-size: .74rem; font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--akzent-text);
}
.ueb-marke code { text-transform: none; letter-spacing: 0; }
.ueb-titel { font-size: 1.9rem; font-weight: 700; overflow-wrap: anywhere; }

.ueb-rechts { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.ueb-pille {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .35rem .8rem; border-radius: 999px;
  background: var(--flaeche); border: 1px solid var(--rand);
  font-size: .88rem; color: var(--text-2); white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ueb-pille svg { width: 1rem; height: 1rem; flex: none; }
/* Der Zustand steht auch im Text - die Farbe allein trüge ihn nicht. */
.ueb-live { font-weight: 600; }
.ueb-live[data-zustand="an"]    { color: var(--gut);      background: var(--gut-hell);      border-color: transparent; }
.ueb-live[data-zustand="ruhig"] { color: var(--warn); }
.ueb-live[data-zustand="aus"]   { color: var(--schlecht); background: var(--schlecht-hell); border-color: transparent; }

.ueb-oben {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: .8rem;
  margin-bottom: 1.1rem;
}
.ueb-kachel {
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: .9rem 1rem .8rem;
  min-width: 0;
}
.ueb-zeichen {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; border-radius: var(--radius-klein);
  background: var(--akzent-hell); color: var(--akzent-text);
  margin-bottom: .55rem;
}
.ueb-zeichen svg { width: 1.15rem; height: 1.15rem; }
.ueb-kachel h2 {
  margin: 0; font-size: .9rem; font-weight: 600; color: var(--text-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ueb-wert { margin: .1rem 0 .15rem; white-space: nowrap; }
.ueb-zahl { font-size: 1.6rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.ueb-wert .ueb-einheit { font-size: 1.1rem; font-weight: 600; color: var(--text); }
.ueb-zeit { margin: 0; font-size: .8rem; color: var(--leise); font-variant-numeric: tabular-nums; }

.ueb-gruppen {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: .8rem;
  align-items: start;
}
.ueb-gruppe {
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--radius);
  box-shadow: var(--schatten);
  padding: 1rem 1.1rem 1.1rem;
  min-width: 0;
}
.ueb-gruppe h2 { font-size: 1.05rem; margin: 0 0 .7rem; }
.ueb-gruppe ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.ueb-gruppe li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: .8rem;
  padding: .5rem .7rem;
  background: var(--flaeche-2);
  border: 1px solid var(--rand);
  border-radius: var(--radius-klein);
}
.ueb-name { font-weight: 600; font-size: .9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ueb-listwert { font-weight: 600; font-size: .95rem; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ueb-listwert .ueb-einheit { font-weight: 500; color: var(--text-2); }
.ueb-gruppe .ueb-zeit { grid-column: 1 / -1; }

@media (max-width: 40rem) {
  .ueb-titel { font-size: 1.5rem; }
  .ueb-oben { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ueb-zahl { font-size: 1.35rem; }
}
