/* -------------------------------------------
   GLOBAL TITANIUM UI 2.0 CLEAN + BLUE
------------------------------------------- */

/* -------------------------------------------
   LOKAL GEHOSTETE SCHRIFTART
   Einzige verwendete Schriftfamilie der Seite, in den Schnitten 400/500/
   600/700. Die Datei wird manuell in fonts/ abgelegt (nicht Teil dieser
   Auslieferung) - erwarteter Dateiname: fonts/source-sans-3-variable.woff2
------------------------------------------- */

@font-face {
  font-family: "Source Sans 3";
  src: url("fonts/source-sans-3-variable.woff2") format("woff2-variations");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

/* War bisher an 10 einzelnen Stellen in der Datei verteilt (immer
   dieselbe Deklaration) - nirgends wird bewusst auf content-box gesetzt,
   daher hier einmal global. */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Der blaue Antipp-"Blitz"/Fokusrahmen, den mobile Browser (v.a. Android
   Chrome/WebKit) auf JEDEM antippbaren Element zeigen - fiel zuerst beim
   #geoToggleButton auf (siehe dessen eigene, jetzt überflüssig gewordene
   Deklarationen weiter unten), betraf aber eigentlich schon immer jeden
   Button/Link auf der Seite (Einstellungen-Speichern-Button, die
   SVG-Icon-Buttons in der Tabellen-Caption, Preisverlauf-Tabs, Karten-
   Links in der Stations-InfoBox, ...). Statt das an jeder Stelle einzeln
   nachzurüsten (und dabei zwangsläufig welche zu übersehen, wie hier
   passiert), jetzt global:
   - -webkit-tap-highlight-color auf * (harmlos auf nicht-antippbaren
     Elementen, hat dort schlicht keine Wirkung) statt nur auf einzelne
     Button-Klassen, damit auch künftig neu hinzukommende antippbare
     Elemente das automatisch mitbekommen.
   - :focus/:focus-visible NUR auf echten interaktiven Steuerelementen
     (button/a/[role="button"]/summary/Elemente mit tabindex) - bewusst
     NICHT auf Eingabefeldern, deren Fokus-Erscheinungsbild (Rahmenfarbe
     o.ä.) an anderer Stelle gezielt und unterschiedlich gestaltet ist
     (siehe #geoInput/.settingsInput). :focus-visible (statt :focus)
     sorgt dafür, dass Tastatur-Nutzung weiterhin einen sichtbaren
     Fokusring bekommt - nur beim Antippen mit Maus/Finger verschwindet
     er, nicht bei echter Tastaturnavigation. */
* {
  -webkit-tap-highlight-color: transparent;
}

button:focus,
a:focus,
[role="button"]:focus,
summary:focus,
[tabindex]:focus {
  outline: none;
}

button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

:root {
  /* -----------------------------------------
     FARBEN – Primitiv-Ebene
     Reine Palette, unabhängig vom Theme. Wird nicht direkt in Komponenten
     verwendet, sondern nur von der Semantik-Ebene unten referenziert.
  ----------------------------------------- */
  --gray-950: #1d1d1f;
  --gray-900: #2a2a2c;
  --gray-850: #2d2d2f;
  --gray-800: #2f2f31;
  --gray-780: #303032;
  --gray-760: #313132;
  --gray-650: #3a3a3c;
  --gray-600: #3d3d3f;
  --gray-550: #454547;
  --gray-300: #b0b0b0;
  --gray-100: #e5e5e7;
  --white: #ffffff;
  --blue-500: #3b82f6;

  /* -----------------------------------------
     KRAFTSTOFF-FARBEN
     Bewusst theme-unabhängig (anders als --color-accent unten): E5/E10/
     Diesel sollen in jedem Theme gleich aussehen, damit die Farbcodierung
     wiedererkennbar bleibt. Werden in keinem [data-theme="..."]-Block
     überschrieben.
     Grundfarben direkt vorgegeben (E5/E10/Diesel) - siehe
     .priceHistorySwatch--e5/e10/diesel weiter unten für die Verwendung.
  ----------------------------------------- */
  --fuel-e5: #41D5F9;
  --fuel-e10: #3FF0AE;
  --fuel-diesel: #FAB241;

  --fuel-e5-grad-light: #7CE2FB;
  --fuel-e5-grad-mid: #41D5F9;
  --fuel-e5-grad-dark: #0697BA;

  --fuel-e10-grad-light: #78F4C6;
  --fuel-e10-grad-mid: #3FF0AE;
  --fuel-e10-grad-dark: #0DA86E;

  --fuel-diesel-grad-light: #FCCA7D;
  --fuel-diesel-grad-mid: #FAB241;
  --fuel-diesel-grad-dark: #BC7505;

  /* -----------------------------------------
     FARBEN – Semantik-Ebene (aktuell: Dark Theme)
     Diese Namen werden im gesamten restlichen CSS verwendet. Ein künftiges
     helles Theme überschreibt nur diesen Block (z.B. unter
     "[data-theme='light'] { ... }"), ohne dass Komponenten-Regeln sich
     ändern müssen. Reihenfolge = Elevation, von Ebene 0 (Hintergrund) bis
     Ebene 3 (Hover, hellste Fläche).
  ----------------------------------------- */
  --color-bg: var(--gray-950);              /* Ebene 0: Seitenhintergrund */
  --color-border: var(--gray-900);
  /* Fallback fürs dunkle Default-Theme: dort reicht der normale Rand
     bereits (der Seitenhintergrund scheint im Spalt sichtbar durch) - nur
     Paper/Modern überschreiben das mit einem kräftigeren Ton, siehe dort. */
  --tab-divider-strong: var(--color-border);
  /* Sonst hätte NUR dieses Default-Theme .locationTable ohne Rand (siehe
     border: var(--panel-border, none) dort) - Paper/Modern/School/
     Creative setzen alle 1px solid mit eigener Farbe. Führte beim
     Wechsel auf ein anderes Theme zu einem sichtbaren Layoutsprung (Tabelle
     wird um die Randbreite größer/kleiner), weil hier vorher gar kein
     Rahmen reserviert war. transparent statt "none": gleiche Breite wie
     überall sonst, nur unsichtbar - das Standard-Theme bleibt optisch
     randlos, ohne dass sich die Kastengröße beim Theme-Wechsel ändert. */
  --panel-border: 1px solid transparent;
  --color-surface: var(--gray-850);         /* Ebene 1: Basis-Panels (Tabelle, Geo-Suche, Hinweis) */
  --color-surface-alt: var(--gray-800);     /* Ebene 1b: Einstellungen-Panel, Footer-Bereich */
  --color-surface-strong: var(--gray-780);  /* Ebene 1c: Header-Leiste, Toggle-Buttons, Tabellenkopf */
  --color-footer: var(--gray-760);
  --color-surface-raised: var(--gray-650);  /* Ebene 2: Fokus-/Eingabe-Hervorhebung */
  --color-surface-2: var(--gray-600);       /* Ebene 2b: Caption, Datenzeilen-Hintergrund */
  --color-hover: var(--gray-550);           /* Ebene 3: Hover-Zustand */
  --color-text-muted: var(--gray-300);
  --color-text: var(--gray-100);
  /* Noch extremer als --color-text (fast reines Weiß/Schwarz statt der
     etwas softeren Off-White/Off-Black-Töne) - für Stellen, an denen
     maximale Lesbarkeit wichtiger ist als das übliche, etwas sanftere
     Erscheinungsbild, z.B. die Achsenbeschriftungen im Preisverlauf-
     Chart. In den drei dunklen Themes (dieses Root-Theme, school,
     creative) unverändert übernommen; die drei hellen Themes
     überschreiben dies weiter unten mit einem entsprechend dunklen Ton. */
  --color-text-strong: #ffffff;
  --color-white: var(--white);
  /* Eigene, kräftigere Variable für Diagramm-Gitterlinien: --color-border
     ist bewusst sehr dezent (für Trennlinien gedacht) und in dunklen
     Themes auf hellem Diagramm-Hintergrund kaum sichtbar. */
  --color-grid: var(--gray-550);
  --color-on-strong: var(--color-white);   /* Text-/Icon-Farbe auf --color-surface-strong */
  --color-accent: var(--blue-500);
  /* War bisher (anders als bei Paper/Modern/School/Creative) für dieses
     Theme gar nicht definiert - als RGB-Tripel von --color-accent (#3b82f6)
     ergänzt, u.a. für --color-row-highlight unten gebraucht. */
  --accent-tint: 59, 130, 246;
  /* Aus --color-accent abgeleiteter Verlauf für "aktiv"-Zustände (aktive
     Sortierspalte, aktiver Tab). War bisher an 4 Stellen wortgleich
     dupliziert - jetzt zentral hier definiert, damit sich das
     85%-Mischverhältnis bei Bedarf an einer Stelle statt vier anpassen
     lässt. Reagiert automatisch auf --color-accent, also auch pro Theme. */
  --accent-gradient: linear-gradient(
    180deg,
    color-mix(in srgb, var(--color-accent) 85%, white),
    color-mix(in srgb, var(--color-accent) 85%, black)
  );
  /* Text auf --accent-gradient-Flächen (aktive Preisverlauf-Tabs) -
     bewusst getrennt von --color-on-strong, das laut seinem eigenen
     Kommentar oben für Text auf --color-surface-strong (helle
     Kartenflächen) gedacht ist. Bisher zufällig überall derselbe Wert
     (weil jedes Theme sowohl einen hellen --color-surface-strong als auch
     einen mittelhellen/kräftigen --color-accent hatte, für die beide
     zufällig dieselbe Textfarbe passte) - bricht aber auseinander, sobald
     ein Theme einen SEHR dunklen --color-accent bekommt (siehe
     [data-theme="modern"] unten). */
  --accent-on-text: var(--color-on-strong, #fff);
  --color-input-border: rgba(255, 255, 255, 0.18);
  --color-card-border: rgba(255, 255, 255, 0.14);
  --color-card-bg: #48484b;
  --color-row-highlight: rgba(var(--accent-tint), 0.08);
  --color-danger: #ef4444;
  --color-danger-hover: #f87171;

  /* -----------------------------------------
     PREISVERLAUF-TABS – inaktiver Hintergrund
     Feste, aus der Mockup-Vorlage übernommene Helltöne. Passen so in den
     dunklen Themes (dieses Root-Theme sowie "school"/"creative", die
     diese Variablen NICHT überschreiben und sie daher automatisch von
     hier erben). Die hellen Themes (light/paper/modern) überschreiben
     diese sechs Variablen weiter unten mit einer aus der jeweiligen
     Theme-Oberflächenfarbe abgeleiteten, künstlich abgedunkelten Variante
     (color-mix), da die festen Helltöne dort kaum sichtbar wären.
  ----------------------------------------- */
  --tab-inactive-start: #F8F8F8;
  --tab-inactive-end: #E5E5E5;
  --tab-inactive-hover-start: #EFEFEF;
  --tab-inactive-hover-end: #DADADA;
  --tab-inactive-text: #050505;
  --tab-inactive-border: #252525;
  /* Fertige Verlaufs-Werte aus den vier Farbtönen oben - war bisher an den
     Verwendungsstellen (Titel-/Bereichs-/Kraftstoff-Tab, je Grund- und
     Hover-Zustand) 3x bzw. 2x wortgleich als linear-gradient(...)
     dupliziert. Referenziert weiterhin --tab-inactive-start/-end, greift
     also in light/paper/modern automatisch auf deren dortige
     Überschreibung zu. */
  --tab-inactive-gradient: linear-gradient(180deg, var(--tab-inactive-start), var(--tab-inactive-end));
  --tab-inactive-hover-gradient: linear-gradient(180deg, var(--tab-inactive-hover-start), var(--tab-inactive-hover-end));

  /* Rand der beiden Preisverlauf-Tab-Leisten (Titel- und Bereichs-Leiste):
     in JEDEM Theme sichtbar vorhanden, 1px solid (siehe
     .priceHistoryTitleBar/.priceHistoryTabs, die Breite/Stil fest
     eintragen). Nur die FARBE unterscheidet sich zwischen den Themes -
     Standard hier ist schlicht --color-border (das variiert ja ohnehin
     schon sinnvoll pro Theme). Einzige Ausnahme: Paper/Modern
     überschreiben das weiter unten auf --tab-divider-strong, weil ihr
     --color-border dort separat für dezente Trennlinien gedacht ist und
     für diesen Zweck zu schwach abhebt (siehe dort). */
  --tab-outline-color: var(--color-border);
  --tab-outer-shadow: none;
  /* Abstand zwischen den beiden gestapelten Leisten (Titel/Tabs, siehe
     .priceHistoryTabsGroup): 0, weil jede der beiden jetzt einen eigenen
     echten Rahmen hat, der die Trennung übernimmt - ein zusätzlicher
     Spalt würde nur als heller/dunkler Streifen ZWISCHEN den Rahmenlinien
     auffallen (siehe --tab-outline-color oben). */
  --tab-seam-gap: 0px;

  /* Typografie */
  /* Einzige Schriftart der Seite (siehe @font-face oben) - alle drei
     Variablen bewusst weiterhin getrennt gehalten (statt zu einer
     zusammengefasst), da an vielen Stellen im CSS gezielt nach
     Display/Body/Numeric referenziert wird; zeigen jetzt aber alle auf
     dieselbe Familie, damit einheitlich nur noch "Source Sans 3" gerendert
     wird. */
  --font-display: "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-numeric: "Source Sans 3", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-size-tiny: 0.75rem;
  --font-size-small: 0.85rem;
  --font-size-base: 0.95rem;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  /* Abstände */
  --space-sm: 12px;
  --space-md: 18px;
  --space-lg: 24px;
  --space-xl: 32px;

  /* Form/Effekte */
  --radius: 10px;
  /* Weitere, kleinere Rundungs-Stufen neben --radius - eigene Variablen
     statt an drei bzw. drei weiteren Stellen wiederholter Literale, analog
     zu --radius selbst (dieselbe Überlegung, die zur Entfernung des
     [data-theme="modern"]-Overrides von --radius geführt hat: Werte, die
     themeübergreifend identisch sein sollen, gehören benannt statt als
     wiederholte Zahl an jeder Verwendungsstelle - sonst wieder dasselbe
     Risiko, dass eine künftige Anpassung nur an einer von mehreren Stellen
     landet). --radius-small: kompakte Formularelemente (Ortssuche-Eingabe,
     deren Fokus-Rahmen, das Ergebnis-Popup). --radius-pill: abgerundete
     Buttons mit fester (nicht über 999px "voll rund" laufender) Kapsel-
     form (Einstellungen-Speichern/Löschen-Button, Kartenlinks in der
     Stations-InfoBox). */
  --radius-small: 6px;
  --radius-pill: 20px;
  --shadow: 0 0 14px rgba(0,0,0,0.55);
  --transition-fast: 0.25s ease;
  --transition-medium: 0.45s cubic-bezier(0.15, 0.85, 0.35, 1);
  /* Auf-/Zuklapp-Animation für alle vier Grid-basierten Collapse-Panels
     (Einstellungen-Panel, Preisverlauf-Panel/-Stats-Box - siehe deren
     grid-template-rows: 0fr/1fr-Übergang) - vorher an allen vier Stellen
     wortgleich wiederholt, jetzt eine Quelle dafür. */
  --collapse-transition: grid-template-rows 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s ease;

  /* Tabellen-Layout */
  --footer-height: 48px;
  /* Entfernungs-Spalte bewusst mit größerem Anteil (1.2fr statt 1fr) als
     E5/E10/Diesel: Grund ist NICHT die Zahl selbst (die bräuchte nicht
     mehr Platz), sondern dass ab genügend Tabellenbreite im Header statt
     des Pfeil-Icons der Text "Entfernung" angezeigt wird (siehe
     @container-Regel bei .headerDistanceText in der Header-Sektion) -
     bei 1fr wäre die Spalte selbst bei --table-max-width (600px) nie
     breit genug dafür. Wert 1.2 und der @container-Schwellwert (580px)
     wurden per Playwright-Messung so kalibriert, dass der Text bei
     Erreichen des Schwellwerts bereits sicher hineinpasst (mit etwas
     Puffer für Font-Rendering-Unterschiede zwischen Browsern/
     Betriebssystemen), statt exakt auf Kante zu stehen. Bewusst so klein
     wie möglich gehalten, damit die Spalte optisch kaum breiter wirkt als
     E5/E10/Diesel. */
  --col-template: 4fr 1.2fr 1fr 1fr 1fr;
  /* Reihenfolge hier: Name, Statistik-Icon, Entfernung, E5, E10, Diesel -
     siehe Kommentar bei --col-template oben zum 1.2fr-Wert der
     Entfernungs-Spalte; hier separat kalibriert, da die zusätzliche
     Statistik-Spalte der Entfernungs-Spalte Platz wegnimmt und der Text
     sonst etwas zu früh eingeblendet würde. */
  --col-template-stats: 4fr minmax(30px, 0.45fr) 1.2fr 1fr 1fr 1fr;
  --table-min-width: 400px;
  --table-max-width: 600px;
  --tables-gap: 20px;

  /* Native Browser-UI (Scrollbar, Autofill, Datepicker, Checkbox/Radio)
     ebenfalls dunkel rendern statt in der Browser-Standardoptik. Wird von
     den hellen Themes unten überschrieben. */
  color-scheme: dark;
}

/* -------------------------------------------
   THEMES
   Überschreiben nur die Semantik-Ebene der Farben (siehe :root oben).
   Header-Leiste (--color-surface-strong) und Akzentfarbe bleiben in jedem
   Theme kräftig/dunkel genug, damit die weiße Schrift auf Buttons/Header
   (siehe --color-white-Verwendungen) überall lesbar bleibt.
   Wird per data-theme-Attribut auf <html> aktiviert, nicht gespeichert.

   WICHTIG beim Hinzufügen/Entfernen eines Themes: die Fallback-Liste in
   script.js (getAvailableThemes()/themeCycle, Suche nach "dark", "light")
   greift nur beim direkten Öffnen als lokale Datei (file://), wo der
   automatische CSS-Scan nicht funktioniert – dort manuell nachpflegen.
------------------------------------------- */

/* Diese beiden hellen Themes leiteten die Preisverlauf-Tab-Farben bisher
   jeweils einzeln (aber wortgleich) aus --color-surface-raised her - nur
   der Schlagschatten (--tab-outer-shadow) unterschied sich tatsächlich
   pro Theme. Jetzt hier einmal gemeinsam definiert; jedes der beiden
   Themes überschreibt unten nur noch seinen eigenen Schatten. */
[data-theme="paper"],
[data-theme="modern"] {
  --tab-inactive-start: color-mix(in srgb, var(--color-surface-raised) 100%, black 8%);
  --tab-inactive-end: color-mix(in srgb, var(--color-surface-raised) 100%, black 22%);
  --tab-inactive-hover-start: color-mix(in srgb, var(--color-surface-raised) 100%, black 14%);
  --tab-inactive-hover-end: color-mix(in srgb, var(--color-surface-raised) 100%, black 28%);
  --tab-inactive-text: var(--color-text);
  /* Deutlich sichtbarer als --color-border (das ist bewusst dezent für
     normale Trennlinien gedacht) - 50/50-Mischung mit --color-text, damit
     die Ränder zwischen den einzelnen Tabs der mittleren Preisverlauf-
     Leiste (Heute/7 Tage/...) und zwischen den drei gestapelten Leisten
     (Titel/Tabs/Kraftstoff) auf dem hellen Untergrund dieser beiden
     Themes überhaupt auffallen - siehe .priceHistoryTabs/
     .priceHistoryFuelTabs/.priceHistoryTitleBar weiter unten. Noch keine
     harte schwarze Linie, bleibt als "Rand" statt als Kante lesbar. */
  --tab-divider-strong: color-mix(in srgb, var(--color-border) 50%, var(--color-text) 50%);
  --tab-inactive-border: var(--tab-divider-strong);
  --tab-outline-color: var(--tab-divider-strong);
}

[data-theme="paper"] {
  /* Warme, neutrale Grautöne + ein gedämpfter Akzent (Blaugrau). */
  color-scheme: light;
  --color-bg: #faf9f7;
  --color-border: #c9c3b7;
  --color-surface: #ffffff;
  --color-surface-alt: #f5f3ef;
  --color-surface-strong: #ffffff;
  --color-footer: #f5f3ef;
  --color-surface-raised: #ffffff;
  --color-surface-2: #f8f6f3;
  --color-hover: #ece8e1;
  --color-text: #2b2823;
  --color-text-muted: #6b6459;
  /* Siehe Kommentar bei --color-text-strong in :root. */
  --color-text-strong: #0d0a06;
  --color-accent: #5c6a7d;
  --color-on-strong: #2b2823;
  --color-input-border: rgba(43, 40, 35, 0.16);
  --color-card-border: rgba(43, 40, 35, 0.12);
  --color-card-bg: #f6f4f0;
  --color-row-highlight: rgba(var(--accent-tint), 0.08);
  --color-danger: #dc2626;
  --color-danger-hover: #b91c1c;
  --accent-tint: 92, 106, 125;
  --panel-border: 1px solid rgba(var(--accent-tint), 0.25);
  --color-grid: rgba(43, 40, 35, 0.28);

  /* Heller/entsättigt statt des ursprünglich dunklen --accent-gradient
     (das auf Basis von --color-accent #5c6a7d recht schwer gegen den
     warmen, hellen Seitenhintergrund wirkte) - selbe Blaugrau-Familie, nur
     aufgehellt. Betrifft die Preisverlauf-Tableisten
     (.priceHistoryTab--active/.priceHistoryFuelTab--active), die darüber
     eingefärbt werden. --color-accent selbst bleibt unverändert (#5c6a7d),
     Buttons & Co, die direkt darauf zugreifen, sind von dieser Aufhellung
     also bewusst NICHT betroffen. Die aktive Sortierspalte im Tabellenkopf
     (.header .col.activeSort) nutzt für ihre Fläche --color-row-highlight
     (dasselbe wie die hervorgehobene Spalte in den Datenzeilen, siehe dort)
     statt --accent-gradient - braucht diese Aufhellung hier also nicht. */
  --accent-gradient: linear-gradient(
    180deg,
    color-mix(in srgb, #aebbc6 85%, white),
    color-mix(in srgb, #aebbc6 85%, black)
  );
  --accent-on-text: #233240;

  /* Preisverlauf-Tabs: gemeinsame Werte siehe Block vor
     [data-theme="paper"] oben. Nur der Schlagschatten unterscheidet sich
     pro Theme. */
  --tab-outer-shadow: 0 3px 10px rgba(30, 26, 18, 0.16);
}

/* =========================================================
   Tanke9 – Modern Theme
   ========================================================= */
[data-theme="modern"] {
  color-scheme: light;

  /* Grundflächen */
  --color-bg: #f5f5f3;
  --color-border: #e6e6e3;
  --color-surface: #fbfbfa;
  --color-surface-alt: #f0f0ee;
  --color-surface-strong: #ffffff;
  --color-footer: #eeeeec;
  --color-surface-raised: #ffffff;
  --color-surface-2: #f7f7f5;
  --color-hover: #ececea;

  /* Typografie */
  --color-text: #282828;
  --color-text-muted: #8a8a87;
  /* Siehe Kommentar bei --color-text-strong in :root. */
  --color-text-strong: #0a0a0a;
  --color-on-strong: #282828;

  /* Anthrazit statt des ursprünglichen Orange (Konzept 3 der vorgeschlagenen
     Alternativen) - --accent-gradient (siehe :root) erzeugt daraus
     automatisch denselben hell-oben/dunkel-unten-Verlauf wie bisher beim
     Orange, nur eben in Anthrazit. --accent-on-text auf hell umgestellt,
     weil Anthrazit (anders als das mittelhelle Orange vorher) mit dem
     bisherigen dunklen --color-on-strong (#282828) nicht mehr lesbar wäre -
     --color-on-strong selbst bleibt unverändert, das ist weiterhin korrekt
     für Text auf den hellen --color-surface-strong-Kartenflächen. */
  --color-accent: #3c3b38;
  --accent-tint: 60, 59, 56;
  --accent-on-text: #f5f5f3;

  /* Karten, Inputs und Zeilen */
  --color-input-border: rgba(40, 40, 40, 0.11);
  --color-card-border: rgba(40, 40, 40, 0.08);
  --color-card-bg: #fafaf9;
  --color-row-highlight: rgba(var(--accent-tint), 0.08);
  --color-grid: rgba(40, 40, 40, 0.16);

  /* Referenzbild: weich, sauber, keine harten Dark-Mode-Schatten */
  --panel-gradient: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.98) 0%,
    rgba(247, 247, 245, 0.98) 100%
  );
  --panel-border: 1px solid rgba(40, 40, 40, 0.08);
  --panel-shadow:
    0 12px 34px rgba(40, 40, 40, 0.07),
    0 2px 8px rgba(40, 40, 40, 0.035);

  /* Caption / Infoflächen */
  --caption-bg: linear-gradient(
    180deg,
    #fbfbfa 0%,
    #f1f1ef 100%
  );
  --caption-border: 1px solid rgba(40, 40, 40, 0.075);

  /* Aktive Elemente - selbe Anthrazit-Familie wie --color-accent oben,
     nur als eigener flacherer Verlauf (135deg statt 180deg, passend zum
     bisherigen Toggle-Look). */
  --accent-strong-bg: linear-gradient(
    135deg,
    #4a4945 0%,
    #2e2d2a 100%
  );
  --accent-strong-text: #ffffff;

  /* Fehler/Warnung */
  --color-danger: #d84a3a;
  --color-danger-hover: #bd382b;

  /* Themes sollen sich nur in Farben unterscheiden, nicht in Form/Timing -
     --radius/--shadow/--transition-fast/--transition-medium (allgemeine,
     nicht farbliche Formgebung) daher bewusst NICHT mehr überschrieben,
     Standardwerte aus :root gelten jetzt auch hier wie bei jedem anderen
     Theme. Vorher nur hier (als einziges Theme) mit eigenen, größeren/
     langsameren Werten "an eine Referenz angepasst" - das ließ u.a. die
     Preisverlauf-Tableisten (Titelleiste, Bereichs-Tabs, untere
     Kraftstoff-Leiste - alle über --radius) sichtbar runder wirken als in
     jedem anderen Theme, obwohl das nie gezielt für gerade diese Elemente
     gedacht war, sondern nur ein Nebeneffekt der geteilten Variable.
     --tab-outer-shadow direkt darunter ist davon nicht betroffen: das ist
     eine eigene, bewusst pro Theme unterschiedliche Variable (nur der
     Schlagschatten, siehe Kommentar dort) - kein Verstoß, alle Themes
     nutzen sie gleichermaßen dafür. */

  /* Preisverlauf-Tabs: gemeinsame Werte siehe Block vor
     [data-theme="paper"] oben. Nur der Schlagschatten unterscheidet sich
     pro Theme. */
  --tab-outer-shadow: 0 3px 10px rgba(20, 20, 20, 0.14);
}

/* -------------------------------------------
   THEME: SCHOOL / WINNENDEN (Inspiriert vom Screenshot)
------------------------------------------- */

[data-theme="school"] {
  /* Hintergrund & Basisflächen (Schiefer- / Blaugrau-Töne) */
  --color-bg: #27303b;
  --accent-tint: 77, 208, 225; /* #4DD0E1, Basis für alle transluzenten Ränder/Glow unten */
  --color-border: rgba(var(--accent-tint), 0.18);
  --color-surface: #323d4a;
  --color-surface-alt: #394654;
  --color-surface-strong: #2d3743;
  --color-footer: #2d3743;
  --color-surface-raised: #465566;
  --color-surface-2: #3c4a5a;
  --color-hover: #4d5e70;

  /* Typografie */
  --color-text: #f0f4f8;
  --color-text-muted: #b0bfc9;
  --color-on-strong: #ffffff;

  /* Akzentfarbe */
  --color-accent: #4DD0E1;

  /* Input- & Card-Styling */
  --color-input-border: rgba(var(--accent-tint), 0.25);
  --color-card-border: rgba(var(--accent-tint), 0.2);
  --color-card-bg: rgba(60, 74, 90, 0.75);
  --color-row-highlight: rgba(var(--accent-tint), 0.08);
  --color-grid: rgba(var(--accent-tint), 0.4);

  /* Panel-Glow (.locationTable / #geoSearchBox / #geoToggleButton) */
  --panel-gradient: linear-gradient(180deg, rgba(78, 94, 112, 0.35) 0%, rgba(50, 61, 74, 0.95) 50%);
  --panel-border: 1px solid rgba(var(--accent-tint), 0.22);
  --panel-shadow: 0 10px 30px rgba(0, 0, 0, 0.6), 0 0 18px rgba(var(--accent-tint), 0.1);

  /* Caption-Verlauf */
  --caption-bg: linear-gradient(180deg, rgba(88, 106, 126, 0.4) 0%, rgba(60, 74, 90, 0.9) 100%);
  --caption-border: 1px solid rgba(var(--accent-tint), 0.2);

  /* Aktive Sortierspalte (geöffneter Toggle-Button übernimmt denselben Verlauf) */
  --accent-strong-bg: linear-gradient(135deg, #4DD0E1 0%, #26a9ba 100%);
  --accent-strong-text: #1a232a;

  /* Preisverlauf-Tabs: aktiver Tab soll dieselbe (dunkle) Schriftfarbe wie
     die inaktiven Tabs bekommen, statt wie in den übrigen dunklen Themes
     auf hellem --color-accent (#4DD0E1, Cyan) weiß zu erscheinen - auf dem
     hellen Cyan-Hintergrund liest sich dunkle Schrift ohnehin deutlich
     besser. Betrifft .priceHistoryTab--active/.priceHistoryFuelTab--active
     (einzige Verwendungsstellen von --accent-on-text). */
  --accent-on-text: var(--tab-inactive-text);
}

/* -------------------------------------------
   THEME: CREATIVE / PORTFOLIO (Inspiriert vom Screenshot)
------------------------------------------- */

[data-theme="creative"] {
  /* Hintergrund & Basisflächen */
  --color-bg: #32353a;
  --accent-tint: 243, 194, 55; /* Goldgelb, Basis für alle transluzenten Ränder/Glow unten */
  --color-border: rgba(var(--accent-tint), 0.18);
  --color-surface: #3c4147;
  --color-surface-alt: #42474f;
  --color-surface-strong: #2a2d32;
  --color-footer: #2a2d32;
  --color-surface-raised: #4d535b;
  --color-surface-2: #383d44;
  --color-hover: #545b64;

  /* Typografie */
  --color-text: #f0f0f2;
  --color-text-muted: #a0a4a8;
  --color-on-strong: #f0f0f2;

  /* Akzentfarbe (Goldgelb aus dem Screenshot) */
  --color-accent: #f3c237;

  /* Input- & Card-Styling */
  --color-input-border: rgba(var(--accent-tint), 0.25);
  --color-card-border: rgba(var(--accent-tint), 0.2);
  --color-card-bg: rgba(60, 65, 71, 0.75);
  --color-row-highlight: rgba(var(--accent-tint), 0.08);
  --color-grid: rgba(var(--accent-tint), 0.4);

  /* Panel-Glow (.locationTable / #geoSearchBox / #geoToggleButton) */
  --panel-gradient: linear-gradient(180deg, rgba(75, 81, 90, 0.4) 0%, rgba(52, 57, 64, 0.95) 50%);
  --panel-border: 1px solid rgba(var(--accent-tint), 0.13); /* blasser als vorher (war: 0.22) */
  --panel-shadow: 0 10px 30px rgba(0, 0, 0, 0.65), 0 0 18px rgba(var(--accent-tint), 0.12);

  /* Caption-Verlauf */
  --caption-bg: linear-gradient(180deg, rgba(85, 92, 102, 0.45) 0%, rgba(56, 61, 68, 0.9) 100%);
  --caption-border: 1px solid rgba(var(--accent-tint), 0.2);

  /* Aktive Sortierspalte (geöffneter Toggle-Button übernimmt denselben Verlauf) */
  --accent-strong-bg: linear-gradient(135deg, #f3c237 0%, #d4a322 100%);
  --accent-strong-text: #222528;

  /* Preisverlauf-Tabs: aktiver Tab soll dieselbe (dunkle) Schriftfarbe wie
     die inaktiven Tabs bekommen, statt wie in den übrigen dunklen Themes
     auf hellem --color-accent (#f3c237, Goldgelb) weiß zu erscheinen - auf
     dem hellen Goldgelb liest sich dunkle Schrift ohnehin deutlich besser.
     Betrifft .priceHistoryTab--active/.priceHistoryFuelTab--active
     (einzige Verwendungsstellen von --accent-on-text). */
  --accent-on-text: var(--tab-inactive-text);
}

/* -------------------------------------------
   THEME: MOKKA
   Warme, gedämpfte Taupe-/Mokkatöne statt einer kräftigen Akzentfarbe -
   Vorlage war ein Android-Schnelleinstellungen-Screenshot in genau dieser
   Kaffee-Grau-Palette (kaum Sättigung, nur warme vs. neutrale Grautöne).
   Struktur/Farbhelligkeits-Abstufung 1:1 von [data-theme="creative"]
   übernommen (siehe dort), nur die Farbtemperatur von kühlem Blaugrau auf
   warmes Taupe-Braun verschoben - bewährte, konsistente Stufung statt
   diese von Grund auf neu auszutarieren.
------------------------------------------- */
[data-theme="mokka"] {
  /* Hintergrund & Basisflächen */
  --color-bg: #32302e;
  --accent-tint: 184, 160, 130; /* warmes Sandbeige, Basis für alle transluzenten Ränder/Glow unten */
  --color-border: rgba(var(--accent-tint), 0.18);
  --color-surface: #3c3733;
  --color-surface-alt: #423d38;
  --color-surface-strong: #2a2724;
  --color-footer: #2a2724;
  --color-surface-raised: #4d453d;
  --color-surface-2: #383430;
  --color-hover: #544c43;

  /* Typografie */
  --color-text: #f0ece6;
  --color-text-muted: #a89d92;
  --color-on-strong: #f0ece6;

  /* Akzentfarbe (warmes Sandbeige statt eines kräftigen Farbtons - passend
     zur insgesamt sehr zurückhaltenden, fast farblosen Vorlage) */
  --color-accent: #b8a082;

  /* Input- & Card-Styling */
  --color-input-border: rgba(var(--accent-tint), 0.25);
  --color-card-border: rgba(var(--accent-tint), 0.2);
  --color-card-bg: rgba(60, 55, 51, 0.75);
  --color-row-highlight: rgba(var(--accent-tint), 0.08);
  --color-grid: rgba(var(--accent-tint), 0.4);

  /* Panel-Glow (.locationTable / #geoSearchBox / #geoToggleButton) */
  --panel-gradient: linear-gradient(180deg, rgba(77, 69, 61, 0.4) 0%, rgba(50, 48, 46, 0.95) 50%);
  --panel-border: 1px solid rgba(var(--accent-tint), 0.22);
  --panel-shadow: 0 10px 30px rgba(0, 0, 0, 0.65), 0 0 18px rgba(var(--accent-tint), 0.12);

  /* Caption-Verlauf */
  --caption-bg: linear-gradient(180deg, rgba(84, 76, 67, 0.45) 0%, rgba(56, 52, 48, 0.9) 100%);
  --caption-border: 1px solid rgba(var(--accent-tint), 0.2);

  /* Aktive Sortierspalte (geöffneter Toggle-Button übernimmt denselben Verlauf) */
  --accent-strong-bg: linear-gradient(135deg, #b8a082 0%, #9c8462 100%);
  --accent-strong-text: #2b2622;

  /* Preisverlauf-Tabs: gleiche Begründung wie bei school/creative - der
     helle Sandbeige-Akzent liest sich mit dunkler statt weißer Schrift
     deutlich besser (siehe dortiger Kommentar für Details). */
  --accent-on-text: var(--tab-inactive-text);
}

/* -------------------------------------------
   THEME: GLASS
   Inspiriert vom hochgeladenen Smart-Home-Dashboard-Mockup: dort sind
   Panels/Karten rein achromatisches Grau (R=G=B, per Pixel-Sample aus der
   Vorlage geprüft, z.B. rgb(113,113,113)/rgb(121,121,121)) - anders als bei
   den übrigen dunklen Themes oben (school = Blaugrau, creative = warmes
   Grau, mokka = Taupe) hier also BEWUSST kein Farbstich in den Flächen.
   Farbe kommt ausschließlich über den einen Akzent rein (Toggle-Schalter,
   aktiver Chart-Balken, Fortschrittsring), exakt wie im Mockup: dort
   überall derselbe Blauton rgb(36,176,255) = #24B0FF (ebenfalls per
   Pixel-Sample bestätigt, u.a. am Thermostat-Schalter und Energy-Balken).
   Helligkeits-Stufung/Variablen-Set strukturell von school/creative/mokka
   übernommen (bewährtes Muster), nur eben neutral statt farbig. */
[data-theme="glass"] {
  /* Hintergrund & Basisflächen (neutrales Grau, kein Farbstich) */
  --color-bg: #1c1c1c;
  --accent-tint: 36, 176, 255; /* #24B0FF, Basis nur noch für Akzent-Glow (Panel-Schatten/Row-Highlight) - Ränder unten sind bewusst NEUTRAL, siehe --color-border. */
  --color-border: rgba(255, 255, 255, 0.14);
  --color-surface: #272727;
  --color-surface-alt: #2b2b2b;
  --color-surface-strong: #3c3c3c; /* etwas heller als #333333 (Caption-Boden/Datenzeilen-Fläche) - sonst kaum vom Tabellenkopf zu unterscheiden, siehe Vorlage anderer Themes */
  --color-footer: #242424;
  --color-surface-raised: #3d3d3d;
  --color-surface-2: #363636;
  --color-hover: #474747;

  /* Typografie */
  --color-text: #f2f2f2;
  --color-text-muted: #a3a3a3;
  --color-on-strong: #ffffff;

  /* Akzentfarbe (helles Himmelblau aus dem Mockup) */
  --color-accent: #24B0FF;

  /* Input- & Card-Styling */
  --color-input-border: rgba(255, 255, 255, 0.22);
  --color-card-border: rgba(255, 255, 255, 0.16);
  --color-card-bg: rgba(51, 51, 51, 0.75);
  --color-row-highlight: rgba(var(--accent-tint), 0.08);
  --color-grid: rgba(255, 255, 255, 0.16);

  /* Panel-Glow (.locationTable / #geoSearchBox / #geoToggleButton) */
  --panel-gradient: linear-gradient(180deg, rgba(80, 80, 80, 0.4) 0%, rgba(39, 39, 39, 0.95) 50%);
  --panel-border: 1px solid rgba(255, 255, 255, 0.16);
  --panel-shadow: 0 10px 30px rgba(0, 0, 0, 0.6), 0 0 18px rgba(var(--accent-tint), 0.12);

  /* Caption-Verlauf */
  --caption-bg: linear-gradient(180deg, rgba(90, 90, 90, 0.42) 0%, rgba(51, 51, 51, 0.9) 100%);
  --caption-border: 1px solid rgba(255, 255, 255, 0.14);

  /* Aktive Sortierspalte (geöffneter Toggle-Button übernimmt denselben Verlauf) */
  --accent-strong-bg: linear-gradient(135deg, #24B0FF 0%, #0A84FF 100%);
  --accent-strong-text: #0d1b26;

  /* Preisverlauf-Tabs: wie bei school/creative/mokka - #24B0FF ist trotz
     kräftiger Wirkung nach WCAG-Rechnung recht hell (Kontrast zu Weiß nur
     ~2.4:1), dunkle Schrift liest sich auf dem aktiven Tab also deutlich
     besser als Weiß (~8.7:1 Kontrast). */
  --accent-on-text: var(--tab-inactive-text);
}

/* Sanfter Theme-Wechsel: alle farbbezogenen Eigenschaften überblenden statt
   abrupt umzuspringen. Elemente mit eigener, spezifischerer transition-Regel
   (z.B. Hover-Effekte) behalten weiterhin ihr eigenes Timing – diese Regel
   greift nur dort als Fallback, wo sonst kein transition gesetzt ist.
   --transition-medium statt --transition-fast: extra für diesen Zweck
   bewusst langsamer/weicher als die 0.22-0.25s, die --transition-fast an
   anderer Stelle für schnelle Hover-Reaktionen braucht - ein kompletter
   Theme-Wechsel darf ruhig spürbar sanfter wirken als ein Hover.
   applyTheme()'s setTimeout in script.js ist auf die längste vorkommende
   --transition-medium-Dauer (0.45s) plus Puffer abgestimmt, damit die
   themeTransition-Klasse nicht vor Ende der Überblendung wieder entfernt
   wird. Bewusst über html.themeTransition statt permanent auf *: Eine
   dauerhafte Universal-Selector-Regel würde bei JEDER Style-Neuberechnung
   für JEDES Element der Seite mitgerechnet (inkl. aller bis zu 61
   Stationszeilen samt Kind-Elementen), nicht nur während eines
   tatsächlichen Theme-Wechsels. applyTheme() in script.js setzt/entfernt
   die Klasse automatisch. */
html.themeTransition *,
html.themeTransition *::before,
html.themeTransition *::after {
  transition: background-color var(--transition-medium), color var(--transition-medium), border-color var(--transition-medium), fill var(--transition-medium), stroke var(--transition-medium);
}

/* -------------------------------------------
   BODY
------------------------------------------- */

body {
  margin: 0;
  background: var(--color-bg);
  font-family: var(--font-body);
  color: var(--color-text);
  padding: 0;
}

/* -------------------------------------------
   HEADER
------------------------------------------- */

#appHeader {
  width: 100%;
  padding: var(--space-sm) 0;
  background: var(--color-surface-strong);
  color: var(--color-on-strong);
  border-bottom: 1px solid var(--color-border);
}

#appHeader .headerInner {
  width: 90%;
  max-width: 700px;
  margin: 0 auto;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
}

#appHeader .headerIcon {
  cursor: pointer;
  transition: transform var(--transition-fast), opacity var(--transition-fast);
}

#appHeader .headerIcon:hover {
  transform: scale(1.06);
  opacity: 0.9;
}

#appHeader .headerIcon svg {
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Äußerer Ring: zeichnet sich beim Laden der Seite einmal komplett ein,
   danach ein kurzer Leucht-Puls als Abschluss. Läuft nur einmal (forwards). */
.headerIconRing {
  stroke-dasharray: 472; /* Umfang bei r=75: 2 * PI * 75 ≈ 471,2, aufgerundet */
  stroke-dashoffset: 472;
  transform-origin: 100px 80px;
  animation:
    headerRingDrawIn 1.1s cubic-bezier(0.65, 0, 0.35, 1) forwards,
    headerRingGlowPulse 0.7s ease-out 1.1s forwards;
}

@keyframes headerRingDrawIn {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes headerRingGlowPulse {
  0% {
    filter: drop-shadow(0 0 0 rgba(59, 130, 246, 0));
  }
  50% {
    filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.9));
  }
  100% {
    filter: drop-shadow(0 0 0 rgba(59, 130, 246, 0));
  }
}

#appHeader .headerText {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
}

