presseportale/dev/frontend/hub-flux/05-PHASE-5-DARK-MODE.md
Kevin Adametz 0a3e52d603 19-05-2026 Rebrand Pressekonto, Hub-Flux UI und Legacy-Media-Migration
Umbenennung presseportale → pressekonto in Domains, Themes und Dokumentation.
Design-Tokens, Portal-Shell, Customer-Dashboard, Auth- und Admin-PM-Views.
Artisan-Befehl migrate:legacy-media mit Tests und Hub-Flux-Entwicklungsdocs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 16:36:13 +00:00

159 lines
7.8 KiB
Markdown

# Phase 5 — Dark Mode konsistent + Appearance-Switcher im User-Menü
> **Vorzugsphase**: Eigentlich Phase 5, vorgezogen vor Phase 3/4 nach
> User-Wunsch. Grund: Der FluxUI-Appearance-Switcher hat in Phase 1 den
> Dark-Mode-Bug ausgelöst (`#6d8ad3` statt Hub-Blau); statt Symptom-Fix
> wollen wir den vollen Dark Mode jetzt richtig.
**Status**: ✅ abgeschlossen · **Aufwand**: ~½ Tag · **Risiko**: niedrig
---
## Ziele
1. Dark Mode funktioniert sauber auf allen Portal-Seiten (Customer-Dashboard,
Sidebar, FluxUI-Komponenten, Hub-Components).
2. Switcher (Light / Dark / System) **direkt im User-Menü** verfügbar — kein
Umweg über `/settings/appearance` mehr nötig.
3. Hub-Frontend (Landing + Auth) bleibt **bewusst Light-Only** — Hub-Atmosphäre
ist Buchpapier.
4. Der Notfall-Hack aus Phase 1 (`portal.css: .dark { --color-accent: var(--color-hub) }`)
wird durch das echte Dark-Token-Mapping ersetzt.
## Quelle der Wahrheit
`dev/frontend/tailwind_v3/User Dashboard presseportale Dark.html`
liefert alle Dark-Werte. Wir spiegeln die Token-Namen aus dem Light-Mode 1:1.
---
## Was sich ändert
### 1. `shared/design-tokens.css`
Der seit Phase 0 vorbereitete `.dark`-Block wird **aktiviert** und um die seit
Phase 2 nachgezogenen Tokens (`--color-bg-rule-2`, `--color-gain-deep`) ergänzt.
Wichtige Umwidmungen im Dark Mode (gleiche Namen, andere Werte):
| Token | Light | Dark | Bedeutung |
| ----------------------- | ----------- | ----------- | ------------------------------------------ |
| `--color-bg` | `#f6f4ef` | `#0e1218` | Page-Background |
| `--color-bg-elev` | `#fbfaf6` | `#14181f` | Sidebar / leicht hervorgehoben |
| `--color-bg-card` | `#ffffff` | `#181d27` | Card-Body |
| `--color-bg-rule` | `#e2ddd0` | `#2a3142` | Trennlinien |
| `--color-bg-rule-2` | `#ede7d7` | `#232838` | Progress-Track |
| `--color-hub` | `#1a2540` | `#5a78c2` | Primary-Akzent (heller im Dark) |
| `--color-hub-soft` | `#e5e9f1` | `#1f2a47` | Hint-Hintergrund |
| `--color-accent` | `#b07a3a` | `#d9a560` | Bernstein-Akzent (heller im Dark) |
| `--color-accent-warm` | `#b07a3a` | `#b07a3a` | **bleibt gleich** — für Border-Akzente |
| `--color-accent-deep` | `#8a5e27` | `#b07a3a` | Action-Link-Color (heller im Dark) |
| `--color-accent-soft` | `#f1e6d3` | `#2a2418` | Hint-Icon-BG |
| `--color-ink` | `#1a1f1c` | `#ece9e0` | Text-Primary |
| `--color-ink-2` | `#3a413d` | `#c9c5b8` | Text-Secondary |
| `--color-ok / -soft` | `#2e8540 / #e2f1e5` | `#4dc076 / #1a2d22` | Status grün |
`--color-accent-warm` als **konstanter** Bernstein-Token (gleicher Wert in
beiden Modi) ist ein bewusster Trick: Im Portal mapt `--color-accent` auf
`var(--color-hub)` (Primary-Akzent), aber Bernstein-Borders (Hint-Card,
Schritt-Karten-Eyebrow) brauchen weiterhin den ungeänderten Bernstein-Wert.
`--color-accent-warm` ist der Token dafür.
### 2. `portal.css`
- Den `.dark { --color-accent: var(--color-hub); … }`-Notfall-Block aus
Phase 1 entfernen — er ist mit echtem Dark-Mapping überflüssig.
- Stattdessen einen kurzen Kommentar setzen, dass das Token-Mapping aus
`design-tokens.css` greift.
- Primary-Button-Hover-Override: heute hartcodiert auf `--color-hub-2`
(`#243152`). Im Dark Mode ist `--color-hub-2` = `#6d8ad3` (heller),
was richtig ist (Hover = noch heller als Default-Button). Override bleibt
via Variable korrekt, kein Eingriff nötig.
- Button-Shadows: `rgba(26, 37, 64, …)` ist Light-Mode-spezifisch. Im Dark
Mode wirkt der bläuliche Shadow auf dunklem Card-BG falsch. Lösung:
per `@media (prefers-color-scheme: dark)` ODER `.dark`-Selektor die
Shadow-Farben auf transparenten Schwarz tönen.
### 3. `shared/hub-components.css`
- Bernstein-Stellen umstellen: `var(--color-accent)`
`var(--color-accent-warm)` für **Hint-Card-Border-Left** und
**Progress-Bar-Fill** (sonst wird's im Portal Hub-Blau gemapt).
- Wegen Tokens-Architektur (`hub-soft` etc. werden im Dark Mode dunkler)
funktioniert der Großteil **automatisch** — keine `.dark`-Overrides nötig.
- Eine Ausnahme: `.panel-dark` und die Brand-Bridge-Boxes — im Light Mode
ist `panel-dark` Hub-Blau (#1a2540). Im Dark Mode bleibt das auch
`var(--color-hub)` — und da ist `--color-hub` heller (#5a78c2). Wir
brauchen also einen **konstanten dunklen Token** für `panel-dark` — sonst
wird die „dunkle“ Bridge-Card im Dark Mode plötzlich hellblau.
→ Neuer Token `--color-panel-dark` (immer #0f1729, in beiden Modi)
oder direkt `var(--color-topbar-deep)` (existiert bereits).
### 4. User-Menü-Switcher
Beide Dropdowns (Desktop in `sidebar.blade.php`, Mobile in derselben Datei)
bekommen vor dem Logout einen Block:
```blade
<flux:menu.separator />
<div class="px-2 py-1.5">
<flux:radio.group x-data variant="segmented" x-model="$flux.appearance" size="sm">
<flux:radio value="light" icon="sun" />
<flux:radio value="dark" icon="moon" />
<flux:radio value="system" icon="computer-desktop" />
</flux:radio.group>
</div>
```
Das ist exakt das Pattern aus `livewire/settings/appearance.blade.php`, nur
kompakt mit Icons-only. `$flux.appearance` ist FluxUI's Magic-Object,
LocalStorage-persistent, von `@fluxAppearance` injiziert.
### 5. Hub-Auth bleibt Light
`auth/pressekonto.blade.php` lädt **kein** `@fluxAppearance` und **kein**
`partials/head` — die Hub-Auth-Pipeline ist eigenständig. Damit wird `class="dark"`
dort nie gesetzt, selbst wenn das LocalStorage `dark` enthält. Hub-Auth bleibt
also automatisch Light. **Kein Eingriff nötig.**
---
## Implementierungs-Schritte (Reihenfolge)
1. `design-tokens.css`: Dark-Block aktivieren, `--color-accent-warm` definieren,
`--color-panel-dark` einführen (oder Re-Use `--color-topbar-deep`).
2. `portal.css`: Hack rausnehmen, Button-Shadow für Dark Mode tönen.
3. `hub-components.css`: Bernstein-Stellen auf `--color-accent-warm`,
`.panel-dark` auf `--color-panel-dark`.
4. `sidebar.blade.php`: Switcher in beide Dropdowns einbauen.
5. Build + Smoke-Test im Browser.
6. Bestehende Tests laufen lassen (sollten alle weiter grün sein, weil
keine Test-Assertion farbbezogen ist).
7. Pint + PROGRESS + Plan-Status.
## Akzeptanzkriterien
- [x] Plan-Dokument geschrieben
- [x] Switcher Light/Dark/System im User-Menü (Desktop + Mobile) sichtbar,
Änderung wirkt sofort + persistent (LocalStorage)
- [x] Dark Mode: Customer-Dashboard rendert mit allen Sektionen korrekt
(Tokens schalten um, kein hellblauer Akzent-Bug)
- [x] Brand-Bridge-Karte bleibt im Dark Mode dunkel (`--color-panel-dark-2`
konstant in beiden Modi)
- [x] Hub-Auth bleibt im Dark Mode Light (lädt kein `@fluxAppearance`)
- [x] Tests grün (18/18)
- [x] Pint clean
- [x] PROGRESS-Eintrag
## Risiken & Mitigation
- **FluxUI-Default-Komponenten im Dark Mode** (z.B. Modals, Dropdowns):
unsere Zinc→Hub-Mapping in `portal.css` bridgt die Skala. Im Dark Mode
müssen die Zinc-Werte auch umgekippt werden — passiert automatisch über
die Token-Vars, weil wir `var(--color-bg-*)` nutzen. Restrisiko: einzelne
FluxUI-Komponenten könnten harte Tailwind-Klassen wie `bg-white` haben,
die im Dark unverändert weiß bleiben. Smoke-Test deckt das auf.
- **Hub-Components-Schatten** sind in Hub-Blau-Alpha definiert
(`rgba(26, 37, 64, …)`). Im Dark Mode auf dunklem Bg wirken sie evtl.
„falsch warm“. Akzeptabel im ersten Wurf; Feintuning per `prefers-color-scheme`
Media-Query falls visuell stört.