presseportale/dev/frontend/hub-flux/PROGRESS.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

812 lines
40 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Fortschritts-Log — Hub × FluxUI
> Tagebuch der Umsetzung. Neue Einträge **oben** anfügen.
> Format pro Eintrag: Datum · Phase · Was wurde gemacht · Wer · Notizen
---
## 2026-05-19 · Phase 4C · Press-Releases Forms (create / edit)
- **Anlass**: User-Freigabe „ja" nach 4B. Drittes Päckchen aus
Phase 4 — Forms (create + edit) für Admin und Customer.
- **Plan-Dokument**: `09-PHASE-4C-PRESS-RELEASES-FORMS.md`.
- **Was umgebaut wurde (alle 4 Forms)**:
- **Page-Header** wie auf Listen und Detail: Hub-Badge
(„Admin Backend" / „User Backend") + Eyebrow + großes H1 +
Subtitle. Bei Edit zusätzlich Status-Pille im Header-Meta
(`@class([])`-Syntax mit `ok|warn|err|hub`) und „ID"-Pill.
Aktions-Buttons rechts (Zurück).
- **Form-Sektionen** als `.panel` mit `.panel-head` und
`section-eyebrow`: „Inhalt", „SEO & Links", „Metadaten",
„Status-Aktionen" (Admin-Edit), „Aktionen". Innenraum
immer `p-5 space-y-4`.
- **Form-Felder** bleiben FluxUI (`<flux:field>`,
`<flux:label>`, `<flux:input>`, `<flux:textarea>`,
`<flux:select>` inkl. Combobox-Variant, `<flux:checkbox>`,
`<flux:error>`) — das Token-Bridging aus Phase 1 zieht.
- **Required-Marker** von `text-red-500` auf Token-Farbe
(`text-[color:var(--color-err)]`) umgestellt.
- **Save-/Submit-Buttons** in eigenem `.panel` mit Header
„Aktionen" statt „nackten" Buttons in der Sidebar.
- **Flash-Boxen** (Success/Error) auf Hub-Token-Pillen.
- **Admin-Edit-spezifisch**: 5 Sidebar-Panels (Status-Aktionen +
Metadaten + Aktionen + Modals). „Status-Aktionen"-Panel zeigt
rechts im Header die aktuelle Status-Pille — visuelle Doppelung
mit dem Page-Header-Status, aber im Kontext der Sidebar
sinnvoll als Vergleichs-Anker für die „Neuer Status"-Auswahl.
- **Was explizit NICHT angefasst wurde**:
- **Volt-Logik** (alle `save`/`publish`/`reject`/`backToDraft`/
`archive`/`changeStatus`/`deletePressRelease`/`mount`/`with`/
`selectedCompany`-Methoden) — Layout-only.
- **Confirm-Modals** der Admin-Edit-Page
(`confirm-status-change`, `confirm-delete-press-release`) —
Tests in `AdminPressReleaseActionsTest` assertieren Wortlaute.
- **Wortlaute**: „Neuer Status", „Status wechseln",
„Status wirklich wechseln?", „Pressemitteilung löschen?",
„Status wurde auf" — alle erhalten.
- **`<livewire:components.press-release-images-manager>`** —
eigene Komponente, kommt im jeweiligen eigenen Päckchen dran.
- **Build/Test**:
- `npm run build:portal` → ok (`portal-D0cNdOWP.css` 418.42 kB).
- Linter clean (alle 4 Dateien).
- `php artisan test --compact --filter='PressRelease|CustomerCompanyContext|CustomerProfileSecurity|PanelConsolidation'`
**72 passed (310 assertions)**.
- Volle Suite: 230 passed, 3 skipped, 1 pre-existing failure
(`ApiDocumentationTest`).
- Pint `--dirty --format agent` → passed.
- **Offene Fragen**: Keine.
- **Nächster Schritt**: Phase 4 für Press-Releases ist mit 4A/4B/4C
komplett abgeschlossen. Nächstes Päckchen je nach Sichtbarkeit:
**4D = Companies** (`admin.companies.*`) ODER
**4E = Settings / Profile** (`me.profile`, `me.security`).
---
## 2026-05-19 · Phase 4B · Press-Releases Detail/Show-Pages
- **Anlass**: User-Freigabe „weiter" nach 4A. Zweites Päckchen aus
Phase 4 — Detail/Show-Pages für Admin und Customer.
- **Plan-Dokument**: `08-PHASE-4B-PRESS-RELEASES-DETAIL.md`.
- **Was umgebaut wurde (beide Show-Pages)**:
- **Page-Header** mit Hub-Badge + Eyebrow + Status-Pill +
Sprache + Portal (Admin nur), darunter großer H1 mit dem
PM-Titel und Subtitle mit Firma/Kategorie/Autor bzw. Datum.
Aktions-Buttons rechts (Bearbeiten/Vorschau-Link/Zurück).
- **Status-Workflow-Aktionsbar** als `.panel` mit `.panel-head`
und passend gefärbtem Badge je nach Status (warn=Review,
ok=Published, err=Rejected, hub=Draft).
- **Content-Hauptbereich** (PM-Text) als `.panel` mit eigenem
Header „Inhalt" + `prose` darunter. Keywords/Backlink darunter
als Footer mit Hub-Rule.
- **Sidebar / Side-Cards** (Admin) als kompakte `.panel` mit
`panel-head` „Details" und „Bilder" + Hub-Badges.
- **Status-Verlauf-Timeline** als `.panel` mit Hub-Badge je
Log-Eintrag (`.badge.ok|warn|err|hub`) statt FluxUI-`color`-Props.
- **Status-Badges** in Header und Timelines komplett auf
`<span class="badge …">` mit `@class([])`-Syntax.
- **Customer-Show-spezifisch**:
- **Rejection-Hinweis** als roter `.panel` mit linker
Akzent-Border (`border-left-width:3px`) und Icon-Box —
statt `<flux:callout color="red">`.
- **Review-Pending-Hinweis** als warner `.panel` mit
Akzent-Border und Clock-Icon-Box — statt `<flux:callout color="yellow">`.
- **Share-Link-Erfolgsblock** als ok-`.panel` mit
Gültigkeits-Badge im Header und readonly-Input im Body.
- **Contacts-Liste** als Hub-Items (`bg-bg-elev` +
`border-bg-rule`), Empty-State mit gestrichelter Border.
- **Status-Tile-Grid** (Aktuell/Erstellt/Veröffentlicht/Aufrufe)
als 4-er-Grid mit kleinen Hub-Tiles statt zinc-Hintergründen.
- **Admin-Show-spezifisch**:
- **Modals** (Publish/Reject/Archive) komplett unverändert —
Tests in `AdminPressReleaseActionsTest` assertieren Wortlaute.
- **Was explizit NICHT angefasst wurde**:
- **Volt-Logik** (publish/reject/archive/submitForReview/
generateShareLink/with-Method) — Layout-only.
- **Wortlaute** „Erneut einreichen", „Werbliche Sprache wurde
markiert." aus `PressReleaseWorkflowTest`.
- **Bestehende Modals** und ihre Wortlaute.
- **Mini-Stolperer (sofort gefixt)**:
- Erst zwei nicht-existente Tokens (`--color-rule`,
`--color-panel-soft`) verwendet. Korrigiert zu
`--color-bg-rule` und `--color-bg-elev` (16 + 5 Vorkommen).
Wäre im Browser stumm gefailed (Tailwind hätte die
Klassen einfach nicht ausgegeben).
- **Build/Test**:
- `npm run build:portal` → ok (`portal-Bq4pkLWt.css` 418.36 kB).
- Linter clean.
- `php artisan test --compact --filter='PressReleaseWorkflow|AdminPressReleaseActions'`
→ 16 passed (52 assertions).
- Volle Suite: 230 passed, 3 skipped, 1 pre-existing failure
(`ApiDocumentationTest`, schon vor 4A bekannt).
- Pint `--dirty --format agent` → passed.
- **Offene Fragen**: Keine.
- **Nächster Schritt**: Päckchen **4C** = Press-Releases Forms
(`create.blade.php` + `edit.blade.php`, Admin + Customer).
Forms sind tendenziell aufwendiger (mehr FluxUI-Felder, ggf.
zusätzliche Logik wie Image-Uploads).
---
## 2026-05-19 · Phase 4A · Press-Releases Listen-Pages
- **Anlass**: User-Freigabe „weiter" nach Phase 3 (Admin-Dashboard).
Phase 4 ist laut Roadmap „der Marathon" über Listen-/Detail-Pages
(~35 Tage iterativ). Wegen Umfang in Päckchen geteilt — A = Listen,
B = Detail/Show, C = Forms, D = Companies, E = Settings, F = Rest.
- **Plan-Dokument**: `07-PHASE-4A-PRESS-RELEASES-LISTEN.md` (knapp,
Scope hart auf zwei `index.blade.php`-Files begrenzt, mit explizitem
„NICHT in diesem Päckchen"-Block).
- **Scope dieses Päckchens**:
- `resources/views/livewire/admin/press-releases/index.blade.php`
- `resources/views/livewire/customer/press-releases/index.blade.php`
- **Was umgebaut wurde (beide Listen)**:
- **Page-Header** im Hub-Stil: `<header>` mit `1fr auto`-Grid,
Hub-Badge („Admin Backend" / „User Backend"), Eyebrow, großes H1,
Subtitle, rechts der CTA-Primary-Button (FluxUI bleibt für den Button).
- **Filter-Bar** als `.panel` + `.panel-head` mit `section-eyebrow`
„Filter & Suche". FluxUI-Inputs (Search-Input, Selects, Combobox
für User/Company/Contact-Lookup) bleiben unverändert — Hub hat
kein eigenes Combobox-Pendant.
- **Tabelle** als `.panel` mit `.panel-head` „Alle Pressemitteilungen"
+ Eintrags-Counter rechts. FluxUI-`<flux:table>` bleibt — das
Zinc-→Hub-Mapping aus Phase 1 zieht hier perfekt.
- **Status-Badges**: `<flux:badge color="green|yellow|red|zinc|blue">`
ersetzt durch `<span class="badge ok|warn|err|hub">` für visuelle
Konsistenz mit dem Dashboard (`@class([...])`-Syntax).
- **Empty-State** mit Icon-Box (`bg-[color:var(--color-hub-soft)]`,
Hub-Border, `flux:icon.newspaper`) + Headline + Subtext.
- **Flash-Boxen** auf Hub-Tokens (`--color-ok-soft`, `--color-err-soft`,
`--color-gain-deep`, `--color-loss`) statt `bg-green-50` etc.
- **Admin-spezifisch**: Vier `<x-portal.stat-card>` (Gesamt/Veröffentlicht/
In Prüfung/Entwürfe) als KPI-Reihe — identisches Layout wie Admin-Dashboard.
- **Was explizit NICHT angefasst wurde**:
- **Confirm-Modals** (Publish/Reject/Archive) — Tests in
`AdminPressReleaseActionsTest` assertieren die Wortlaute
(„Pressemitteilung veröffentlichen?" etc.) → unverändert.
- **Volt-Logik** (Sort, Filter, alle Methods) — Layout-only.
- **Bonus-Fix**: `customer/dashboard.blade.php` Subtitle bekommt
einen „Übersicht für :company —"-Einschub, wenn `$selectedCompany`
gesetzt ist. Korrigiert eine Phase-2-Regression bei
`CustomerCompanyContextTest > customer dashboard is filtered by …`.
- **Build/Test**:
- `npm run build:portal` → ok (`portal-DaL-tXm-.css` 418.75 kB).
- Linter clean.
- `php artisan test --compact --filter='PressReleaseWorkflow|AdminPressReleaseActions|Dashboard|CustomerCompanyContext'`
→ 45 passed (163 assertions).
- Volle Suite: 230 passed, 3 skipped, 1 failed.
Der einzelne Fail (`ApiDocumentationTest`) ist **pre-existing**
via `git stash` verifiziert, war auch vor diesem Päckchen rot
(`/docs/api/v1` liefert nicht das erwartete YAML).
- Pint `--dirty --format agent` → passed.
- **Offene Fragen**: Keine.
- **Nächster Schritt**: Päckchen **4B** = Detail/Show-Pages
(`admin/press-releases/show.blade.php` +
`customer/press-releases/show.blade.php`). Dort ist mit der
„Werbliche Sprache wurde markiert."- und „Erneut einreichen"-
Assertion aus `PressReleaseWorkflowTest` zu rechnen — Wortlaute
bleiben unverändert.
---
## 2026-05-19 · Phase 3 · Admin-Dashboard im Hub-Vokabular
- **Anlass**: User-Freigabe „weiter" nach Phase 5 (Dark Mode). Phase 3
laut Roadmap: Admin-Dashboard (`/dashboard`) im selben Vokabular wie
Customer-Dashboard.
- **Plan-Dokument**: `06-PHASE-3-ADMIN-DASHBOARD.md` (knapper als
Phase 2 — niedrig-risiko, keine neuen Konzepte, reine
Vokabular-Migration auf die DRY-Schicht aus Phase 2).
- **Ausgangslage**: `admin/dashboard.blade.php` war Controller-rendered
(kein Volt), nutzte reines Tailwind mit `zinc-*`-Klassen, harten
Farb-Pillen (`bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 …`)
und keiner FluxUI-Komponente. Visuell aus der Zeit gefallen.
- **`admin/dashboard.blade.php` komplett umgeschrieben**:
- **Page-Header**: Hub-Badge „Admin Backend" + Eyebrow + großes H1
+ Subtitle mit `auth()->user()->name`. Rechts: ok-Pille
„Alle Systeme operational".
- **KPI-Reihe** (5 Stat-Cards via `<x-portal.stat-card>`):
- Pressemitteilungen → `primary` mit Trend-Slot
„X pub · Y prüf · Z entwurf" (Wortlaut für Test-Assertions
bewusst beibehalten).
- In Prüfung → `warn` als eigene KPI (war vorher nur in der PM-Card
versteckt — jetzt klickbar direkt in den Filter).
- Firmen / Kontakte / Benutzer → `muted` mit kurzen Sublines.
- Alle Cards sind klickbar (link-wrapped) → CRM-/Content-Übersichten.
- **2-Spalten-Grid** (`2fr 1fr`):
- Links: Panel „Letzte Pressemitteilungen" mit Hub-Liste +
`.badge.ok|warn|err|hub`-Pillen (statt Tailwind-Farben).
- Rechts: Panel „Zur Prüfung" mit warn-Pille (Count) oder
ok-Pille „leer". „+ N weitere"-Link im Footer.
- **Newsletter + Quick-Actions** (`1fr 2fr`, NEU):
- Links: `panel-warm` Newsletter-Block mit Mono-Zahl
+ Subline + Sync-Link.
- Rechts: Quick-Action-Grid mit 4 Icon-Buttons (Pressemitteilungen,
Firmen, Rechnungen, Voreinstellungen) — Icon-Tile wechselt auf
Hover ins gefüllte Hub-Blau.
- **Footer**: subtle Link-Reihe (Benutzer / Rollen / Performance).
- **Was bewusst NICHT geändert**:
- Controller-Logik, Datenform, Cache-Strategie (`AdminPerformanceCache`).
- Newsletter-Count bleibt, wandert nur in eigenen Block.
- **Build/Verifikation**:
- `npm run build:portal``portal: 417.81 kB` (Δ -0.7 kB,
weil viele Zinc-Tailwind-Klassen weggefallen sind).
- `php artisan test --filter='DashboardTest|AuthenticationTest|RegistrationTest|CustomerPortalTest'`
**18/18 passed**, 70 Assertions. `DashboardTest` mit seinen
Wortlaut-Assertions (`3`, `1 pub`, `1 prüf`, `1 entwurf`,
`Review Dashboard PM`) bleibt grün ohne Anpassung.
- `vendor/bin/pint --dirty``passed`.
- Linter: 0 Errors.
- **Lessons learned**:
- Vokabular-Migrations ohne Logik-Eingriff brauchen ~15 Minuten dank
DRY-Schicht aus Phase 2 — der Wert der `shared/hub-components.css`
+ `<x-portal.stat-card>`-Investition zahlt sich ab Phase 3 deutlich aus.
- Der `<x-portal.stat-card>` ist auch ohne `:value`-Number-Format
flexibel (`number_format()` direkt im Aufruf eingebettet).
- Test-Assertions können bei Layout-Refactors überraschend stabil
bleiben, wenn man die Original-Strings im neuen Layout an
sinnvollen Stellen behält (hier: im Trend-Slot der KPI-Card).
---
## 2026-05-19 · Phase 5 · Dark Mode + Switcher im User-Menü
- **Anlass**: User-Feedback nach Phase 2: „Switch in den Dark Mode funktioniert
nicht. Zusätzlich hätte ich gerne einen Switcher hell/dunkel direkt im
User-Menü." → Phase 5 vorgezogen vor Phase 3/4, weil der Switcher der
natürliche UX-Einstiegspunkt für Dark Mode ist und der Notfall-Hack
aus Phase 1 (`portal.css: .dark { --color-accent: var(--color-hub) }`)
endlich verschwinden soll.
- **Plan-Dokument**: `05-PHASE-5-DARK-MODE.md` mit Token-Mapping-Tabelle,
drei wichtigen Token-Konstanten-Tricks (`--color-accent-warm`,
`--color-panel-dark`, `--color-panel-dark-2`) und Switcher-Snippet.
- **`design-tokens.css` — Dark-Block aktiviert**:
- Vollständiger `.dark { … }`-Block mit Werten aus
`User Dashboard presseportale Dark.html`.
- Surfaces: bg/elev/card/rule schalten auf `#0e1218`-Familie.
- Hub-Blau wird **heller** im Dark Mode (`#5a78c2` statt `#1a2540`) —
notwendig für Lesbarkeit auf dunklem Bg.
- Bernstein-Akzent ebenfalls heller (`#d9a560`).
- Status-Farben (`ok/warn/err`) auf dunkle, gesättigte Variante.
- Schatten-Tokens neutral-schwarz statt hub-blau-warm.
- `color-scheme: dark;` als Hint für native Form-Controls.
- **3 neue Token-Konstanten** (gleicher Wert in beiden Modi):
- `--color-accent-warm` (`#b07a3a`) — für Stellen, die explizit Bernstein
bleiben müssen (Hint-Card-Border-Left, Progress-Bar-Fill); löst die
Kollision auf, dass `--color-accent` im Portal auf Hub-Blau gemapt
ist und im Dark Mode noch heller würde.
- `--color-panel-dark` (`#0f1729`) und `--color-panel-dark-2` (`#1a2540`)
— für `.panel-dark` und Brand-Bridge-Inner-Boxes. Ohne diese würde
der dunkle Bridge-Container im Dark Mode plötzlich hellblau, weil
`var(--color-hub)` zum hellen Wert wird.
- **`portal.css` — Notfall-Hack aus Phase 1 entfernt**:
- Der `.dark { --color-accent: var(--color-hub); … }`-Block ist
überflüssig, weil das echte Dark-Token-Mapping in `design-tokens.css`
`--color-hub` automatisch auf `#5a78c2` schaltet — und
`--color-accent` darüber per `var(--color-hub)`-Verweis dynamisch
mitkommt.
- Primary-Button-Shadows zusätzlich für `.dark` überschrieben: statt
`rgba(26, 37, 64, …)` (warmer Hub-Blau-Alpha) jetzt `rgba(0, 0, 0, …)`
(neutral-schwarz), weil der hub-blaue Schatten auf dunklem Card-BG
zu sichtbar wirkt.
- **`hub-components.css` — Dark-tauglich gemacht**:
- `.panel-dark` nutzt jetzt `var(--color-panel-dark-2)` und
`var(--color-panel-dark)` (vorher `var(--color-hub)` und
`var(--color-topbar-deep)`) → bleibt im Dark Mode dunkel.
- `.hint-card border-left` und `.hint-bar > span` nutzen
`var(--color-accent-warm)` (konstant Bernstein) statt `var(--color-accent)`
(im Portal Hub-Blau-Mapping).
- `.hint-card background` schaltet auf `var(--color-bg-card-warm)`
ist im Light Mode `#efeadc` (warmes Buchpapier), im Dark Mode
`#1f1a12` (warm-dunkles Bernstein-Substrat).
- Restliche Klassen funktionieren **automatisch**, weil alle Werte
über Tokens laufen — DRY-Architektur zahlt sich aus.
- **`customer/dashboard.blade.php`**:
- Brand-Bridge-Inner-Boxes auf `bg-[color:var(--color-panel-dark-2)]`
umgestellt (statt `--color-hub-2`, das im Dark Mode hell würde).
- **Switcher im User-Menü** (`sidebar.blade.php` — Desktop + Mobile):
- Vor dem Logout-Button: kleiner Block mit Eyebrow „Erscheinung" und
FluxUI-Segmented-Radio-Group mit Icons-only.
```blade
<flux:radio.group x-data variant="segmented" size="sm" x-model="$flux.appearance">
<flux:radio value="light" icon="sun" :title="__('Hell')" />
<flux:radio value="dark" icon="moon" :title="__('Dunkel')" />
<flux:radio value="system" icon="computer-desktop" :title="__('System')" />
</flux:radio.group>
```
- `$flux.appearance` ist FluxUIs Magic-Object — LocalStorage-persistent,
`@fluxAppearance`-Script setzt `class="dark"` auf `<html>`.
- In BEIDEN Dropdowns (Desktop in der Sidebar, Mobile im Header).
- **Hub-Frontend bleibt Light-Only** (Plan-Vorgabe):
- `auth/pressekonto.blade.php` lädt KEIN `@fluxAppearance` und KEIN
`partials/head`. Damit wird `class="dark"` dort nie gesetzt — auch
nicht, wenn LocalStorage `dark` enthält. Kein Eingriff nötig.
- Hub-Landing analog (eigene `<head>`-Pipeline).
- **Build/Verifikation**:
- `npm run build:portal` → `portal: 418.55 kB` (Δ +1.5 kB für
Dark-Tokens + Switcher).
- `php artisan test --filter='DashboardTest|AuthenticationTest|RegistrationTest|CustomerPortalTest'`
→ **18/18 passed**, 70 Assertions. Keine Regressions.
- `vendor/bin/pint --dirty` → `passed`.
- Linter: 0 Errors.
- **Lessons learned**:
- Tailwind v4's `@theme`-Variables sind **dynamisch** zur Laufzeit —
`--color-accent: var(--color-hub)` schaltet beim `.dark`-Switch
automatisch mit, ohne dass man `.dark { --color-accent: … }` extra
setzen muss.
- Wenn ein Wert in beiden Modes IDENTISCH bleiben soll (`--color-panel-dark-2`,
`--color-accent-warm`), gehört er in den Light-Block und wird im
`.dark`-Block bewusst NICHT überschrieben. Vererbung tut den Rest.
- FluxUI's `flux:radio.group variant="segmented"` mit Icons-only ist
perfekt für Dropdown-Switcher; `:title="…"` liefert Tooltips ohne
sichtbares Label.
- **Bonus**: Der ursprüngliche Symptom-Fix aus Phase 1
(Multi-Alpine + Dark-Mode-Bug) ist jetzt strukturell aufgelöst:
- Alpine kommt ausschließlich aus `@fluxScripts`.
- Dark Mode ist echt umgesetzt, nicht maskiert.
---
## 2026-05-19 · Phase 2 · Customer-Dashboard auf Mockup-Stil
- **Anlass**: User-Freigabe „weiter“ nach Behebung des Dark-Mode/Alpine-Bugs.
Phase 2 laut Plan: Customer-Dashboard (`/admin/me`) an
`User Dashboard presseportale.html` angleichen.
- **Vorab-Doku**: `04-PHASE-2-CUSTOMER-DASHBOARD.md` mit Mockup-Diff-Tabelle,
CSS-Strategie, Component-Skizzen, Akzeptanzkriterien.
- **CSS-Architektur — DRY-Schritt**:
- Neue Datei `resources/css/shared/hub-components.css` als **Single Source
of Truth** für Hub-Layout-Bausteine: `.panel` (warm/dark/head),
`.stat-card` (+ Varianten `is-primary|ok|warn|muted`, `.stat-strip`,
`.stat-label`, `.stat-num`, `.stat-meta`, `.stat-trend`), `.hint-card`
(+ `.hint-ico`, `.hint-bar`, `.hint-action`), `.badge` (+ `.warn|ok|hub|err|dot`),
`.bridge-row`/`.dot-pe`/`.dot-bp`, portable `.eyebrow` und
`.section-eyebrow` (für Portal — Web-Build überschreibt idempotent).
- Importiert in **beiden** Builds:
- `resources/css/portal.css` (nach `flux.css`)
- `resources/css/web/shared-styles.css` (nach `design-tokens.css`)
- Alle Werte nutzen `var(--color-*)`-Tokens — keine Hex-Literale.
- Fehlende Tokens nachgezogen in `shared/design-tokens.css`:
`--color-bg-rule-2` (hellere Progress-Track-Variante) und
`--color-gain-deep` (dunkles Grün für `is-ok`-Stat-Num).
- **Neue Blade-Components** in `resources/views/components/portal/`:
- `<x-portal.stat-card variant="…" label="…" :value="…">`
mit Slots `meta` (oben rechts) und `trend` (unten).
- `<x-portal.hint-card :icon :title :percent :href :action>`
mit Progress-Bar bei gesetztem `$percent` und `wire:navigate`-Link.
- **`livewire/customer/dashboard.blade.php` komplett neu**:
- **Page-Header**: Hub-Badge „User Backend“ + Eyebrow + großes H1
+ Subtitle. Rechts entweder Aktive-Firma-Pille **oder** Warn-Pille
„Keine Firma zugeordnet → zuordnen“.
- **KPI-Reihe** (4 `stat-card`s): Gesamt (primary, mit Δ-zu-Vormonat),
Veröffentlicht (ok), In Prüfung (warn), Entwürfe (muted).
- **Zweispalten-Grid** (`lg:grid-cols-[2fr_1fr]`):
- Links: Panel mit Pressemitteilungen-Liste oder Empty-State (Icon-Box
mit Notification-Dot, Headline, Action-Button, Schritt-Karten 01/02/03,
Footer-Tipp „4 Stunden“).
- Rechts: Panel „Datenqualität“ mit `<x-portal.hint-card>`s oder
Success-State („Alles im grünen Bereich“).
- **Unteres Grid**: Firmen-Panel (Liste **oder** dashed Empty-Slot
+ Hinweis-Box) + Brand-Bridge-Dark-Panel (presseecho + businessportal24
mit Status, API-Status-Indikator, Tarif).
- **Footer**: Subtle-Link-Reihe (Sicherheit, API & Tokens, Profil).
- **Volt-`with()` erweitert**:
- `stats.deltaMonth` — Monatsvergleich via zweiter `whereBetween`-Query.
- `profileCompleteness` (Heuristik auf 6 Profile-Kernfelder).
- `billingCompleteness` (5 Address-Pflichtfelder).
- `bridgeStatus` (vorerst hardcoded `connected` — Phase 3+).
- `qualityHints[]` optional um `percent`-Feld erweitert — wenn gesetzt,
rendert Progress-Bar in der Hint-Card.
- **Edge-Case beim Bauen**: Blade interpretierte `<flux:icon>` im PHPDoc-
Kommentar von `hint-card.blade.php` als echten Component-Tag und produzierte
`Undefined variable $component`. Fix: Doc-Block entkontaminiert
(„flux:icon“ ohne Spitzklammern).
- **Tests neu** in `tests/Feature/Customer/DashboardTest.php` (5 Cases):
1. Customer-Dashboard rendert Core-Sections ohne Fehler
2. Empty-State mit 3-Schritt-Intro wird gezeigt
3. PR-Liste + KPI-Zahlen rendern bei vorhandenen Daten
4. Profile-Completeness-Hint mit Prozentwert erscheint bei Teildaten
5. Vollständiges Profil + Billing → Hints werden ausgeblendet,
„Alles im grünen Bereich“ wird gezeigt
- **Ergebnis**: 5/5 passed, 21 Assertions.
- Cross-Check: Verwandte Tests (`Dashboard|Authentication|Registration|CustomerPortal`)
→ **18/18 grün**, 70 Assertions. Keine Regressions.
- **Build/Verifikation**:
- `npm run build:portal` → `portal: 417.02 kB` (Δ +8 kB für neue
Hub-Components-Klassen + Dashboard-Klassen). Web-Build unverändert.
- `vendor/bin/pint --dirty` → `passed`.
- **Was bewusst weggelassen**:
- Sparklines auf den Stat-Cards (kommen mit echten Trend-Daten in Phase 4).
- Topbar-Anpassung (eigene Phase, später).
- `<x-portal.bridge-card>`-Extraktion (Brand-Bridge bleibt inline, bis
sie an mehr Stellen gebraucht wird).
- **Lessons learned**:
- PHPDoc in Blade-Components darf KEINE `<flux:*>`-Tags enthalten —
der Blade-Pre-Compiler scannt das gesamte File vor dem PHP-Parsing.
- `shared/hub-components.css` ist der richtige Hebel für Phase 3
(Admin-Dashboard) und Phase 4 (Listen/Detail) — Components-CSS muss
nicht mehr pro Phase neu definiert werden.
---
## 2026-05-19 · Phase 1 Refinement · Dark-Mode-Bug + Multi-Alpine
- **Anlass**: User-Review nach Kontrast-Refinement: zwei konkrete Befunde
aus der Browser-Konsole.
1. `[Warning] Detected multiple instances of Alpine running (me, line 114)`
2. Button-Default-Farbe ist `rgb(109, 138, 211)` (helles Blau), nicht
das gewünschte Hub-Blau `rgb(26, 37, 64)`. Computed Style zeigt:
`.bg-[var(--color-accent)] { background-color: var(--color-accent); }`
→ `var(--color-accent)` löst zu `#6d8ad3` auf.
- **Diagnose Bug 1 (Alpine)**:
- `partials/head.blade.php` lädt `resources/js/app.js` über `@vite`.
`app.js` ruft `Alpine.start()` auf.
- Am Ende des `<body>` injiziert `@fluxScripts` (sidebar.blade.php Zeile
nahe `</body>`) **eine eigene Alpine-Instanz** (FluxUI bringt Alpine
selbst mit).
- Ergebnis: zwei `window.Alpine`-Objekte, Bindings teils tot, Warning.
- Auf der Login-Seite hatten wir das **bereits** gefixt (app.js dort
rausgenommen), aber im Portal-Layout war der Fix noch offen.
- **Diagnose Bug 2 (Button-Farbe)**:
- Der Wert `rgb(109, 138, 211)` = `#6d8ad3` ist **exakt** der
Dark-Mode-Fallback, den ich in `portal.css` unter `.dark { --color-accent: #6d8ad3 }`
definiert hatte.
- FluxUI's `@fluxAppearance`-Helper schreibt `class="dark"` auf
`<html>`, sobald der User den Appearance-Switcher mal auf "dark"
gestellt hatte (gespeichert in `localStorage`).
- Damit überschreibt der Dark-Block den Light-Mode-Akzent
`var(--color-hub)` (`#1A2540`) — Buttons sehen plötzlich blassblau aus.
- Dark Mode ist laut Plan erst Phase 5, war aber durch den
Fallback-Block bereits halb aktiv.
- **Fixes**:
- `resources/views/partials/head.blade.php`: `resources/js/app.js`
aus dem `@vite`-Aufruf **entfernt**. Alpine kommt im Portal
ausschließlich über `@fluxScripts`. (Hub-Landing nutzt
`partials/head` nicht — eigene `<head>`-Pipeline.)
- `resources/css/portal.css`: Der `.dark { --color-accent: ... }`-
Block setzt jetzt **bewusst** alle Akzent-Tokens auf
`var(--color-hub)` (also den Light-Mode-Wert). Damit bleibt das
Hub-Blau auch bei eingeschaltetem `class="dark"` konsistent.
Kommentar dokumentiert, dass Phase 5 diesen Block durch das
echte Dark-Token-Mapping aus `shared/design-tokens.css` ersetzt.
- **Build/Verifikation**:
- `npm run build:portal` → `portal: 408.97 kB` (Δ +0.02 kB).
- `php artisan test --compact --filter='AuthenticationTest|RegistrationTest'`
→ **6 passed, 19 assertions**, 1.93s.
- `vendor/bin/pint --dirty --format agent` → `passed`.
- **User-Action zur Verifikation**:
- Im Portal Hard-Reload (Cmd/Strg+Shift+R) — die alte `app.js`
hängt sonst im HTTP-Cache.
- Konsole sollte **keine** Multi-Alpine-Warning mehr werfen.
- Primary-Buttons sind im Default-State sattes Hub-Blau (`#1A2540`),
Hover noch dunkler (`#243152`).
---
## 2026-05-19 · Phase 1 Refinement · Kontraste & Button-Hover
- **Anlass**: User-Review nach Phase 1: „Buttons als Primary auf
`rgb(26, 37, 64)` einsetzen, die andere Farbe ist deutlich zu hell.
Es fehlen noch deutliche Kontraste."
- **Diagnose**:
- FluxUI-Primary-Buttons sind eigentlich **schon** auf `var(--color-accent)`
= `var(--color-hub)` = `#1A2540` = `rgb(26, 37, 64)` gesetzt
(im Build verifiziert). Sollte stimmen.
- **ABER**: Der FluxUI-Default-Hover ist
`hover:bg-[color-mix(in_oklab,_var(--color-accent),_transparent_10%)]`
— auf hellem Buchpapier wirkt das hell-blau statt der gewünschten
Hub-Konvention `hover:bg-hub-2` (dunkler als Default).
- Außerdem zu wenig Schatten/Border-Kontrast für klare Button-Kanten.
- **Erkenntnis**: Frühere `[data-flux-button][data-variant="primary"]`-
Overrides griffen **nie**, weil FluxUI kein `data-variant`-Attribut
rendert. Variant-Styling kommt komplett über Tailwind-Klassen
(z.B. `bg-[var(--color-accent)]`). Neue Selektor-Strategie nutzt
jetzt diese Klassen direkt (mit escapeten Brackets).
- **Fixes in `portal.css`**:
- **Primary-Button-Hover** auf `var(--color-hub-2)` (#243152) statt
FluxUI's color-mix-Hellung. Selektor:
`[data-flux-button].hover\:bg-\[color-mix\(in_oklab\,_var\(--color-accent\)\,_transparent_10\%\)\]:hover`
- **Primary-Button-Shadow**: kräftigeres Inset-Highlight + warmer
Drop-Shadow in Hub-Blau-Alpha für klare Kanten auf Buchpapier.
Border zusätzlich auf `var(--color-hub-2)` für definierten Rand.
- **Hover-State**: noch stärkerer Shadow + Drop für Tiefenwirkung.
- **Input-Focus** auf Hub-Blau-Ring (statt blassem Default-Akzent),
mit Buchpapier-Offset für saubere Trennung.
- Alter (defunkter) `[data-flux-button][data-variant="primary"]`-
Block entfernt, weil Selektor nicht existiert.
- **Build/Verifikation**:
- `npm run build:portal` → `portal: 408.95 kB` (von 409.03 kB, -0.08 kB).
- Im finalen CSS verifiziert:
* Hub-2-Hover-Override:
`[data-flux-button].hover\:bg-…:hover{background-color:var(--color-hub-2)!important}`
* Shadow-Override:
`[data-flux-button].bg-\[var\(--color-accent\)\]{border-color:var(--color-hub-2);box-shadow:inset 0 1px #ffffff2e,0 1px 2px #1a254040,…}`
* Input-Focus-Ring auf Hub-Blau.
- `vendor/bin/pint --dirty` → passed.
- **Wirkung**:
- Primary-Button **Default**: `#1A2540` (Hub-Blau), klarer warmer
Schatten, definierter Rand → fühlt sich „solid" an wie auf der
Hub-Landing.
- Primary-Button **Hover**: `#243152` (Hub-2, dunkler statt heller)
— Hub-Konvention, signalisiert Interaktion ohne den Eindruck einer
schwächeren Farbe zu erzeugen.
- Inputs zeigen jetzt einen **erkennbaren Hub-Blau-Ring** beim Fokus
statt eines blassen Bernstein-Schimmers.
- **Hinweis an User**: **Hard-Reload** (Cmd+Shift+R) ist nötig — das
CSS-Bundle hat einen neuen Hash (`portal-kuU-opFv.css`).
- **Verfeinerungen noch offen für Phase 2 / Iteration**:
- Subtle/Filled/Ghost-Buttons (`<flux:button variant="filled">`) sind
weiterhin transparent-zinc → bei Bedarf in Phase 2 angleichen.
- Sidebar-Active-Item hat schon Hub-Soft + 2 px-Strip; ggf. den
Strip noch sichtbarer machen wenn weiter zu unauffällig.
---
## 2026-05-19 · Phase 1 abgeschlossen · Portal-Shell auf Hub-Design
- **Was**: Portal-Shell (Sidebar, Topbar, Layout-Container, Customer-Banner)
visuell ans Hub-Design angeglichen. FluxUI bleibt komplett erhalten —
Anpassung erfolgt über CSS-Token-Bridging und `[data-flux-*]`-Overrides.
Brand-Mark ersetzt das Starter-Kit-Logo. Light Mode ist Default; Dark
Mode für Phase 5 vorbereitet (heller Hub-Blau).
- **Dateien (geändert)**:
- `resources/css/portal.css` — komplett refactored:
* `--font-sans: "Inter Tight"` statt `Instrument Sans`
* `--color-accent: var(--color-hub)` (#1A2540) statt `#3ea3dc`
* `--color-zinc-50..950` auf Hub-Buchpapier-Familie gemappt
(Zinc-100 = #F6F4EF, Zinc-700 = #1A1F1C, Zinc-900 = Hub-Blau)
* Hub-Stil-Overrides: `[data-flux-sidebar]`, `[data-flux-navlist]`,
`[data-flux-navlist-item]` mit Active-Strip links, `[data-flux-button]`
Primary/Filled auf Hub-Blau, `[data-flux-card]` Buchpapier
* Dark-Mode-Block bleibt vorerst minimal (nur Accent), Vollumstellung
in Phase 5
- `resources/views/partials/head.blade.php` — Bunny-Font auf
`inter-tight + jetbrains-mono + source-serif-4` (für Brand-Mark)
- `resources/views/components/layouts/app/sidebar.blade.php`:
* `class="dark"` aus `<html>` entfernt
* `<body>` jetzt `bg-bg text-ink antialiased` (Hub-Buchpapier)
* `<x-app-logo>` ersetzt durch `<x-web.brand-mark brand="pressekonto"
:serif="false" />` + Eyebrow "Publisher · Hub" — sowohl im Desktop-
Brand-Block als auch im Mobile-Header
* Testmodus-Block (Impersonation) komplett im Hub-Stil: dunkles
Hub-Blau-Panel mit Bernstein-Eyebrow „Testmodus aktiv", weiße CTA
„Zurück zum Admin" (statt Amber-Warnfarbe wie zuvor)
* Resources-Block (Tailwind/HeroIcons/Flux/Repository) entfernt —
gehört nicht ins Live-Portal
- `resources/views/components/layouts/app.blade.php`:
* Customer-Banner („User Backend") visuell auf Hub-Stil: Hub-Soft-
Hintergrund + Hub-Soft-2-Border, Hub-Blau-Pille mit Dot, Eyebrow
„Firmenkontext" in Sperrschrift, Heading in Hub-Ink
- **Dateien (Test-Anpassungen, weil rollen-basierter Redirect aus Login-Fix
weitere Tests berührt hat)**:
- `tests/Feature/Auth/AuthenticationTest.php` — Test-User auf
`superAdmin()` umgestellt (sonst `canAccessAdmin() === false` →
Redirect auf `/` statt `/dashboard`)
- `tests/Feature/Auth/RegistrationTest.php` — `terms_accepted` im
Formular gesetzt + Redirect-Erwartung auf `/` angepasst (frisch
registrierte User haben keine Rolle → Fallback `/`)
- **Build/Test**:
- `npm run build:portal` → `portal: 409.03 kB` (vorher 408.89 kB,
+0.14 kB). Unter dem 10 %-Akzeptanzkriterium (≤ 450 kB).
- CSS-Inspektion bestätigt Phase-1-Tokens:
* `--color-accent: var(--color-hub)` und `.dark { --color-accent:
#6d8ad3 }` im `:root`
* `--color-zinc-700: #1a1f1c` (Hub-Ink statt Zinc-Grau)
* `--font-sans: "Inter Tight"` ohne Instrument-Sans-Vorlauf
* Hub-Overrides im Output: `[data-flux-sidebar]{background:var(...)}`,
`[data-flux-navlist-item][aria-current=page]{background:var(
--color-hub-soft);...}`
- Auth-Test-Suite: **0 zusätzliche Regressionen** verifiziert (8 fail
/ 15 passed vor & nach Phase 1; verbleibende Failures sind pre-existing
Domain-Mismatch- und CSRF-Issues im Test-Setup).
- Smoke-Test: `/dashboard`, `/admin/me`, `/settings/profile`,
`/admin/companies`, `/admin/press-releases` antworten alle HTTP 302
→ `/login` (erwartetes Verhalten ohne Auth-Session via curl).
- `vendor/bin/pint --dirty` → passed.
- **Bewusst NICHT in Phase 1**:
- **Topbar** mit Breadcrumb + Bridge-Row + Search + „Neue Mitteilung"-CTA
aus dem Mockup → ist für Phase 2 (Customer-Dashboard) sinnvoller,
weil die Topbar dort Page-Kontext (Breadcrumb-Titel) braucht. Aktuell
nutzen wir FluxUI's Default-Layout ohne dedizierte Topbar.
- Konto-Switcher als Sidebar-Header (Avatar + Name + Firma als
Dropdown-Trigger oben statt unten) → das User-Menü unten bleibt
vorerst FluxUI-Standard. Iterativ in Phase 2.
- Dashboard-Inhalte (Stat-Cards, Hint-Cards) → Phase 2 & 3.
- Listen-Pages → Phase 4 (automatisch durch Token-Bridge schon „okay").
- **Beobachtungen**:
- FluxUI-Navlist-Item-Selektor: `[aria-current="page"]` greift. Falls
künftige FluxUI-Versionen `[data-current="true"]` statt
`[aria-current="page"]` setzen, deckt der Override beides ab.
- Vendor-Pfad in `partials/head.blade.php` bewusst nicht geändert —
Vite-Setup mit `build/portal` bleibt wie gehabt.
- **Nächster Schritt**: **Review-Stopp**. Bei Freigabe → entweder
Phase 2 (Customer-Dashboard-Stat-Cards & Hint-Cards) oder Topbar-
Iteration. Entscheidung bei dir/Frank nach Anschauen.
---
## 2026-05-19 · Login-Funktionsfix · Doppelte Alpine-Instanz
- **Was**: Nach Phase 0 trat ein funktionaler Bug auf: Login-Form ging
nicht durch, Browser-Logs zeigten „Detected multiple instances of
Alpine running" und „Livewire: published assets out of date".
- **Ursache**: Das Hub-Auth-Layout (`pressekonto.blade.php`) lud sowohl
`resources/js/app.js` (das `Alpine.start()` aufruft) als auch
`@livewireScripts` (das Alpine intern mitbringt). Zwei Alpine-Instanzen
→ `wire:submit`, `x-data`, `wire:model` brachen.
- **Fixes**:
- `app.js` aus `@vite([…])` im Auth-Layout entfernt — Alpine kommt nun
nur noch über Livewire.
- `php artisan livewire:publish --assets` → `livewire.js` von 450 kB
auf 552 kB aktualisiert (Versions-Mismatch behoben).
- Login/Register-Redirect auf rollen-basierte Logik umgestellt
(Admin → `/dashboard`, Customer → `/admin/me`, sonst `/`) und
`navigate: true` entfernt — SPA-Navigation kann den Wechsel zwischen
Web-Build (Hub-Auth) und Portal-Build (FluxUI-Dashboard) nicht
handhaben.
- **Dateien**:
- `resources/views/components/layouts/auth/pressekonto.blade.php`
- `resources/views/livewire/auth/login.blade.php`
- `resources/views/livewire/auth/register.blade.php`
- **Verifikation**: Login funktioniert (User bestätigt), Redirect zum
Dashboard läuft, keine Browser-Warnings mehr.
---
## 2026-05-19 · Phase 0 abgeschlossen · Token-Unifizierung
- **Was**: Single Source of Truth für Design-Tokens etabliert. Web- und
Portal-Build importieren beide `resources/css/shared/design-tokens.css`.
Visuelle Unverändertheit verifiziert — FluxUI-Defaults gewinnen im
Portal weiterhin (Instrument Sans, Zinc, `#3ea3dc`), wird in Phase 1
abgelöst.
- **Dateien**:
- `resources/css/shared/design-tokens.css` **neu** — alle Hub-Tokens
plus Status-Reihe (`--color-warn`, `--color-warn-soft`,
`--color-err`, `--color-err-soft`, `--color-ok-soft`), Bridge-Dots
(`--color-bridge-presseecho`, `--color-bridge-businessportal`),
Radii (`--radius-xs/sm/md/lg`) und Schatten (`--shadow-soft`,
`--shadow-auth`). Dark-Mode-Block als auskommentierter Vorgriff.
- `resources/css/web/shared-styles.css` — Token-Import nach
`tailwindcss` ergänzt. Wirkt damit für alle Web-Themes
(pressekonto, presseecho, businessportal24).
- `resources/css/web/theme-pressekonto.css` — kompletter `@theme {}`-
Block entfernt (lebt jetzt in der Token-Datei). HSL-Legacy-Variablen
und `@layer components { … }` blieben unverändert.
- `resources/css/portal.css` — Token-Datei importiert, FluxUI-Setup
mit Zinc + Instrument Sans bleibt vorerst dominant. Phase 1 löst
es ab.
- **Build/Test**:
- `npm run build:web` → `theme-pressekonto: 193 kB` (vorher 189 kB,
+4 kB für neu gebridgde Status-Tokens), `theme-presseecho: 189 kB`,
`theme-businessportal24: 189 kB`.
- `npm run build:portal` → `portal: 408 kB` (vorher 397 kB, +12 kB
für die zusätzlich verfügbaren Hub-Tokens als CSS-Vars im `:root`).
Wird in Phase 1 wieder egalisiert, wenn das Zinc-Setup wegfällt.
- Smoke-Test: `pressekonto.test/`, `/login`, `/register`,
`/dashboard` (302→login), `presseecho.test/`, `businessportal24.test/`
— alle HTTP 200/302 wie erwartet.
- CSS-Inspektion: `--color-hub: #1a2540` und `--color-warn: #a87a1f`
sind in `theme-pressekonto-*.css` enthalten. Im Portal-Build
bleibt `--font-sans: "Instrument Sans"` — bestätigt visuelle
Unverändertheit.
- `vendor/bin/pint --dirty` → passed.
- **Offene Fragen / Beobachtungen**:
- Weil Tailwind v4 alle in `@theme {}` definierten Tokens als CSS-
Variablen im `:root` ausgibt (auch ohne Utility-Verwendung), wird
der Portal-CSS-Wuchs in Phase 1 nicht komplett zurückgehen —
die Hub-Tokens bleiben als Variablen verfügbar. Der Nettoeffekt
nach Phase 1 sollte ähnlich bleiben (+/- 510 kB).
- Dark-Mode-Block in `design-tokens.css` ist auskommentiert
vorbereitet, aber bewusst noch nicht aktiv (Phase 5).
- **Nächster Schritt**: **Review-Stopp**. Bei Freigabe →
Phase 1 starten: Portal-Shell (Sidebar, Topbar, Layout-Container)
auf Hub-Style mappen, Zinc-Palette ablösen, FluxUI-Overrides via
`[data-flux-*]`-Selektoren in `portal.css`. Details:
`02-PHASE-1-PORTAL-SHELL.md`.
---
## 2026-05-19 · Setup
- **Was**: Architektur-Entscheidung getroffen → **Plan B** (Tokens teilen,
Komponenten getrennt lassen). Dokumentation in `dev/frontend/hub-flux/`
angelegt:
- `README.md` — Übersicht & Entscheidung
- `01-PHASE-0-TOKENS.md` — Detail-Plan für Tokens-Vereinheitlichung
- `02-PHASE-1-PORTAL-SHELL.md` — Detail-Plan für Portal-Shell-Refresh
- `03-WEITERE-PHASEN.md` — Outline Phase 26
- `PROGRESS.md` — dieses Log
- **Bestätigt**:
- Hub-Blau als **Primärer Akzent** im Portal (klarer Kontrast zum hellen
Buchpapier-Hintergrund)
- Bernstein als **Sekundärer Akzent** (Notifications, Datenqualität,
Akzent-Ribbons)
- Brand bleibt **pressekonto** (auch im Portal-Sidebar via
`<x-web.brand-mark>`)
- Reihenfolge: erst Phase 0 + 1, dann Review
- **Nächster Schritt**: Phase 0 umsetzen
→ `resources/css/shared/design-tokens.css` erstellen,
`theme-pressekonto.css` refactoren, `portal.css` minimal vorbereiten.
---
## Vorlauf (zur Erinnerung, was schon steht)
- **Hub-Landing** (`web/pressekonto.blade.php`) — fertig, lebt im Web-Build
mit `theme-pressekonto.css`
- **Hub-Auth** (Login, Register, Forgot, Reset, Verify, Confirm) — fertig
im Hub-Design, neues Layout `auth/pressekonto.blade.php` im Web-Build
- **Register-AGB-Checkbox** mit Server-Side-Validierung ergänzt
- **Portal-Backend** mit FluxUI funktional vorhanden (Admin-Dashboard,
Customer-Dashboard, 77 Blade-Dateien mit FluxUI), aber **visuell noch
Starter-Kit-Look** (Zinc + `#3ea3dc` + Instrument Sans)
---
## Template für neue Einträge
```markdown
## YYYY-MM-DD · Phase N · Kurztitel
- **Was**: [Was wurde konkret gemacht?]
- **Dateien**: [Pfade]
- **Build/Test**: [Wie verifiziert?]
- **Offene Fragen**: [Falls etwas unklar geblieben ist]
- **Nächster Schritt**: [Was als Nächstes ansteht]
```