#appHeader .headerText h1 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.7rem;
  font-weight: var(--font-weight-semibold);
  letter-spacing: 0.02em;
  white-space: nowrap;
}

/* -------------------------------------------
   GEO TOGGLE BUTTON
------------------------------------------- */

#geoToggleButton {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 18px 32px;
  margin: 32px auto;
  background: var(--color-surface-strong);
  background-image: var(--panel-gradient, none);
  color: var(--color-on-strong);
  font-size: 1.25rem;
  font-weight: var(--font-weight-bold);
  border: var(--panel-border, none);
  border-radius: 50px;
  cursor: pointer;
  box-shadow: var(--panel-shadow, var(--shadow));
  transition:
    transform var(--transition-fast),
    box-shadow var(--transition-fast),
    background var(--transition-fast),
    color var(--transition-fast);
}

#geoToggleButton::-moz-focus-inner {
  border: 0;
}

#geoToggleButton svg {
  width: 22px;
  height: 22px;
  transition: transform 0.35s cubic-bezier(0.25, 0.85, 0.35, 1);
}

#geoToggleButton.open {
  background: var(--toggle-open-bg, var(--accent-strong-bg, var(--color-accent)));
  color: var(--toggle-open-text, var(--accent-strong-text, var(--color-white)));
}

#geoToggleButton.open .vline {
  opacity: 0;
  transition: opacity var(--transition-fast);
}

