/* Wandtablet-Oberflaeche.
 *
 * Drei Regeln, aus denen alles andere folgt:
 *
 * 1. Ein Wandtablet wird im Vorbeigehen bedient, mit einem Finger,
 *    manchmal aus zwei Metern Abstand. Deshalb grosse Flaechen, grosse
 *    Zahlen, wenig davon.
 * 2. Es leuchtet den ganzen Tag in einem Wohnraum. Deshalb dunkel,
 *    kuehl und ruhig - nichts blinkt, nichts springt.
 * 3. Farbe bedeutet etwas. Warm = Waerme oder Licht, kuehl = Kaelte,
 *    gruen = eigener Strom, rot = Strom vom Netz. Farbe wird nie nur
 *    zur Zierde eingesetzt, und nie allein - neben jeder Farbe steht
 *    ein Wort oder eine Zahl.
 */

:root {
  /* Grundflaechen - die Farben von alpasana.ch.
   *
   * Wunsch des Nutzers vom 11.09.2026: "baue nun das Design nach
   * Galaxy, so wie der header von alpasana.ch im Hintergrund."
   *
   * Aus deren Kopfbild uebernommen: #232434 als dunkler Grund, #1C7CB0
   * bis #269CD9 als Blau, #A8E8FF und #D8F6FF als Lichter. Die frueheren
   * Werte (#060b15) waren fast schwarz - richtig fuer ein Wandtablet im
   * dunklen Flur, aber eben nicht die Handschrift der Firma.
   *
   * Die BEDEUTUNGEN weiter unten bleiben unveraendert. Sonne bleibt
   * warm, Netzbezug bleibt rot - Farbe ist in dieser Oberflaeche eine
   * Aussage und keine Zierde, und eine Aussage aendert man nicht, weil
   * ein Hintergrund neu ist.
   */
  --tief:        #191a29;
  --tief-2:      #232434;
  --blau:        #1c7cb0;
  --blau-hell:   #2ea3f2;
  --blau-licht:  #a8e8ff;
  --flaeche:     rgba(255, 255, 255, .055);
  --flaeche-2:   rgba(255, 255, 255, .09);
  --rand:        rgba(255, 255, 255, .10);
  --rand-hell:   rgba(255, 255, 255, .18);

  /* Schrift. Rubik ist die Schrift von alpasana.ch - wenn sie auf dem
     Geraet liegt, wird sie genommen, sonst die des Systems. Nachladen
     aus dem Netz waere eine Abhaengigkeit, die genau dann fehlt, wenn
     die Leitung weg ist. */
  --text:        #eaf4ff;
  --text-2:      #a9bdd8;
  --text-3:      #7489a6;

  /* Bedeutungen */
  --sonne:       #ffc94d;
  --akku:        #2fdca6;
  --netz-bezug:  #ff6b81;
  --netz-gabe:   #7bdcff;
  --auto:        #8ab4ff;
  --warm:        #ff8a5b;
  --kalt:        #4cc9f0;
  --neutral:     #93a6c4;
  --licht:       #ffd479;

  /* Gefuellte Saeulen der Energiekarte (energie.js). Eigene Toene, weil
     die Signalfarben oben im Dunkeln fuer Flaechen zu hell sind; mit
     scripts/validate_palette.js gegen die Kartenflaeche geprueft
     (dunkel #262736: alles bestanden). Die Bedeutung bleibt dieselbe:
     rot das Netz, gruen die eigene Anlage, gold das Dach. */
  --e-netz:      #d23e5a;
  --e-eigen:     #2d9f93;
  --e-dach:      #b98a24;

  --r-gross:     28px;
  --r-mittel:    20px;
  --r-klein:     14px;

  /* Senkrechter Rhythmus zwischen den Bloecken der Startseite.
     Eine Zahl fuer alle, damit sie nicht auseinanderlaufen.

     26 px oben statt der frueheren 18: Am 08.09.2026 standen drei
     Bloecke untereinander - Kachelreihe, Balkonkraftwerke, Wer zieht
     Strom - und die unteren zwei hatten gar keinen Abstand. Sie sahen
     aus wie ein einziger langer Kasten. Der Rhythmus muss groesser
     sein als die 14 px Innenabstand einer Geraetezeile, sonst liest
     man die Grenze zwischen zwei Karten nicht. */
  --abstand-block: clamp(16px, 2.4vw, 26px);

  --schatten:    0 18px 50px rgba(0, 0, 0, .45);
  --tempo:       .28s cubic-bezier(.22, .61, .36, 1);
}

/* Heller Raum am Tag. Dieselbe Bedeutung der Farben, nur andere
   Traeger - nicht die Rollen tauschen, sonst lernt man die Anzeige
   zweimal. */
@media (prefers-color-scheme: light) {
  :root {
    --tief:      #eef3fb;
    --tief-2:    #dce6f5;
    --flaeche:   rgba(255, 255, 255, .78);
    --flaeche-2: rgba(255, 255, 255, .95);
    --rand:      rgba(20, 40, 80, .10);
    --rand-hell: rgba(20, 40, 80, .18);
    --text:      #0f1e34;
    --text-2:    #3d5578;
    --text-3:    #6b7f9f;
    --sonne:     #e09300;
    --akku:      #068f68;
    --netz-bezug:#d92c4b;
    --netz-gabe: #0f7fa8;
    --auto:      #2f62c4;
    --warm:      #d4552a;
    --kalt:      #1479a8;
    --neutral:   #5a6f90;
    --licht:     #b8860b;
    /* Hell gegen #fbfcfe geprueft. Das Gold liegt unter 3:1 - deshalb
       hat die Karte Zahlen, Ablesezeile und Tabelle. */
    --e-netz:    #d92c4b;
    --e-eigen:   #00897a;
    --e-dach:    #e09300;
    --schatten:  0 14px 40px rgba(30, 60, 110, .16);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
}

body {
  background: var(--tief);
  color: var(--text);
  font: 400 16px/1.45 Rubik, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  padding: 0 clamp(14px, 3vw, 40px) calc(96px + env(safe-area-inset-bottom));
  overflow-x: hidden;
}

/* --- Hintergrund ------------------------------------------------------ */

/* DER GALAXIE-HINTERGRUND.
 *
 * Die Zeichnung liegt in galaxie.svg und ist nach dem Kopfbild von
 * alpasana.ch gebaut - dunkler Verlauf, weiche Lichtflecken, ein Netz
 * aus Knoten. Warum eine eigene Datei und kein Nachladen von dort: Das
 * Wandtablet muss auch ohne Internet funktionieren.
 *
 * FIXIERT UND NICHT MITSCROLLEND. Die Seite ist lang; ein mitlaufender
 * Hintergrund wuerde bei jedem Wisch das Netz verschieben und das Auge
 * vom Lesen abhalten.
 *
 * Der Verlauf DARUEBER ist nicht doppelt gemoppelt: Er dunkelt die
 * Mitte ab, wo die Karten stehen, und laesst die Raender leuchten. Ohne
 * ihn stuenden weisse Zahlen ueber den hellen Knoten. */
.himmel {
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg,
      rgba(25, 26, 41, .42) 0%,
      rgba(25, 26, 41, .68) 46%,
      rgba(25, 26, 41, .88) 100%),
    url("galaxie.svg") center / cover no-repeat,
    var(--tief);
  overflow: hidden;
}

.schleier {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: .30;
  will-change: transform;
}

.schleier-a {
  width: 55vmax; height: 55vmax;
  left: -14vmax; top: -18vmax;
  background: radial-gradient(circle, var(--blau) 0%, transparent 68%);
  animation: treiben-a 54s ease-in-out infinite alternate;
}

.schleier-b {
  width: 48vmax; height: 48vmax;
  right: -16vmax; bottom: -20vmax;
  background: radial-gradient(circle, var(--blau-hell) 0%, transparent 70%);
  animation: treiben-b 68s ease-in-out infinite alternate;
}

@keyframes treiben-a { to { transform: translate3d(8vmax, 6vmax, 0) scale(1.15); } }
@keyframes treiben-b { to { transform: translate3d(-7vmax, -5vmax, 0) scale(1.1); } }

/* --- Kopf ------------------------------------------------------------- */

.kopf {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  padding: clamp(18px, 3.4vw, 34px) 4px clamp(12px, 2vw, 22px);
}

.kopf h1 {
  margin: 0;
  font-size: clamp(26px, 4.4vw, 44px);
  font-weight: 600;
  letter-spacing: -.02em;
}

.kopf-unter {
  margin: 4px 0 0;
  color: var(--text-2);
  font-size: clamp(14px, 1.7vw, 18px);
}

.kopf-rechts {
  display: flex;
  align-items: center;
  gap: 14px;
}

