/*
 * Stylesheet des Wetterstation-Dashboards (index.php) – Karten-Layout mit weichem
 * Schatten, heller/dunkler Theme-Umschalter. Eigener Variablen-/Klassen-Namensraum
 * (Präfix "--app-" bzw. ".app-"). Ziel-Geräte: iPhone/iPad/MacBook, eine responsive
 * Ansicht für alle drei. Ergänzt assets/css/weather-icons.css (Wetter-Icon-Font).
 *
 * Historie: hervorgegangen aus dem früheren "Cards"-Entwurf (assets/css/cards.css,
 * Namensraum "--cc-"/".cc-"); mit der Release-Umstellung am 2026-07-10 zu app.css /
 * "--app-"/".app-" umbenannt und alleiniges Dashboard-Stylesheet geworden.
 */

:root{
  --app-bg:#eef1f6; --app-card:#ffffff; --app-card-soft:#f4f6fb;
  --app-line:#eef0f4; --app-text:#161a24; --app-muted:#8a93a6; --app-muted-2:#b7bec9;
  --app-shadow: 0 1px 2px rgba(16,24,40,.04), 0 12px 28px rgba(16,24,40,.07);
  --app-accent:#3169ff; --app-accent-soft:rgba(49,105,255,.10); --app-accent-ink:#ffffff;

  --app-frost:#7a4fd0; --app-cold:#4aa8ff; --app-good:#3ecf8e; --app-warm:#ffb454; --app-hot:#ff6b6b;
  --app-hum:#4aa8ff;

  /* Wetter-Zustands-Icons (wx_icon()) fest je Tag/Nacht, temperaturunabhängig – wie in
     index.php (--wx-day/--wx-night), aber theme-abhängig (Hell/Dunkel-Umschalter). Dunkles
     Theme = identisch zu index.php (Tag weiß, Nacht bläulich); helles Theme = wärmerer/
     dunklerer Tag-Ton, da Weiß auf der hellen Karte unsichtbar wäre. Siehe app_wx_color(). */
  --app-wx-day:#e0920c; --app-wx-night:#5b6ba3;

  /* Langzeitverlauf (Monat/Jahr, .app-chartpanel-long): Ø-Linie in einem festen, neutralen
     Dunkelgrau statt einer Akzentfarbe – bewusst nicht im Hell/Dunkel-Theme-Block neu
     definiert, da derselbe Farbton auf weißem UND dunklem Kartenhintergrund lesbar bleibt
     (anders als z.B. --app-text, das je Theme fast schwarz/fast weiß wird). */
  --app-avgline:#4b5563;

  /* Fünf-Bänder-Skala für den Luftfeuchte-Gauge (.app-gaugebar, siehe dort): sehr trocken/
     trocken nutzen zwei Orange-Töne (dunkler = kritischer), feucht/sehr feucht analog zwei
     Blau-Töne – --app-warm/--app-good/--app-cold decken die mittleren drei Bänder bereits ab. */
  --app-hum-vdry:#c1650a; --app-hum-vhumid:#1f4e8c;

  /* Zusätzliche Zwischentöne für den Luftqualitäts-Gauge (.app-gaugebar.aqi, sechs EAQI-
     Bänder analog wx_aqi_label()): gut/mittel/schlecht nutzen die bereits vorhandenen
     --app-good/--app-warm/--app-hot, nur Gelb (mäßig) sowie Lila/Weinrot (sehr schlecht/
     extrem schlecht) sind neu – Farbfamilie an die offizielle AQI-Skala (aqicn.org/scale/de)
     angelehnt, Töne aber ans bestehende Design angepasst statt 1:1 übernommen. */
  --app-aqi-yellow:#e8c94a; --app-aqi-purple:#9b5fc0; --app-aqi-maroon:#7a2748;

  --app-radius-s:12px; --app-radius-m:18px; --app-radius-l:22px; --app-radius-full:999px;

  --app-sans:-apple-system,"SF Pro Text","SF Pro Display",system-ui,"Segoe UI",Roboto,sans-serif;
  --app-mono:"SF Mono",ui-monospace,Menlo,Consolas,monospace;
}

html[data-theme="dark"]{
  --app-bg:#11141d; --app-card:#1a1e29; --app-card-soft:#20242f;
  --app-line:#262b38; --app-text:#eef1f6; --app-muted:#8b93a5; --app-muted-2:#4d5566;
  --app-shadow: 0 1px 2px rgba(0,0,0,.35), 0 14px 32px rgba(0,0,0,.4);
  --app-accent:#5b8bff; --app-accent-soft:rgba(91,139,255,.18); --app-accent-ink:#0d1017;
  --app-wx-day:#ffffff; --app-wx-night:#7c8fc9;
}
@media (prefers-color-scheme: dark){
  html:not([data-theme="light"]){
    --app-bg:#11141d; --app-card:#1a1e29; --app-card-soft:#20242f;
    --app-line:#262b38; --app-text:#eef1f6; --app-muted:#8b93a5; --app-muted-2:#4d5566;
    --app-shadow: 0 1px 2px rgba(0,0,0,.35), 0 14px 32px rgba(0,0,0,.4);
    --app-accent:#5b8bff; --app-accent-soft:rgba(91,139,255,.18); --app-accent-ink:#0d1017;
    --app-wx-day:#ffffff; --app-wx-night:#7c8fc9;
  }
}