#geoToggleButton .hline {
  transition: opacity var(--transition-fast);
}

#geoToggleButton.open svg {
  transform: rotate(180deg);
}

/* -------------------------------------------
   GEO SEARCH BOX (SLIDE PANEL)
------------------------------------------- */

#geoSearchBox {
  width: 90%;
  max-width: 800px;

  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;

  margin: 0 auto;

  border-radius: var(--radius);
  background: var(--color-surface);
  background-image: var(--panel-gradient, none);
  border: var(--panel-border, none);

  box-shadow: var(--panel-shadow, var(--shadow));

  transition:
    grid-template-rows var(--transition-medium),
    opacity 0.35s ease-out,
    padding 0.3s ease-out,
    margin-top 0.3s ease-out;
}

#geoSearchBox.open {
  grid-template-rows: 1fr;
  opacity: 1;
  margin-top: var(--space-lg);
  margin-bottom:var(--space-xl);
  /* Oben etwas knapper als unten (space-sm statt space-md), damit der
     Abstand zur "Gib einen Ort ein"-Zeile direkt darunter kleiner wirkt -
     unten bleibt der größere Wert, da dort noch das Suchfeld folgt. */
  padding: var(--space-sm) 0 var(--space-md);
}

#geoSearchBoxInner {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-height: 0;
}