.uhr {
  font-size: clamp(22px, 3.4vw, 36px);
  font-weight: 300;
  color: var(--text-2);
  letter-spacing: .01em;
}

/* Ein einziger Punkt sagt, ob die Anzeige noch lebt. Er blinkt nicht,
   er atmet - sonst zieht er staendig den Blick auf sich. */
.puls span {
  display: block;
  width: 11px; height: 11px;
  border-radius: 50%;
  background: var(--akku);
  box-shadow: 0 0 0 0 currentColor;
  animation: atmen 3.4s ease-in-out infinite;
}
.puls.puls-weg span { background: var(--netz-bezug); animation: none; }

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

/* --- Karten ----------------------------------------------------------- */

/* DIE KARTEN, nach dem Vorbild aus dem Foto vom 11.09.2026.
 *
 * Der Nutzer hat eine Plesk-Uebersicht gezeigt: Abschnitte mit
 * Ueberschrift, darunter Kacheln, jede mit farbigem Symbolfeld, Titel
 * und kleiner Unterzeile. Uebernommen ist davon die ORDNUNG, nicht das
 * Aussehen im Einzelnen - dort steht dunkle Schrift auf Weiss, hier
 * helle auf einem Galaxiehimmel.
 *
 * Was von dort kommt: klar getrennte Flaechen mit ruhigem Rand, viel
 * Luft, und eine Lichtkante oben, die jede Karte vom Hintergrund
 * abhebt. Das Bild lebt von seinen Verlaeufen; ohne die Kante
 * verschwaemmen die Karten darin. */
.karte {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .085) 0%,
      rgba(255, 255, 255, .04) 38%,
      rgba(255, 255, 255, .03) 100%);
  border: 1px solid var(--rand);
  border-radius: var(--r-gross);
  box-shadow: var(--schatten);
  backdrop-filter: blur(16px) saturate(1.1);
  -webkit-backdrop-filter: blur(16px) saturate(1.1);
  position: relative;
}

/* Die Lichtkante. Ein Strich, der links und rechts ausblendet - eine
   durchgehende Linie saehe nach Rahmen aus, nicht nach Licht. */
.karte::before {
  content: "";
  position: absolute;
  left: 14%;
  right: 14%;
  top: 0;
  height: 1px;
  border-radius: 1px;
  background: linear-gradient(90deg,
    transparent, rgba(168, 232, 255, .5), transparent);
  pointer-events: none;
}

.ansicht { display: none; }

/* DER SENKRECHTE RHYTHMUS EINER GANZEN SEITE.

   GEMESSEN am 08.09.2026 im Browser, als jeder Block seinen Abstand
   noch selbst mitbrachte:

       Haus      26 / 26 / 26 px
       Autos      0 /  0 px      <- die drei Karten klebten aneinander
       Kameras   26 px
       Mehr      20 px

   Der Nutzer wollte "die Abstaende wie beim Haus" ueberall. Solange
   jeder Block seinen eigenen margin-top trug, hiess das: an jede neue
   Karte denken. Genau daran ist die Autoansicht gescheitert - ihre
   Karten kommen aus dem Javascript und hatten nie einen bekommen.

   Deshalb steht der Abstand jetzt EINMAL an der Seite. Ein
   Spaltenfluss mit gap trennt alles, was direkt darin liegt, gleich
   weit - egal was das Javascript spaeter hineinschreibt. Man kann
   den Abstand nicht mehr vergessen, weil man ihn nicht mehr setzt. */
.ansicht-aktiv,
#raum-inhalt,
#verlauf-inhalt,
.erweitert-inhalt {
  display: flex;
  flex-direction: column;
  gap: var(--abstand-block);
}
.ansicht-aktiv { animation: auftauchen .34s ease both; }

/* Ein LEERER Behaelter darf keinen Abstand erzeugen. Die Balkonkarte
   bleibt leer, solange sie nichts zu zeigen hat; ein gap davor und
   dahinter waeren 52 px Loch ohne Inhalt. display:none nimmt sie aus
   dem Fluss, dann faellt auch ihr gap weg - was :empty bei margin
   nicht konnte. */
.ansicht-aktiv > div:empty,
#raum-inhalt > div:empty,
#verlauf-inhalt > div:empty,
.erweitert-inhalt > div:empty { display: none; }

/* Der Zurueck-Knopf ist kein Block: im Spaltenfluss wuerde er sonst
   ueber die ganze Breite gezogen. */
.zurueck { align-self: flex-start; }

@keyframes auftauchen {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* --- Energiefluss ----------------------------------------------------- */

.karte-fluss { padding: clamp(6px, 1.6vw, 18px) clamp(4px, 1vw, 14px) 6px; }

/* Hoehe deckeln. Ohne das ist das Bild bei 1280 px Breite rund
   740 px hoch - auf einem Wandtablet im Querformat steht der
   erklaerende Satz dann unter der Kante, und genau der ist der
   Grund, warum das Bild ueberhaupt da ist. */
#fluss {
  width: 100%;
  height: auto;
  max-height: 54vh;
  display: block;
  margin: 0 auto;
}

.leitung {
  stroke: var(--rand-hell);
  stroke-width: 3;
}

/* Die bewegte Linie. Die Bewegung selbst traegt die Aussage: Richtung
   des Flusses und - ueber das Tempo - die Menge. Steht sie still, ist
   auf dieser Leitung nichts los. */
.leitung-fluss {
  stroke: var(--neutral);
  stroke-width: 6;
  stroke-dasharray: 3 20;
  opacity: 0;
  transition: opacity var(--tempo), stroke .4s;
  animation: fliessen 1.6s linear infinite;
}

.leitung-fluss.aktiv { opacity: .95; }
.leitung-fluss.rueckwaerts { animation-direction: reverse; }

@keyframes fliessen { to { stroke-dashoffset: -46; } }

/* Wer Bewegung nicht vertraegt, bekommt eine ruhige, volle Linie -
   die Aussage bleibt, nur das Tempo fehlt. */
@media (prefers-reduced-motion: reduce) {
  .leitung-fluss { animation: none; stroke-dasharray: none; stroke-width: 4; }
  .schleier { animation: none; }
  .puls span { animation: none; opacity: .9; }
}

.knoten text {
  text-anchor: middle;
  fill: var(--text);
  font-family: inherit;
  font-variant-numeric: tabular-nums;
}

.knoten .wert       { font-size: 26px; font-weight: 600; }
.knoten .wert-gross { font-size: 38px; font-weight: 600; }
.knoten .wert-klein { font-size: 21px; font-weight: 500; }
.knoten .marke      { font-size: 19px; fill: var(--text-2); font-weight: 400; }
.knoten .marke-auto { font-size: 20px; fill: var(--text); font-weight: 500; }

.knoten .scheibe { transition: opacity .5s; }

/* Die Sonne verliert nachts ihre Strahlen und wird blass - so sieht
   man auf einen Blick, ob ueberhaupt etwas produziert wird. */
.strahlen path {
  stroke: var(--sonne);
  stroke-width: 6;
  stroke-linecap: round;
  fill: none;
  opacity: .85;
  transform-origin: center;
  animation: kreisen 44s linear infinite;
}
.knoten-sonne.ruht .strahlen path { opacity: .12; animation: none; }
.knoten-sonne.ruht .scheibe { opacity: .28; }
@keyframes kreisen { to { transform: rotate(360deg); } }

.scheibe-netz { fill: none; stroke: var(--rand-hell); stroke-width: 3; }
.mast path, .dach {
  fill: none;
  stroke: var(--text);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.mast path { stroke: var(--text-2); }

.akku-huelle, .akku-kopf {
  fill: none;
  stroke: var(--rand-hell);
  stroke-width: 3;
}
.akku-kopf { fill: var(--rand-hell); }
.akku-fuellung { transition: y .8s var(--tempo), height .8s var(--tempo); }

.auto-form path, .auto-form circle {
  fill: none;
  stroke: var(--text-2);
  stroke-width: 5;
  stroke-linejoin: round;
  transition: stroke .4s;
}
.knoten-auto.laedt .auto-form path,
.knoten-auto.laedt .auto-form circle { stroke: var(--akku); }
.knoten-auto.fern { opacity: .32; }

.fluss-satz {
  margin: 2px clamp(10px, 2vw, 26px) clamp(14px, 2vw, 20px);
  text-align: center;
  color: var(--text-2);
  font-size: clamp(15px, 1.9vw, 19px);
  line-height: 1.5;
}

/* --- Zahlenkacheln ---------------------------------------------------- */

.kachelreihe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: clamp(10px, 1.6vw, 16px);
}

