/* Inter, self-hosted (fonts/Inter-Variable.woff2) instead of Google Fonts CDN
   (Nutzerwunsch 14.08.2026) — a single variable-font file covering weights
   300-700, latin subset only (U+0000-00FF, covers German umlauts). No CDN
   round-trip/preconnect needed anymore; see sw.js STATIC precache list.
   15.09.2026: Range auf 300-700 erweitert (deckt den leichtesten aktuell
   genutzten Schnitt ab, siehe "Font-Gewicht" in
   styleguide/foundations.html) — ein Schnitt unterhalb 300 läge ausserhalb
   dieser @font-face-Range und würde vom Browser nur genähert/gefaked statt
   vom echten Schriftschnitt bedient. */
@font-face {
	font-family: 'Inter';
	font-style: normal;
	font-weight: 300 700;
	font-display: swap;
	src: url('../fonts/Inter-Variable.woff2') format('woff2-variations'), url('../fonts/Inter-Variable.woff2') format('woff2');
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ── TOKENS ── */
:root {
	/* Inter throughout (replaces IBM Plex Sans/Mono) — one typeface for both
	   roles, own tabular figures (font-variant-numeric: tabular-nums, already
	   used wherever --fm was used for financial figures) cover the column-
	   alignment job a separate mono family used to. See the @font-face above
	   and memory-bank/design-system.md for the full rationale. */
	--ff: 'Inter', system-ui, sans-serif;
	--fm: 'Inter', system-ui, sans-serif;

	/* Font-size scale (Token-Audit 26.08.2026) — the 6 distinct clamp()
	   values already in use across css/*.css, collected into one shared
	   token per role instead of the same clamp() re-typed at each call site
	   (same "single source of truth" reasoning as --col-gap/--gap-group
	   above). Ordered --fs-1 (smallest) → --fs-6 (largest), not by usage
	   frequency. */
	/* Recalibrated 07.09.2026 (Nutzerwunsch, Safari-Cmd+-Vergleich): bei
	   393px (iPhone-17-Pro-Breite) sollten alle Grössen ~+20% wirken (2x
	   Cmd+ ≈ 120%), bei 2560px (Safari max. auf Studio-Display-Standard-
	   skalierung) ~+10% (1x Cmd+ ≈ 110%) — UND die Skalierung soll erst bei
	   2560px auslaufen statt wie zuvor schon bei ~1440-1900px (die alten
	   reinen "Xvw"-Terme liefen weit vor Studio-Display-Breite in den
	   oberen clamp()-Anschlag). Jeder Wert ist linear zwischen (393px →
	   alter-Min×1.2) und (2560px → alter-Max×1.1) interpoliert, Formel
	   clamp(min, A + Bvw, max) statt der alten reinen "Xvw"-Form. Alte
	   Werte (Token-Audit 26.08.2026, Basis vor dieser Kalibrierung):
	   --fs-1: clamp(10px, 0.75vw, 12px)
	   --fs-2: clamp(11px, 0.85vw, 13px)
	   --fs-3: clamp(11px, 0.85vw, 14px)
	   --fs-4: clamp(12px, 0.9vw, 15px)
	   --fs-5: clamp(13px, 1vw, 16px)
	   --fs-6: clamp(14px, 1.1vw, 18px)
	   --fs-heading: clamp(1.05rem, 0.95rem + 0.3vw, 1.3rem)
	   --fs-heading-sm: clamp(0.88rem, 0.82rem + 0.2vw, 1rem) */
	/* Zweite Runde, 07.09.2026, Nutzerwunsch: bei 393px (iPhone-17-Pro-Breite)
	   nochmal +10% auf den bereits kalibrierten Min-Wert oben. Bei --fs-1/
	   -2/heading-sm hätte das den neuen Min über den bisherigen Max-Wert
	   gehoben (ungültige clamp()-Reihenfolge) — dort wurde der Max-Wert um
	   dieselbe Differenz (alte Bandbreite max-min) mit angehoben, damit die
	   Skalierung fluid bleibt statt bei einem fixen Wert zu landen
	   (Projektregel: keine fixen Grössen, siehe frontend.md). Alle anderen
	   Tokens: nur der Min-Wert (+10%) geändert, Max unverändert.
	   09.09.2026, Nutzerwunsch: Anker-Breite von 393px auf 402px verschoben
	   (echte iPhone-17-Pro-Breite) — Min-/Max-Zielwerte bleiben unverändert,
	   nur A+Bvw neu berechnet, damit derselbe Min-Wert jetzt exakt bei 402px
	   statt 393px erreicht wird. Dabei einen bestehenden Rechenfehler bei
	   den beiden rem-basierten Heading-Tokens gefunden und mitkorrigiert:
	   deren B-Koeffizient war ca. 17x zu klein (rem/px-Verwechslung bei der
	   ursprünglichen Berechnung), wodurch sie ihren deklarierten Max-Wert bei
	   2560px real nie erreichten (clamp()'s Mittelwert blieb unterhalb von
	   max). Alle anderen (px-basierten) Tokens waren bereits korrekt
	   berechnet und nur die Anker-Breite musste neu durchgerechnet werden. */
	/* Stufen+Alias-System (15.09.2026, überarbeitet 15.09.2026) — die
	   einzelnen Tokens unten deklarieren keine eigenen clamp()-Werte mehr,
	   sondern zeigen per var() auf eine der wenigen --fs-step-*-"Stufen" hier.
	   Grund: Token-Audit 26.08.2026 + mehrere Kalibrierungsrunden hatten 23
	   Tokens hinterlassen, von denen viele nur 0.2-1.3px auseinanderlagen —
	   kaum sichtbar unterscheidbar. Erster Anlauf (zwei getrennte Basis-/KPI-
	   Leitern, nur exakte Duplikate zusammengelegt) reduzierte nur auf 16
	   Stufen und liess die Skala laut Nutzer immer noch zu eng. Diese Fassung
	   geht weiter: EINE gemeinsame Stufen-Leiter über Basis UND KPI hinweg
	   (Nutzerentscheid 15.09.2026 — die frühere Basis-/KPI-Trennung schützte
	   nur die Möglichkeit künftiger unabhängiger Kalibrierung, nicht den
	   heutigen Wert; ein Alias kann jederzeit später auf eine neue, eigene
	   Stufe umgehängt werden, auch wenn er heute eine Stufe mit anderen
	   Tokens teilt), mit spürbar grösseren Lücken zwischen benachbarten
	   Stufen (~1.5-2px statt ~0.2-1.3px) statt einer reinen Superset-
	   Verbreiterung. Das ist keine reine Umbenennung mehr — mehrere bisher
	   unterschiedlich grosse Tokens (u.a. --fs-4/--fs-5, --fs-6/--fs-body)
	   wachsen dabei sichtbar zusammen. --fs-heading/-heading-sm bleiben eine
	   eigene, rem-basierte Zwei-Stufen-Headline-Hierarchie, bewusst nicht in
	   die px-Leiter gemischt. Volle Herleitung/Cluster-Tabelle:
	   memory-bank/progress.md (15.09.2026). */
	--fs-badge: 9.9px;
	--fs-1: clamp(12px, 11.85px + 0.037vw, 12.8px);
	--fs-2: clamp(13.6px, 13.38px + 0.056vw, 14.8px);
	--fs-3: clamp(15.6px, 15.3px + 0.074vw, 17.2px);
	--fs-4: clamp(17.8px, 17.46px + 0.083vw, 19.6px);
	--fs-5: clamp(20px, 19.66px + 0.083vw, 21.8px);
	--fs-6: clamp(24.5px, 23.66px + 0.209vw, 29px);
	--fs-7: clamp(27px, 25.88px + 0.278vw, 33px);
	--fs-heading-sm: clamp(1.046rem, 1.016rem + 0.119vw, 1.206rem);
	/* Um ~10% verkleinert (15.09.2026, Nutzerwunsch: ".tab"/".position-symbol"
	   auf --fs-heading wirkten zu gross) — beide Endpunkte gleichermassen
	   reduziert (19.95px/22.88px → 17.92px/20.64px bei 16px-Root), Bandbreite
	   proportional mitgeschrumpft statt nur den Max-Wert zu senken. */
	--fs-heading: clamp(1.088rem, 1.088rem + 0.126vw, 1.29rem);

	/* Semantische Rollen-Tokens (16.09.2026, Nutzerwunsch) — zeigen per var()
	   auf eine der Stufen oben. Ersetzen die vorherigen kryptischen
	   --fs-1…6-Namen: die trugen keinerlei Rollen-Information, sodass z.B.
	   --fs-2 und --fs-3 identisch gross waren, ohne dass der Name das
	   erklärte. Mehrere Rollen-Tokens dürfen weiterhin dieselbe Stufe teilen
	   (z.B. --fs-table-head/--fs-label-sm beide auf --fs-2) — das ist jetzt
	   kein Widerspruch mehr, weil der Name die tatsächlich unterschiedliche
	   Rolle trägt, nicht nur eine Zahl. */
	--fs-table-head: var(--fs-2);
	--fs-label-sm: var(--fs-2);
	--fs-table-body: var(--fs-3);
	--fs-hint: var(--fs-3);
	--fs-form-label: var(--fs-4);
	/* --fs-prominent/--fs-body auf --fs-3-Niveau abgesenkt (21.09.2026,
	   Nutzerwunsch: --fs-body wirkte zu gross, sollte ungefähr
	   Tabellenzellen-Grösse haben) — direkt auf --fs-3 statt weiterhin über
	   --fs-5 (das bleibt für Header-Icons/KPI-Sub-Werte auf altem, grossem
	   Niveau; siehe --fs-modal-title unten für den einen --fs-prominent-
	   Konsumenten, der die grosse Stufe behalten sollte). */
	--fs-prominent: var(--fs-3);
	--fs-icon: var(--fs-5);
	--fs-body: var(--fs-3);
	/* Eigener Token statt --fs-prominent (21.09.2026) — .modal-title soll
	   die alte, grosse Stufe behalten, während --fs-prominents übrige
	   Konsumenten (.btn-primary, .pos-item .sym, Formularfelder) auf die neue
	   kleinere Stufe wechseln. */
	--fs-modal-title: var(--fs-5);
	--fs-cagr-proj-mode: var(--fs-3);
	/* War schon vorher fix 13.2px ohne vw-Anteil (einziger Konsument,
	   .position-chevron) — bewusst ausserhalb des Stufensystems belassen,
	   ein Alias auf eine fluide Stufe würde hier unbegründet eine vw-
	   Komponente einführen. */
	--fs-position-chevron: 13.2px;
	/* Glocke-Dropdown: dreistufige Hierarchie innerhalb eines Listeneintrags -
	   Titel bleibt auf --fs-body, Meldungstext eine Stufe darunter, Zeitstempel
	   nochmal eine. Eigene Rollen-Tokens statt --fs-label-sm, damit die Absicht
	   am Namen ablesbar bleibt (siehe Kommentar oben: gleiche Stufe, andere
	   Rolle ist ausdrücklich erlaubt). */
	--fs-push-body: var(--fs-2);
	--fs-push-ts: var(--fs-1);
	--fs-kpi-ext-label: var(--fs-1);
	--fs-kpi-ext-label-sm: var(--fs-badge);
	--fs-kpi-fallback-badge: var(--fs-badge);
	--fs-kpi-label: var(--fs-3);
	--fs-kpi-sub: var(--fs-2);
	--fs-kpi-value-sub: var(--fs-5);
	--fs-kpi-meta: var(--fs-2);
	/* --kpi-fs-scale-Faktor greift weiterhin an der Konsumentenstelle
	   (calc(var(--fs-kpi-price-chg) * var(--kpi-fs-scale)), css/kpi.css) —
	   unverändert durch diesen Umbau. */
	--fs-kpi-price-chg: var(--fs-3);
	--fs-kpi-price-chg-sm: var(--fs-2);
	--fs-kpi-value: var(--fs-6);
	--fs-kpi-value-lg: var(--fs-7);
	/* --kpi-fs-scale-Faktor greift weiterhin an der Konsumentenstelle
	   (calc(var(--fs-kpi-value-device) * var(--kpi-fs-scale)), css/chrome.css)
	   — unverändert durch diesen Umbau. */
	--fs-kpi-value-device: var(--fs-5);
	/* Skalierungsfaktor für Kurs/grosse Zahl (--fs-kpi-value/-value-lg/
	   -value-device), NICHT für Label/Sub/Meta/Badges - bewusst eng gehalten
	   (Nutzerentscheid 11.09.2026: ein ursprünglich breiterer Faktor über
	   ALLE --fs-kpi-*-Tokens wirkte live überladen, zu viele unterschiedliche
	   Schriftgrössen in derselben Kachel). Default 1; im einspaltigen
	   Slider-Zustand (.kpi-strip--paired, css/kpi.css) auf >1 gesetzt. Der
	   Faktor multipliziert bewusst dort, wo die font-size gesetzt wird
	   (calc() in css/kpi.css/chrome.css), nicht hier an der
	   Token-Deklaration: ein erst auf einem Nachfahren gesetzter Faktor
	   erreicht ein auf :root deklariertes Custom Property nie (siehe
	   gotchas-css.md). Einziger Justierpunkt für die Stärke der
	   Vergrösserung ist der Wert im .kpi-strip--paired-Block. */
	--kpi-fs-scale: 1;

	--bg: #fafaf8;
	--bg2: #f2f2ee;
	--bg3: #e8e8e2;
	--line: rgba(0, 0, 0, 0.09);
	--line2: rgba(0, 0, 0, 0.05);
	--t1: #0a0a08;
	--t2: #5a5a54;
	--t3: #9a9a92;
	/* Nutzerwunsch 02.09.2026: Light-Mode-Grün/Rot wirkten auf weissem
	   Hintergrund zu dunkel/gedeckt (Dark Mode gefiel bereits unverändert).
	   Aufgehellt um dieselbe HSL-Lightness-Differenz je Farbe (+0.08,
	   #1a6b3c→#1f8f4f bzw. #a32d2d→#c33636) - ein zweiter, noch hellerer
	   Schritt (+0.03 obendrauf) wurde wieder verworfen, dem Nutzer dort zu
	   hell/zu wenig Kontrast. Kontrast gegen Weiss: Grün 4.12:1, Rot 5.38:1
	   (beide über WCAG-AA 4.5:1 bzw. knapp drunter für Grün als Grosstext-
	   Ausnahme). */
	--pos: #1f8f4f;
	--pos-bg: #eaf3de;
	--neg: #c33636;
	--neg-bg: #fcebeb;
	/* Nur für die Teslanaire-Milestone-Balken (milestoneBarColor(),
	   js/views/overview.js) - dort dürfen Grün/Rot heller sein als der
	   Fliesstext-Standard oben, weil sie als Flächenfüllung statt als Text
	   gelesen werden (Kontrast-gegen-Hintergrund ist dort weniger kritisch).
	   In zwei Schritten aufgehellt, jeweils dieselbe HSL-Lightness-Differenz
	   auf beide Farben angewandt, um das Grün/Rot-Verhältnis zu erhalten:
	   #219754/#c93b3b (+0.02), dann #24a45b/#cc4747 (+0.03), dann
	   #26ac60/#ce4f4f (+0.02), dann #28b465/#d05757 (+0.02), dann
	   #2abc6a/#d25f5f (+0.02 weiter). Im Dark Mode unverändert identisch zu
	   --pos/--neg (siehe dark-Blöcke unten) - dort war keine Anpassung
	   gewünscht. */
	--pos-bar: #2abc6a;
	--neg-bar: #d25f5f;
	/* Deliberately separate from --neg: --neg is tuned as body-text-on-background
	   (dimmed in light mode, pale pink in dark mode, see --dark-neg below) —
	   using it as a small solid badge fill (.holiday-badge, css/layout.css)
	   would look washed out, especially in dark mode's #f09595. This is a
	   constant, saturated "notification red" that stays the same in both
	   themes (not redefined in the dark blocks below) since a small red dot
	   needs to read as urgent regardless of theme, not blend with body text. */
	--badge-neg: #dc2626;
	--blue: #185fa5;
	--blue-bg: #e6f1fb;
	--amber: #ba7517;
	--amber-bg: #faeeda;
	--bg-hover: #f6f6f2;
	/* Theme-invariant like --badge-neg above: white badge text and the modal
	   scrim need to stay the same in both themes, not track --t1/--line
	   (Token-Audit 26.08.2026). */
	--white: #fff;
	--overlay: rgba(0, 0, 0, 0.4);
	/* Milestone-pulse resting-state lightness shift (css/tables.css,
	   oklch(from var(--bar-color) calc(l + var(--pulse-lighten)) c h)).
	   Light mode's --pos/--neg/--amber are already dark, so the resting
	   slice needs to go LIGHTER (positive) to read as a pale/dimmed tint
	   without crushing toward black or washing out toward gray; dark mode's
	   tokens are already bright, so it needs the opposite — see the dark
	   blocks below for that value. */
	--pulse-lighten: 0.26;
	/* Swiss/International-Typographic-Style direction: no corner rounding
	   anywhere (buttons, pills, cards) — see memory-bank/design-system.md.
	   Circular glyphs that are deliberately round shapes (e.g. a status dot)
	   aren't affected, they don't use this token. */
	--radius: 0px;
	--topbar-h: 48px;
	--nav-h: 38px;

	/* Transition durations/easing (Token-Audit 26.08.2026) — the values
	   already repeated identically across css/*.css, collected as tokens.
	   --dur-slow + --ease-out-expo together reproduce the exact
	   "1s cubic-bezier(0.16, 1, 0.3, 1)" pair used identically in
	   layout.css and kpi.css. --dur-xs/-sm/-md + --ease-out-back added in the
	   follow-up pass (still 26.08.2026) for three single-use durations that
	   didn't fit the original 4-step scale — kept as their own tokens rather
	   than rounded to the nearest existing value, since that would have
	   silently changed the actual animation timing. */
	--dur-xs: 0.08s;
	--dur-sm: 0.1s;
	--dur-instant: 0.12s;
	--dur-fast: 0.15s;
	--dur-base: 0.3s;
	--dur-md: 0.35s;
	--dur-slow: 1s;
	--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
	--ease-out-back: cubic-bezier(0.22, 1, 0.36, 1);

	/* z-index scale (Token-Audit 26.08.2026) — named stacking levels
	   replacing the previously scattered, undocumented raw numbers
	   (-1, 1, 2, 100, 150, 200, 201, 9999). --z-scrollbar stays far above
	   the rest deliberately (custom scrollbar thumb must win over any
	   other stacked UI, css/chrome.css). */
	--z-behind: -1;
	--z-base: 1;
	--z-raised: 2;
	/* Klebende Kartenüberschriften (.card-h, css/tables.css) — bewusst
	   UNTERHALB von --z-sticky: sie haften unmittelbar unter der Kopfleisten-
	   Gruppe und dürfen diese (und erst recht ein Dropdown) nie überdecken. */
	--z-sticky-card: 50;
	--z-sticky: 100;
	--z-dropdown: 150;
	--z-overlay: 200;
	--z-modal: 201;
	--z-scrollbar: 9999;

	/* Spacing scale from the mockups (memory-bank/design-mockups/) — one
	   shared value per role, never the same clamp() re-typed independently
	   at each call site (that caused a real, if minor, grid drift between
	   containers in an earlier mockup iteration). --gap-group is only for
	   space BETWEEN independent sections (KPI strip → Teslanaire → Tage/CAGR
	   row → …), never inside a single row with two halves (use --col-gap
	   there, or it reads as unwanted empty padding toward the row's middle). */
	/* Values copied 1:1 from the mockup (v14) — not re-approximated. */
	--col-gap: clamp(1.25rem, 2vw, 2.25rem);
	--gap-group: clamp(2.25rem, 1.8rem + 1.8vw, 3.75rem);
	/* Vertikaler Abstand, wenn Spalten/Kacheln, die eigentlich nebeneinander
	   stehen, bei wenig Platz untereinander rutschen (KPI-Strip-Paare
	   .kpi-strip--paired .kpi-slide, js/kpi-strip-overflow.js; Top10-Spalten
	   .top10-block, css/tables.css, bei den chrome.css-Breakpoints 1200/900/
	   600px) - deutlich grösser als --col-gap, damit die gestapelten Blöcke
	   klar getrennt lesbar bleiben. Kein --gap-group (s.o. nur für Abstände
	   ZWISCHEN unabhängigen Seiten-Sektionen reserviert, nicht innerhalb
	   einer Komponente). Generalisiert 09.09.2026 aus dem ursprünglich
	   KPI-spezifischen --kpi-row-gap, statt einen zweiten, wertgleichen
	   Token für denselben Zweck anzulegen. */
	--gap-stack: clamp(2rem, 1.5rem + 2vw, 3.25rem);
	/* Page's own left/right inset — no fixed max-width/centering, the page
	   fills the full viewport width instead. Was previously exactly double
	   --col-gap (Nutzerwunsch 09.08.2026); replaced with its own clamp
	   (Nutzerwunsch 02.09.2026: halbiert + responsiv bis 320px) — the 2x
	   relationship to --col-gap no longer holds, this scales independently
	   down to a real 10px at a 320px viewport instead of flooring at 40px.
	   3.125vw is exact: 3.125% of 320px = 10px, and the 36px ceiling (half
	   of the old 72px max) is reached at 1152px viewport width. */
	--page-pad: clamp(10px, 3.125vw, 36px);

	/* Notch/Dynamic-Island/Home-Indicator safe-area compensation (08.09.2026).
	   max() keeps --page-pad's calibrated value exactly unchanged on devices
	   without insets (env() resolves to 0 there); only grows where the device
	   actually needs it. --safe-top/--safe-bottom have no --page-pad
	   counterpart to max() against — those axes had no existing padding
	   concept to protect, so a plain env() with a 0px fallback is enough. */
	--page-pad-safe-left: max(var(--page-pad), env(safe-area-inset-left));
	--page-pad-safe-right: max(var(--page-pad), env(safe-area-inset-right));
	--safe-top: env(safe-area-inset-top, 0px);
	--safe-bottom: env(safe-area-inset-bottom, 0px);
	/* .topbar/.device-topbar grow by --safe-top via padding-top
	   (min-height statt height, siehe layout.css/device-views.css) - jede
	   Stelle, die "verfügbare Höhe unterhalb der Topbar" per
	   calc(100vh - var(--topbar-h) - …) berechnet, muss diesen echten,
	   variablen Total-Wert verwenden statt des festen Tokens, sonst ist das
	   Budget auf einem Gerät mit Top-Inset um --safe-top zu grosszügig
	   (code-reviewer-Fund, 08.09.2026). */
	--topbar-h-total: calc(var(--topbar-h) + var(--safe-top));
	/* Höhe der gesamten feststehenden Kopfleisten-Gruppe (.chrome-stack) in der
	   Tab-Ansicht: Topbar inkl. Top-Inset + Navtabs. Die .chrome-stack selbst
	   braucht den Wert NICHT (sie ist sticky und misst sich selbst) - er ist der
	   Haftpunkt für alles, was unterhalb davon kleben soll (.card-h,
	   css/tables.css) und das Ziel-Offset für scrollIntoView-Sprünge
	   (scroll-padding-top, css/layout.css). Der Wert ist konstant, weil die
	   Banner bewusst ausserhalb der .chrome-stack liegen (siehe index.html) -
	   lägen sie darin, wäre er um deren variable Höhe daneben und eine
	   klebende Kartenüberschrift verschwände hinter der Leiste. */
	--chrome-h: calc(var(--topbar-h-total) + var(--nav-h));

	/* Höhe des sanften Ausblend-Verlaufs unter sticky Kartenüberschriften
	   (.card-h::after, css/tables.css) UND der reservierte Abstand vor dem
	   jeweils folgenden Element (.card-h + *, dieselbe Datei) — ein Token,
	   damit beide Stellen nicht auseinanderlaufen können. */
	--card-h-fade-h: 18px;

	/* Sockel-Variante von --page-pad-safe-left/-right, nur für .kpi-strip
	   (css/kpi.css). Geschichte (08.09.2026, zwei verworfene Zwischenstände):
	   (1) erster Versuch bare --page-pad-safe-left/-right - liess den Bleed
	   auf schmalen Phones OHNE Notch unter die alte, fest kalibrierte 20px
	   sinken (--page-pad kann bis auf 10px runter), Glow-Puffer wurde dort
	   spürbar knapper. (2) Korrektur auf reinen festen Sockel
	   max(20px, env(safe-area-inset-left/right)) - behob das, kappte damit
	   aber auf JEDEM Gerät (auch breitem Desktop, wo --page-pad-safe-left
	   normal weit über 20px liegt) den Bleed hart auf 20px - der Container
	   erreichte den echten Rand nicht mehr, sichtbar als abgeschnittener/
	   nicht bis zum Rand blutender Puls-Glow (Nutzer-Screenshot). Endgültig:
	   max(20px, var(--page-pad-safe-left/-right)) - 20px ist nur eine
	   UNTERGRENZE, kein Deckel. Auf schmalen Phones ohne Notch bleibt der
	   Sockel (--page-pad-safe-left kleiner als 20), auf Desktop/breiten
	   Screens UND echten Notch-Geräten gewinnt --page-pad-safe-left/-right
	   (grösser als 20) und der Bleed reicht wie bei .intraday-chart--bleed
	   bis zum echten Rand. */
	--kpi-strip-bleed-left: max(20px, var(--page-pad-safe-left));
	--kpi-strip-bleed-right: max(20px, var(--page-pad-safe-right));

	/* Single source of truth for the dark palette. Consumed via var() by both
	   the explicit-dark selector below (applies regardless of system
	   preference) and the prefers-color-scheme block (applies only for
	   data-theme="auto" + dark system) — a real @media condition can't be
	   merged into one selector list with :is(), so the two consuming blocks
	   stay separate, but a changed/new dark value now only needs editing
	   once here instead of in two places (was R188's actual failure mode). */
	/* Nutzerwunsch 10.08.2026: dark mode overall slightly darker. --dark-bg2 is
	   already pure black (the floor); bg/bg3/bg-hover shifted down by the same
	   ~4-per-channel step so the existing relative contrast between them is
	   preserved, not just the primary background in isolation. */
	--dark-bg: #0a0a08;
	--dark-bg2: #000000;
	--dark-bg3: #1a1a17;
	--dark-bg-hover: #131311;
	--dark-line: rgba(255, 255, 255, 0.08);
	--dark-line2: rgba(255, 255, 255, 0.04);
	--dark-t1: #f0f0ec;
	--dark-t2: #888880;
	--dark-t3: #4a4a44;
	--dark-pos: #5dcaa5;
	--dark-pos-bg: rgba(29, 158, 117, 0.14);
	--dark-neg: #f09595;
	--dark-neg-bg: rgba(226, 75, 74, 0.14);
	--dark-blue: #85b7eb;
	--dark-blue-bg: rgba(24, 95, 165, 0.18);
	--dark-amber: #ef9f27;
	--dark-amber-bg: rgba(186, 117, 23, 0.18);
}

:is([data-theme='dark'], .dark) {
	--bg: var(--dark-bg);
	--bg2: var(--dark-bg2);
	--bg3: var(--dark-bg3);
	--bg-hover: var(--dark-bg-hover);
	--line: var(--dark-line);
	--line2: var(--dark-line2);
	--t1: var(--dark-t1);
	--t2: var(--dark-t2);
	--t3: var(--dark-t3);
	--pos: var(--dark-pos);
	--pos-bg: var(--dark-pos-bg);
	--neg: var(--dark-neg);
	--neg-bg: var(--dark-neg-bg);
	--pos-bar: var(--dark-pos);
	--neg-bar: var(--dark-neg);
	--blue: var(--dark-blue);
	--blue-bg: var(--dark-blue-bg);
	--amber: var(--dark-amber);
	--amber-bg: var(--dark-amber-bg);
	--pulse-lighten: -0.20;
}

@media (prefers-color-scheme: dark) {
	[data-theme='auto'] {
		--bg: var(--dark-bg);
		--bg2: var(--dark-bg2);
		--bg3: var(--dark-bg3);
		--bg-hover: var(--dark-bg-hover);
		--line: var(--dark-line);
		--line2: var(--dark-line2);
		--t1: var(--dark-t1);
		--t2: var(--dark-t2);
		--t3: var(--dark-t3);
		--pos: var(--dark-pos);
		--pos-bg: var(--dark-pos-bg);
		--neg: var(--dark-neg);
		--neg-bg: var(--dark-neg-bg);
		--pos-bar: var(--dark-pos);
		--neg-bar: var(--dark-neg);
		--blue: var(--dark-blue);
		--blue-bg: var(--dark-blue-bg);
		--amber: var(--dark-amber);
		--amber-bg: var(--dark-amber-bg);
		--pulse-lighten: -0.20;
	}
}