/* -------------------------------------------
   GEO INPUT
------------------------------------------- */

#geoInputHint {
  width: 90%;
  margin: 0 auto var(--space-sm);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.4;
  text-align: center;
}

/* Erster Satz ("Gib einen Ort ein.") optisch als eigene, hervorgehobene
   Zeile abgesetzt - kräftiger und in der normalen Textfarbe statt im
   gedämpften --color-text-muted des restlichen Hinweistextes. Die
   Zentrierung übernimmt bereits text-align: center von #geoInputHint oben
   (der Zeilenumbruch direkt danach im HTML sorgt dafür, dass dieser Teil
   wirklich als eigene Zeile umbricht). */
#geoInputHintLead {
  color: var(--color-text);
  font-weight: var(--font-weight-bold);
  /* Etwas größer als --font-size-base (0.95rem) - keine eigene Skalenstufe
     dafür vorhanden, daher fester Wert statt einer neuen, nur hier
     genutzten CSS-Variable. */
  font-size: 1.05rem;
}

#geoInput {
  width: 90%;
  margin: 0 auto;
  padding: var(--space-sm);
  font-size: 1.1rem;
  border-radius: var(--radius-small);
  border: 1px solid var(--color-border);
  outline: none;
  background: var(--color-surface-raised);
  color: var(--color-text);
  transition: background var(--transition-fast), border var(--transition-fast);
}

#geoInput:focus {
  background: var(--color-hover);
  border-color: var(--color-accent);
}

/* -------------------------------------------
   GEO: "ODER"-TRENNER + AKTUELLER STANDORT
------------------------------------------- */

.geoOrDivider {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 90%;
  margin: 14px auto;
  color: var(--color-text-muted);
  font-size: var(--font-size-tiny);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.geoOrDivider::before,
.geoOrDivider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--color-border);
}

#geoCurrentLocationBtn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 90%;
  margin: 0 auto;
  padding: var(--space-sm);
  background: transparent;
  color: var(--color-accent);
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  font-family: inherit;
  border: 1.5px solid var(--color-accent);
  border-radius: var(--radius-small);
  cursor: pointer;
  transition:
    background var(--transition-fast),
    color var(--transition-fast),
    border-color var(--transition-fast),
    transform var(--transition-fast);
}

#geoCurrentLocationBtn:not(:disabled):hover {
  background: var(--color-accent);
  color: var(--color-white);
  transform: translateY(-1px);
}

#geoCurrentLocationBtn svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

#geoCurrentLocationBtn:disabled {
  opacity: 0.7;
  cursor: default;
  transform: none;
}

#geoCurrentLocationBtn.loading svg {
  animation: geoLocatingPulse 1.1s ease-in-out infinite;
}

@keyframes geoLocatingPulse {
  0%, 100% { opacity: 0.4; transform: scale(0.85); }
  50% { opacity: 1; transform: scale(1.05); }
}

/* -------------------------------------------
   GEO RESULT — AUTO VISIBILITY
------------------------------------------- */

#geoResult {
  opacity: 0;
  padding: 0;
  width: 90%;
  margin: 0 auto;
  background: transparent;
  border-radius: var(--radius-small);
  min-height: 0;
  transition:
    opacity 0.35s ease,
    padding 0.35s ease,
    background 0.35s ease,
    margin 0.35s ease;
}

#geoResult.visible {
  opacity: 1;
  padding: 10px;
  margin: 14px auto;
  background: var(--color-surface);
  min-height: 20px;
}

/* Sanftes Einblenden des Inhalts */
.geoFadeIn {
  opacity: 0;
  transform: translateY(6px);
  animation: geoFadeInAnim 0.45s ease-out forwards;
}

@keyframes geoFadeInAnim {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Bestätigungsicon */
.geoConfirmBox {
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  padding:20px;
  background: var(--color-surface);
  border-radius:10px;
  color:var(--color-accent);
  font-size:1.35rem;
  box-shadow:0 0 12px rgba(0,0,0,0.45);
  opacity:0;
  transition:opacity 0.45s ease;
}

.geoConfirmText {
  margin-top: 10px;
}

/* -------------------------------------------
   GEO RESULT — MODERN LOCATION PIN (VARIANTE 2)
------------------------------------------- */

.geoResultItem {
  display: flex;
  gap: 14px;
  align-items: center;
  background: var(--color-surface-alt);
  padding: 14px 16px;
  border-radius: var(--radius);
  margin-top: 10px;
  border: 1px solid var(--color-hover);
  cursor: pointer;
  opacity: 0;
  transform: translateY(6px);
  animation: geoResultFadeIn 0.4s ease-out forwards;
  transition: background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}

.geoResultItem:hover,
.geoResultItem:focus-visible {
  background: var(--color-hover);
  border-color: var(--color-accent);
  transform: translateY(-2px);
  outline: none;
}

@keyframes geoResultFadeIn {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.geoPin {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  filter: drop-shadow(0 0 6px rgba(77, 163, 255, 0.55));
}

.geoResultText {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.geoResultLabel {
  font-size: var(--font-size-tiny);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 3px;
}

.geoResultAddress {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--font-size-base);
  color: var(--color-text);
  margin-bottom: 6px;
}

.geoResultCta {
  font-size: var(--font-size-tiny);
  font-weight: var(--font-weight-semibold);
  color: var(--color-accent);
}

/* Status-Meldungen im Geo-Suchergebnis (Fehler, kein Treffer, Bestätigung) */
.geoMessage {
  padding: 10px;
  color: var(--color-text-muted);
}

.geoMessage--error {
  /* War: fest #ffb4b4 (helles Pastellrot) - auf den beiden hellen Themes
     (paper/modern, siehe deren --color-bg: #faf9f7/#f5f5f3) ist das gegen
     den hellen Hintergrund kaum lesbar; das war für dunkle Hintergründe
     gedacht. var(--color-danger) wird bereits pro Theme passend kalibriert
     (siehe .settingsError, das dieselbe Variable schon für Text nutzt) und
     löst das automatisch für alle sechs Themes richtig statt nur fürs
     Dark-Theme, für das der alte Fixwert ursprünglich gewählt wurde. */
  color: var(--color-danger);
}

/* Deutlich hervorgehobene Variante für wichtige, aber nicht fehlerhafte
   Hinweise (z.B. "Ort bereits gespeichert") - im Gegensatz zu .geoMessage
   (blasser Fließtext) und .geoMessage--error (Fehlerrot) bewusst mit
   eigenem Farbfeld, Rahmen und Icon, damit sie nicht als beiläufige
   Statuszeile überlesen wird. */
.geoMessage--notice {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 16px;
  color: #7a5900;
  background: #ffe4a3;
  border: 1px solid #f0c04d;
  border-radius: var(--radius);
  font-weight: var(--font-weight-bold);
  text-align: center;
}

.geoMessage--notice svg {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
}

/* -------------------------------------------
   TABLE
------------------------------------------- */

.table {
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius);
  overflow: hidden;
}

#tablesWrapper {
  width: 95%;
  /* Kein fester Cap auf 2 Spalten mehr – wächst mit dem Bildschirm, damit
     auf breiten Screens auch 3+ Tabellen nebeneinander passen können.
     Generöser Sanity-Cap bei 6 Spalten, damit es auf Ultrawide nicht
     ausufert. */
  max-width: calc(var(--table-max-width) * 6 + var(--tables-gap) * 5);
  margin: 0 auto;
}

/* Tabellen nebeneinander anordnen, sobald die Breite reicht – unabhängig von
   der Geräte-Ausrichtung. Jede Spalte ist zwischen --table-min-width und
   --table-max-width breit; der Browser berechnet die Spaltenanzahl einmal
   für den ganzen Container, daher sind alle Zeilen konsistent breit. */
#tablesContainer {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(var(--table-min-width), 100%), 1fr));
  justify-content: center;
  align-items: start;
  gap: var(--tables-gap);
}

/* Sicherheitsnetz: im Querformat IMMER mindestens 2 Spalten, unabhängig davon,
   ob die exakte verfügbare Breite (z.B. wegen Adressleiste/Notch) knapper
   ausfällt als erwartet. Der Mindestwert ist das Minimum aus der gewünschten
   --table-min-width und der Breite, die exakt 2 Spalten ermöglicht – so kann
   auto-fit nie auf 1 Spalte zurückfallen. */
@media (orientation: landscape) {
  #tablesContainer {
    grid-template-columns: repeat(
      auto-fit,
      minmax(min(var(--table-min-width), calc((100% - var(--tables-gap)) / 2)), 1fr)
    );
  }
}

#noLocationsNotice {
  text-align: center;
  color: var(--color-text-muted);
  font-size: 1.15rem;
  padding: 28px 12px;
  border-radius: var(--radius);
  background: var(--color-surface);
  box-shadow: var(--shadow);
}

.locationTable {
  max-width: var(--table-max-width);
  justify-self: center;
  width: 100%;
  margin-bottom: 0;
  background-image: var(--panel-gradient, none);
  border: var(--panel-border, none);
  box-shadow: var(--panel-shadow, none);
  /* .table (siehe oben) macht daraus per flex-direction:column bereits
     einen vertikalen Stapel für Caption/locationTableBody. */
  container-type: inline-size;
}