/* Die Kacheln wie im Foto: eigene Flaeche, ruhiger Rand, viel Luft.
 *
 * Anders als dort tragen sie hier kein Symbol, sondern eine ZAHL. Das
 * ist der eine Punkt, an dem die Vorlage nicht passt: In Plesk fuehrt
 * jede Kachel woandershin, hier sagt jede etwas aus. Ein Symbol neben
 * "2,97 kW" waere Schmuck - und die erste Regel dieser Oberflaeche
 * ist, dass nichts nur zur Zierde dasteht. */
.kachel {
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, .075) 0%,
      rgba(255, 255, 255, .035) 100%);
  border: 1px solid var(--rand);
  border-radius: var(--r-mittel);
  padding: 16px 18px 15px;
  transition: border-color var(--tempo), transform var(--tempo);
}

.kachel:hover { border-color: rgba(168, 232, 255, .28); }

.kachel-marke {
  color: var(--text-3);
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.kachel-wert {
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 600;
  margin-top: 4px;
  line-height: 1.15;
}

.kachel-zusatz { color: var(--text-2); font-size: 14px; margin-top: 2px; }

/* --- Raumgitter ------------------------------------------------------- */

.raumgitter {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: clamp(12px, 1.8vw, 20px);
  padding-top: 4px;
}

.raumkarte {
  position: relative;
  display: block;
  width: 100%;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--r-gross);
  padding: 0;
  overflow: hidden;
  transition: transform var(--tempo), border-color var(--tempo);
  -webkit-tap-highlight-color: transparent;
}

.raumkarte:hover { border-color: var(--rand-hell); }
.raumkarte:active { transform: scale(.977); }
.raumkarte:focus-visible { outline: 3px solid var(--auto); outline-offset: 3px; }

/* Der Waermestreifen am oberen Rand. Er ist die einzige Stelle, an der
   Farbe eine Zahl ersetzt - deshalb steht die Zahl direkt darunter. */
.raum-streifen { height: 6px; width: 100%; }

.raum-innen { padding: 16px 18px 18px; }

.raum-name {
  font-size: clamp(18px, 2.2vw, 21px);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 9px;
}

.raum-zahlen {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-top: 12px;
}

.raum-gross { font-size: clamp(34px, 4.6vw, 46px); font-weight: 300; line-height: 1; }
.raum-klein { color: var(--text-2); font-size: 15px; }
.raum-fuss  { margin-top: 12px; color: var(--text-3); font-size: 14px; }

.pille {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 13px;
  border: 1px solid var(--rand-hell);
  color: var(--text-2);
}
.pille-warm  { color: var(--warm); border-color: color-mix(in srgb, var(--warm) 45%, transparent); }
.pille-licht { color: var(--licht); border-color: color-mix(in srgb, var(--licht) 45%, transparent); }
.pille-defekt{ color: var(--netz-bezug); border-color: color-mix(in srgb, var(--netz-bezug) 45%, transparent); }

/* --- Ein Raum --------------------------------------------------------- */

.zurueck {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0;
  padding: 11px 18px;
  font: inherit;
  font-size: 16px;
  color: var(--text);
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: 999px;
  cursor: pointer;
}
.zurueck:active { transform: scale(.97); }

.raum-kopf { margin: 0; }
.raum-kopf h2 {
  margin: 0;
  font-size: clamp(28px, 4.4vw, 42px);
  font-weight: 600;
  letter-spacing: -.02em;
}

/* DAS GITTER ALLER UEBRIGEN SEITEN - Autos, Raum, Kameras,
   Einstellungen, Erweitert. Es benutzt denselben Rhythmus wie die
   Startseite: der Nutzer wollte am 08.09.2026 ausdruecklich "diese
   Abstaende wie beim Haus" ueberall.

   Und es ist ein gap, kein margin. Ein gap gilt in BEIDE Richtungen -
   nebeneinander wie untereinander - und schiebt keine Karte nach
   unten, wenn zwei nebeneinander stehen. Genau daran war Stunden
   vorher ein ".karte + .karte" gescheitert: In der Autoansicht stand
   die rechte Karte 26 px tiefer als die linke. */
.spalten {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: var(--abstand-block);
}

.block { padding: clamp(18px, 2.4vw, 26px); }
/* DIE ABSCHNITTSUEBERSCHRIFT, aus dem Foto uebernommen.
 *
 * Dort stehen "Dateien und Datenbanken", "Entwicklertools",
 * "Sicherheit" als ruhige Ueberschriften ueber ihren Kacheln - gross
 * genug zum Wiederfinden, nicht so gross, dass sie den Inhalt
 * uebertoenen.
 *
 * Vorher stand hier 15 px in Grossbuchstaben und Grau. Das liest sich
 * aus zwei Metern wie eine Fussnote; die Ueberschrift soll aber die
 * erste Stufe der Gliederung sein. Jetzt groesser, heller, gemischte
 * Schreibung - und davor ein kurzer blauer Strich als Anker fuers
 * Auge. */
.block h3 {
  margin: 0 0 18px;
  font-size: clamp(17px, 1.9vw, 20px);
  letter-spacing: .01em;
  color: var(--text);
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 12px;
}

.block h3::before {
  content: "";
  width: 4px;
  height: 1.05em;
  border-radius: 2px;
  flex: none;
  background: linear-gradient(180deg, var(--blau-licht), var(--blau-hell));
  box-shadow: 0 0 12px rgba(46, 163, 242, .55);
}

/* Die grosse Temperatur. Eine Zahl, so gross wie moeglich - sie ist
   die Antwort auf die einzige Frage, die im Raum gestellt wird. */
.thermo {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2.4vw, 28px);
  flex-wrap: wrap;
}

.thermo-zahl {
  font-size: clamp(62px, 11vw, 104px);
  font-weight: 200;
  line-height: .95;
  letter-spacing: -.03em;
}
.thermo-grad { font-size: .42em; font-weight: 400; color: var(--text-2); }

.thermo-neben { display: grid; gap: 8px; min-width: 148px; }

.messwert {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 9px 0;
  border-bottom: 1px solid var(--rand);
  font-size: 16px;
}
.messwert:last-child { border-bottom: 0; }
.messwert span:first-child { color: var(--text-2); }
.messwert b { font-weight: 600; }

/* Sollwert stellen. Zwei sehr grosse Knoepfe, dazwischen die Zahl -
   mehr braucht es nicht, und weniger geht nicht. */
.steller {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 18px;
}

.rundknopf {
  width: clamp(64px, 9vw, 82px);
  height: clamp(64px, 9vw, 82px);
  flex: 0 0 auto;
  border-radius: 50%;
  border: 1px solid var(--rand-hell);
  background: var(--flaeche-2);
  color: var(--text);
  font: 300 clamp(34px, 4.6vw, 44px)/1 system-ui, sans-serif;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: transform .12s, background var(--tempo);
  -webkit-tap-highlight-color: transparent;
}
.rundknopf:active { transform: scale(.92); background: var(--rand-hell); }
.rundknopf:disabled { opacity: .3; cursor: default; }

.steller-mitte { text-align: center; flex: 1 1 auto; }
.steller-zahl { font-size: clamp(38px, 5.4vw, 52px); font-weight: 300; line-height: 1.05; }
.steller-marke { color: var(--text-3); font-size: 14px; letter-spacing: .04em; text-transform: uppercase; }

/* Lampen */
.lampe-zeile {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 0;
  border-bottom: 1px solid var(--rand);
  flex-wrap: wrap;
}
.lampe-zeile:last-child { border-bottom: 0; }

.lampe-name { flex: 1 1 130px; font-size: 17px; font-weight: 500; }
.lampe-unter { color: var(--text-3); font-size: 13px; font-weight: 400; }

.schalter {
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  padding: 13px 24px;
  border-radius: 999px;
  border: 1px solid var(--rand-hell);
  background: var(--flaeche-2);
  color: var(--text);
  cursor: pointer;
  min-width: 148px;
  transition: transform .12s;
}
.schalter:active { transform: scale(.96); }
.schalter-an {
  background: color-mix(in srgb, var(--licht) 22%, transparent);
  border-color: color-mix(in srgb, var(--licht) 55%, transparent);
  color: var(--licht);
}
.schalter:disabled { opacity: .45; cursor: default; }

.farbreihe { display: flex; gap: 10px; flex-wrap: wrap; width: 100%; margin-top: 4px; }