*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0; min-height:100vh; background:var(--app-bg); color:var(--app-text);
  font-family:var(--app-sans); -webkit-font-smoothing:antialiased;
  transition:background .2s ease, color .2s ease;
}
.tnum{font-variant-numeric:tabular-nums}

/* ---------- Topbar: Marke + Raum-Menü (statt Suchleiste) + Hell/Dunkel-Schalter ---------- */
.app-topbar{
  display:flex; align-items:center; gap:18px; padding:14px 20px; max-width:1280px; margin:0 auto;
}
.app-brand{display:flex; align-items:center; gap:8px; font-weight:700; font-size:16px; flex:0 0 auto; color:var(--app-text)}
.app-brand svg{width:20px; height:20px; stroke:var(--app-accent)}

.app-menu{
  flex:1 1 auto; display:flex; gap:4px; overflow-x:auto; scrollbar-width:none;
  background:var(--app-card); border-radius:var(--app-radius-full); padding:5px; box-shadow:var(--app-shadow);
}
.app-menu::-webkit-scrollbar{display:none}
.app-menuitem{
  flex:0 0 auto; display:flex; align-items:center; gap:6px; font-family:var(--app-sans); font-size:13.5px;
  color:var(--app-muted); background:transparent; border:0; border-radius:var(--app-radius-full);
  padding:8px 16px; cursor:pointer; white-space:nowrap; transition:background .15s, color .15s;
}
.app-menuitem svg{width:16px; height:16px; stroke:currentColor}
.app-menuitem.active{background:var(--app-accent); color:var(--app-accent-ink)}
.app-menuitem:not(.active):hover{background:var(--app-card-soft); color:var(--app-text)}

.app-themebtn{
  flex:0 0 auto; display:flex; align-items:center; gap:7px; font-family:var(--app-sans); font-size:13px;
  color:var(--app-text); background:var(--app-card); border:0; border-radius:var(--app-radius-full);
  padding:9px 15px; cursor:pointer; box-shadow:var(--app-shadow);
}
.app-themebtn svg{width:16px; height:16px; stroke:currentColor}

/* ---------- Grundgerüst ---------- */
.app-wrap{max-width:1280px; margin:0 auto; padding:6px 20px 40px}
.app-tabsection{display:none}
.app-tabsection.active{display:grid; grid-template-columns:1fr; gap:16px; animation:app-in .25s ease}
/* Grid-Spalten schrumpfen ohne min-width:0 standardmäßig nicht unter den Inhalt der Kinder
   (.app-col / .app-chartpanel) – ein einzelnes unschrumpfbares Element darin (z.B. eine
   lange Zeile ohne Umbruch) hätte sonst die ganze Spalte und damit die Seite in die Breite
   gedrückt (Ursache des gemeldeten Overflow auf schmalen Handy-Breiten, betraf mehrere Karten
   gleichzeitig, da sie alle in derselben zu breit gewordenen Spalte steckten). */
.app-tabsection.active > *{min-width:0}
@keyframes app-in{from{opacity:0; transform:translateY(6px)}to{opacity:1; transform:none}}
@media (min-width:980px){
  .app-tabsection.active{grid-template-columns:minmax(300px,420px) 1fr; align-items:start}
}
.app-card{
  background:var(--app-card); border-radius:var(--app-radius-l); box-shadow:var(--app-shadow); padding:20px;
}
.app-col{display:flex; flex-direction:column; gap:16px}
.app-col > *{min-width:0}

/* ---------- Aktuelles Wetter / Raum-Hero ---------- */
.app-hero .hd{display:flex; align-items:center; justify-content:space-between; margin-bottom:14px}
.app-hero .hd .ttl{font-size:14px; color:var(--app-muted)}
.app-now{display:flex; align-items:center; gap:16px}
.app-now .icon{flex:0 0 auto; display:flex; align-items:center; color:var(--app-warm); line-height:1}
.app-now .big{font-size:44px; font-weight:700; letter-spacing:-.02em; line-height:1}
.app-now .big .u{font-size:20px; font-weight:500; color:var(--app-muted); margin-left:2px}
.app-now .cond{font-size:14.5px; color:var(--app-text); margin-top:2px}
.app-now .feels{font-size:12.5px; color:var(--app-muted); margin-top:2px}
.app-desc{font-size:13.5px; color:var(--app-muted); line-height:1.5; margin-top:14px; padding-top:14px; border-top:1px solid var(--app-line)}