/* Zeile unterhalb der Caption mit mainCol darin - eigene Zeile bleibt
   bestehen (statt mainCol direkt in .locationTable zu hängen), auch ohne
   die früher hier ebenfalls untergebrachte Preisverlauf-Seitenleiste. */
.locationTableBody {
  display: flex;
  flex-direction: row;
  align-items: stretch;
}

.locationTableMain {
  /* Eigener Flex-Column-Kontext für Header/StationContainer/Footer -
     entspricht 1:1 dem, was vorher .table (flex-direction:column) direkt
     für diese Elemente geleistet hat (Caption liegt jetzt eine Ebene
     höher, siehe .locationTable oben). */
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  /* Die cqw-Einheiten für Header-/Zeilen-/Namen-Schriftgrößen sollen sich
     an DIESER Spalte orientieren - entspricht seit Entfernen der
     Preisverlauf-Seitenleiste ohnehin immer der vollen Breite von
     .locationTable. Die Caption (jetzt außerhalb von mainCol) nutzt
     bewusst den weiter oben gesetzten container-type von .locationTable
     selbst, damit ihre Schriftgröße mit der vollen, sichtbaren Breite
     mitskaliert. */
  container-type: inline-size;
}

/* Status-Meldungen innerhalb einer stationContainer (Laden/Leer/Fehler) */
.stationMessage {
  padding: 18px;
  color: var(--color-text-muted);
}

.stationMessage--error {
  /* Gleiche Begründung wie bei .geoMessage--error oben - war fest auf
     dunkle Hintergründe kalibriert, auf paper/modern kaum lesbar. */
  color: var(--color-danger);
}

/* -------------------------------------------
   CAPTION
------------------------------------------- */
.caption {
  background: var(--caption-bg, var(--color-surface-2));
  border-bottom: var(--caption-border, none);
  padding: 10px 20px 10px 14px;
  font-family: var(--font-display);
  font-size: clamp(1.3rem, calc(0.9rem + 1.6cqw), 1.5rem);
  font-weight: 500;
  letter-spacing: 0.3px;
  /* Icon | Text | Spiegel-Spacer, damit der Text visuell mittig bleibt.
     Die äußeren Spalten sind minmax(40px, auto) statt starr 40px: in der
     schmalen Ansicht bleiben sie exakt 40px (= Button-Größe), können aber
     wachsen, sobald ab einer Container-Breite zusätzlich der Label-Text
     ("Einstellungen"/"Preisverlauf") neben dem Icon eingeblendet wird -
     siehe .captionBtnLabel weiter unten. Das Icon ist dadurch weiterhin ein
     echtes Grid-Item und beansprucht garantiert Platz – der Text kann
     rechnerisch nie mehr darunter rutschen, unabhängig von JS-Timing oder
     Web-Font-Ladezeit. */
  display: grid;
  grid-template-columns: minmax(40px, auto) 1fr minmax(40px, auto);
  align-items: center;
  gap: 12px;
  opacity: 0;
  animation: captionFadeIn 0.8s ease-out forwards;
}

/* Ohne Einstellungen-Icon (z.B. Session-Standort-Tabelle): nur eine Spalte,
   Text zentriert sich dadurch ganz normal über die volle Breite. */
.caption.caption--noIcon {
  grid-template-columns: 1fr;
}

/* Die dritte Spalte (26px) ist normalerweise nur ein unsichtbarer
   Spiegel-Spacer (gleiche Breite wie das Einstellungen-Icon links), damit
   der Text visuell mittig bleibt. Ist die Preisverlauf-Erfassung aktiv,
   nimmt genau diese Spalte stattdessen das Preisverlauf-Icon auf – die
   Breite passt exakt, keine Grid-Anpassung nötig. */

.captionIcon {
  width: 22px;
  height: 22px;
  transition: transform var(--transition-medium);
}

.captionHistoryIcon {
  width: 22px;
  height: 22px;
  transition: transform var(--transition-medium);
}

/* .captionHistoryBtn.open (nicht .captionHistoryIcon.open direkt) - seit
   dem Button-Wrapper-Umbau landet die open-Klasse nur noch auf dem
   Button, nie mehr auf dem Icon selbst. */
.captionHistoryBtn.open .captionHistoryIcon {
  transform: scale(1.1);
}

/* Button-Wrapper um Zahnrad-/Trend-Icon: schlichte, komplett gefüllte
   Pille statt Skeuomorph-Badge - genau dieselbe Sprache wie
   .settingsSaveBtn/.settingsDeleteBtn (Vollfläche, --radius-pill, Hover
   mit leichtem Lift). Ruhezustand nutzt --color-surface-strong/
   --color-on-strong (dieselbe Kombi wie Header-Leiste/Toggle-Buttons laut
   deren eigenem Kommentar oben - dafür gedacht), passt sich also jedem
   Theme automatisch an, ohne eigene Farbwerte pflegen zu müssen. */
.captionSettingsBtn,
.captionHistoryBtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 40px;
  height: 40px;
  background: var(--color-surface-strong);
  color: var(--color-on-strong);
  border: none;
  border-radius: var(--radius-pill);
  padding: 0;
  margin: 0;
  cursor: pointer;
  font: inherit;
  transition: background var(--transition-fast), transform var(--transition-fast);
}

.captionSettingsBtn:hover,
.captionHistoryBtn:hover {
  background: color-mix(in srgb, var(--color-surface-strong) 85%, white);
  transform: translateY(-1px);
}

/* Offener Zustand: derselbe Wechsel zur Akzentfarbe wie beim
   "Speichern"-Button (dort bei :hover, hier dauerhaft solange das Panel
   offen ist) - macht auf einen Blick klar, welches Icon gerade aktiv ist,
   ganz ohne zusätzliche Schatten-/Glanz-Konstruktion. */
.captionSettingsBtn.open,
.captionHistoryBtn.open {
  background: var(--color-accent);
  color: var(--accent-on-text);
}

.captionSettingsBtn.open:hover,
.captionHistoryBtn.open:hover {
  background: color-mix(in srgb, var(--color-accent) 82%, white);
}

.captionBtnLabel {
  display: none;
  font-size: 0.78rem;
  font-weight: 500;
  white-space: nowrap;
}

/* 500px auf Wunsch gesetzt (vorher per Playwright-Test bei 640px ermittelt
   - dieser neue Wert wurde nicht auf dieselbe Art nachgetestet). Ab hier
   soll genug Platz für Icon + Label auf beiden Seiten sein, ohne dass die
   Standort-Caption in der Mitte spürbar gequetscht wird oder die Buttons
   sich mit ihr überlappen - bei sehr langen Ortsnamen lohnt sich ein Blick,
   ob das bei 500px noch zutrifft. */
@container (min-width: 500px) {
  .captionSettingsBtn,
  .captionHistoryBtn {
    width: auto;
    padding: 0 18px 0 12px;
  }

  .captionBtnLabel {
    display: inline;
  }
}

.captionText {
  min-width: 0; /* erlaubt dem Grid-Item, unter seine Inhaltsbreite zu schrumpfen */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis; /* Sicherheitsnetz, falls JS (noch) nicht gelaufen ist */
  text-align: center;
  font-weight: 600;
}

/* Wird per JS gesetzt, wenn der Ortsname selbst bei minimaler Schriftgröße
   nicht einzeilig passt: dann lieber umbrechen als mit "…" abzuschneiden. */
.captionText.captionTextWrapped {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: break-word;
  line-height: 1.25;
}

/* .captionSettingsBtn.open (nicht .captionIcon.open direkt) - siehe
   Kommentar bei .captionHistoryBtn.open weiter oben, gleicher Grund. */
.captionSettingsBtn.open .captionIcon {
  transform: rotate(90deg);
}

@keyframes captionFadeIn {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* -------------------------------------------
   TABELLENKOPF (SORTIERBARE SPALTEN)
------------------------------------------- */
.header {
  position: relative;
  display: grid;
  grid-template-columns: var(--col-template);
}

/* Zusätzliche schmale Statistik-Spalte: nur vorhanden, wenn für den Ort
   "Preisverlauf erfassen" aktiv ist (Klasse wird von buildLocationTableElement
   / syncHistoryIcon in script.js gesetzt bzw. entfernt). */
.locationTable--withStats .header,
.locationTable--withStats .stationRow {
  grid-template-columns: var(--col-template-stats);
}

.header .col {
  background: var(--color-surface-strong);
  color: var(--color-on-strong);
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 12px 0;
  font-size: clamp(1.1rem, calc(0.7rem + 1.6cqw), 1.3rem);
  font-weight: 600;
  transition: background var(--transition-fast), color var(--transition-fast);
  /* Ohne das hier würde jede 1fr-Spalte mindestens so breit werden wie ihr
     Inhalt ("Diesel" ist z.B. breiter als "e5") - CSS-Grid behandelt 1fr
     intern als minmax(auto, 1fr), "auto" = Inhaltsbreite. Das Textwort
     "Diesel" zwingt seine Spalte dadurch über ihren fairen 1fr-Anteil
     hinaus und nimmt der Namensspalte Platz weg - und zwar NUR im Header
     (die Datenzeilen darunter zeigen ja nur kurze Zahlen, kein Textwort),
     wodurch Header- und Datenspalten unterschiedlich breit wurden. */
  min-width: 0;
}

.header .col[data-sort] {
  cursor: pointer;
  /* Gleiches horizontales Padding wie bei den Datenzeilen (siehe
     .stationRow .col:not(.stationNameCol)), damit Spaltenköpfe und Werte
     sauber übereinander ausgerichtet bleiben. */
  padding-left: 4px;
  padding-right: 4px;
}

.header .col.activeSort {
  /* Gleicher Hintergrund wie die hervorgehobene Spalte in den Datenzeilen
     (siehe .stationRow .col.colHighlight::before, nutzt dieselbe Variable
     --color-row-highlight) - Kopf- und Datenspalte sollen optisch als eine
     zusammenhängende, hervorgehobene Spalte wirken statt nur der Kopf
     einen andersartigen (reinen Border-)Indikator zu zeigen. Der
     Rand oben (2px) bleibt bestehen, zusätzlich gibt es unten einen
     1px-Rand - beide sind bewusst kein Ersatz für die Fläche.
     Kein eigener ::before nötig wie bei den Datenzeilen (dort wegen der
     dortigen Rundungen/Überlappungen mit dem Zeilen-Hover) - der
     Tabellenkopf ist eine flache Leiste ohne solche Überschneidungen,
     background direkt auf dem Element reicht hier aus. */
  background: var(--color-row-highlight);
  border-top: 2px solid var(--color-accent);
  border-bottom: 1px solid var(--color-accent);
  /* Padding jeweils um genau die Randbreite reduziert (oben 12px - 2px,
     unten 12px - 1px), damit border + padding auf beiden Seiten weiterhin
     12px ergeben wie bei den inaktiven Spalten (nur padding, kein border)
     - sonst würde der Text hier gegenüber den Nachbarspalten verrutschen. */
  padding-top: 10px;
  padding-bottom: 11px;
}

.header .col.headerStationName {
  justify-content: flex-start;
  padding-left: 10px;
}

.headerStationName::before {
  content: "Tankstelle";
}

.header .col[data-sort="e5"]::before {
  content: "e5";
}
.header .col[data-sort="e10"]::before {
  content: "e10";
}
.header .col[data-sort="diesel"]::before {
  content: "Diesel";
}

/* Kraftstoffarten-Spalten etwas kleiner setzen, damit "Diesel" ausgeschrieben
   in die gleiche Spaltenbreite passt wie zuvor "Die". Gilt einheitlich für
   e5/e10/diesel, damit die Header-Schriftgröße innerhalb der Zeile konsistent
   bleibt. */
.header .col[data-sort="e5"],
.header .col[data-sort="e10"],
.header .col[data-sort="diesel"] {
  font-size: clamp(0.85rem, calc(0.55rem + 1.2cqw), 1rem);
}

.headerDistanceText {
  display: none;
  /* Gleiche Schriftgröße wie e5/e10/diesel (siehe Regel oben), statt der
     größeren Standard-Header-Schrift - sonst wirkt "Entfernung" neben den
     Kraftstoffarten-Spalten unpassend groß. */
  font-size: clamp(0.85rem, calc(0.55rem + 1.2cqw), 1rem);
}

.distanceIcon {
  width: 22px;
  height: 22px;
  opacity: 0.9;
}

/* Zeigt "Entfernung" als Text statt des Pfeil-Icons, sobald die Tabelle
   (.locationTableMain, container-type:inline-size) genug Breite hat, dass
   das Wort in die Sortierspalte passt, ohne dass diese dafür breiter
   werden müsste als mit dem Icon - dank min-width:0 auf .header .col
   (siehe dort) kann die Spalte ohnehin nicht mehr wachsen, das Wort würde
   sonst nur unschön abgeschnitten.
   580px per Playwright-Test ermittelt: deckt sowohl die normale Variante
   (--col-template) als auch die Variante mit zusätzlicher Statistik-
   Spalte (--col-template-stats, die der Entfernungs-Spalte Platz
   wegnimmt) sicher ab, jeweils mit ein paar Pixeln Puffer für Font-
   Rendering-Unterschiede zwischen Browsern/Betriebssystemen. */
@container (min-width: 580px) {
  .headerDistanceIcon {
    display: none;
  }

  .headerDistanceText {
    display: block;
  }
}

/* -------------------------------------------
   EINSTELLUNGEN-PANEL (Slide-Down/Up wie bei der Stations-InfoBox)
------------------------------------------- */
.tableSettingsPanel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  background: var(--color-surface-alt);
  transition: var(--collapse-transition);
}

