presseportale/dev/frontend/hub-flux/17-PHASE-5-DARK-MODE.md
Kevin Adametz 9b47296cea
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Rebrand Hub+Flux
2026-05-20 15:44:15 +02:00

5.6 KiB
Raw Blame History

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 04) · 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. 182248) 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 <html> 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

  • Plan
  • Recherche aller hardcoded Farbklassen
  • --color-ink-deep--color-panel-dark-2 in customer/tokens.blade.php
  • bg-white für 2FA-QR-Code in security.blade.php mit erklärendem Kommentar versehen
  • Build + Pint + Tests grün
  • 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.