/* Kopfzeile einer Karte: Ueberschrift links, Sammelknopf rechts. */
.karten-kopf {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.karten-kopf h3 { margin: 0; }
.karten-kopf .schalter { margin-left: auto; }

/* Ein schlafendes Auto: ruhig, nicht alarmierend. */
.pille-schlaf {
  background: color-mix(in srgb, var(--auto) 16%, transparent);
  border-color: color-mix(in srgb, var(--auto) 40%, transparent);
  color: var(--auto);
}

/* Werte, die nicht von jetzt sind. Gedaempft, damit man den Unterschied
   zu einem frischen Wert sieht, ohne die Zeile darunter zu lesen. */
.thermo-alt { opacity: .55; }
.standzeile {
  color: var(--text-3);
  font-size: 14px;
  line-height: 1.5;
  margin: 10px 0 16px;
}

.schalter-klein {
  font-size: 14px;
  padding: 9px 18px;
  min-width: 0;
}

/* Der Ladeauftrag unter den Messwerten eines Autos. Durch eine Linie
   getrennt, weil hier eingestellt wird und darueber nur abgelesen. */
.auftrag {
  margin-top: 22px;
  padding-top: 18px;
  border-top: 1px solid var(--rand);
}
.auftrag-titel {
  margin: 0;
  color: var(--text-2);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.auftrag-status { margin: 10px 0 2px; }
.auftrag-info { margin-top: 10px; }
.auftrag-info .lampe-unter { margin: 4px 0; }
.auftrag > .schalter { margin-top: 16px; }
.auftrag > .schalter + .lampe-unter { margin-top: 14px; }

/* Schieberegler.

   Die Bahn ist bewusst hoch und der Griff gross: das hier wird mit dem
   Daumen im Vorbeigehen bedient, nicht mit einer Maus. 44 Pixel ist das
   Mass, unter dem Treffer zur Gluecksache werden. */
.hellregler {
  width: 100%;
  margin-top: 10px;
}
.hellregler-kopf {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 6px;
}
.hellregler-marke {
  color: var(--text-3);
  font-size: 13px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.hellregler-wert {
  color: var(--text);
  font-size: 17px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.hellregler-bahn {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 44px;
  background: transparent;
  cursor: pointer;
  margin: 0;
}
.hellregler-bahn::-webkit-slider-runnable-track {
  height: 12px;
  border-radius: 999px;
  background: var(--flaeche-2);
  border: 1px solid var(--rand-hell);
}
.hellregler-bahn::-moz-range-track {
  height: 12px;
  border-radius: 999px;
  background: var(--flaeche-2);
  border: 1px solid var(--rand-hell);
}
.hellregler-bahn::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 34px;
  height: 34px;
  margin-top: -12px;
  border-radius: 50%;
  background: var(--licht);
  border: 2px solid var(--tief);
  box-shadow: 0 3px 10px rgba(0, 0, 0, .35);
}
.hellregler-bahn::-moz-range-thumb {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--licht);
  border: 2px solid var(--tief);
  box-shadow: 0 3px 10px rgba(0, 0, 0, .35);
}
.hellregler-bahn:focus-visible { outline: 3px solid var(--auto); outline-offset: 4px; }

.farbtupf {
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 2px solid var(--rand-hell);
  cursor: pointer;
  padding: 0;
  transition: transform .12s;
}
.farbtupf:active { transform: scale(.9); }
.farbtupf:focus-visible { outline: 3px solid var(--text); outline-offset: 3px; }

.hinweiszeile {
  margin: 10px 0 0;
  color: var(--text-3);
  font-size: 14px;
  line-height: 1.5;
}

.leer {
  color: var(--text-3);
  font-size: 16px;
  padding: 6px 0;
}

/* --- Fussleiste ------------------------------------------------------- */

.fussleiste {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(14px + env(safe-area-inset-bottom));
  display: flex;
  gap: 6px;
  padding: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tief-2) 82%, transparent);
  border: 1px solid var(--rand);
  box-shadow: var(--schatten);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  z-index: 20;
}

.fuss-knopf {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 12px 26px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-2);
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  cursor: pointer;
  transition: background var(--tempo), color var(--tempo);
  -webkit-tap-highlight-color: transparent;
}