.tableSettingsPanel.open {
  grid-template-rows: 1fr;
  opacity: 1;
  border-bottom: 1px solid var(--color-border);
}

.tableSettingsCollapse {
  overflow: hidden;
  min-height: 0;
}

.tableSettingsContent {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  padding: 22px 24px;
}

/* -------------------------------------------
   PREISVERLAUF-PANEL (gleiche Slide-Down/Up-Technik wie Einstellungen)
------------------------------------------- */
.tablePriceHistoryPanel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  background: var(--color-surface-alt);
  transition: var(--collapse-transition);
}

.tablePriceHistoryPanel.open {
  grid-template-rows: 1fr;
  opacity: 1;
  border-bottom: 1px solid var(--color-border);
}

.tablePriceHistoryCollapse {
  overflow: hidden;
  min-height: 0;
}

.tablePriceHistoryContent {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Einheitlicher Abstand (16px) zu ALLEN gerahmten Blöcken innerhalb
     des Preisverlaufs - siehe auch .priceHistoryChartArea weiter unten,
     die denselben Wert für die Blöcke darin nutzt. Vorher hatte praktisch
     jeder Übergang (hier, dort, einzelne Margins an den Kindern) einen
     eigenen, leicht anderen Wert - wirkte dadurch uneinheitlich. */
  gap: 16px;
  /* Nur oben/unten, in gleicher Höhe wie gap - sorgt dafür, dass der
     Abstand vom ersten Block nach oben und vom letzten Block nach unten
     genauso groß ist wie zwischen den Blöcken selbst. Bewusst OHNE
     links/rechts (siehe Kommentar unten): die gerahmten Blöcke darin
     setzen ihre width:96% bereits selbst relativ zu diesem Element - ein
     zusätzliches horizontales Padding hier würde sich mit deren eigener
     96%-Breite addieren und sie optisch schmaler wirken lassen, als "96%"
     erwarten lässt. */
  padding: 16px 0;
  min-height: 120px;
}

.priceHistoryPlaceholder {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-base);
  text-align: center;
}

/* Wenn die gestapelten 7-Tage-Sektionen (.priceHistoryWeekStack, siehe
   dort) vorhanden sind (auch im "keine Daten"-Zustand), soll der Inhalt
   oben bleiben statt vertikal zu zentrieren - sonst vergrößert sich bei
   kurzem Inhalt der Abstand zur Leiste darüber, weil
   .tablePriceHistoryContent sonst den ganzen Block mittig im
   min-height-Bereich zentriert. */
.tablePriceHistoryContent:has(.priceHistoryWeekStack) {
  justify-content: flex-start;
}

.settingsOption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
  max-width: 400px;
  text-align: center;
  padding: 16px 14px;
  border: 1px solid var(--color-card-border);
  border-radius: var(--radius);
  background: var(--color-card-bg);
}

.settingsLabel {
  font-size: var(--font-size-base);
  color: var(--color-text-muted);
}

.settingsInput {
  background: var(--color-hover);
  border: 1px solid var(--color-input-border);
  border-radius: 8px;
  padding: 9px 12px;
  color: var(--color-text);
  font-size: 1.05rem;
  font-family: inherit;
  text-align: center;
  width: 85%;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.settingsInput:focus {
  outline: none;
  border-color: var(--color-accent);
  background: var(--color-surface-raised);
}

.settingsInput.invalid {
  border-color: var(--color-danger);
}

/* Koordinaten-Fußzeile: liegt bewusst AUSSERHALB von .settingsOption (kein
   Rahmen, kein Hintergrund, keine Card-Umrandung), da es sich um reine
   Zusatzinfo ohne Bedienelement handelt - steht deshalb als letzte Zeile
   ganz unten im Panel statt zwischen den echten Einstellungs-Optionen.
   Dezente Optik (Monospace, gedämpfte Farbe, niedrige Deckkraft) - gleiche
   Behandlung wie .stationInfoId, da beides reine Zusatzinfo ohne
   Handlungsbedarf ist, kein Bedienelement. */
.settingsCoordinatesFooter {
  width: 100%;
  margin-top: 4px;
  text-align: center;
  color: var(--color-text-muted);
  opacity: 0.6;
  font-size: var(--font-size-tiny);
  font-family: ui-monospace, "SF Mono", "Cascadia Code", monospace;
}

.settingsInputNumber {
  width: 56px;
  max-width: 56px;
  flex: none;
  padding-right: 26px;
  text-align: center;
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.5px;
}

.settingsRadiusInputWrapper {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.settingsRadiusUnit {
  position: absolute;
  right: 9px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  pointer-events: none;
}

.settingsSwitch {
  position: relative;
  display: inline-block;
  cursor: pointer;
}

.settingsSwitch .settingsCheckbox {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.settingsSwitchTrack {
  position: relative;
  display: flex;
  align-items: center;
  width: 96px;
  height: 38px;
  border-radius: 19px;
  background: var(--color-hover);
  border: 1px solid var(--color-input-border);
  transition: background var(--transition-fast), border-color var(--transition-fast);
}

.settingsSwitchOn,
.settingsSwitchOff {
  flex: 1;
  text-align: center;
  font-size: var(--font-size-small);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text-muted);
  user-select: none;
  z-index: 1;
  transition: color var(--transition-fast);
}

.settingsSwitchKnob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 44px;
  height: 32px;
  border-radius: 16px;
  background: var(--color-accent);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  transition: transform var(--transition-fast), background var(--transition-fast);
}

.settingsCheckbox:checked + .settingsSwitchTrack,
.settingsCheckbox:not(:checked) + .settingsSwitchTrack {
  border-color: var(--color-input-border);
}

.settingsCheckbox:not(:checked) + .settingsSwitchTrack .settingsSwitchKnob {
  transform: translateX(48px);
}

.settingsCheckbox:checked + .settingsSwitchTrack .settingsSwitchOn {
  color: var(--color-text);
  font-weight: var(--font-weight-bold);
}

.settingsCheckbox:not(:checked) + .settingsSwitchTrack .settingsSwitchOff {
  color: var(--color-text);
  font-weight: var(--font-weight-bold);
}

.settingsCheckbox:focus-visible + .settingsSwitchTrack {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.settingsError {
  display: none;
  color: var(--color-danger);
  font-size: var(--font-size-small);
  text-align: center;
  max-width: 320px;
}

.settingsError.visible {
  display: block;
}

.settingsSaveRow {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  width: 100%;
  margin-top: 4px;
}

.settingsSaveBtn {
  background: var(--color-accent);
  color: var(--color-white);
  border: none;
  border-radius: var(--radius-pill);
  padding: 10px 30px;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  font-family: inherit;
  cursor: pointer;
  transition: background var(--transition-fast), transform var(--transition-fast);
}

.settingsSaveBtn:hover {
  /* War: fest #5b9cff - passte nur zufällig zum Blau des Dark-Themes
     (--color-accent dort: var(--blue-500) = #3b82f6), zeigte in JEDEM
     anderen Theme (paper/modern/school/creative/mokka) beim Hover einen
     unpassenden blauen Farbton statt einer aufgehellten Version der
     jeweiligen Akzentfarbe. color-mix() macht das jetzt für jedes Theme
     automatisch richtig, ohne pro Theme einen eigenen Hover-Wert pflegen
     zu müssen. Erste background-Zeile ist der Fallback für Browser ohne
     color-mix()-Unterstützung (bleibt dann schlicht bei der normalen
     Akzentfarbe statt eines falschen Fixtons).
     Gleiches Muster bereits an anderer Stelle im Code etabliert (siehe
     --accent-gradient bei [data-theme="paper"]/[data-theme="modern"]). */
  background: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 82%, white);
  transform: translateY(-1px);
}

.settingsDeleteBtn {
  background: var(--color-danger);
  color: var(--color-white);
  border: none;
  border-radius: var(--radius-pill);
  padding: 10px 30px;
  font-size: var(--font-size-base);
  font-weight: var(--font-weight-semibold);
  font-family: inherit;
  cursor: pointer;
  transition: background var(--transition-fast), transform var(--transition-fast);
}

.settingsDeleteBtn:hover {
  background: var(--color-danger-hover);
  transform: translateY(-1px);
}

/* -------------------------------------------
   DATENZEILEN
------------------------------------------- */
.stationContainer {
  background: var(--color-surface-2);
  /* Viele Orts-/Stationstabellen können untereinander liegen. Offscreen-
     Tabellen müssen dadurch nicht vollständig layouten/painten. */
  content-visibility: auto;
  contain-intrinsic-size: 0 420px;
}

.stationRow {
  display: grid;
  grid-template-columns: var(--col-template);
  border-bottom: 1px solid var(--color-border);
  font-size: clamp(1.05rem, calc(0.75rem + 1.2cqw), 1.2rem);
  transition: background var(--transition-fast);
  opacity: 0;
  animation: rowFadeIn 0.8s ease-out forwards;
}

.stationRow:hover {
  background: var(--color-hover);
}

.stationRow .col:not(.stationNameCol) {
  font-family: var(--font-numeric);
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  font-size: clamp(0.87rem, calc(0.64rem + 0.85cqw), 0.92rem);
  letter-spacing: 0.5px;
  /* Etwas Luft links/rechts, damit die Zahlen nicht direkt an der
     Spaltengrenze kleben (vorher: padding:6px 0 von .stationRow .col
     unten, also gar kein horizontales Padding). Bewusst nur hier und
     nicht am .stationNameCol-Padding weiter unten geändert - der Name
     behält so exakt so viel Platz wie vorher. */
  padding-left: 4px;
  padding-right: 4px;
}

.stationRow .col {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  overflow: hidden;
  padding: 6px 0;
  /* Siehe Kommentar bei .header .col - dieselbe Absicherung, damit auch
     hier künftig kein Inhalt eine 1fr-Spalte über ihren fairen Anteil
     hinaus aufblähen kann. */
  min-width: 0;
}

/* .stationNameCol hat als einzelne Klasse eine NIEDRIGERE Spezifität als
   dieser Vorfahren-Selektor (.stationRow .col) und würde ihr eigenes
   justify-content/align-items sonst nicht durchsetzen können - deshalb
   hier explizit ausgenommen, statt die Werte weiter unten (wirkungslos)
   zu überschreiben. */
.stationRow .col.stationNameCol {
  justify-content: center;
  align-items: flex-start;
  /* Gleiches linkes Padding wie .header .col.headerStationName (10px),
     damit "Tankstellenname" in den Datenzeilen bündig unter "Tankstelle"
     im Tabellenkopf steht (war vorher 6px, leicht nach links versetzt). */
  padding-left: 10px;
}

/* Spaltenhighlight */
.stationRow .col.colHighlight::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--color-row-highlight);
  pointer-events: none;
}

.stationNameCol {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  padding: 6px 8px;
  text-align: left;
}

.stationStatsCol {
  color: var(--color-accent);
  padding-left: 6px;
  padding-right: 6px;
}

.stationStatsIcon {
  width: 18px;
  height: 18px;
  color: var(--color-accent);
  opacity: 0.85;
  cursor: pointer;
  transition: opacity var(--transition-fast), transform var(--transition-medium);
}

.stationStatsIcon:hover {
  opacity: 1;
}

.stationStatsIcon.open {
  transform: scale(1.12);
}

.headerStationStats {
  color: var(--color-on-strong);
}

.stationName {
  font-size: clamp(0.95rem, calc(0.68rem + 1.1cqw), 1.1rem);
  font-weight: 500;
}

.stationAddress {
  font-size: clamp(0.72rem, calc(0.54rem + 0.72cqw), 0.82rem);
  color: var(--color-text-muted);
  font-weight: 400;
}

/* Entfernungsspalte: Zahl + "km" statt in einer Zeile ("1,3 km") jetzt
   zweizeilig ("1,3" / "km") - eine Zeile wurde auf schmalen Bildschirmen
   zu breit für die Spalte und ist umgebrochen. .stationRow .col setzt
   bereits display:flex; hier zusätzlich auf Spaltenrichtung umgestellt,
   damit sich die zwei <span> darin untereinander statt nebeneinander
   anordnen. */
.distanceCol {
  flex-direction: column;
  gap: 1px;
}

.distanceUnit {
  /* Gleiche Optik wie die Adresszeile unter dem Tankstellennamen
     (.stationAddress) - bewusst kein eigener Font-Size-Wert, damit beide
     Stellen bei künftigen Anpassungen automatisch synchron bleiben.
     letter-spacing explizit zurückgesetzt, da .stationRow .col (Elternteil)
     dafür 0.5px setzt (wirkt bei den reinen Zahlenspalten gut, bei
     Fließtext wie "km" aber unpassend). */
  font-size: clamp(0.72rem, calc(0.54rem + 0.72cqw), 0.82rem);
  color: var(--color-text-muted);
  font-weight: 400;
  letter-spacing: normal;
}

