# Phase 5 — Dark Mode > Dark Mode für das Portal (Customer + Admin), gesteuert > über den FluxUI Appearance-Switcher. Hub-Frontend bleibt > Light-Only. **Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag (meiste Arbeit war Vorbereitung in Phase 0–4) · **Risiko**: niedrig --- ## Befund Beim Start in Phase 5 war faktisch ~95 % der Arbeit schon in den vorherigen Phasen erledigt worden. Konkret: ### Was bereits da war 1. **`shared/design-tokens.css`** hat einen kompletten `.dark { … }`-Block (Z. 182–248) mit: - Surfaces (bg, bg-elev, bg-rule, bg-card, bg-card-warm) - Hub-Blau (heller im Dark Mode: `#5a78c2`) - Bernstein (heller: `#d9a560`), `--color-accent-warm` bewusst konstant - Ink-Skala (invertiert) - Status-Farben (ok/warn/err in helleren Varianten) - Bridge-Dots (heller) - Schatten (neutral schwarz statt warm-blau) - `color-scheme: dark` für native Controls 2. **`portal.css`** hat: - `@custom-variant dark (&:where(.dark, .dark *))` für Tailwind-`dark:`-Variants - Dark-Mode Shadow-Overrides für FluxUI-Primary-Buttons - Klare Erläuterung, warum kein Notfall-`.dark { … }`-Hack mehr nötig ist 3. **`shared/hub-components.css`** ist **zu 100 % token-basiert** (panels, badges, view-tabs, filter-chips, active-chips, portal-pills, inline-actions, empty-stage, counter-strip). Sobald die Tokens umschalten, schalten alle Komponenten automatisch um. 4. **`panel-dark`** nutzt `--color-panel-dark-2` / `--color-panel-dark` — die sind in beiden Modi identisch. Die Brand-Bridge-Card bleibt damit immer dunkel. 5. **`@fluxAppearance`** ist in beiden Head-Partials eingebunden (`partials/head.blade.php` + `partials/admin-head.blade.php`). 6. **Switcher** ist an drei Stellen verfügbar: - Sidebar Desktop User-Menü (`components/layouts/app/sidebar.blade.php`) - Sidebar Mobile User-Menü (gleiche Datei) - `settings/appearance.blade.php` (volle Card mit Light/Dark/System) Alle drei nutzen `x-model="$flux.appearance"` — FluxUI's Magic-Object, das LocalStorage-persistent ist und automatisch `class="dark"` auf `` setzt. ### Was zu fixen war Bei der Inventur fielen nur zwei Stellen auf, die im Dark Mode brechen würden: 1. **`customer/tokens.blade.php` Z. 137**: Token-Anzeige nach Generierung nutzte ein nicht existentes `--color-ink-deep`-Token. Damit war der Hintergrund bisher schlicht transparent (Light: kaum sichtbar, Dark: ebenso). Außerdem würde `--color-ink` im Dark Mode hell werden — weißer Text auf hellem Bg wäre unlesbar. Fix: auf `--color-panel-dark-2` (konstant dunkel) umstellen. 2. **`customer/security.blade.php` Z. 270**: 2FA-QR-Code in `bg-white`-Block. Das ist **bewusst** so — QR-Codes brauchen schwarz-auf-weiß, sonst werden sie nicht eingescannt. Kein Fix, nur Kommentar zur Klarstellung. ### Was unkritisch ist - `customer/dashboard.blade.php`: 8 Treffer für `bg-white` / `text-white` — alle im `panel-dark` Brand-Bridge Block (konstant dunkel, weiße Texte korrekt) und im Empty-State Counter-Badge auf `--color-accent` (Bernstein-Bg, beides Modi). - `admin/dashboard.blade.php` Z. 235: Quick-Action Hover-State `group-hover:bg-hub group-hover:text-white` — Hub-Bg ist sowohl Light (dunkles Hub-Blau) als auch Dark (helleres Hub-Blau) okay für weißen Text. - Sidebar-`dark:bg-zinc-…` Klassen aus dem Starter-Kit: Die Zinc-Skala ist in `portal.css` auf warmes Buchpapier gemapped, das funktioniert weiter — die Avatar-Bg's sind sowieso nur 8×8-Pixel-Spots. - `customer/press-kits/show.blade.php` Z. 440: Logo-Bg `bg-white` — bewusst, weil Firmen-Logos einen weißen Hintergrund für korrekte Darstellung brauchen. ### Was außerhalb von Phase 5 ist - **`shared-styles.css`** hat `.dark .card`, `.dark .slider-*`, `.dark .highlight-*`, `.dark .section-*` Regeln. Diese sind für den **Web-Bereich** (Hub-Frontend, presseecho, businessportal24), nicht fürs Portal. `portal.css` importiert `shared-styles.css` **nicht** — die Regeln landen also nicht im Portal-Bundle. - **Web-Frontend** bleibt Light-Only — wie in der Roadmap definiert. ## Akzeptanzkriterien - [x] Plan - [x] Recherche aller hardcoded Farbklassen - [x] `--color-ink-deep` → `--color-panel-dark-2` in `customer/tokens.blade.php` - [x] `bg-white` für 2FA-QR-Code in `security.blade.php` mit erklärendem Kommentar versehen - [x] Build + Pint + Tests grün - [x] PROGRESS.md + 03-WEITERE-PHASEN.md auf ✅ ## Lessons Learned - Konsequente Token-Disziplin (kein Hex außer in `design-tokens.css`) zahlt sich beim Dark Mode massiv aus: Statt 15 Pages × dutzende Klassen anzufassen, schaltet das gesamte Portal mit einem `.dark {…}` Block um. - Die wenigen Ausnahmen (panel-dark, QR-Code-Bg, Logo-Bg) sind dokumentierte Bewusst-Entscheidungen, keine Schuld. - FluxUI's `$flux.appearance` Magic-Object spart eine eigene Alpine-Component und persistiert über LocalStorage. ## Manueller Smoke-Test (Empfehlung) Da Pest keine echte Browser-Rendering-Pipeline hat: - Im Browser: User-Menü → Erscheinung → „Dunkel" - Folgende Seiten besuchen + visuell prüfen: - `/dashboard` (Admin) + `/me/dashboard` (Customer) - `/me/press-releases` (Customer-Liste mit Saved-Views-Tabs, Filter-Chips, Portal-Pills, Row-Tints) - `/admin/press-releases` (Admin-Liste mit Inline-Actions) - `/me/security` (2FA-QR mit `bg-white`) - `/me/tokens` (Token-Anzeige nach Generierung) - `/admin/companies/{id}` (Detail-View mit allen Panels) - Erwartung: Lesbar, konsistent, keine grellen Kontraste, keine „weißen Inseln" auf dunklem Bg.