.fuss-knopf svg {
  width: 22px; height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.fuss-aktiv { background: var(--flaeche-2); color: var(--text); }

/* --- Kleine Bildschirme ----------------------------------------------- */

@media (max-width: 560px) {
  .kachelreihe { grid-template-columns: repeat(2, 1fr); }

  /* Die Fussleiste stand als schwebende Pille mittig, so breit wie ihr
     Inhalt. Auf einem Telefon ist ihr Inhalt breiter als das Display:
     die fuenf Knoepfe brauchen rund 560 Pixel, ein iPhone hat 375. Weil
     sie ueber left:50% und translateX(-50%) zentriert war, ragte sie auf
     BEIDEN Seiten hinaus - und damit waren genau die zwei aeusseren
     Eintraege nicht mehr zu treffen: "Haus" links und "Mehr" rechts.
     Am 06.09.2026 am Telefon des Nutzers gesehen.

     Auf schmalen Bildschirmen spannt sie deshalb ueber die volle
     Breite, und die Beschriftung rutscht unter das Zeichen. Das ist die
     Form, die jedes Telefon fuer eine Navigationsleiste benutzt - und
     die einzige, in die fuenf Eintraege sicher passen. */
  .fussleiste {
    left: 8px;
    right: 8px;
    transform: none;
    border-radius: 24px;
    gap: 2px;
    padding: 5px;
  }
  .fuss-knopf {
    flex: 1 1 0;
    min-width: 0;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 2px;
    font-size: 11px;
    letter-spacing: -0.01em;
  }
  .fuss-knopf span {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .fuss-knopf svg { width: 21px; height: 21px; }

  /* Die Leiste ist zweizeilig und damit hoeher als die einzeilige. */
  main { padding-bottom: 124px; }
}

/* --- Anmeldung -------------------------------------------------------- *
 * zugang.js baut dieses Feld selbst; hier stehen nur die Farben und
 * Groessen dafuer. Die Namen der Klassen stammen aus zugang.js und
 * duerfen nicht geaendert werden.
 *
 * Undurchsichtig, nicht durchscheinend: Solange niemand angemeldet ist,
 * soll man nicht halb die Hausdaten dahinter sehen.
 */

/* AUCH DIE ANMELDUNG BEKOMMT DEN GALAXIEHIMMEL.
 *
 * Sie ist das Erste, was man sieht - und sie deckt vollflaechig ab,
 * damit niemand die Hausdaten dahinter durchscheinen sieht. Genau
 * deshalb muss sie den Hintergrund selbst mitbringen: Sonst faengt die
 * Oberflaeche mit einer leeren Flaeche an und wird erst nach dem
 * Anmelden schoen.
 *
 * Dieselbe Zeichnung wie bei .himmel, also auch dieselben zwei
 * Stimmungen - der Hell-Modus weiter unten deckt beide ab. */
.pin-huelle {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: none;
  align-items: center;
  justify-content: center;
  background:
    linear-gradient(180deg,
      rgba(25, 26, 41, .42) 0%,
      rgba(25, 26, 41, .68) 46%,
      rgba(25, 26, 41, .88) 100%),
    url("galaxie.svg") center / cover no-repeat,
    var(--tief);
}
.pin-huelle.sichtbar { display: flex; }

.pin-karte {
  width: min(23rem, 92vw);
  text-align: center;
  padding: 26px 22px 22px;
  background: var(--flaeche);
  border: 1px solid var(--rand);
  border-radius: var(--r-gross);
  box-shadow: var(--schatten);
}

.pin-titel { font-size: 26px; font-weight: 600; }
.pin-unter { font-size: 15px; color: var(--text-2); margin: 6px 0 22px; }

.pin-punkte {
  display: flex;
  justify-content: center;
  gap: 11px;
  min-height: 18px;
  margin-bottom: 22px;
}
.pin-punkt {
  width: 15px; height: 15px;
  border-radius: 50%;
  border: 2px solid var(--rand-hell);
}
.pin-punkt.voll { background: var(--auto); border-color: var(--auto); }

.pin-tasten { display: grid; grid-template-columns: repeat(3, 1fr); gap: 11px; }

/* 72 px hoch: An der Wand wird mit dem Daumen im Vorbeigehen getippt,
   nicht gezielt. */
.pin-taste {
  font: inherit;
  font-size: 26px;
  min-height: 72px;
  border-radius: var(--r-klein);
  border: 1px solid var(--rand);
  background: var(--flaeche-2);
  color: inherit;
  cursor: pointer;
}
.pin-taste:active { background: var(--rand-hell); }
.pin-taste-weg, .pin-taste-ok { font-size: 16px; font-weight: 600; }
.pin-taste-ok {
  background: var(--auto);
  color: #06101f;
  border-color: var(--auto);
}

.pin-meldung {
  min-height: 2.4em;
  margin-top: 16px;
  font-size: 15px;
  color: var(--text-2);
}
.pin-meldung-fehler { color: var(--netz-bezug); }

/* Anmeldung von unterwegs: E-Mail und Passwort statt Zahlenfeld. */
.anmeld-form { display: grid; gap: 12px; }
.anmeld-feld {
  font: inherit;
  font-size: 17px;
  min-height: 56px;
  padding: 0 14px;
  border-radius: var(--r-klein);
  border: 1px solid var(--rand-hell);
  background: var(--flaeche-2);
  color: inherit;
}
.anmeld-feld:focus { outline: 3px solid var(--auto); outline-offset: 1px; }
.anmeld-knopf { min-height: 60px; font-size: 17px; }

/* Von aussen gesperrte Bereiche gar nicht erst anbieten. */
body.von-aussen .nur-innen { display: none; }

/* Der Weg zum alten Werkzeug ist ein Link, kein Knopf - er wechselt
   die Seite, statt eine Ansicht umzuschalten. Er sieht gleich aus,
   damit die Fussleiste eine Reihe bleibt. */
a.fuss-knopf { text-decoration: none; }

/* --- 19. Raumbilder ---------------------------------------------------
   Farbtoken und Zustandsregeln, unveraendert uebernommen aus
   konzepte/bilder/. Sie dort zu aendern und hier nicht waere der
   sichere Weg zu zwei Bildsprachen im selben Haus.
--------------------------------------------------------------------- */
/* HELL */
:root{
  --bild-grund:#eceff3;
  --bild-t1:#9dabbb; --bild-t2:#7d8b9e; --bild-t3:#5e6c80; --bild-t4:#414e61; --bild-t5:#27303d;
  --bild-licht:#f0bb52; --bild-licht-kern:#ffe6ae;
  --bild-kalt-2:#8ec2f2; --bild-kalt-1:#2a78d6; --bild-passt:#9dabbb; --bild-warm-1:#e34948; --bild-warm-2:#a3231c;
}

/* DUNKEL */
@media (prefers-color-scheme: dark){
  :root{
    --bild-grund:#14171b;
    --bild-t1:#404b5a; --bild-t2:#556275; --bild-t3:#6e7b8e; --bild-t4:#8d9aac; --bild-t5:#adbaca;
    --bild-licht:#d8b871; --bild-licht-kern:#f2d79c;
    --bild-kalt-2:#9ccdf7; --bild-kalt-1:#4d9df0; --bild-passt:#6e7b8e; --bild-warm-1:#f0a07f; --bild-warm-2:#d4553a;
  }
}

[data-modus="hell"]{
  --bild-grund:#eceff3;
  --bild-t1:#9dabbb; --bild-t2:#7d8b9e; --bild-t3:#5e6c80; --bild-t4:#414e61; --bild-t5:#27303d;
  --bild-licht:#f0bb52; --bild-licht-kern:#ffe6ae;
  --bild-kalt-2:#8ec2f2; --bild-kalt-1:#2a78d6; --bild-passt:#9dabbb; --bild-warm-1:#e34948; --bild-warm-2:#a3231c;
}

[data-modus="dunkel"]{
  --bild-grund:#14171b;
  --bild-t1:#404b5a; --bild-t2:#556275; --bild-t3:#6e7b8e; --bild-t4:#8d9aac; --bild-t5:#adbaca;
  --bild-licht:#d8b871; --bild-licht-kern:#f2d79c;
  --bild-kalt-2:#9ccdf7; --bild-kalt-1:#4d9df0; --bild-passt:#6e7b8e; --bild-warm-1:#f0a07f; --bild-warm-2:#d4553a;
}

/* NACHT */
[data-modus="nacht"],[data-nacht]{
  --bild-grund:#05070c;
  --bild-t1:#40495a; --bild-t2:#4e5a6c; --bild-t3:#5f6c81; --bild-t4:#74829a; --bild-t5:#8b99ac;
  --bild-licht:#a07d2e; --bild-licht-kern:#c39a3d;
  /* Nachts traegt das Waermeband nur Hoehe + Zeichen, Ton = --bild-t3. */
}

.bild{background:var(--bild-grund);--bild-light:none;--bild-rise:none;--bild-sk:none;--bild-k:none;--bild-p:none;--bild-w:none;--bild-sw:none;--bild-lamp:var(--bild-t4);--bild-band:var(--bild-passt);--bild-band-grad:url(#band-h-p);--bild-rise-grad:url(#rise-h-w)}
.bild[data-licht="an"]{--bild-light:inline;--bild-lamp:var(--bild-licht-kern)}
.bild[data-waerme="sehr-kalt"]{--bild-sk:inline;--bild-band:var(--bild-kalt-2)}.bild[data-waerme="kalt"]{--bild-k:inline;--bild-band:var(--bild-kalt-1)}.bild[data-waerme="passt"]{--bild-p:inline;--bild-band:var(--bild-passt)}.bild[data-waerme="warm"]{--bild-w:inline;--bild-rise:inline;--bild-band:var(--bild-warm-1)}.bild[data-waerme="sehr-warm"]{--bild-sw:inline;--bild-rise:inline;--bild-band:var(--bild-warm-2)}
.bild[data-modus="hell"]{--bild-wall:url(#wall-h);--bild-floor:url(#floor-h);--bild-g2:url(#g2-h);--bild-g3:url(#g3-h);--bild-g4:url(#g4-h);--bild-shadow:url(#shadow-h);--bild-cone:url(#cone-h);--bild-glow:url(#glow-h);--bild-pool:url(#pool-h);--bild-edge2:var(--bild-t1);--bild-edge3:var(--bild-t2);--bild-edge4:var(--bild-t3)}
.bild[data-modus="dunkel"]{--bild-wall:url(#wall-d);--bild-floor:url(#floor-d);--bild-g2:url(#g2-d);--bild-g3:url(#g3-d);--bild-g4:url(#g4-d);--bild-shadow:url(#shadow-d);--bild-cone:url(#cone-d);--bild-glow:url(#glow-d);--bild-pool:url(#pool-d);--bild-edge2:var(--bild-t3);--bild-edge3:var(--bild-t4);--bild-edge4:var(--bild-t5)}
.bild[data-modus="nacht"]{--bild-wall:url(#wall-n);--bild-floor:url(#floor-n);--bild-g2:url(#g2-n);--bild-g3:url(#g3-n);--bild-g4:url(#g4-n);--bild-shadow:url(#shadow-n);--bild-cone:url(#cone-n);--bild-glow:url(#glow-n);--bild-pool:url(#pool-n);--bild-edge2:var(--bild-t3);--bild-edge3:var(--bild-t4);--bild-edge4:var(--bild-t5)}
.bild[data-modus="hell"][data-waerme="sehr-kalt"]{--bild-band-grad:url(#band-h-sk)}.bild[data-modus="hell"][data-waerme="kalt"]{--bild-band-grad:url(#band-h-k)}.bild[data-modus="hell"][data-waerme="passt"]{--bild-band-grad:url(#band-h-p)}.bild[data-modus="hell"][data-waerme="warm"]{--bild-band-grad:url(#band-h-w);--bild-rise-grad:url(#rise-h-w)}.bild[data-modus="hell"][data-waerme="sehr-warm"]{--bild-band-grad:url(#band-h-sw);--bild-rise-grad:url(#rise-h-sw)}
.bild[data-modus="dunkel"][data-waerme="sehr-kalt"]{--bild-band-grad:url(#band-d-sk)}.bild[data-modus="dunkel"][data-waerme="kalt"]{--bild-band-grad:url(#band-d-k)}.bild[data-modus="dunkel"][data-waerme="passt"]{--bild-band-grad:url(#band-d-p)}.bild[data-modus="dunkel"][data-waerme="warm"]{--bild-band-grad:url(#band-d-w);--bild-rise-grad:url(#rise-d-w)}.bild[data-modus="dunkel"][data-waerme="sehr-warm"]{--bild-band-grad:url(#band-d-sw);--bild-rise-grad:url(#rise-d-sw)}
.bild[data-nacht][data-waerme]{--bild-band:var(--bild-t3);--bild-band-grad:url(#band-n);--bild-rise-grad:url(#rise-n)}
.bild { display: block; width: 100%; height: 100%; }

/* Das Raumbild in der Kachel: es liegt hinter der Zahl und traegt sie,
   statt mit ihr zu kaempfen. Deshalb beschnitten statt eingepasst -
   ein vollstaendig sichtbares Bild wuerde zur zweiten Abbildung neben
   der Zahl und beide waeren dann gleich laut. */
.kachelbild {
  position: absolute;
  inset: auto 0 0 0;
  height: 68%;
  opacity: .92;
  pointer-events: none;
  /* Oben ausblenden, damit die Zahl auf ruhigem Grund steht. Unten voll
     sichtbar: dort ist das Bild die zweite Lesart der Zahl, und ein
     Bild, das man suchen muss, ist keine. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 46%);
          mask-image: linear-gradient(to bottom, transparent, #000 46%);
}
body[data-modus="nacht"] .kachelbild { opacity: .7; }
.raumbild-huelle { aspect-ratio: 400 / 250; }
.raumbild-huelle .bild { border-radius: inherit; }

/* Das Raumbild in der Karte. Es liegt UNTER dem Text, nicht dahinter -
   so kaempfen Bild und Zahl nicht um dieselbe Flaeche. Oben weich
   auslaufend, damit die Karte nicht in zwei Haelften zerfaellt. */
.raumbild {
  height: 104px;
  margin: -6px 0 -14px;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 34%, #000 82%, transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 34%, #000 82%, transparent);
}
.raumbild .bild { width: 100%; height: 100%; }

/* --- Rueckmeldung ------------------------------------------------------
   Ein Tesla-Befehl weckt das Auto und braucht bis zu 45 Sekunden. Ohne
   diese Zeile sieht es aus, als waere nichts passiert - und dann tippt
   man ein zweites Mal, was der Server mit "hoechstens ein Befehl pro
   Minute" quittiert.
--------------------------------------------------------------------- */
.melder {
  position: fixed;
  left: 50%;
  bottom: calc(104px + env(safe-area-inset-bottom));
  transform: translate(-50%, 14px);
  max-width: min(560px, 90vw);
  padding: 13px 24px;
  border-radius: 999px;
  background: var(--flaeche-2);
  border: 1px solid var(--rand-hell);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--schatten);
  font-size: 16px;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--tempo), transform var(--tempo);
  z-index: 50;
}
.melder-sichtbar { opacity: 1; transform: translate(-50%, 0); }
.melder-fehler {
  color: var(--netz-bezug);
  border-color: color-mix(in srgb, var(--netz-bezug) 55%, transparent);
}

/* --- Kameras -----------------------------------------------------------
   Standbilder, kein Dauerstrom: sechs laufende Videobilder wuerden das
   Tablet heiss laufen lassen und die Kameras belegen. Antippen holt ein
   frisches Bild.
--------------------------------------------------------------------- */
.kameragitter {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--abstand-block);
}
.kamerakachel {
  position: relative;
  padding: 0;
  border: 1px solid var(--rand);
  border-radius: var(--r-mittel);
  background: var(--flaeche);
  overflow: hidden;
  cursor: pointer;
  aspect-ratio: 16 / 9;
  font: inherit;
  color: inherit;
  transition: transform var(--tempo), border-color var(--tempo);
}
.kamerakachel:active { transform: scale(.98); }
.kamerakachel:focus-visible { outline: 3px solid var(--auto); outline-offset: 3px; }
.kamerakachel img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.kamera-name {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 10px 14px;
  font-size: 16px;
  font-weight: 500;
  text-align: left;
  color: #fff;
  background: linear-gradient(to top, rgba(0,0,0,.72), transparent);
}
.kamera-alter { font-weight: 400; opacity: .74; }
.kamera-weg img { opacity: .12; }
.kamera-weg .kamera-name::after { content: ' – kein Bild'; opacity: .8; }

/* Fuenf Reiter statt drei. Der Grund ist nicht Symmetrie, sondern dass
   Autos und Kameras sonst gar nicht erreichbar waeren - sie lagen
   vorher nur im alten Werkzeug. */
.fussleiste { grid-auto-columns: 1fr; }

/* --- Formulare in den Einstellungen ------------------------------------
   Grosse Felder, weil das oft auf einem Handy in schlechtem Licht
   passiert - und weil ein Wandtablet keine Tastatur hat, sondern eine
   eingeblendete, die die halbe Seite verdeckt.
--------------------------------------------------------------------- */
.formular { display: grid; gap: 12px; margin-top: 14px; }

.eingabe {
  font: inherit;
  font-size: 17px;
  min-height: 56px;
  padding: 0 16px;
  border-radius: var(--r-klein);
  border: 1px solid var(--rand-hell);
  background: var(--flaeche-2);
  color: var(--text);
  width: 100%;
}
.eingabe::placeholder { color: var(--text-3); }
.eingabe:focus-visible { outline: 3px solid var(--auto); outline-offset: 2px; }

.benutzerliste { margin-top: 8px; }

.benutzer-mehr, .benutzer-neu {
  width: 100%;
  margin-top: 10px;
  border-top: 1px solid var(--rand);
  padding-top: 12px;
}
.benutzer-mehr summary, .benutzer-neu summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
  color: var(--text-2);
  font-size: 16px;
}

/* Loeschen ist endgueltig und traegt deshalb die Warnfarbe - aber erst
   beim zweiten Tippen passiert etwas. Ein einzelner Fehlgriff auf einem
   Wandtablet darf keinen Zugang vernichten. */
.loeschknopf {
  margin-top: 12px;
  color: var(--netz-bezug);
  border-color: color-mix(in srgb, var(--netz-bezug) 45%, transparent);
}

/* --- Verlauf -----------------------------------------------------------
   Eine Achse fuer alle drei Watt-Reihen. Der Ladestand steht darunter in
   einem eigenen Bild - Prozent gehoert nicht auf eine Watt-Achse, und
   eine zweite Achse im selben Bild ist die bequeme Luege: man kann die
   Kurven durch Skalierung beliebig zum Schneiden bringen.
--------------------------------------------------------------------- */
.karte-tippbar { cursor: pointer; transition: border-color var(--tempo); }
.karte-tippbar:hover { border-color: var(--rand-hell); }
.karte-tippbar:focus-visible { outline: 3px solid var(--auto); outline-offset: 3px; }

.verlauf-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap; margin-bottom: 4px;
}
.verlauf-kopf h3 { margin: 0; }

.zeitwahl { display: flex; gap: 8px; }
.zeitknopf {
  font: inherit; font-size: 15px;
  min-height: 44px; padding: 0 18px;
  border-radius: 999px;
  border: 1px solid var(--rand-hell);
  background: var(--flaeche);
  color: var(--text-2);
  cursor: pointer;
}
.zeit-aktiv {
  background: var(--flaeche-2);
  color: var(--text);
  font-weight: 600;
  border-color: var(--rand-hell);
}

.verlauf-huelle { margin-top: 10px; }
.verlauf-bild { display: block; width: 100%; height: auto; touch-action: pan-y; }
.verlauf-untertitel { margin-top: 22px !important; }

.gitter-linie { stroke: var(--rand); stroke-width: 1; }
.gitter-null  { stroke: var(--rand-hell); stroke-width: 1.6; }
.gitter-text  { fill: var(--text-3); font-size: 17px; text-anchor: end;
                font-variant-numeric: tabular-nums; }
.verlauf-gitter text[text-anchor="middle"],
.verlauf-gitter text[text-anchor="start"] { text-anchor: inherit; }

/* Duenne Linien: die Kurve ist die Aussage, nicht ihre Dicke. */
.verlauf-linie { fill: none; stroke-width: 2.4; stroke-linejoin: round;
                 stroke-linecap: round; }
.verlauf-flaeche { fill: var(--sonne); opacity: .13; stroke: none; }
.verlauf-akkuflaeche { fill: var(--akku); opacity: .13; stroke: none; }
.verlauf-strich { stroke: var(--rand-hell); stroke-width: 1.6;
                  stroke-dasharray: 4 5; }
.verlauf-kugel { stroke: var(--tief); stroke-width: 2; }

/* Die Ablesezeile ist die Legende UND der Messwert an der Fingerstelle.
   Zwei getrennte Dinge dafuer waeren zwei Dinge zu viel. */
.ablesezeile {
  display: flex; flex-wrap: wrap; gap: 8px 20px;
  align-items: baseline;
  min-height: 30px;
  font-size: 16px;
  color: var(--text-2);
  margin-top: 8px;
}
.ablese-zeit { font-weight: 600; color: var(--text); min-width: 96px; }
.ablese-wert { display: inline-flex; align-items: baseline; gap: 7px; }
.ablese-punkt {
  width: 11px; height: 11px; border-radius: 50%;
  display: inline-block; transform: translateY(1px);
}
.ablese-name { color: var(--text-3); }
.ablesezeile b { color: var(--text); font-weight: 600; }


/* ======================================================================
   Erweiterte Ansicht
   ====================================================================== */

/* Reiter innerhalb der erweiterten Ansicht. Bewusst keine zweite
   Fussleiste: die untere Leiste sagt, wo man im Haus ist, diese Reihe
   sagt, was man hier gerade aufhat. Zwei Leisten mit derselben Optik
   waeren nicht auseinanderzuhalten. */
.reiterreihe {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.reiter-knopf {
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  padding: 11px 20px;
  border-radius: 999px;
  border: 1px solid var(--rand);
  background: var(--flaeche);
  color: var(--text-2);
  cursor: pointer;
  transition: background var(--tempo), color var(--tempo);
}
.reiter-knopf:hover { background: var(--flaeche-2); }
.reiter-an {
  background: var(--flaeche-2);
  border-color: var(--rand-hell);
  color: var(--text);
}
.reiter-knopf:focus-visible { outline: 3px solid var(--auto); outline-offset: 2px; }

/* Freiraum unter dem Inhalt, damit die schwebende Fussleiste nichts
   verdeckt.

   Das stand bis zum 07.09.2026 NUR im Medienblock fuer schmale
   Bildschirme. Hochkant auf dem Wandtablet ging es trotzdem auf, weil
   die Seite genau 1024 hoch ist und die Kachelreihe darueber endete -
   das war Glueck, nicht Absicht. Quer auf 1280x800 lag die Leiste ueber
   den vier Zahlen der Kachelreihe, und niemand konnte sie lesen.

   Die Leiste ist rund 70 px hoch und sitzt 14 px ueber dem Rand, dazu
   der sichere Bereich des Geraets. */
main {
  padding-bottom: calc(104px + env(safe-area-inset-bottom));
}

/* Quer auf einem Wandtablet muss die Startseite OHNE Scrollen
   aufgehen.

   Gemessen am 07.09.2026 bei 1280x800: Kopf 150 + Flussbild 509 +
   Kachelreihe 119 ergeben mit den Abstaenden 995 Pixel Seitenhoehe.
   Nutzbar sind aber nur rund 711 - die schwebende Fussleiste braucht
   die unteren 89. Also lagen die vier Zahlen der Kachelreihe hinter
   der Leiste, und man musste scrollen, um den Ertrag des Tages zu
   sehen. Hochkant ging es auf, weil die Seite dort genau 1024 hoch
   ist; das war Glueck, nicht Absicht.

   54vh sind bei 800 Pixel Hoehe 432 - zu viel. Auf niedrigen, breiten
   Bildschirmen wird das Bild deshalb kleiner, damit die Zahlen darunter
   ins Bild passen. Ein Wandtablet zeigt nichts, wozu man wischen muss. */
@media (orientation: landscape) and (max-height: 900px) {
  #fluss { max-height: 42vh; }
}

/* Mehrere Sammelknoepfe nebeneinander, auf schmalen Geraeten
   untereinander - nie halb abgeschnitten. */
.knopfreihe {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 14px;
}

/* Ein Sammelknopf, der nachfragt. Warm eingefaerbt, damit der zweite
   Druck als das gelesen wird, was er ist: die Ausfuehrung. */
.schalter-frage {
  background: color-mix(in srgb, var(--warm) 24%, transparent);
  border-color: color-mix(in srgb, var(--warm) 60%, transparent);
  color: var(--warm);
}

/* Geraete- und Suchergebnisliste. Dieselbe Zeilenform wie bei den
   Lampen - wer die eine lesen kann, kann die andere auch. */
.geraeteliste { margin-top: 12px; }
.geraetzeile {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid var(--rand);
  flex-wrap: wrap;
}
.geraetzeile:last-child { border-bottom: 0; }
.geraetzeile-text { flex: 1 1 200px; min-width: 0; }
.geraetzeile .pille { margin-left: auto; }

/* In den schmalen Spalten der erweiterten Ansicht brach "15 °C" auf
   zwei Zeilen um - die Zahl stand dann ueber der Einheit und las sich
   wie zwei Werte. */
.erweitert-inhalt .steller-zahl { white-space: nowrap; }
.erweitert-inhalt .steller { margin: 22px 0 6px; }

/* Auswahlfeld und Knopf in der Netzwerksuche brauchen Luft - sonst
   kleben sie aneinander und sehen aus wie ein Bedienelement. */
.erweitert-inhalt select.eingabe { margin: 14px 0; width: 100%; }
.erweitert-inhalt .karte > .schalter { margin-top: 4px; }

/* Zwei Ausgaenge in einem Kasten: der Abstand zwischen Knopf und
   naechstem Absatz muss groesser sein als der zwischen Absatz und
   seinem Knopf - sonst liest man die falsche Beschreibung zum Knopf. */
.karte.block > .schalter + .lampe-unter { margin-top: 26px; }
.karte.block > .lampe-unter + .schalter { margin-top: 10px; }

/* Wohin der Strom geht. Gestapelt ist hier richtig und sonst selten:
   die Teile ergeben zusammen genau den Hausverbrauch, und diese Summe
   ist die Aussage. */
.modus-wahl { margin-top: 12px; }
.stapel-gemessen { opacity: .82; stroke: none; }
/* Die Restgroesse ist schraffiert, nicht voll: sie ist eine Differenz,
   keine Messung, und das soll man sehen, bevor man es liest. */
.stapel-rest { opacity: .38; stroke: none; }

.boiler-band {
  fill: var(--warm);
  opacity: .10;
  stroke: var(--warm);
  stroke-opacity: .34;
  stroke-width: 1;
  stroke-dasharray: 5 4;
}
.boiler-text {
  fill: var(--warm);
  font-size: 17px;
  opacity: .9;
}

/* Das PIN-Feld der Benutzerverwaltung steht oben und gilt fuer die
   ganze Karte - einmal eintippen, dann arbeiten. Dreimal denselben PIN
   tippen erzieht nur dazu, ihn irgendwo aufzuschreiben. */
.pin-oben { margin-bottom: 4px; }


/* ======================================================================
   Statistik je Raum (raumstatistik.js)
   ====================================================================== */

/* Eigene Klassennamen mit rk-, damit sie sich mit den Diagrammklassen
   der Verlaufsansicht nicht ins Gehege kommen. Das ist ein anderes
   Bild mit einer anderen Aufgabe: ein Raum statt des ganzen Hauses. */
.raumkurve {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 6px;
  overflow: visible;
}
.rk-gitter { stroke: var(--rand); stroke-width: 1; }
.rk-achse {
  fill: var(--text-3);
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

.rk-legende {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  margin-top: 10px;
  font-size: 14px;
  color: var(--text-2);
}
.rk-legende-eintrag { display: flex; align-items: center; gap: 7px; }
.rk-legende-punkt {
  width: 10px; height: 10px;
  border-radius: 3px;
  flex: 0 0 auto;
}

/* Die Statistik nimmt die ganze Breite, auch wenn Waerme und Licht
   daneben in Spalten stehen. Eine Kurve in einem Drittel einer
   Tabletbreite ist nicht mehr abzulesen - und Ablesen ist ihr ganzer
   Zweck. */
.raumstatistik { grid-column: 1 / -1; }

/* Die Messwerte darunter nebeneinander statt untereinander: es sind
   sieben Zeilen, und die Karte ist breit. */
.raumstatistik .thermo-neben {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0 clamp(16px, 3vw, 40px);
}

/* Die Restgroesse ist schraffiert, nicht nur blasser. Ein
   Deckkraftunterschied bedeutet fuer jeden Menschen "unwichtig", nicht
   "gerechnet" - und aus zwei Metern ist er gar nicht zu sehen. */
.stapel-rest { opacity: 1; stroke: none; }

/* Zeit ohne aufgezeichnete Ladeleistung. Dort wird KEINE Null
   gestapelt - das Bild wuerde sonst rueckwirkend behaupten, es habe
   kein Auto geladen. */
.luecke-band {
  fill: var(--text-3);
  opacity: .07;
  stroke: var(--text-3);
  stroke-opacity: .22;
  stroke-width: 1;
  stroke-dasharray: 3 5;
}

/* --- Bilanz -----------------------------------------------------------
   Die Frage "wie viel war es zusammen" beantwortet keine Kurve. Zahlen
   in einer Spalte, rechts ausgerichtet, mit Tabellenziffern - damit man
   sie untereinander vergleichen kann, ohne zu zielen.
--------------------------------------------------------------------- */
.bilanz { margin-top: 10px; }
.bilanz-zeile {
  display: grid;
  grid-template-columns: minmax(140px, 1fr) auto;
  grid-template-areas: "marke wert" "zusatz zusatz";
  gap: 2px 16px;
  align-items: baseline;
  padding: 11px 0;
  border-bottom: 1px solid var(--rand);
  font-size: 17px;
}
.bilanz-zeile:last-of-type { border-bottom: 0; }
.bilanz-marke  { grid-area: marke; color: var(--text-2); }
.bilanz-wert   { grid-area: wert; font-weight: 600; font-size: 19px;
                 font-variant-numeric: tabular-nums; }
.bilanz-zusatz { grid-area: zusatz; color: var(--text-3); font-size: 14px; }
.bilanz-zusatz:empty { display: none; }

/* Farbe wie im Strombild, damit man nichts neu lernen muss. Sie traegt
   nie allein: die Marke sagt in Worten, was gemeint ist. */
.bilanz-gabe  .bilanz-wert { color: var(--netz-gabe); }
.bilanz-bezug .bilanz-wert { color: var(--netz-bezug); }
.bilanz-sonne .bilanz-wert { color: var(--sonne); }
.bilanz-akku  .bilanz-wert { color: var(--akku); }
.bilanz-auto  .bilanz-wert { color: var(--auto); }

.bilanz-trenner { height: 14px; }

/* --- Energiekarte (energie.js) ---------------------------------------- */
/* Vier Reiter in einer Zeile, auch am Handy - ein umgebrochener
   "Jahr"-Knopf sieht aus wie etwas anderes. */
.energie-reiter { margin-top: 2px; flex-wrap: nowrap; gap: 6px; }
.energie-reiter .reiter-knopf { flex: 1 1 0; min-width: 0; padding: 10px 6px; }
.energie-kopf { align-items: center; flex-wrap: nowrap; }
.energie-kopf .schalter { min-width: 48px; padding: 9px 14px; flex: none; }
.energie-kopf .geraetzeile-text { text-align: center; }

.energie-zahlen {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px 18px;
  margin: 18px 0 6px;
}
.energie-marke { color: var(--text-2); font-size: 15px; display: flex;
                 align-items: center; gap: 8px; }
.energie-punkt { width: 11px; height: 11px; border-radius: 50%;
                 display: inline-block; flex: none; }
.energie-wert  { font-size: clamp(22px, 3.2vw, 30px); font-weight: 600;
                 color: var(--text); margin-top: 2px;
                 font-variant-numeric: tabular-nums; }
.energie-zusatz { color: var(--text-3); font-size: 13px; margin-top: 2px; }
@media (max-width: 560px) {
  .energie-zahlen { grid-template-columns: 1fr; gap: 10px; }
  .energie-zahl { display: grid; grid-template-columns: 1fr auto;
                  column-gap: 12px; align-items: baseline; }
  .energie-wert { margin: 0; font-size: 22px; }
  .energie-zusatz { grid-column: 1 / -1; }
}

.energie-flaeche { margin-top: 14px; width: 100%; }
.energie-bild { display: block; width: 100%; height: auto; overflow: visible; }
.energie-gitter { stroke: var(--rand); stroke-width: 1; }
.energie-null   { stroke: var(--rand-hell); stroke-width: 1; }
.energie-achse  { fill: var(--text-3); font-size: 11px;
                  font-variant-numeric: tabular-nums; }
.energie-blass  { opacity: .45; }
.energie-treffer { fill: transparent; cursor: pointer; }
.energie-marke-fach { fill: var(--rand); }
.energie-legende { margin-top: 6px; }
.energie-ablese { min-height: 26px; margin-top: 4px; font-size: 15px; }

.energie-tabelle { margin-top: 12px; }
.energie-tabelle summary { cursor: pointer; color: var(--text-2);
                           font-size: 15px; padding: 8px 0; }
.energie-tabelle-huelle { overflow-x: auto; }
.energie-tabelle table { border-collapse: collapse; width: 100%;
                         font-size: 14px; font-variant-numeric: tabular-nums; }
.energie-tabelle th, .energie-tabelle td {
  padding: 6px 8px; border-bottom: 1px solid var(--rand);
  text-align: right; white-space: nowrap;
}
.energie-tabelle th:first-child { text-align: left; }
.energie-tabelle thead th { color: var(--text-3); font-weight: 500; }
.energie-tabelle tbody th { font-weight: 400; color: var(--text-2); }
.energie-fuss { margin-top: 12px; }

/* [hidden] MUSS GEWINNEN.
 *
 * Der Browser bringt zwar "[hidden] { display: none }" mit, aber das
 * steht in der UA-Regel und verliert gegen jede eigene Regel mit
 * display. .knopfreihe hat display:flex - also blieb ein
 * el.hidden = true wirkungslos, und die zugeklappte Verbraucherliste
 * zeigte ihre Knoepfe trotzdem.
 *
 * Am 07.09.2026 im Browser gesehen, nicht vermutet: Die Karte war
 * zugeklappt, "Gang alles aus" stand darunter.
 */
[hidden] { display: none !important; }

/* --- Aufklappbarer Kartentitel --------------------------------------
 *
 * Der Titel IST der Schalter. Kein zusaetzliches Symbol daneben, das
 * man treffen muss - auf einem Wandtablet mit dem Daumen ist die
 * ganze Zeile die Flaeche.
 *
 * h3-Groesse, damit die Karte aussieht wie jede andere: Dass hier
 * etwas aufgeht, verraet der Pfeil, nicht eine fremde Schriftart.
 */
.aufklapp {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 0;
  margin: 0 0 6px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: 17px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  min-height: 44px;          /* Daumenbreite, nicht Zeigerbreite */
}

.aufklapp-pfeil {
  display: inline-block;
  width: 14px;
  color: var(--text-3);
  font-size: 13px;
}

.aufklapp:active { opacity: .7; }


/* =====================================================================
   DER HELLE TAG - die Regeln, die den Grundstil ueberschreiben.
   =====================================================================

   Sie stehen AM ENDE und nicht oben bei den Variablen, und das ist kein
   Ordnungsgeschmack, sondern die Ursache eines Fehlers vom 11.09.2026:
   Zuerst standen sie oben, verloren dort gegen die spaeteren
   Grundregeln gleicher Staerke - und der helle Bildschirm zeigte den
   dunklen Galaxiehimmel mit heller Karte darauf. Unlesbar und haesslich
   zugleich.

   Variablen duerfen oben stehen; sie wirken ueber die Vererbung. Ganze
   Regeln muessen nach hinten.
   ===================================================================== */
@media (prefers-color-scheme: light) {
  /* DIESELBE ZEICHNUNG, ANDERE STIMMUNG.
   *
   * Der Galaxiehintergrund ist dunkel; die Schrift ist hier aber
   * dunkel. Ohne diese Regel stuende schwarz auf schwarz - der
   * Hell-Modus waere unbrauchbar geworden.
   *
   * Ein heller Schleier ueber der dunklen Zeichnung war der erste
   * Versuch und wurde grau: Der Verlauf von #191A29 nach #269CD9 wird
   * unter Weiss nicht hell, er wird schmutzig, und das Netz verschwand
   * ganz. Am 11.09.2026 am Bildschirm gesehen.
   *
   * Deshalb eine ZWEITE Zeichnung, galaxie-hell.svg: dieselben Knoten,
   * aber ohne Grund und mit kraeftigeren Linien - auf Weiss traegt eine
   * Linie mit 20 % Deckkraft nicht. Im Dunkeln leuchtet das Netz aus
   * dem Grund heraus, im Hellen liegt es als feine Zeichnung darauf.
   * Zwei Aufgaben, zwei Dateien.
   *
   * Das trifft auch die Vorlage aus dem Foto vom 11.09.2026: Die ist
   * selbst hell und lebt von Luft. */
  .himmel {
    background:
      url("galaxie-hell.svg") center / cover no-repeat,
      linear-gradient(160deg, #f7fafe 0%, var(--tief) 48%, #e3ecf9 100%);
  }

  /* Die Lichtkante auf den Karten wuerde auf Weiss verschwinden. Im
     Hellen traegt stattdessen ein zarter blauer Strich - dieselbe
     Aufgabe, andere Richtung. */
  .karte::before {
    background: linear-gradient(90deg,
      transparent, rgba(28, 124, 176, .30), transparent);
  }

  .karte {
    background:
      linear-gradient(180deg,
        rgba(255, 255, 255, .88) 0%,
        rgba(255, 255, 255, .78) 100%);
  }

  .kachel {
    background:
      linear-gradient(180deg,
        rgba(255, 255, 255, .90) 0%,
        rgba(255, 255, 255, .76) 100%);
  }

  .kachel:hover { border-color: rgba(28, 124, 176, .32); }

  /* Die Anmeldung im Hellen - derselbe Schleier wie bei .himmel. */
  .pin-huelle {
    background:
      url("galaxie-hell.svg") center / cover no-repeat,
      linear-gradient(160deg, #f7fafe 0%, var(--tief) 48%, #e3ecf9 100%);
  }

  .pin-karte {
    background:
      linear-gradient(180deg,
        rgba(255, 255, 255, .92) 0%,
        rgba(255, 255, 255, .82) 100%);
  }
}