.app-chip{
  display:inline-flex; align-items:center; gap:5px; font-family:var(--app-mono); font-size:10px;
  letter-spacing:.3px; text-transform:uppercase; padding:3px 9px; border-radius:var(--app-radius-full);
  background:var(--app-card-soft); color:var(--app-muted);
}
.app-chip.calc{color:#c9821f}
.app-chip.meas{color:#1e9d68}
html[data-theme="dark"] .app-chip.calc{color:var(--app-warm)}
html[data-theme="dark"] .app-chip.meas{color:var(--app-good)}
@media (prefers-color-scheme:dark){
  html:not([data-theme="light"]) .app-chip.calc{color:var(--app-warm)}
  html:not([data-theme="light"]) .app-chip.meas{color:var(--app-good)}
}

/* ---------- Kachel-Grid (Wind/Luftfeuchte/…) ---------- */
.app-grid{display:grid; grid-template-columns:repeat(3, 1fr); gap:12px}
@media (max-width:560px){.app-grid{grid-template-columns:repeat(2, 1fr)}}
.app-tile{padding:15px}

/* Sechs-Spalten-Variante nur für die Außen-Kacheln Wind/Sichtweite/Luftfeuchte/Luftdruck/
   Luftqualität/Gefühlt: Wind, Luftfeuchte und Luftqualität brauchen durch Kompass/
   Gradient-Gauge/Richtungsdetail spürbar mehr Platz und werden auf Nutzerwunsch doppelt so
   breit wie die übrigen drei (span 4 von 6 Spalten statt span 2 = exakt Faktor 2). Eigene
   Klasse statt der Basis-.app-grid, da .app-grid auch für andere auto-fit-Kachelraster (DWD-
   Zeile, Raum-Kacheln) genutzt wird, die diese feste Spaltenaufteilung nicht bekommen sollen.
   Beide Regeln als .app-grid.app-grid-metrics (Klassen-Kombination) geschrieben, damit sie die
   Basis-.app-grid-Regel unabhängig von der Reihenfolge im Stylesheet sicher überschreiben. */
.app-grid.app-grid-metrics{grid-template-columns:repeat(6, 1fr)}
.app-grid.app-grid-metrics .app-tile{grid-column:span 2}
.app-grid.app-grid-metrics .app-tile-wide{grid-column:span 4}
@media (max-width:700px){
  .app-grid.app-grid-metrics{grid-template-columns:1fr}
  .app-grid.app-grid-metrics .app-tile, .app-grid.app-grid-metrics .app-tile-wide{grid-column:span 1}
}

/* Wind-Kachel: Textzeilen (Wind/Windböen/Richtung) links, Kompass-SVG rechts (app_wind_compass()
   in index-cards.php, Designvorlage idea_images/wind.png). */
.app-wind-body{display:flex; align-items:center; gap:14px; margin-top:2px}
.app-wind-rows{flex:1 1 auto; display:flex; flex-direction:column; gap:9px; min-width:0}
.app-wind-rows .r{display:flex; justify-content:space-between; align-items:baseline; gap:10px; font-size:13px}
.app-wind-rows .r .k{color:var(--app-muted)}
.app-wind-rows .r .v{font-weight:600; white-space:nowrap}
.app-wind-compass{flex:0 0 auto; width:100px; height:100px}
.app-wind-compass svg{width:100%; height:100%; overflow:visible}
.app-compass-ring{fill:none; stroke:var(--app-line); stroke-width:2}
.app-compass-tick{stroke:var(--app-muted-2); stroke-width:2}
.app-compass-cd{font-family:var(--app-mono); font-size:10px; font-weight:600; fill:var(--app-muted)}
.app-compass-arrow{stroke:var(--app-accent); stroke-width:2.5; stroke-linecap:round}
.app-compass-arrowhead{fill:var(--app-accent)}
.app-compass-dot{fill:var(--app-warm); stroke:var(--app-card); stroke-width:2}
.app-compass-val{font-family:var(--app-sans); font-size:18px; font-weight:700; fill:var(--app-text)}
.app-compass-unit{font-family:var(--app-mono); font-size:9px; fill:var(--app-muted)}

/* Wind als volle Karte (seit 2026-07-10, auf Nutzerwunsch aus dem Kachelraster herausgelöst und
   über die Sonnenverlauf-Karte gesetzt – damit Textzeilen + Kompass nicht in der halbbreiten
   Kachel gedrängt wirken). Kopf im selben Icon+Titel-Stil wie die Kacheln (.app-tile .lbl) bzw.
   die Sonnenverlauf-Karte; .app-windcard ist keine .app-tile, daher eine eigene, inhaltsgleiche
   Kopf-Kopie. Körper zentriert mit großzügigem Abstand, Kompass etwas größer als in der Kachel. */
.app-windcard .lbl{display:flex; align-items:center; gap:7px; font-size:12px; color:var(--app-muted); margin-bottom:2px}
.app-windcard .lbl .ic{width:26px; height:26px; border-radius:var(--app-radius-full); background:var(--app-card-soft);
  display:flex; align-items:center; justify-content:center; flex:0 0 auto}
.app-windcard .lbl svg{width:14px; height:14px; stroke:currentColor}
/* Körper wie die Sonnenverlauf-Karte aufgebaut (Textzeilen nehmen die linke Restbreite, Kompass
   fest rechts) statt fester Mindestbreiten – so bleibt es in der schmalen linken Spalte nebeneinander
   statt umzubrechen (der Kompass rutschte sonst unter die Zeilen). Auf echten Handy-Breiten bricht es
   dank flex-wrap trotzdem um (Zeilen über Kompass). */
.app-windcard .app-wind-body{gap:16px; margin-top:14px; flex-wrap:wrap}
.app-windcard .app-wind-rows{flex:1 1 auto; min-width:0}
.app-windcard .app-wind-compass{flex:0 0 auto; width:112px; height:112px}
.app-tile .lbl{display:flex; align-items:center; gap:7px; font-size:12px; color:var(--app-muted); margin-bottom:8px}
.app-tile .lbl .ic{width:26px; height:26px; border-radius:var(--app-radius-full); background:var(--app-card-soft);
  display:flex; align-items:center; justify-content:center; flex:0 0 auto}
.app-tile .lbl svg{width:14px; height:14px; stroke:currentColor}
.app-tile .val{font-size:21px; font-weight:700}
.app-tile .val .u{font-size:13px; font-weight:500; color:var(--app-muted); margin-left:1px}
/* Bandlabel neben dem Luftfeuchte-%-Wert (z.B. "45 %  ideal"), siehe app_hum_band()/humBand() */
.app-tile .val .app-hum-band{font-size:12.5px; font-weight:500; color:var(--app-muted); margin-left:9px}
/* Erläuternde Zusatzzeile unter dem Kachel-Hauptwert (z.B. Regenwahrscheinlichkeit-Kontext
   in der Niederschlag-Kachel) – kleiner und gedämpft, eigene Zeile statt neben dem Wert. */
.app-tile .app-tile-sub{font-size:11.5px; color:var(--app-muted); margin-top:7px; line-height:1.4}

/* Segmentierter Luftfeuchte-Gauge (Detail übernommen aus einer der Referenz-Ideen) – macht
   den Zustand auf einen Blick sichtbar, nicht nur als nackte Zahl. Fünf Bänder statt eines
   generischen gut/normal/schlecht-Verlaufs, da .app-gaugebar aktuell ausschließlich für
   Luftfeuchte genutzt wird (Außen- und Raum-Kacheln): 0–30 % sehr trocken, 30–40 % trocken,
   40–60 % ideal, 60–70 % feucht, 70–100 % sehr feucht. Farbstopps sitzen bewusst auf der
   jeweiligen Bandmitte statt an den Bandgrenzen (mit doppeltem Stop = harter Kante) – so
   gehen die Bänder fließend ineinander über (Nutzerwunsch), nur die beiden äußersten Enden
   bleiben auf kurzer Strecke flach, damit 0 % und 100 % nicht schon mitten in der
   Übergangsfarbe zur Nachbarfarbe liegen. */
.app-gaugebar{position:relative; height:7px; border-radius:99px; margin-top:10px;
  background:linear-gradient(90deg,
    var(--app-hum-vdry) 0%, var(--app-hum-vdry) 15%, var(--app-warm) 35%, var(--app-good) 50%,
    var(--app-cold) 65%, var(--app-hum-vhumid) 85%, var(--app-hum-vhumid) 100%); opacity:.9}
.app-gaugebar .dot{position:absolute; top:50%; width:11px; height:11px; border-radius:50%; background:var(--app-text);
  border:2px solid var(--app-card); transform:translate(-50%,-50%)}

/* Luftqualitäts-Variante desselben Gauges (.app-gaugebar.aqi) – sechs EAQI-Bänder analog
   wx_aqi_label() (<=20 gut … >100 extrem schlecht), Farbstopps wieder auf Bandmitte statt
   -grenze für fließende Übergänge (siehe Kommentar oben). Der letzte Stop (Weinrot) sitzt
   bewusst auf 100 % als Anker für "extrem schlecht" (>100, außerhalb der 0–100-Skala) – der
   Positions-Punkt wird serverseitig auf 100 % geklemmt (siehe app_gaugebar-Aufruf in
   index-cards.php), das Ende der Leiste zeigt also "aus der Skala heraus", nicht falsch hoch. */
.app-gaugebar.aqi{background:linear-gradient(90deg,
    var(--app-good) 0%, var(--app-good) 10%, var(--app-aqi-yellow) 30%, var(--app-warm) 50%,
    var(--app-hot) 70%, var(--app-aqi-purple) 90%, var(--app-aqi-maroon) 100%)}

/* UV-Index-Variante desselben Gauges (.app-gaugebar.uv) – fünf WHO-UV-Bänder analog
   wx_uv_label() (<3 niedrig … 11+ extrem), Skala auf einen Referenz-Höchstwert von 12
   normiert (Positions-Punkt/Farbstopps in index-cards.php entsprechend auf 0–100 %
   umgerechnet). Keine neuen Farbtöne nötig – die WHO-Skala (grün/gelb/orange/rot/violett)
   deckt sich mit den bereits vorhandenen fünf Tönen aus der Luftqualitäts-Skala oben. */
.app-gaugebar.uv{background:linear-gradient(90deg,
    var(--app-good) 0%, var(--app-good) 8%, var(--app-aqi-yellow) 33%, var(--app-warm) 54%,
    var(--app-hot) 75%, var(--app-aqi-purple) 100%)}

/* Temperatur-Variante desselben Gauges (.app-gaugebar.temp) – die kanonischen fünf
   Temperaturbänder (frost <5, cold 5–16, good 16–23, warm 23–27, hot ab 27) auf einer festen
   Referenzskala −10…40 °C (siehe tempGaugePct() in app.js bzw. die Inline-Berechnung in
   index.php). Farbstopps auf der jeweiligen Bandmitte für fließende Übergänge (analog zum
   Luftfeuchte-Gauge oben): 5°→30%, 16°→52%, 23°→66%, 27°→74% sind die Bandgrenzen, die Stops
   liegen bei deren Mitten. Da es hier keine „aus der Skala heraus"-Werte gibt (Punkt wird auf
   0–100 % geklemmt), sitzen die beiden Endfarben flach an den Rändern. */
.app-gaugebar.temp{background:linear-gradient(90deg,
    var(--app-frost) 0%, var(--app-frost) 15%, var(--app-cold) 41%, var(--app-good) 59%,
    var(--app-warm) 70%, var(--app-hot) 87%, var(--app-hot) 100%)}

/* ---------- Eigener Außensensor (gemessen) ---------- */
.app-sensor .hd{display:flex; align-items:center; justify-content:space-between; margin-bottom:14px}

/* ---------- Sonne (seit 2026-07-05 im Kachel-Look der anderen Widgets) ---------- */
/* Kopfzeile im selben Icon+Titel-Stil wie die Wind/Luftfeuchte/…-Kacheln (.app-tile .lbl) –
   .app-sunmoon ist aber keine .app-tile (steht als volle Zeile unter dem Kachelraster, nicht
   als Grid-Kachel), daher hier eine eigene, inhaltsgleiche Kopie statt .app-tile vorauszusetzen. */
.app-sunmoon .lbl{display:flex; align-items:center; gap:7px; font-size:12px; color:var(--app-muted); margin-bottom:2px}
.app-sunmoon .lbl .ic{width:26px; height:26px; border-radius:var(--app-radius-full); background:var(--app-card-soft);
  display:flex; align-items:center; justify-content:center; flex:0 0 auto}
.app-sunmoon .lbl svg{width:14px; height:14px; stroke:currentColor}

/* Körper: linkes Drittel Aufgang/Untergang-Zeiten, rechte zwei Drittel der Bogen-Graph
   (dynamisch auf die verbleibende Breite, kein fester px-Wert). */
.app-sun-body{display:flex; align-items:center; gap:16px; margin-top:14px}
.app-sun-times{flex:0 0 33%; display:flex; flex-direction:column; gap:12px; min-width:0}
.app-sun-times .t{display:flex; flex-direction:column; gap:2px}
.app-sun-times .k{font-size:11px; color:var(--app-muted)}
.app-sun-times .v{font-size:16px; font-weight:700}
.app-arc{flex:1 1 auto; min-width:0; height:52px}
/* Auf schmalen Handy-Breiten reicht die Zeile für Zeiten + Bogen nebeneinander nicht mehr –
   Zeiten rutschen dann über die volle Breite auf eine eigene Zeile über den Bogen statt
   seitlich zusammengequetscht zu werden (analog zum früheren Overflow-Bug an dieser Stelle). */
@media (max-width:560px){
  .app-sun-body{flex-wrap:wrap}
  .app-sun-times{flex:1 1 100%; flex-direction:row; justify-content:space-between; gap:10px}
}

/* ---------- Rechte Spalte: Stunden-/Tages-Vorhersage (Außen) ---------- */
.app-hourly .hd, .app-daily .hd{display:flex; align-items:center; justify-content:space-between; margin-bottom:14px; gap:10px; flex-wrap:wrap}
/* .app-pills wird hier nicht mehr verwendet (die Stunden-Karte zeigt seit 2026-07-05 einen
   fortlaufenden Streifen ohne Umschalter, siehe app_hour_strip()) – die Klasse bleibt für die
   Zeitraum-Pillen des Räume-Verlaufsdiagramms (buildRoomSectionHtml() in app.js) bestehen. */
.app-pills{display:flex; flex-wrap:wrap; gap:4px; background:var(--app-card-soft); border-radius:var(--app-radius-full); padding:4px}
.app-pills button{
  font-family:var(--app-sans); font-size:12.5px; color:var(--app-muted); background:transparent; border:0;
  border-radius:var(--app-radius-full); padding:7px 14px; cursor:pointer; white-space:nowrap;
}
.app-pills button.active{background:var(--app-card); color:var(--app-text); box-shadow:var(--app-shadow)}

/* Vor/Zurück-Blocknavigation im Raum-Verlaufsdiagramm (siehe assets/js/app.js drawRoomChart()) */
.app-navbtn{
  font-family:var(--app-sans); font-size:14px; line-height:1; color:var(--app-text); background:var(--app-card-soft);
  border:0; border-radius:var(--app-radius-full); padding:6px 11px; cursor:pointer;
}
.app-navbtn:hover:not(:disabled){background:var(--app-line)}
.app-navbtn:disabled{opacity:.35; cursor:default}
.app-navlabel{font-family:var(--app-mono); font-size:10.5px; color:var(--app-muted); white-space:nowrap}

/* Verlauf-Kopf (Raum-Chart, buildRoomSectionHtml() in app.js) – zwei eigene Zeilen statt einer
   gemeinsamen, analog zum Vorbild in index.php (dashboard.css .panel-head/.legend/.chartnav):
   eine gemeinsame Zeile aus Zurück-Pfeil + Datumsbereich + 4 Zeitraum-Pillen + Vor-Pfeil war auf
   echten iPhone-Breiten zu eng (Pillen-Text brach mitten im Wort um, letzte Pille ragte über den
   Kartenrand) – Aufteilen auf zwei Zeilen behebt das an der Wurzel, statt die Enge nur per
   Umbruch-Reihenfolge zu kaschieren.
   Zeile 1 (.app-chart-toprow): „Verlauf" links, Zeitraum-Pillen rechts.
   Zeile 2 (.app-chart-navrow): Farb-Legende links, Zurück/Datumsbereich/Vor rechts. */
.app-chart-toprow{display:flex; align-items:center; justify-content:space-between; gap:10px; flex-wrap:wrap}
.app-chart-toprow-right{display:flex; align-items:center; gap:8px; flex-wrap:wrap}
.app-chart-navrow{display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:10px; flex-wrap:wrap}
.app-chart-nav{display:flex; align-items:center; gap:8px}

/* Vollbild-Umschalter der Verlauf-Panels (assets/js/app.js wireFullscreenBtn()). Standardmäßig
   ausgeblendet und nur auf Geräten mit Maus/Trackpad eingeblendet (hover+pointer:fine) – auf
   Touchgeräten (Handy/Tablet) bringt eine Vollbildansicht wenig Mehrwert und wurde auf
   Nutzerwunsch bewusst nicht angeboten. */
.app-fsbtn{
  flex:0 0 auto; display:none; align-items:center; justify-content:center; width:30px; height:30px;
  color:var(--app-muted); background:var(--app-card-soft); border:0; border-radius:var(--app-radius-full);
  cursor:pointer;
}
.app-fsbtn:hover{background:var(--app-line); color:var(--app-text)}
.app-fsbtn svg{width:15px; height:15px; stroke:currentColor}
@media (hover:hover) and (pointer:fine){
  .app-fsbtn{display:flex}
}

/* Der Browser macht das Panel im Vollbild automatisch bildschirmfüllend (Fullscreen-API) – hier
   zusätzlich Inhalt vertikal zentrieren und auf sehr breiten Monitoren die Breite begrenzen (sonst
   wirkt das Chart-SVG bei 4K/Ultrawide unnötig flach-gestreckt, da das Seitenverhältnis über sein
   viewBox fix bleibt). */
.app-chartpanel:fullscreen, .app-chartpanel-long:fullscreen{
  display:flex; flex-direction:column; justify-content:center; padding:32px 6vw; overflow:auto;
  box-sizing:border-box;
}
.app-chartpanel:fullscreen>*, .app-chartpanel-long:fullscreen>*{
  max-width:1200px; width:100%; margin-left:auto; margin-right:auto;
}

/* Stunden-Streifen (Außen-Tab, neu 2026-07-05: fortlaufend statt 4×12h-Blöcken mit
   Umschalter-Pillen – Nutzerwunsch für eine durchgehende Übersicht, im selben Kachel-Look
   wie die 7-Tage-Karten (.app-day) statt einer weiteren Umschalter-Bedienung).
   app_hour_strip()/app_prob_chart() (index-cards.php) bauen dafür drei gestapelte Reihen mit
   fester, identischer Pixelbreite/-abstand statt der früheren prozentualen
   Container-Positionierung: Stunden-Karten, darunter der Regenwahrscheinlichkeits-Graph,
   darunter die Niederschlagsmenge – alle drei innerhalb eines gemeinsamen horizontal
   scrollbaren Containers (.app-hourscroll), damit sie beim Scrollen zusammenbleiben (ein
   früherer Versuch mit unabhängig scrollendem Streifen + volle-Breite-Graph hatte das
   auseinandergerissen). Kartenbreite (60px)/-abstand (8px)/linker Rand (30px, Platz für die
   Prozent-Achsenbeschriftung des Graphs) sind FESTE Konstanten, identisch zu $cw/$gap/$ml in
   app_hour_strip()/app_prob_chart() – das erlaubt PHP, Graph- und Niederschlags-Positionen
   pixelgenau auf die Kartenmitten zu berechnen, ohne die tatsächliche Containerbreite zur
   Laufzeit zu kennen (der Streifen ist ohnehin oft breiter als der sichtbare Bereich).
   Kein @media-Sonderfall für schmale Breiten mehr nötig (anders als bei der alten
   Block-Variante) – die feste Kartenbreite scrollt einfach wie bei .app-days-row. */
/* Umschließt den scrollenden Stunden-Streifen UND seinen Hover-Tooltip. position:relative =
   Bezugsrahmen für den absolut positionierten .app-tooltip, der bewusst AUSSERHALB von
   .app-hourscroll liegt: dessen overflow-x:auto (nötig fürs horizontale Scrollen) klippt sonst
   auch vertikal/an den sichtbaren Rändern (overflow-y wird bei overflow-x:auto zu auto), was den
   Tooltip an den äußeren Stellen abschnitt. Von hier aus kann er frei über die Karte ragen. */
.app-hourwrap{position:relative}
.app-hourscroll{overflow-x:auto; padding-bottom:6px}
/* Schmale, eingefärbte Scrollbar statt der dicken Standard-Leiste des Betriebssystems –
   dasselbe Muster wie .hours in assets/css/dashboard.css (index.php), hier aber über
   --app-muted-2/--app-muted statt hartkodierter Hex-Werte, damit Hell- UND Dunkelmodus
   automatisch passende Töne bekommen. Gilt für beide horizontal scrollbaren
   Vorhersage-Streifen (Stunden UND 7-Tage). */
.app-hourscroll, .app-days-row{scrollbar-width:thin; scrollbar-color:var(--app-muted-2) transparent}
.app-hourscroll::-webkit-scrollbar, .app-days-row::-webkit-scrollbar{height:8px}
.app-hourscroll::-webkit-scrollbar-track, .app-days-row::-webkit-scrollbar-track{background:transparent; margin:0 4px}
.app-hourscroll::-webkit-scrollbar-thumb, .app-days-row::-webkit-scrollbar-thumb{background:var(--app-muted-2); border-radius:8px}
.app-hourscroll::-webkit-scrollbar-thumb:hover, .app-days-row::-webkit-scrollbar-thumb:hover{background:var(--app-muted)}
.app-hourinner{display:flex; flex-direction:column; gap:10px}
.app-hours-row{display:flex; gap:8px; margin-left:30px}
.app-hour{
  flex:0 0 60px; width:60px; display:flex; flex-direction:column; align-items:center; gap:6px;
  padding:12px 4px; border-radius:var(--app-radius-m); background:var(--app-card-soft);
}
.app-hour.now{background:var(--app-accent-soft)}
.app-hour .hh{font-family:var(--app-mono); font-size:10.5px; color:var(--app-muted)}
.app-hour .ic{color:var(--app-warm); line-height:1}
.app-hour .tt{font-size:14px; font-weight:700}
.app-hour .ws{display:flex; align-items:center; gap:3px; font-size:10px; color:var(--app-muted)}

/* Feine vertikale Stunden-Referenzlinien im Regengraph (Nutzerwunsch) – Farbe wie die
   horizontalen .grid-line, Deckkraft kommt als SVG-Attribut direkt von app_precip_chart()
   (aktuelle Stunde etwas kräftiger als leiser Bezug zur .app-hour.now-Hervorhebung oben). */
.app-hourchart .vtick{stroke:var(--app-line)}

/* Niederschlagsmengen-Balken im kombinierten Bar/Line-Chart (app_precip_chart()) – Farbe
   analog zur vormaligen Text-Zeile (Regen kalt-blau, Schnee frost-violett). */
.app-precipbar{opacity:.55}
.app-precipbar.rain{fill:var(--app-cold)}
.app-precipbar.snow{fill:var(--app-frost)}

/* 7-Tage-Karten (ersetzt die frühere Listenzeile) – Bedingungstext jetzt als Hover-Tooltip
   auf dem Icon (title-Attribut) statt Fließtext, da im kompakten Kartenformat kein Platz. */
.app-days-row{display:flex; gap:10px; overflow-x:auto; padding-bottom:6px}
/* flex:1 0 78px = 78px als MINDESTbreite (basis + kein Schrumpfen), aber Wachstum auf breiten
   Bildschirmen, damit die 7 Karten die volle Kartenbreite füllen (vorher flex:0 0 auto → feste
   Breite → rechts blieb bei WQHD/Ultrawide eine leere Lücke). Passen sie nicht mehr nebeneinander
   (schmale Fenster), floort die 78px-Basis und .app-days-row scrollt horizontal wie zuvor. */
.app-day{
  flex:1 0 78px; min-width:78px; display:flex; flex-direction:column; align-items:center; gap:5px;
  padding:14px 10px; border-radius:var(--app-radius-m); background:var(--app-card-soft);
}
.app-day.today{background:var(--app-accent-soft)}
.app-day .wd{font-size:12.5px; font-weight:600}
.app-day .dt{font-size:10.5px; color:var(--app-muted); margin-top:-3px}
.app-day .ic{color:var(--app-warm); line-height:1; margin:2px 0}
.app-day .tmax{font-size:15px; font-weight:700}
.app-day .tmin{font-size:12px; color:var(--app-muted)}
.app-day .prob{font-size:10.5px; color:var(--app-cold)}
/* Zusatzangaben je Tag (Niederschlag/Wind+Böen/Sonnenstunden) – aus widget.php übernommen,
   kompakt untereinander unter den Temperaturen. Icon links, Wert rechts. */
.app-day-ext{display:flex; flex-direction:column; gap:3px; margin-top:4px; padding-top:6px;
  border-top:1px solid var(--app-line); width:100%; font-size:10.5px; color:var(--app-muted)}
.app-day-ext .x{display:flex; align-items:center; justify-content:center; gap:4px; white-space:nowrap; font-family:var(--app-mono)}
.app-day-ext .xic{display:inline-flex; color:var(--app-muted-2)}
.app-day-ext .xic svg{width:12px; height:12px; stroke:currentColor; fill:none}
.app-day-ext .g{margin-left:4px; opacity:.8}
.app-days-cap{font-size:11px; color:var(--app-muted); margin-top:10px; line-height:1.5}

/* 15-Minuten-Regen-Balken (Nowcast nächste 12h, aus widget.php) – theme-abhängige Farben
   statt der hartkodierten Hex-Werte in widget.css (dort nur ein festes dunkles Theme). */
.app-rainbar-bars{display:flex; align-items:flex-end; gap:2px; height:60px; padding:2px 0;
  border-bottom:1px solid var(--app-line)}
.app-rbar{flex:1 1 0; min-width:2px; background:var(--app-cold); border-radius:2px 2px 0 0; opacity:.85}
.app-rainbar-labels{display:flex; justify-content:space-between; margin-top:6px; font-family:var(--app-mono);
  font-size:10px; color:var(--app-muted)}
.app-rainbar-cap{font-size:11px; color:var(--app-muted); margin-top:8px; line-height:1.4}

/* ---------- Verlaufsdiagramm (Räume) ---------- */
.app-chart-legend{display:flex; gap:12px; font-size:11px; color:var(--app-muted)}
.app-chart-legend span{display:inline-flex; align-items:center; gap:5px}
.app-chart-legend i{display:inline-block; width:8px; height:8px; border-radius:50%}
.app-chart{padding-top:16px}
.app-chart svg{display:block; width:100%; height:auto; overflow:visible}
.app-chart .grid-line{stroke:var(--app-line); stroke-width:1}
.app-chart .area{opacity:.1}
.app-chart .line{fill:none; stroke-width:2; stroke-linecap:round; stroke-linejoin:round}
.app-chart .line-hum{fill:none; stroke:var(--app-hum); stroke-width:1.3; stroke-linecap:round; stroke-linejoin:round}
.app-chart .axis-t{font-family:var(--app-mono); font-size:10px; fill:var(--app-muted)}
.app-chart .hoverdot{fill:var(--app-card); stroke-width:2.5}
.app-chart .hoverline{stroke:var(--app-muted-2); stroke-width:1; stroke-dasharray:3 3}
.app-tooltip{
  position:absolute; pointer-events:none; transform:translate(-50%,-125%); background:var(--app-text);
  color:var(--app-card); font-family:var(--app-mono); font-size:11px; padding:5px 9px; border-radius:8px;
  white-space:nowrap; opacity:0; transition:opacity .1s;
}
.app-chartwrap{position:relative}

.app-roomhead{display:flex; align-items:center; justify-content:space-between; gap:10px}
.app-roomhead h2{margin:0; font-size:20px; font-weight:700}
.app-roomhead .age{font-size:12px; color:var(--app-muted); font-family:var(--app-mono)}

/* Temperatur-Farb-Legende (aus index.php übernommen) – erklärt die temperaturabhängige
   Farbe des Raum-Hero-Werts. Steht je Raum-Tab unter den Kacheln (kompakt, umbruchfähig). */
.app-tempkey{display:flex; flex-wrap:wrap; align-items:center; gap:6px 12px; font-size:11px; color:var(--app-muted)}
.app-tempkey .tk-title{font-weight:600; color:var(--app-text)}
.app-tempkey .tk{display:inline-flex; align-items:center; gap:5px}
.app-tempkey .tk i{display:inline-block; width:9px; height:9px; border-radius:50%}

/* Statistik-Zeile unter dem Raum-Verlaufsdiagramm (aus index.php: aktuell/min/max/Ø/Messpunkte
   fürs gewählte Zeitfenster). */
.app-chartstats{display:flex; flex-wrap:wrap; gap:8px 18px; margin-top:12px; font-size:12px; color:var(--app-muted)}
.app-chartstats b{font-weight:600; color:var(--app-text); font-family:var(--app-mono); margin-right:5px}

.app-note{font-size:12px; color:var(--app-muted); text-align:center; margin-top:22px}

/* Zweistufiges Fehlerbanner (analog index.php/widget.php .err): Totalausfall
   (kein Cache-Stand vorhanden) vs. Hinweis (Abruf fehlgeschlagen, letzter
   zwischengespeicherter Stand wird noch gezeigt). Farben aus der bestehenden
   Temperatur-/Status-Palette, kein neues Token nötig. */
.app-err{color:var(--app-hot)}
.app-err.hint{color:var(--app-warm)}

/* Warnhinweis im Räume-Verlaufsdiagramm: im geladenen Fenster wurden als fehlerhaft
   markierte Messwerte (switchbot_logger.php, Spalte `import`=1) gefunden und
   ausgeschlossen – analog .corrupt-warn in dashboard.css, aber mit --app-*-Tokens. */
.app-corrupt-warn{margin-top:10px; padding:8px 11px; border-radius:var(--app-radius-m);
  background:var(--app-card-soft); border:1px solid var(--app-warm); color:var(--app-warm);
  font-size:11.5px; overflow-wrap:anywhere}

@media (max-width:640px){
  .app-topbar{flex-wrap:wrap}
  .app-menu{order:3; flex-basis:100%}
}

/* ---------------------------------------------------------------------------
   Amtliche Warnungen (Unwetter DWD + Zivilschutz NINA/BBK) – Warn-Banner oben
   über den Tabs (siehe wx_get_alerts()/index.php). Vier Warnstufen (1 gelb …
   4 weinrot) über eine je Stufe gesetzte --lvl-Farbe. Nutzt <details>/<summary>
   für das native Auf-/Zuklappen (kein JS, kein CSP-Konflikt).
   --------------------------------------------------------------------------- */
.app-alerts{display:flex; flex-direction:column; gap:10px; margin:4px 0 14px}
.app-alert{
  background:var(--app-card); border-radius:var(--app-radius-l); box-shadow:var(--app-shadow);
  border-left:5px solid var(--lvl,var(--app-warm)); overflow:hidden;
}
.app-alert.lvl1{--lvl:var(--app-aqi-yellow)}
.app-alert.lvl2{--lvl:var(--app-warm)}
.app-alert.lvl3{--lvl:var(--app-hot)}
.app-alert.lvl4{--lvl:var(--app-aqi-maroon)}
.app-alert>summary{
  list-style:none; cursor:pointer; display:flex; align-items:center; gap:12px; padding:13px 16px;
}
.app-alert[data-nobody]>summary{cursor:default}
.app-alert>summary::-webkit-details-marker{display:none}
.app-alert-ic{flex:0 0 auto; display:flex; color:var(--lvl)}
.app-alert-ic svg{width:23px; height:23px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round}
.app-alert-main{flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px}
.app-alert-head{font-weight:650; font-size:14px; color:var(--app-text); line-height:1.32}
.app-alert-meta{font-size:12px; color:var(--app-muted); line-height:1.35}
.app-alert-chev{flex:0 0 auto; display:flex; color:var(--app-muted); transition:transform .15s ease}
.app-alert-chev svg{width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round}
.app-alert[open] .app-alert-chev{transform:rotate(180deg)}
.app-alert-body{
  padding:12px 16px 15px; margin-top:2px; border-top:1px solid var(--app-line);
  font-size:13px; color:var(--app-text); line-height:1.55;
}
.app-alert-body p{margin:0 0 8px}
.app-alert-body p:last-child{margin-bottom:0}
.app-alert-instr{color:var(--app-muted)}
