diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d1ee5..dbf0278 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.20.17] - 2026-04-20 + +### Changed +- Design: dark-mode token architecture refactored to private-variable indirection (`--_name`) in `tokens.css` — all tokens with dark-mode overrides now have a private `--_token` variant that holds the actual value, while public tokens (`--color-*`, `--module-*`, `--glass-*` etc.) are stable `var(--_token)` references. Both dark blocks (`@media prefers-color-scheme: dark` and `[data-theme="dark"]`) now only override the compact private tokens; the public API never needs to be touched again for dark-mode changes. The redundant explicit `--color-surface-2` override was removed from both dark blocks (it is already correctly derived via `var(--neutral-50)`). No visual change. + ## [0.20.16] - 2026-04-19 ### Changed diff --git a/docs/color-redesign-proposal.md b/docs/color-redesign-proposal.md index 4d049d8..4676ea8 100644 --- a/docs/color-redesign-proposal.md +++ b/docs/color-redesign-proposal.md @@ -452,6 +452,8 @@ Vorteil: Eine Zeile Änderung statt zwei. Nachteil: Zwei CSS-Ebenen (private `-- **Priorität:** Niedrig — wartungstechnisch sinnvoll, kein UX-Impact. Als eigener PR. +**Status:** ✅ Umgesetzt — Private-Token-Indirektion (`--_name`) in `tokens.css`. Beide Dark-Blöcke überschreiben nur noch private Tokens; öffentliche API (`--color-*`, `--module-*` etc.) ist stabil und muss bei zukünftigen Dark-Mode-Änderungen nicht mehr doppelt angepasst werden. + ### 8.3 Glass.css Specular-Token-Konsolidierung `glass.css` wiederholt dieselben `rgba`-Werte für specular highlights (0.18, 0.22, 0.28, 0.32) und inset shadows. **Umgesetzt:** 5 neue Tokens in `tokens.css` (Abschnitt `/* d2) Inset-Specular */`): @@ -487,7 +489,7 @@ Zeilen 1738–1745 enthielten `#fff`, `#000`, `#ddd` in einem `@media print`-Blo | `tasks.css` | `.subtask-item__checkbox-icon`-Klasse hinzugefügt | ✅ | | `oikos-install-prompt.js` | Fallback `#2554C7` → `#4338CA`; `#fff` → `var(--color-text-on-accent, #fff)` | ✅ §8.1 | | `index.html` | `theme-color="#2563EB"` → `#4F46E5` | ✅ §8.1 | -| Dark-Mode-Dedup | `@media` + `[data-theme]` kollabieren | 🔲 §8.2 | +| Dark-Mode-Dedup | `@media` + `[data-theme]` kollabieren auf private `--_` Tokens | ✅ §8.2 | | `tokens.css` | 5 neue `--glass-inset-*` Tokens (0.18–0.32) | ✅ §8.3 | | `glass.css` | 9 specular rgba-Literale → `var(--glass-inset-*)` | ✅ §8.3 | | `tasks.css` | 1 specular rgba-Literal → `var(--glass-inset-base)` | ✅ §8.3 | diff --git a/package.json b/package.json index 11170b5..ab97013 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oikos", - "version": "0.20.15", + "version": "0.20.17", "description": "Self-hosted family planner - calendar, tasks, shopping, meal planning, budget and more. Private, open-source, no subscription.", "main": "server/index.js", "type": "module", diff --git a/public/styles/tokens.css b/public/styles/tokens.css index 6b0796d..a7b00dd 100644 --- a/public/styles/tokens.css +++ b/public/styles/tokens.css @@ -19,73 +19,109 @@ * 13. Übergänge * 14. Z-Indizes * 15. Dark Mode + * + * Dark-Mode-Architektur (§8.2): + * Private Tokens (--_name) halten den aktuellen Wert. + * Öffentliche Tokens (--name) zeigen immer auf var(--_name). + * Dark-Mode-Blöcke überschreiben nur die privaten Tokens — + * die öffentliche API bleibt stabil und muss nie doppelt geändert werden. */ :root { /* -------------------------------------------------------- * 1. Farben - Neutral-Skala * Leicht warmgetönt (kein reines Grau) für einladende Atmosphäre. - * Benannt als --neutral-{stufe} für direkte Nutzung, - * plus semantische Aliase (--color-bg, --color-surface etc.) - * die bestehender Code bereits referenziert. + * Private --_neutral-* für Dark-Mode-Überschreibungen; + * öffentliche --neutral-* sind die stabile API. * -------------------------------------------------------- */ - --neutral-50: #FAFAF8; - --neutral-100: #F5F4F1; - --neutral-150: #EFEEE9; - --neutral-200: #E8E7E2; - --neutral-250: #DDDCD7; - --neutral-300: #D1D0CB; - --neutral-400: #B5B4AF; - --neutral-500: #8E8D89; - --neutral-600: #6C6B67; - --neutral-700: #4A4A46; - --neutral-800: #2E2E2B; - --neutral-900: #1C1C1A; - --neutral-950: #121211; + --_neutral-50: #FAFAF8; + --neutral-50: var(--_neutral-50); + --_neutral-100: #F5F4F1; + --neutral-100: var(--_neutral-100); + --_neutral-150: #EFEEE9; + --neutral-150: var(--_neutral-150); + --_neutral-200: #E8E7E2; + --neutral-200: var(--_neutral-200); + --_neutral-250: #DDDCD7; + --neutral-250: var(--_neutral-250); + --_neutral-300: #D1D0CB; + --neutral-300: var(--_neutral-300); + --_neutral-400: #B5B4AF; + --neutral-400: var(--_neutral-400); + --_neutral-500: #8E8D89; + --neutral-500: var(--_neutral-500); + --_neutral-600: #6C6B67; + --neutral-600: var(--_neutral-600); + --_neutral-700: #4A4A46; + --neutral-700: var(--_neutral-700); + --_neutral-800: #2E2E2B; + --neutral-800: var(--_neutral-800); + --_neutral-900: #1C1C1A; + --neutral-900: var(--_neutral-900); + --_neutral-950: #121211; + --neutral-950: var(--_neutral-950); /* Semantische Aliase (abwärtskompatibel) */ --color-bg: var(--neutral-100); - --color-surface: #FFFFFF; + --_color-surface: #FFFFFF; + --color-surface: var(--_color-surface); --color-surface-2: var(--neutral-50); - --color-surface-3: var(--neutral-150); + --_color-surface-3: var(--_neutral-150); + --color-surface-3: var(--_color-surface-3); --color-border: var(--neutral-200); --color-border-subtle: var(--neutral-150); --color-text-primary: var(--neutral-900); --color-text-secondary: var(--neutral-600); /* WCAG AA: ~5.0:1 auf weiß */ - --color-text-tertiary: #6A6964; /* WCAG AA: 4.61:1 auf --color-bg (wärmer, mehr Puffer) */ + --_color-text-tertiary: #6A6964; + --color-text-tertiary: var(--_color-text-tertiary); /* WCAG AA: 4.61:1 auf --color-bg */ --color-text-disabled: var(--neutral-300); - --color-text-on-accent: #ffffff; /* Weißer Text auf farbigen Hintergründen (Buttons, Badges, FAB) */ + --color-text-on-accent: #ffffff; /* Weißer Text auf farbigen Hintergründen */ /* -------------------------------------------------------- * 2. Farben - Akzent (konfigurierbar) * Indigo mit leichtem Violett-Drall — charaktervoller als Default-Blau, * harmoniert mit --color-accent-secondary und --module-calendar. * -------------------------------------------------------- */ - --color-accent: #4F46E5; /* Indigo-600 — 4.93:1 auf weiß */ - --color-accent-hover: #4338CA; /* Indigo-700 */ - --color-accent-active: #3730A3; /* Indigo-800 */ - --color-accent-deep: #2E2D82; /* Tiefer Akzent für Gradienten, Wetter-Widget */ - --color-accent-secondary: #7C5CFC; /* Sekundärer Akzent für Logo-Gradient */ - --color-accent-light: #EEF2FF; /* Indigo-50 */ - --color-accent-subtle: #E0E7FF; /* Indigo-100 */ - --color-btn-primary: #4338CA; /* Indigo-700 — WCAG AAA: 7.04:1 auf weiß */ - --color-btn-primary-hover: #3730A3; /* Indigo-800 */ + --_color-accent: #4F46E5; + --color-accent: var(--_color-accent); /* Indigo-600 — 4.93:1 auf weiß */ + --_color-accent-hover: #4338CA; + --color-accent-hover: var(--_color-accent-hover); /* Indigo-700 */ + --_color-accent-active: #3730A3; + --color-accent-active: var(--_color-accent-active); /* Indigo-800 */ + --color-accent-deep: #2E2D82; /* Tiefer Akzent für Gradienten, Wetter-Widget */ + --_color-accent-secondary: #7C5CFC; + --color-accent-secondary: var(--_color-accent-secondary); /* Sekundärer Akzent für Logo-Gradient */ + --_color-accent-light: #EEF2FF; + --color-accent-light: var(--_color-accent-light); /* Indigo-50 */ + --_color-accent-subtle: #E0E7FF; + --color-accent-subtle: var(--_color-accent-subtle); /* Indigo-100 */ + --_color-btn-primary: #4338CA; + --color-btn-primary: var(--_color-btn-primary); /* Indigo-700 — WCAG AAA: 7.04:1 auf weiß */ + --_color-btn-primary-hover: #3730A3; + --color-btn-primary-hover: var(--_color-btn-primary-hover); /* Indigo-800 */ /* -------------------------------------------------------- * 3. Farben - Semantisch * -------------------------------------------------------- */ - --color-success: #15803D; - --color-success-hover: #166534; - --color-success-light: #DAFBE1; - --color-warning: #A15C0A; /* Hue-Trennung von --module-meals, 5.23:1 auf weiß */ - --color-warning-hover: #824908; - --color-warning-light: #FFF4D4; - --color-danger: #B91C1C; /* Red-700 — 6.90:1 auf weiß (vorher 4.85:1) */ - --color-danger-hover: #991B1B; /* Red-800 */ - --color-danger-light: #FFE2E0; - --color-info: #0969DA; /* WCAG AA: ~4.6:1 auf weiß */ - --color-info-hover: #0550AE; - --color-info-light: #DDF4FF; + --_color-success: #15803D; + --color-success: var(--_color-success); + --color-success-hover: #166534; + --_color-success-light: #DAFBE1; + --color-success-light: var(--_color-success-light); + --_color-warning: #A15C0A; + --color-warning: var(--_color-warning); /* Hue-Trennung von --module-meals, 5.23:1 auf weiß */ + --color-warning-hover: #824908; + --_color-warning-light: #FFF4D4; + --color-warning-light: var(--_color-warning-light); + --_color-danger: #B91C1C; + --color-danger: var(--_color-danger); /* Red-700 — 6.90:1 auf weiß */ + --color-danger-hover: #991B1B; /* Red-800 */ + --_color-danger-light: #FFE2E0; + --color-danger-light: var(--_color-danger-light); + --color-info: #0969DA; /* WCAG AA: ~4.6:1 auf weiß */ + --color-info-hover: #0550AE; + --_color-info-light: #DDF4FF; + --color-info-light: var(--_color-info-light); /* -------------------------------------------------------- * 4. Farben - Modul-Akzente @@ -93,28 +129,43 @@ * Einsatz in Modul-Headern, Icons, aktiven States. * Domain-Farben von Severity entkoppelt — siehe §2.5 des Redesign-Vorschlags. * -------------------------------------------------------- */ - --module-dashboard: #4F46E5; /* Indigo - Übersicht, neutral (= --color-accent, bewusster Share) */ - --module-tasks: #15803D; /* Grün - Erledigung, Fortschritt (= --color-success, bewusster Share) */ - --module-calendar: #8250DF; /* Violett - Termine, Zeit */ - --module-meals: #C2410C; /* Orange-700 - Essen, Wärme */ - --module-shopping: #DB2777; /* Pink-600 - Einkaufen, Aktion (trennt von Meals) */ - --module-notes: #CA8A04; /* Gold - Notizen, Pinnwand (nur Icons/Large-Text: 4.08:1) */ - --module-contacts: #0969DA; /* Kräftiges Blau - Kontakte */ - --module-budget: #0F766E; /* Teal-700 - Finanzen, Stabilität */ - --module-settings: #6E7781; /* Grau - Konfiguration */ + --_module-dashboard: #4F46E5; + --module-dashboard: var(--_module-dashboard); /* Indigo - Übersicht (= --color-accent, bewusster Share) */ + --_module-tasks: #15803D; + --module-tasks: var(--_module-tasks); /* Grün - Erledigung (= --color-success, bewusster Share) */ + --_module-calendar: #8250DF; + --module-calendar: var(--_module-calendar); /* Violett - Termine, Zeit */ + --_module-meals: #C2410C; + --module-meals: var(--_module-meals); /* Orange-700 - Essen, Wärme */ + --_module-shopping: #DB2777; + --module-shopping: var(--_module-shopping); /* Pink-600 - Einkaufen (trennt von Meals) */ + --_module-notes: #CA8A04; + --module-notes: var(--_module-notes); /* Gold - Notizen (nur Icons/Large-Text: 4.08:1) */ + --_module-contacts: #0969DA; + --module-contacts: var(--_module-contacts); /* Kräftiges Blau - Kontakte */ + --_module-budget: #0F766E; + --module-budget: var(--_module-budget); /* Teal-700 - Finanzen, Stabilität */ + --_module-settings: #6E7781; + --module-settings: var(--_module-settings); /* Grau - Konfiguration */ /* -------------------------------------------------------- * 5. Farben - Mahlzeit-Typen * Zentrale Tokens statt Hardcoding in meals.css * -------------------------------------------------------- */ - --meal-breakfast: #A15C0A; /* Morgensonne-Amber (= --color-warning, bewusster Share) */ - --meal-breakfast-light: #FFF4D4; - --meal-lunch: #2DA44E; - --meal-lunch-light: #DAFBE1; - --meal-dinner: #4F46E5; /* Indigo - ruhiger Tag-Ausklang (= --color-accent) */ - --meal-dinner-light: #EEF2FF; - --meal-snack: #C2410C; /* = --module-meals — Snack ist Sub-Domain von Meals */ - --meal-snack-light: #FFECE3; + --_meal-breakfast: #A15C0A; + --meal-breakfast: var(--_meal-breakfast); /* Morgensonne-Amber (= --color-warning, bewusster Share) */ + --_meal-breakfast-light: #FFF4D4; + --meal-breakfast-light: var(--_meal-breakfast-light); + --meal-lunch: #2DA44E; + --_meal-lunch-light: #DAFBE1; + --meal-lunch-light: var(--_meal-lunch-light); + --_meal-dinner: #4F46E5; + --meal-dinner: var(--_meal-dinner); /* Indigo - ruhiger Tag-Ausklang (= --color-accent) */ + --_meal-dinner-light: #EEF2FF; + --meal-dinner-light: var(--_meal-dinner-light); + --meal-snack: #C2410C; /* = --module-meals — Snack ist Sub-Domain */ + --_meal-snack-light: #FFECE3; + --meal-snack-light: var(--_meal-snack-light); /* -------------------------------------------------------- * 6. Farben - Prioritäten @@ -125,18 +176,25 @@ --color-priority-high: #C2410C; /* = --module-meals (bewusster Share: „heiß") */ --color-priority-urgent: #B91C1C; /* = --color-danger (bewusster Share: „gefährlich") */ - /* Hintergrundfarben für Priority-Badges — RGB-Tripel folgen den Base-Tokens */ - --color-priority-none-bg: rgba(142, 141, 137, 0.08); - --color-priority-low-bg: rgba(142, 141, 137, 0.12); - --color-priority-medium-bg: rgba(161, 98, 7, 0.12); - --color-priority-high-bg: rgba(194, 65, 12, 0.12); - --color-priority-urgent-bg: rgba(185, 28, 28, 0.12); + /* Hintergrundfarben für Priority-Badges */ + --_color-priority-none-bg: rgba(142, 141, 137, 0.08); + --color-priority-none-bg: var(--_color-priority-none-bg); + --_color-priority-low-bg: rgba(142, 141, 137, 0.12); + --color-priority-low-bg: var(--_color-priority-low-bg); + --_color-priority-medium-bg: rgba(161, 98, 7, 0.12); + --color-priority-medium-bg: var(--_color-priority-medium-bg); + --_color-priority-high-bg: rgba(194, 65, 12, 0.12); + --color-priority-high-bg: var(--_color-priority-high-bg); + --_color-priority-urgent-bg: rgba(185, 28, 28, 0.12); + --color-priority-urgent-bg: var(--_color-priority-urgent-bg); /* -------------------------------------------------------- * 7. Overlay / Backdrop * -------------------------------------------------------- */ - --color-overlay: rgba(0, 0, 0, 0.45); - --color-overlay-light: rgba(0, 0, 0, 0.2); + --_color-overlay: rgba(0, 0, 0, 0.45); + --color-overlay: var(--_color-overlay); + --_color-overlay-light: rgba(0, 0, 0, 0.2); + --color-overlay-light: var(--_color-overlay-light); /* Glass-Overlays (fuer Elemente auf farbigen Hintergruenden) */ --color-glass: rgba(255, 255, 255, 0.18); @@ -149,9 +207,12 @@ * 3 Stufen: subtle (Karten), medium (Dropdowns, Hover), * elevated (Modals, FAB). * -------------------------------------------------------- */ - --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 4px rgba(0, 0, 0, 0.03); - --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04); - --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.04); + --_shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04), 0 1px 4px rgba(0, 0, 0, 0.03); + --shadow-sm: var(--_shadow-sm); + --_shadow-md: 0 2px 8px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04); + --shadow-md: var(--_shadow-md); + --_shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.04); + --shadow-lg: var(--_shadow-lg); /* -------------------------------------------------------- * 9. Border-Radien @@ -233,10 +294,13 @@ * 13. Sidebar * Reduzierter Neumorphismus - subtilere Schatten. * -------------------------------------------------------- */ - --sidebar-bg: var(--neutral-100); - --sidebar-shadow-light: rgba(255, 255, 255, 0.6); - --sidebar-shadow-dark: rgba(0, 0, 0, 0.08); - --safe-area-inset-top: env(safe-area-inset-top, 0px); + --_sidebar-bg: var(--_neutral-100); + --sidebar-bg: var(--_sidebar-bg); + --_sidebar-shadow-light: rgba(255, 255, 255, 0.6); + --sidebar-shadow-light: var(--_sidebar-shadow-light); + --_sidebar-shadow-dark: rgba(0, 0, 0, 0.08); + --sidebar-shadow-dark: var(--_sidebar-shadow-dark); + --safe-area-inset-top: env(safe-area-inset-top, 0px); --safe-area-inset-bottom: env(safe-area-inset-bottom, 0px); /* -------------------------------------------------------- @@ -277,20 +341,30 @@ * -------------------------------------------------------- */ /* a) Glass-Hintergründe */ - --glass-bg: rgba(255, 255, 255, 0.72); - --glass-bg-hover: rgba(255, 255, 255, 0.82); - --glass-bg-elevated: rgba(255, 255, 255, 0.88); - --glass-border: rgba(255, 255, 255, 0.60); - --glass-border-subtle: rgba(255, 255, 255, 0.35); + --_glass-bg: rgba(255, 255, 255, 0.72); + --glass-bg: var(--_glass-bg); + --_glass-bg-hover: rgba(255, 255, 255, 0.82); + --glass-bg-hover: var(--_glass-bg-hover); + --_glass-bg-elevated: rgba(255, 255, 255, 0.88); + --glass-bg-elevated: var(--_glass-bg-elevated); + --_glass-border: rgba(255, 255, 255, 0.60); + --glass-border: var(--_glass-border); + --_glass-border-subtle: rgba(255, 255, 255, 0.35); + --glass-border-subtle: var(--_glass-border-subtle); /* a2) Glass-Hintergründe: Vibrancy-Stufe (transparenter, mehr Durchschein) */ - --glass-bg-card: rgba(255, 255, 255, 0.52); - --glass-bg-card-hover: rgba(255, 255, 255, 0.65); - --glass-bg-input: rgba(255, 255, 255, 0.48); - --glass-bg-toolbar: rgba(255, 255, 255, 0.58); + --_glass-bg-card: rgba(255, 255, 255, 0.52); + --glass-bg-card: var(--_glass-bg-card); + --_glass-bg-card-hover: rgba(255, 255, 255, 0.65); + --glass-bg-card-hover: var(--_glass-bg-card-hover); + --_glass-bg-input: rgba(255, 255, 255, 0.48); + --glass-bg-input: var(--_glass-bg-input); + --_glass-bg-toolbar: rgba(255, 255, 255, 0.58); + --glass-bg-toolbar: var(--_glass-bg-toolbar); /* a3) Tint: Modul-Akzentfarbe als subtile Glass-Tonung */ - --glass-tint-strength: 6%; + --_glass-tint-strength: 6%; + --glass-tint-strength: var(--_glass-tint-strength); /* b) Blur-Stufen */ --blur-xs: blur(4px); @@ -305,8 +379,10 @@ --opacity-glass-elevated: 0.92; /* d) Highlights / Specular */ - --glass-highlight: rgba(255, 255, 255, 0.70); - --glass-highlight-subtle: rgba(255, 255, 255, 0.35); + --_glass-highlight: rgba(255, 255, 255, 0.70); + --glass-highlight: var(--_glass-highlight); + --_glass-highlight-subtle: rgba(255, 255, 255, 0.35); + --glass-highlight-subtle: var(--_glass-highlight-subtle); /* d2) Inset-Specular: Oberrand-Sheen für Glass-Elemente (volle inset-Kurzform) */ --glass-inset-soft: inset 0 1px 0 rgba(255, 255, 255, 0.18); @@ -316,9 +392,12 @@ --glass-inset-strong: inset 0 1px 0 rgba(255, 255, 255, 0.32); /* e) Glass-Schatten */ - --glass-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(255, 255, 255, 0.55); - --glass-shadow-md: 0 4px 20px rgba(0, 0, 0, 0.10), 0 0 0 1px rgba(255, 255, 255, 0.50); - --glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.14), 0 0 0 1px rgba(255, 255, 255, 0.45); + --_glass-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.06), 0 0 0 1px rgba(255, 255, 255, 0.55); + --glass-shadow-sm: var(--_glass-shadow-sm); + --_glass-shadow-md: 0 4px 20px rgba(0, 0, 0, 0.10), 0 0 0 1px rgba(255, 255, 255, 0.50); + --glass-shadow-md: var(--_glass-shadow-md); + --_glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.14), 0 0 0 1px rgba(255, 255, 255, 0.45); + --glass-shadow-lg: var(--_glass-shadow-lg); /* f) Glass-Radien */ --radius-glass-card: 20px; @@ -332,215 +411,201 @@ } /* ================================================================ - * Dark Mode - * Zwei Selektoren: (1) System-Preference, (2) manueller Override - * via data-theme="dark" auf . - * data-theme="light" erzwingt Light Mode (kein Dark-Override). - * Ohne data-theme folgt die App der System-Einstellung. + * Dark Mode — private Tokens überschreiben, öffentliche API bleibt stabil. + * + * Beide Selektoren überschreiben nur --_private Tokens. Die öffentlichen + * --color-* / --module-* / --glass-* Tokens müssen nie angefasst werden. + * + * (1) System-Preference — greift, wenn kein data-theme gesetzt ist. + * (2) Manueller Override — greift, wenn JS data-theme="dark" setzt + * (auch bei System in Light-Mode). * ================================================================ */ @media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { /* Neutral-Skala invertiert (warm-dunkel) */ - --neutral-50: #1A1A18; - --neutral-100: #222220; - --neutral-150: #2A2A28; - --neutral-200: #333331; - --neutral-250: #3D3D3A; - --neutral-300: #48484A; - --neutral-400: #636360; - --neutral-500: #8E8D89; - --neutral-600: #AEADB0; /* WCAG AA: ~4.8:1 auf #2A2A28 */ - --neutral-700: #C8C7C3; - --neutral-800: #E2E1DC; - --neutral-900: #F5F4F1; - --neutral-950: #FAFAF8; + --_neutral-50: #1A1A18; + --_neutral-100: #222220; + --_neutral-150: #2A2A28; + --_neutral-200: #333331; + --_neutral-250: #3D3D3A; + --_neutral-300: #48484A; + --_neutral-400: #636360; + --_neutral-500: #8E8D89; + --_neutral-600: #AEADB0; /* WCAG AA: ~4.8:1 auf #2A2A28 */ + --_neutral-700: #C8C7C3; + --_neutral-800: #E2E1DC; + --_neutral-900: #F5F4F1; + --_neutral-950: #FAFAF8; /* Semantische Aliase folgen automatisch via var(--neutral-*) */ - --color-surface: #2A2A28; - --color-surface-2: #1A1A18; - --color-surface-3: #333331; + --_color-surface: #2A2A28; + --_color-surface-3: #333331; /* = neutral-200 dark */ /* Sidebar */ - --sidebar-bg: #1A1A18; - --sidebar-shadow-light: rgba(255, 255, 255, 0.04); - --sidebar-shadow-dark: rgba(0, 0, 0, 0.4); + --_sidebar-bg: #1A1A18; + --_sidebar-shadow-light: rgba(255, 255, 255, 0.04); + --_sidebar-shadow-dark: rgba(0, 0, 0, 0.4); /* Akzent - Dark Mode (Indigo bleibt, nur Lightness/Saturation rücken) */ - --color-accent: #818CF8; /* Indigo-400 — 6.8:1 auf #2A2A28 */ - --color-accent-hover: #6366F1; /* Indigo-500 */ - --color-accent-active: #4F46E5; /* Indigo-600 (= Light-Primary, Mirroring) */ - --color-accent-light: #2E2D5B; - --color-accent-subtle: #252255; - --color-btn-primary: #6366F1; /* Indigo-500 — 5.5:1 auf Dark-Surface */ - --color-btn-primary-hover: #4F46E5; + --_color-accent: #818CF8; /* Indigo-400 — 6.8:1 auf #2A2A28 */ + --_color-accent-hover: #6366F1; /* Indigo-500 */ + --_color-accent-active: #4F46E5; /* Indigo-600 (= Light-Primary, Mirroring) */ + --_color-accent-light: #2E2D5B; + --_color-accent-subtle: #252255; + --_color-btn-primary: #6366F1; /* Indigo-500 — 5.5:1 auf Dark-Surface */ + --_color-btn-primary-hover: #4F46E5; + --_color-accent-secondary: #A78BFA; - --color-accent-secondary: #A78BFA; + /* Semantische Farben */ + --_color-success: #4ADE80; + --_color-warning: #F59E0B; + --_color-danger: #FCA5A5; + --_color-text-tertiary: #A3A3A0; + --_color-success-light: #1A3325; + --_color-warning-light: #332400; + --_color-danger-light: #3D1C1A; + --_color-info-light: #1A2D40; - /* Semantische Farben - Dark Mode */ - --color-success: #4ADE80; - --color-warning: #F59E0B; - --color-danger: #FCA5A5; - --color-text-tertiary: #A3A3A0; + /* Modul-Akzente (Entflechtung Meals/Shopping spiegelt Light-Mode) */ + --_module-dashboard: #818CF8; /* Indigo-400 */ + --_module-tasks: #4ADE80; + --_module-calendar: #A78BFA; + --_module-meals: #FB923C; /* Orange-400 */ + --_module-shopping: #F472B6; /* Pink-400 */ + --_module-notes: #FCD34D; + --_module-contacts: #60A5FA; + --_module-budget: #2DD4BF; /* Teal-400 */ + --_module-settings: #94A3B8; - --color-success-light: #1A3325; - --color-warning-light: #332400; - --color-danger-light: #3D1C1A; - --color-info-light: #1A2D40; - - /* Modul-Akzente - Dark Mode (Entflechtung Meals/Shopping spiegelt Light-Mode) */ - --module-dashboard: #818CF8; /* Indigo-400 - folgt neuem Dark-Accent */ - --module-tasks: #4ADE80; - --module-calendar: #A78BFA; - --module-meals: #FB923C; /* Orange-400 */ - --module-shopping: #F472B6; /* Pink-400 - trennt wie in Light */ - --module-notes: #FCD34D; - --module-contacts: #60A5FA; - --module-budget: #2DD4BF; /* Teal-400 - folgt Light-Mode-Teal */ - --module-settings: #94A3B8; - - /* Mahlzeit-Typ - Dark Mode */ - --meal-breakfast: #F59E0B; - --meal-dinner: #818CF8; /* Indigo-400 - folgt Dark-Accent */ - - /* Mahlzeit-Typ Light-Varianten */ - --meal-breakfast-light: #332400; - --meal-lunch-light: #1A3325; - --meal-dinner-light: #2E2D5B; /* Indigo-Dark-Tint (folgt --meal-dinner) */ - --meal-snack-light: #3D2010; + /* Mahlzeit-Typ */ + --_meal-breakfast: #F59E0B; + --_meal-breakfast-light: #332400; + --_meal-lunch-light: #1A3325; + --_meal-dinner: #818CF8; /* Indigo-400 */ + --_meal-dinner-light: #2E2D5B; + --_meal-snack-light: #3D2010; /* Priority-Badge Hintergründe */ - --color-priority-none-bg: rgba(142, 141, 137, 0.12); - --color-priority-low-bg: rgba(142, 141, 137, 0.18); - --color-priority-medium-bg: rgba(230, 147, 10, 0.18); - --color-priority-high-bg: rgba(212, 81, 30, 0.18); - --color-priority-urgent-bg: rgba(229, 83, 75, 0.18); + --_color-priority-none-bg: rgba(142, 141, 137, 0.12); + --_color-priority-low-bg: rgba(142, 141, 137, 0.18); + --_color-priority-medium-bg: rgba(230, 147, 10, 0.18); + --_color-priority-high-bg: rgba(212, 81, 30, 0.18); + --_color-priority-urgent-bg: rgba(229, 83, 75, 0.18); /* Overlay */ - --color-overlay: rgba(0, 0, 0, 0.6); - --color-overlay-light: rgba(0, 0, 0, 0.35); + --_color-overlay: rgba(0, 0, 0, 0.6); + --_color-overlay-light: rgba(0, 0, 0, 0.35); /* Schatten stärker im Dark Mode */ - --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25); - --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35); - --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45); + --_shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25); + --_shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35); + --_shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45); - /* Glass - Dark Mode */ - --glass-bg: rgba(40, 40, 38, 0.75); - --glass-bg-hover: rgba(50, 50, 48, 0.82); - --glass-bg-elevated: rgba(58, 58, 55, 0.90); - --glass-border: rgba(255, 255, 255, 0.12); - --glass-border-subtle: rgba(255, 255, 255, 0.07); - --glass-highlight: rgba(255, 255, 255, 0.10); - --glass-highlight-subtle: rgba(255, 255, 255, 0.06); - --glass-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.30), 0 0 0 1px rgba(255, 255, 255, 0.08); - --glass-shadow-md: 0 4px 20px rgba(0, 0, 0, 0.40), 0 0 0 1px rgba(255, 255, 255, 0.07); - --glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06); - - /* Vibrancy - Dark Mode */ - --glass-bg-card: rgba(38, 38, 36, 0.50); - --glass-bg-card-hover: rgba(48, 48, 46, 0.62); - --glass-bg-input: rgba(34, 34, 32, 0.45); - --glass-bg-toolbar: rgba(40, 40, 38, 0.55); - --glass-tint-strength: 8%; + /* Glass */ + --_glass-bg: rgba(40, 40, 38, 0.75); + --_glass-bg-hover: rgba(50, 50, 48, 0.82); + --_glass-bg-elevated: rgba(58, 58, 55, 0.90); + --_glass-border: rgba(255, 255, 255, 0.12); + --_glass-border-subtle: rgba(255, 255, 255, 0.07); + --_glass-highlight: rgba(255, 255, 255, 0.10); + --_glass-highlight-subtle: rgba(255, 255, 255, 0.06); + --_glass-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.30), 0 0 0 1px rgba(255, 255, 255, 0.08); + --_glass-shadow-md: 0 4px 20px rgba(0, 0, 0, 0.40), 0 0 0 1px rgba(255, 255, 255, 0.07); + --_glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06); + --_glass-bg-card: rgba(38, 38, 36, 0.50); + --_glass-bg-card-hover: rgba(48, 48, 46, 0.62); + --_glass-bg-input: rgba(34, 34, 32, 0.45); + --_glass-bg-toolbar: rgba(40, 40, 38, 0.55); + --_glass-tint-strength: 8%; } } -/* Manueller Dark-Mode-Override: data-theme="dark" auf */ +/* Manueller Dark-Mode-Override: data-theme="dark" auf (auch bei System in Light-Mode) */ :root[data-theme="dark"] { - --neutral-50: #1A1A18; - --neutral-100: #222220; - --neutral-150: #2A2A28; - --neutral-200: #333331; - --neutral-250: #3D3D3A; - --neutral-300: #48484A; - --neutral-400: #636360; - --neutral-500: #8E8D89; - --neutral-600: #AEADB0; - --neutral-700: #C8C7C3; - --neutral-800: #E2E1DC; - --neutral-900: #F5F4F1; - --neutral-950: #FAFAF8; + --_neutral-50: #1A1A18; + --_neutral-100: #222220; + --_neutral-150: #2A2A28; + --_neutral-200: #333331; + --_neutral-250: #3D3D3A; + --_neutral-300: #48484A; + --_neutral-400: #636360; + --_neutral-500: #8E8D89; + --_neutral-600: #AEADB0; + --_neutral-700: #C8C7C3; + --_neutral-800: #E2E1DC; + --_neutral-900: #F5F4F1; + --_neutral-950: #FAFAF8; - --color-surface: #2A2A28; - --color-surface-2: #1A1A18; - --color-surface-3: #333331; + --_color-surface: #2A2A28; + --_color-surface-3: #333331; - --sidebar-bg: #1A1A18; - --sidebar-shadow-light: rgba(255, 255, 255, 0.04); - --sidebar-shadow-dark: rgba(0, 0, 0, 0.4); + --_sidebar-bg: #1A1A18; + --_sidebar-shadow-light: rgba(255, 255, 255, 0.04); + --_sidebar-shadow-dark: rgba(0, 0, 0, 0.4); - /* Akzent - Dark Mode (Indigo bleibt, nur Lightness/Saturation rücken) */ - --color-accent: #818CF8; /* Indigo-400 — 6.8:1 auf #2A2A28 */ - --color-accent-hover: #6366F1; /* Indigo-500 */ - --color-accent-active: #4F46E5; /* Indigo-600 (= Light-Primary, Mirroring) */ - --color-accent-light: #2E2D5B; - --color-accent-subtle: #252255; - --color-btn-primary: #6366F1; /* Indigo-500 — 5.5:1 auf Dark-Surface */ - --color-btn-primary-hover: #4F46E5; - --color-accent-secondary: #A78BFA; + --_color-accent: #818CF8; + --_color-accent-hover: #6366F1; + --_color-accent-active: #4F46E5; + --_color-accent-light: #2E2D5B; + --_color-accent-subtle: #252255; + --_color-btn-primary: #6366F1; + --_color-btn-primary-hover: #4F46E5; + --_color-accent-secondary: #A78BFA; - /* Semantische Farben - Dark Mode */ - --color-success: #4ADE80; - --color-warning: #F59E0B; - --color-danger: #FCA5A5; - --color-text-tertiary: #A3A3A0; + --_color-success: #4ADE80; + --_color-warning: #F59E0B; + --_color-danger: #FCA5A5; + --_color-text-tertiary: #A3A3A0; + --_color-success-light: #1A3325; + --_color-warning-light: #332400; + --_color-danger-light: #3D1C1A; + --_color-info-light: #1A2D40; - --color-success-light: #1A3325; - --color-warning-light: #332400; - --color-danger-light: #3D1C1A; - --color-info-light: #1A2D40; + --_module-dashboard: #818CF8; + --_module-tasks: #4ADE80; + --_module-calendar: #A78BFA; + --_module-meals: #FB923C; + --_module-shopping: #F472B6; + --_module-notes: #FCD34D; + --_module-contacts: #60A5FA; + --_module-budget: #2DD4BF; + --_module-settings: #94A3B8; - /* Modul-Akzente - Dark Mode (Entflechtung Meals/Shopping spiegelt Light-Mode) */ - --module-dashboard: #818CF8; /* Indigo-400 - folgt neuem Dark-Accent */ - --module-tasks: #4ADE80; - --module-calendar: #A78BFA; - --module-meals: #FB923C; /* Orange-400 */ - --module-shopping: #F472B6; /* Pink-400 - trennt wie in Light */ - --module-notes: #FCD34D; - --module-contacts: #60A5FA; - --module-budget: #2DD4BF; /* Teal-400 - folgt Light-Mode-Teal */ - --module-settings: #94A3B8; + --_meal-breakfast: #F59E0B; + --_meal-breakfast-light: #332400; + --_meal-lunch-light: #1A3325; + --_meal-dinner: #818CF8; + --_meal-dinner-light: #2E2D5B; + --_meal-snack-light: #3D2010; - /* Mahlzeit-Typ - Dark Mode */ - --meal-breakfast: #F59E0B; - --meal-dinner: #818CF8; /* Indigo-400 - folgt Dark-Accent */ + --_color-priority-none-bg: rgba(142, 141, 137, 0.12); + --_color-priority-low-bg: rgba(142, 141, 137, 0.18); + --_color-priority-medium-bg: rgba(230, 147, 10, 0.18); + --_color-priority-high-bg: rgba(212, 81, 30, 0.18); + --_color-priority-urgent-bg: rgba(229, 83, 75, 0.18); - --meal-breakfast-light: #332400; - --meal-lunch-light: #1A3325; - --meal-dinner-light: #2E2D5B; /* Indigo-Dark-Tint (folgt --meal-dinner) */ - --meal-snack-light: #3D2010; + --_color-overlay: rgba(0, 0, 0, 0.6); + --_color-overlay-light: rgba(0, 0, 0, 0.35); - --color-priority-none-bg: rgba(142, 141, 137, 0.12); - --color-priority-low-bg: rgba(142, 141, 137, 0.18); - --color-priority-medium-bg: rgba(230, 147, 10, 0.18); - --color-priority-high-bg: rgba(212, 81, 30, 0.18); - --color-priority-urgent-bg: rgba(229, 83, 75, 0.18); + --_shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25); + --_shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35); + --_shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45); - --color-overlay: rgba(0, 0, 0, 0.6); - --color-overlay-light: rgba(0, 0, 0, 0.35); - - --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.25); - --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.35); - --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.45); - - /* Glass - Dark Mode */ - --glass-bg: rgba(40, 40, 38, 0.75); - --glass-bg-hover: rgba(50, 50, 48, 0.82); - --glass-bg-elevated: rgba(58, 58, 55, 0.90); - --glass-border: rgba(255, 255, 255, 0.12); - --glass-border-subtle: rgba(255, 255, 255, 0.07); - --glass-highlight: rgba(255, 255, 255, 0.10); - --glass-highlight-subtle: rgba(255, 255, 255, 0.06); - --glass-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.30), 0 0 0 1px rgba(255, 255, 255, 0.08); - --glass-shadow-md: 0 4px 20px rgba(0, 0, 0, 0.40), 0 0 0 1px rgba(255, 255, 255, 0.07); - --glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06); - - /* Vibrancy - Dark Mode */ - --glass-bg-card: rgba(38, 38, 36, 0.50); - --glass-bg-card-hover: rgba(48, 48, 46, 0.62); - --glass-bg-input: rgba(34, 34, 32, 0.45); - --glass-bg-toolbar: rgba(40, 40, 38, 0.55); - --glass-tint-strength: 8%; + --_glass-bg: rgba(40, 40, 38, 0.75); + --_glass-bg-hover: rgba(50, 50, 48, 0.82); + --_glass-bg-elevated: rgba(58, 58, 55, 0.90); + --_glass-border: rgba(255, 255, 255, 0.12); + --_glass-border-subtle: rgba(255, 255, 255, 0.07); + --_glass-highlight: rgba(255, 255, 255, 0.10); + --_glass-highlight-subtle: rgba(255, 255, 255, 0.06); + --_glass-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.30), 0 0 0 1px rgba(255, 255, 255, 0.08); + --_glass-shadow-md: 0 4px 20px rgba(0, 0, 0, 0.40), 0 0 0 1px rgba(255, 255, 255, 0.07); + --_glass-shadow-lg: 0 8px 40px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.06); + --_glass-bg-card: rgba(38, 38, 36, 0.50); + --_glass-bg-card-hover: rgba(48, 48, 46, 0.62); + --_glass-bg-input: rgba(34, 34, 32, 0.45); + --_glass-bg-toolbar: rgba(40, 40, 38, 0.55); + --_glass-tint-strength: 8%; } /* ================================================================