@keyframes rowFadeIn {
  0% {
    opacity: 0;
    transform: translateY(10px);
    filter: blur(3px);
  }
  60% {
    opacity: 0.7;
    transform: translateY(2px);
    filter: blur(1px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* -------------------------------------------
   STATIONS-INFOBOX (Slide-Down bei Klick auf eine Zeile)
------------------------------------------- */

.stationInfoBox {
  grid-column: 1 / -1; /* volle Tabellenbreite */
  background: var(--color-surface-alt);
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: var(--collapse-transition);
}

.stationInfoBox.open {
  grid-template-rows: 1fr;
  opacity: 1;
  border-left: 3px solid var(--color-accent);
  border-bottom: 1px solid var(--color-border);
}

.stationInfoCollapse {
  overflow: hidden;
  min-height: 0;
}

.stationInfoContent {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  font-size: 1rem;
  padding: 16px 18px;
}

/* -------------------------------------------
   STATIONS-PREISVERLAUF-BOX (gleiche Slide-Down/Up-Mechanik wie die
   Stations-InfoBox) – aktuell nur Platzhalter, echte Statistik folgt später.
------------------------------------------- */
.stationStatsBox {
  grid-column: 1 / -1; /* volle Tabellenbreite */
  background: var(--color-surface-alt);
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: var(--collapse-transition);
}

.stationStatsBox.open {
  grid-template-rows: 1fr;
  opacity: 1;
  border-left: 3px solid var(--color-accent);
  border-bottom: 1px solid var(--color-border);
}

.stationStatsCollapse {
  overflow: hidden;
  min-height: 0;
}

.stationStatsContent {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Gleicher Wert wie .tablePriceHistoryContent (siehe dort) - beide
     Varianten sollen dieselben Abstände zwischen den Blöcken zeigen. */
  gap: 16px;
  min-height: 100px;
  padding: 6px 8px;
}

.priceHistoryTabsGroup {
  display: flex;
  flex-direction: column;
  /* stretch statt center: Titelleiste und Bereichs-Tab-Leiste sollen
     beide die volle Breite der Gruppe einnehmen, statt jede für sich nur
     an ihren eigenen Inhalt angepasst zu sein - das führte vorher dazu,
     dass die Titelleiste breiter wirkte als die schmalere, inhaltsbasiert
     bemessene Tab-Leiste darunter. */
  align-items: stretch;
  align-self: center;
  /* Eigener Rahmen um die ganze Gruppe (Titel- + Bereichs-Tab-Leiste
     zusammen) - zusätzlich zu deren jeweils EIGENEM Rahmen (siehe
     .priceHistoryTitleBar/.priceHistoryTabs), nicht statt dessen. */
  width: 96%;
  box-sizing: border-box;
  background: color-mix(in srgb, currentColor 5%, transparent);
  border: 1px solid var(--tab-outline-color);
  border-radius: var(--radius);
  padding: 14px;
  /* --tab-seam-gap statt hartem Wert: 0 in allen Themes (siehe Kommentar
     bei --tab-seam-gap in :root) - jede der drei Leisten hat jetzt einen
     eigenen echten Rahmen, der die Trennung übernimmt. */
  gap: var(--tab-seam-gap);
}

/* "Preisverlauf"-Titelleiste über der Bereichs-Tab-Leiste: nur ein
   einzelner, nicht interaktiver Tab. Bewusst etwas SCHMALER als die
   Bereichs-Tab-Leiste darunter (statt volle Gruppenbreite wie diese) -
   dadurch wirkt sie sichtbar als "Titel" über der eigentlichen Leiste,
   nicht als gleichrangige dritte Leiste. Seitlich deutlich mehr
   Innenabstand als bei .priceHistoryTab darunter; oben/unten dagegen
   bewusst knapper. Nur die oberen Ecken abgerundet - die unteren bleiben
   eckig, da direkt darunter (nur 1px Abstand) die Bereichs-Tab-Leiste mit
   eigener voller Rundung folgt. */
.priceHistoryTitleBar {
  /* Überschreibt das stretch der Gruppe - schmaler als 100% und über
     auto-Ränder zentriert. 88% der Gruppe = 70,4% vom Panel - liegt damit
     sichtbar schmaler als die volle Gruppenbreite, wirkt dadurch als
     eigener "Titel" über der Bereichs-Tab-Leiste darunter. */
  align-self: center;
  width: 88%;
  display: flex;
  border-radius: var(--radius) var(--radius) 0 0;
  overflow: hidden;
  /* Rand + Schlagschatten - nur in den hellen Themes sichtbar (siehe
     --tab-outline-color/--tab-outer-shadow in :root bzw. den Theme-
     Blöcken), damit sich die Leiste dort klar vom hellen Seitenhintergrund
     abhebt. Unten bewusst OHNE Rand: direkt darunter (--tab-seam-gap
     Abstand, siehe :root) folgt die Bereichs-Tab-Leiste mit eigenem
     Oberrand - zwei so eng benachbarte Rahmenlinien hätten den Abstand
     optisch breiter wirken lassen, als er tatsächlich ist. */
  border: 1px solid var(--tab-outline-color);
  border-bottom: none;
  box-shadow: var(--tab-outer-shadow);
}

.priceHistoryTitleTab {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* Fallback für Browser ohne color-mix()-Unterstützung (die
     --tab-inactive-*-Variablen sind in helleren Themes darüber
     abgeleitet - siehe :root/Theme-Blöcke) - wird von der Zeile darunter
     überschrieben, sobald color-mix() unterstützt wird. */
  background: #E5E5E5;
  background: var(--tab-inactive-gradient);
  color: var(--tab-inactive-text);
  font-family: inherit;
  font-size: var(--font-size-base);
  font-weight: 600;
  line-height: 1.2;
  padding: 8px 40px;
  white-space: nowrap;
}

.priceHistoryTabs {
  display: flex;
  width: 100%;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--tab-outline-color);
  box-shadow: var(--tab-outer-shadow);
}

.priceHistoryTab {
  flex: 1 1 0;
  /* Ohne das hier würde der Browser jedem Tab trotz flex:1 1 0 weiterhin
     mindestens seine Inhalts-Breite geben (Flexbox-Standard: min-width:
     auto) - "30 Tage" bekäme dadurch mehr Platz als "Jahr". Erzwingt
     wirklich gleich breite Tabs. */
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  border: none;
  border-right: 1px solid var(--tab-inactive-border);
  /* Farben über --tab-inactive-* Variablen (siehe :root/Theme-Blöcke):
     dunkle Themes nutzen einen festen Hellton, helle Themes eine aus der
     eigenen Oberflächenfarbe abgeleitete, abgedunkelte Variante.
     Fallback für Browser ohne color-mix()-Unterstützung s.u. */
  background: #E5E5E5;
  background: var(--tab-inactive-gradient);
  color: var(--tab-inactive-text);
  font-family: inherit;
  font-size: var(--font-size-small);
  font-weight: 600;
  line-height: 1.2;
  /* Mehr Höhe als zuvor (war 8px 14px) */
  padding: 14px 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.priceHistoryTab:last-child {
  border-right: none;
}

.priceHistoryTab:hover:not(.priceHistoryTab--active) {
  background: #DADADA;
  background: var(--tab-inactive-hover-gradient);
}

.priceHistoryTab--active {
  /* Highlight-Farbe kommt aus der Theme-Variable --color-accent (ändert
     sich automatisch mit dem gewählten Farbthema) - color-mix() erzeugt
     daraus einen hellen oberen und dunkleren unteren Verlaufston, analog
     zum bereits vorhandenen Muster bei den Balkendiagramm-Farbverläufen.
     Fallback (flache Akzentfarbe ohne Verlauf) für Browser ohne
     color-mix()-Unterstützung. */
  background: var(--color-accent);
  background: var(--accent-gradient);
  color: var(--accent-on-text, #fff);
}

.priceHistoryChartArea {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* Gleicher Wert wie beim übergeordneten .tablePriceHistoryContent/
     .stationStatsContent (siehe dort) - dadurch ist JEDER Übergang
     zwischen den gerahmten Blöcken des Preisverlaufs gleich groß,
     unabhängig davon, ob er von hier oder von einer Ebene weiter oben
     kommt. Ersetzt die vorher an den einzelnen Kindern verstreuten,
     uneinheitlichen Margins (.priceHistoryWeekStack/.priceHistoryLegend -
     deren margin-top/bottom sind deshalb jeweils auf 0 bzw. reines
     "auto" zur Zentrierung reduziert). */
  gap: 16px;
  min-height: 100px;
  /* Sanfter Übergang beim Umschalten zwischen den Ansichten (Heute/7 Tage/
     30 Tage/Jahr) - siehe --loading-Klasse unten und loadPriceHistoryChart()
     in script.js: alter Inhalt bleibt beim Nachladen sichtbar und wird nur
     abgedunkelt, statt abrupt durch einen Platzhaltertext ersetzt zu
     werden. */
  transition: opacity 0.18s ease;
}

.priceHistoryChartArea--loading {
  opacity: 0.35;
}

/* Gleiches Problem wie bei .tablePriceHistoryContent: sobald die
   gestapelten 7-Tage-Sektionen (.priceHistoryWeekStack) im Spiel sind,
   soll nicht zentriert werden - sonst wird bei kurzem Inhalt (< 100px)
   der ganze Block innerhalb der Chart-Area nach unten zentriert und der
   Abstand zur Zeitraum-Leiste darüber wächst sichtbar. */
.priceHistoryChartArea:has(.priceHistoryWeekStack) {
  justify-content: flex-start;
}

.priceHistoryChart {
  width: 96%;
  height: 230px;
  display: block;
  margin: 0 auto;
  box-sizing: border-box;
  background: color-mix(in srgb, currentColor 5%, transparent);
  border: 1px solid var(--tab-outline-color);
  border-radius: var(--radius);
  /* Links/rechts deutlich knapper als oben/unten (war: 10px rundum) -
     mit vollem 10px-Innenabstand auf allen Seiten wirkte das Diagramm
     spürbar schmaler/gequetschter als vor dem Rahmen. */
  padding: 10px 4px;
}

.priceHistoryAxisLine {
  stroke: var(--color-grid);
  stroke-width: 1;
}

.priceHistoryTick {
  stroke: var(--color-grid);
  stroke-width: 1;
}

.priceHistoryTick--major {
  stroke: var(--color-text-muted);
}

.priceHistoryGridLine {
  stroke: var(--color-grid);
  stroke-width: 1;
  opacity: 0.8;
}

.priceHistoryAxisLabel {
  font-size: 15px;
  fill: var(--color-text-strong);
  font-family: var(--font-numeric);
}

.priceHistorySwatch {
  width: 12px;
  height: 3px;
  border-radius: 2px;
  display: inline-block;
}

.priceHistorySwatch--e5,
polyline.priceHistorySwatch--e5,
line.priceHistorySwatch--e5 {
  background: var(--fuel-e5);
  stroke: var(--fuel-e5);
}

circle.priceHistorySwatch--e5 {
  fill: var(--fuel-e5);
}

.priceHistorySwatch--e10,
polyline.priceHistorySwatch--e10,
line.priceHistorySwatch--e10 {
  background: var(--fuel-e10);
  stroke: var(--fuel-e10);
}

circle.priceHistorySwatch--e10 {
  fill: var(--fuel-e10);
}

.priceHistorySwatch--diesel,
polyline.priceHistorySwatch--diesel,
line.priceHistorySwatch--diesel {
  background: var(--fuel-diesel);
  stroke: var(--fuel-diesel);
}

circle.priceHistorySwatch--diesel {
  fill: var(--fuel-diesel);
}

.stationInfoRow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--color-text);
  text-align: center;
}

.stationInfoAddress {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.stationInfoBrand {
  font-weight: var(--font-weight-semibold);
  font-size: 1.05rem;
  color: var(--color-text);
  margin-bottom: 6px;
}

.stationInfoAddressLines {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 8px;
  color: var(--color-text-muted);
  font-size: var(--font-size-small);
  line-height: 1.45;
  text-align: left;
}

.stationInfoAddressLines .stationInfoRowIcon {
  margin-top: 2px; /* optische Ausrichtung zur ersten Textzeile */
}

.stationInfoRowIcon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: var(--color-text-muted);
}

.stationInfoDivider {
  width: 100%;
  max-width: 220px;
  height: 1px;
  background: var(--color-border);
  margin: 2px 0;
}

.stationInfoMapLinks {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

/* Tankerkönig-Stationskennung - bewusst dezent (klein, gedämpfte Farbe,
   niedrige Deckkraft), da sie nur für Support-/Debug-Zwecke gedacht ist
   und im normalen Gebrauch keine Aufmerksamkeit verdient. */
.stationInfoId {
  font-size: var(--font-size-tiny);
  color: var(--color-text-muted);
  opacity: 0.6;
  text-align: center;
  font-family: var(--font-numeric);
  user-select: all;
}

.mapLinkBtn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  background: var(--color-surface-raised);
  color: var(--color-text);
  font-size: var(--font-size-small);
  font-weight: 500;
  text-decoration: none;
  transition:
    background var(--transition-fast),
    transform var(--transition-fast);
}

.mapLinkBtn:hover {
  background: var(--color-hover);
  transform: translateY(-1px);
}

.mapLinkBtn svg {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
}

/* -------------------------------------------
   FOOTER (zentriert, stabile Höhe, SVG-Animation)
------------------------------------------- */

/* Footer Grundlayout (zentriert) */
.footer {
  display: flex;
  align-items: center;        /* vertikal zentrieren */
  justify-content: center;    /* horizontal zentrieren */
  height: var(--footer-height);
  padding: 0 16px;
  background: var(--color-footer);
  font-size: 1rem;
  font-weight: 500;
  color: var(--color-text-muted);
  user-select: none;
  line-height: 1;             /* verhindert Baseline‑Offsets */
  overflow: visible;
}

/* Reset nur für direkte Footer-Kinder, um unerwünschte Offsets zu vermeiden */
.footer > * {
  margin: 0;
  padding: 0;
  vertical-align: middle;
}

/* FooterShowMore: Icon + Text mittig */
.footerShowMore {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  color: var(--color-accent);
  font-size: 1rem;
  margin: 0;
  height: 100%;
  line-height: 1;
  cursor: pointer;
}

/* Feinjustierung für eingebettetes Footer-Chevron (nur optische Korrektur) */
.footerShowMore svg {
  display: block;               /* verhindert Baseline-Offsets */
  width: 16px;
  height: 16px;
  margin: 0;
  transform-origin: 50% 50%;
  transform: translateY(-1.5px); /* leichte Verschiebung nach oben */
}

/* Animation: leichte Auf-/Ab-Bewegung, optisch zentriert */
.footerShowMore.animate svg {
  animation: footerChevronPulse 1.2s ease-in-out infinite;
}

@keyframes footerChevronPulse {
  0%   { transform: translateY(0); opacity: 0.85; }
  50%  { transform: translateY(-3px); opacity: 1; } /* nach oben bewegen für optische Mitte */
  100% { transform: translateY(0); opacity: 0.85; }
}

/* Mobile Anpassung (zusammengeführt - vorher zwei getrennte
   @media (max-width: 520px)-Blöcke an unterschiedlichen Stellen der
   Datei) */
@media (max-width: 520px) {
  :root {
    --footer-height: 44px;
    --col-template: 5fr 1fr 1fr 1fr 1fr;
    --col-template-stats: 5fr minmax(28px, 0.45fr) 1fr 1fr 1fr 1fr;
  }
  .footer { height: var(--footer-height); padding: 0 12px; }

  .priceHistoryAxisLabel {
    font-size: 13px;
  }
}




/* -------------------------------------------
   Geteilte Legende für Tages-/Monats-/Jahres-Chart
   (buildPriceLegend() in script.js)
------------------------------------------- */
.priceHistoryLegend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 16px;
  width: 96%;
  box-sizing: border-box;
  margin: 0 auto;
  padding: 10px 14px;
  background: color-mix(in srgb, currentColor 5%, transparent);
  border: 1px solid var(--tab-outline-color);
  border-radius: var(--radius);
  color: var(--color-text-muted);
  font-size: 12px;
}

.priceHistoryLegendItem {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

@media (max-width: 560px) {
  .priceHistoryLegend {
    gap: 9px;
    font-size: 11px;
  }
}


/* ============================================================
   7-TAGE-CHART – Tief / Durchschnitt / Hoch
   ============================================================ */
/* Umhüllt die drei gestapelten Kraftstoffart-Sektionen (E5/E10/Diesel,
   siehe renderWeeklyPriceChart()/buildWeeklyFuelSectionHtml() in
   priceHistory.js) - ersetzt die frühere Tab-Leiste zur Kraftstoffart-
   Auswahl, da inzwischen alle drei gleichzeitig sichtbar sind statt
   umschaltbar zu sein. */
.priceHistoryWeekStack {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Der EINE gemeinsame Rahmen für alle drei Kraftstoffart-Sektionen
     (E5/E10/Diesel) plus die Wochentag-Achse darunter - vorher hatte jede
     der drei Sektionen über .priceHistoryWeekChartWrap (siehe dort) einen
     eigenen Rahmen. Dieselben Werte wie bei den übrigen 96%-breiten
     gerahmten Blöcken des Preisverlaufs (.priceHistoryChart/
     .priceHistoryLegend), damit sich die Karte optisch einreiht statt wie
     ein Fremdkörper zu wirken. */
  width: 96%;
  box-sizing: border-box;
  margin: 0 auto;
  background: color-mix(in srgb, currentColor 5%, transparent);
  border: 1px solid var(--tab-outline-color);
  border-radius: var(--radius);
  padding: 12px 0;
  /* Abstand Diagramm -> Label der NÄCHSTEN Sektion: größer als der
     Abstand Label -> eigenes Diagramm (siehe .priceHistoryWeekFuelSection),
     damit die Gruppierung (Label gehört zum Diagramm darunter) klar
     erkennbar bleibt. */
  gap: 18px;
}

.priceHistoryWeekFuelSection {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  /* Abstand Label -> zugehöriges Diagramm. Bewusst kleiner als der
     Abstand zwischen zwei Sektionen (siehe .priceHistoryWeekStack), damit
     das Label erkennbar zu SEINEM Diagramm gehört. */
  gap: 6px;
}

/* Farbiges Badge statt schlichter Textzeile (Vorschlag A aus dem Mockup-
   Vergleich) - Hintergrund je Kraftstoffart in derselben Farbgebung wie
   die Säulen im Diagramm darunter (siehe FUEL_RANGE_COLORS in
   priceHistory.js), damit die Zuordnung auch ohne den Text auf einen
   Blick klar ist. inline-block statt volle Breite - wirkt dadurch als
   eigenständiges Element statt als Überschriftenzeile.
   margin:0 ist hier absichtlich explizit gesetzt, nicht nur der gap am
   Eltern-Flex-Container: <h4> bringt im Browser einen eigenen
   Standard-Außenabstand (oben UND unten) mit, der den flex-gap sonst
   einfach überlagert - ohne dieses Reset hätte sich der Abstand zum
   Diagramm trotz kleinerem gap gar nicht sichtbar verringert. */
.priceHistoryWeekFuelSectionTitle {
  align-self: flex-start;
  margin: 0 0 0 14px;
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: var(--font-size-small);
  font-weight: 700;
  /* Fixer dunkler Ton statt der jeweiligen "dunklen" Verlaufsfarbe der
     Kraftstoffart (war: var(--fuel-*-grad-dark)) - die ist gegen die
     zugehörige HELLE Verlaufsfarbe als Badge-Hintergrund zu kontrastarm
     (rechnerisch nur ca. 2,3:1 statt der nötigen 4,5:1). Derselbe dunkle
     Ton für alle drei Badges funktioniert zuverlässig gegen jede der drei
     hellen Hintergrundfarben (jeweils >10:1) - die Farbunterscheidung
     zwischen den Kraftstoffarten trägt ohnehin schon der Hintergrund,
     nicht der Text. */
  color: var(--color-bg);
}

.priceHistoryWeekFuelSectionTitle--e5 {
  background: var(--fuel-e5-grad-light);
}

.priceHistoryWeekFuelSectionTitle--e10 {
  background: var(--fuel-e10-grad-light);
}

.priceHistoryWeekFuelSectionTitle--diesel {
  background: var(--fuel-diesel-grad-light);
}

.priceHistoryWeekChartWrap {
  /* width:100% statt vorher 96% - sitzt jetzt selbst schon innerhalb des
     gemeinsamen .priceHistoryWeekStack-Rahmens und braucht keine eigene
     zusätzliche Einrückung mehr. Kein eigener Rahmen/Hintergrund mehr
     (war: background/border/border-radius wie bei .priceHistoryChart) -
     das übernimmt jetzt .priceHistoryWeekStack für alle drei Sektionen
     gemeinsam. */
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  /* Preis-Labels (oben/unten) im inneren .priceHistoryChartOverlayWrap
     sind position:absolute und tragen dadurch NICHT zu dessen Höhe bei -
     das umschließende Panel nutzt aber overflow:hidden für die
     Aufklapp-Animation und würde die frei schwebenden Labels sonst
     abschneiden. Das Padding hier reserviert den nötigen Platz, ohne die
     Prozent-Positionierung der Labels zu verfälschen (die bezieht sich
     auf die Padding-Box von .priceHistoryChartOverlayWrap, die selbst
     padding-frei bleibt und exakt 100% dieses Wraps einnimmt - SVG und
     Labels teilen sich dadurch weiterhin denselben Koordinatenraum).
     Deutlich knapper als beim früheren Einzelchart (war: 30px 5px 46px,
     zwischenzeitlich 20px 5px 20px) - drei gestapelte Sektionen sollen
     erkennbar zusammengehören statt mit viel Luft dazwischen wie
     einzelne, unabhängige Diagramme zu wirken; 12px oben/unten reichen
     für die (seit der kleineren Diagrammhöhe ebenfalls kleineren)
     Preis-Label-Überstände. */
  padding: 12px 5px 12px;
}

/* Nur die letzte Sektion (siehe includeXAxis in
   buildWeeklyFuelSectionHtml()) zeigt die Wochentag-/Datums-Achse unter
   dem Chart - braucht deshalb unten spürbar mehr Platz als die übrigen
   Sektionen (deren .priceHistoryWeekChartWrap ohne diesen Zusatz
   auskommt, siehe oben). Bewusst mit spürbarem Sicherheitspuffer über den
   rechnerisch benötigten ca. 49px (16px Abstand zum Diagramm + Wochentag-
   und Datumszeile plus deren gap, siehe .priceHistoryXLabelGroup) hinaus -
   die Zeile ist sonst die einzige Stelle im gesamten Preisverlauf, die
   tatsächlich AUSSERHALB der eigentlichen Diagrammfläche in reserviertem
   Leerraum hineinragt, und soll unter keinen Umständen am unteren
   Kartenrand abgeschnitten wirken. */
.priceHistoryWeekChartWrap--withAxis {
  padding-bottom: 70px;
}

/* Wrapper für die HTML-Beschriftungen, die über dem SVG schweben (siehe
   Kommentar bei overlayLabels in renderWeeklyPriceChart() für den Grund:
   SVG-Text mit px-Größe im viewBox-System wird bei preserveAspectRatio=
   "none" auf die tatsächliche Containerbreite gestreckt und kommt auf
   schmalen Bildschirmen dadurch viel kleiner an als deklariert -
   unabhängig von rem/Bedienungshilfen. Echtes HTML/rem hat dieses
   Problem nicht. */
.priceHistoryChartOverlayWrap {
  position: relative;
  width: 100%;
}

/* Bekommt bewusst KEINEN eigenen Rahmen/Hintergrund (obwohl .priceHistoryChart
   das jetzt generell tut, siehe dort) - hier übernimmt stattdessen
   .priceHistoryWeekChartWrap den Rahmen, weil SVG UND die HTML-Preis-
   Labels (.priceHistoryChartOverlayWrap) sich denselben Koordinatenraum
   teilen müssen: würde nur das SVG eingerahmt (schmaler + eingerückt),
   die Labels aber nicht, liefen beide auseinander. */
.priceHistoryRangeChart {
  display: block;
  width: 100%;
  margin: 0;
  box-sizing: content-box;
  background: none;
  border: none;
  border-radius: 0;
  padding: 0;
  /* Muss zur viewBox-Höhe in buildWeeklyFuelSectionHtml() (height = 130)
     passen - preserveAspectRatio="none" streckt sonst den kleineren
     viewBox-Inhalt wieder auf die hier angegebene Pixelhöhe. */
  height: 130px;
  overflow: visible;
}

/* Normale Theme-Trennlinienfarbe statt einem festen hellen Wert - die
   Karte hat seit dem Wegfall des festen dunklen Hintergrunds (siehe
   .priceHistoryRangeCap-Kommentar weiter oben in priceHistory.js) keinen
   eigenen Untergrund mehr, läuft also auf der normalen Panel-Fläche wie
   bei Heute/30 Tage/Jahr auch - dieselbe Randfarbe wie dort ist deshalb
   konsistenter als ein eigener fester Wert. */
.priceHistoryRangeDivider {
  stroke: var(--color-border);
  stroke-width: 1;
}

/* Kreis-Markierung an den Enden jeder Säule (Höchst-/Tiefstpreis). HTML
   statt SVG, damit sie trotz des nicht-uniform gestreckten SVG
   (preserveAspectRatio="none") wirklich rund bleibt - Position (left/top
   in %) und Farbe kommen inline aus buildWeeklyFuelSectionHtml(). */
.priceHistoryRangeDot {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  transition: filter var(--transition-fast);
}

.priceHistoryRangeDot:hover {
  filter: brightness(1.15);
}

/* Preis-Label als HTML-<span>, absolut über dem SVG positioniert (left/top
   in % sowie die Farbe werden inline von renderWeeklyPriceChart() gesetzt,
   passend zur gewählten Kraftstoffart - siehe FUEL_RANGE_COLORS dort) -
   siehe .priceHistoryChartOverlayWrap oben für den Grund, warum HTML statt
   SVG-<text>. Hoch-Label sitzt ÜBER seinem Punkt, Tief-Label UNTER seinem
   Punkt - anders als beim früheren Balkendiagramm liegen beide Punkte
   einer Säule ja nicht mehr beide nahe der Grundlinie, sondern am
   jeweils eigenen Ende der Spanne. */
.priceHistoryRangeLabelHtml {
  position: absolute;
  transform: translate(-50%, -50%);
  pointer-events: none;
  white-space: nowrap;
  font-family: var(--font-numeric);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.priceHistoryRangeLabelHtml--high {
  transform: translate(-50%, calc(-100% - 11px));
}

.priceHistoryRangeLabelHtml--low {
  transform: translate(-50%, 11px);
}

/* Wochentag + Datum als gemeinsame Gruppe unterhalb der Grundlinie,
   ebenfalls per % positioniert und horizontal zentriert. */
.priceHistoryXLabelGroup {
  position: absolute;
  top: 100%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  /* War 4px - saß dadurch praktisch direkt am unteren Diagrammrand statt
     als eigene Achse erkennbar abgesetzt zu sein. */
  margin-top: 16px;
}

.priceHistoryXLabelHtml {
  color: var(--color-text-strong);
  font-size: 0.88rem;
  font-weight: 700;
}

.priceHistoryXDateHtml {
  color: var(--color-text-strong);
  font-size: 0.72rem;
}

.priceHistoryXLabelHtml--current,
.priceHistoryXDateHtml--current {
  color: var(--color-accent);
}

@media (max-width: 720px) {
  .priceHistoryRangeChart {
    height: 115px;
  }
}

@media (max-width: 480px) {
  /* Zusätzliche Sicherheitsmarge gegen Umbruch der Range-Tabs (Heute/
     7 Tage/30 Tage/Jahr) auf sehr schmalen Bildschirmen - Höhe bewusst
     nicht mehr wie früher auf 8px zurückgesetzt, sonst wäre die extra
     Höhe von .priceHistoryTab (14px 14px) auf kleinen Handys wieder weg.
     Schriftgröße bleibt jetzt bei --font-size-small stehen (früher hier
     zusätzlich auf --font-size-tiny reduziert) - war zusammen mit der
     zwischenzeitlich größeren Titelleiste zu deutlich sichtbarer
     Abstand. */
  .priceHistoryTab {
    padding: 12px 10px;
  }

  .priceHistoryRangeChart {
    height: 105px;
  }
}

