` umgestellt, weil zwei
Links nebeneinander (Titel-Link + Inline-Action) sonst
HTML-invalid wären
- Hover-Underline auf Titel-Link für klare Klickbarkeit
### Tests/Verifikation
- `DashboardTest` (Customer) → 5/5 grün, 21 Assertions
- Volle Suite → 230/231 grün, 1 pre-existing Fail
(`ApiDocumentationTest`)
- `npm run build:portal` → grün (424 KB CSS, +0,2 KB)
- `vendor/bin/pint --dirty` → passed
### Dateien
- `dev/frontend/hub-flux/16-PHASE-4J-DASHBOARD-LISTS.md` (neu)
- `resources/views/livewire/customer/dashboard.blade.php`
- `resources/views/admin/dashboard.blade.php`
- `dev/frontend/hub-flux/PROGRESS.md` (dieser Eintrag)
- `dev/frontend/hub-flux/03-WEITERE-PHASEN.md` (4J +
Phase 2/3 retroaktiv auf ✅)
---
## 2026-05-20 · Phase 4I · Admin „Pressemitteilungen" auf Mockup-Patterns
- **Anlass**: Direktes Folgepäckchen zu 4H — die in der Customer-Liste
entwickelten Mockup-Patterns werden auf die zentrale
Admin-Pressemitteilungen-Liste übertragen (Editorial-Workflow).
- **Plan-Dokument**: `15-PHASE-4I-ADMIN-PRESS-RELEASES.md`.
### Volt-Komponente erweitert (`admin/press-releases/index.blade.php`)
- `pressReleaseStats()` um `rejected` + `archived` Counter
erweitert (zwei zusätzliche `selectRaw` im gleichen Statement,
weiter über `AdminPerformanceCache`)
- Neue Methoden: `setView($view)` (setzt Statusfilter +
resetPage), `resetFilters()` (kompletter Reset inkl.
Entity-Lookups)
### Markup auf Mockup-Stil
- **Saved-Views-Tabs**: 6 Tabs (Alle, In Prüfung,
Veröffentlicht, Entwürfe, Abgelehnt, Archiv) mit
Counter-Pillen, `is-active`-State spiegelt `$statusFilter`
- **Active-Chips** unter Filter-Panel: 8 Filter-Typen
(Suche, Status, Portal, Sprache, Kategorie, User, Firma,
Kontakt) mit Remove-Button + „Alle zurücksetzen"-Link
- **Tabelle umgestellt** (8 → 7 Spalten):
- Status + Inline-Action (Freigeben/Ablehnen für Review,
Archivieren für Published) — Inline-Actions sind
`flux:modal.trigger` für die bestehenden, test-kritischen
Modals
- Titel mit Sub-Zeile (PM-ID + Firma + Sprache, klickbar)
- Portal-Pills (presseecho/businessportal24, bei
`Portal::Both` beide nebeneinander)
- Kategorie (truncate)
- Datum mit Status-Kontext-Sub („veröffentlicht · HH:MM",
„eingereicht · HH:MM", …) und `published_at` als
Primärdatum wenn vorhanden
- Hits monospace
- Aktionen-Spalte rechts reduziert auf view + edit
(Status-Actions wandern in die Status-Zelle)
- **Row-Tinting**: review → `is-row-warn`,
rejected → `is-row-err`
- **Empty-State 2-stufig**: „mit Filter" → Reset-CTA,
„ohne Filter" → Anlegen-CTA
### Was unangetastet bleibt (Test-kritisch)
- `publish()`, `reject()`, `archive()`, `sort()`,
`with()`, alle `clearXFilter()`, `resetEntityFilters()`
- 3 Modals mit Strings „Pressemitteilung veröffentlichen?",
„Pressemitteilung ablehnen?", „Pressemitteilung
archivieren?" — werden weiter vom Markup gemountet,
jetzt zusätzlich via Inline-Action triggerbar
- Combobox-Lookups für User/Firma/Kontakt (Schema +
Verhalten unverändert)
### Pitfall + Fix
- `@php(...)` Inline-Form kompilierte zu ` 0, mit semantisch eingefärbten
Zahlen (ok/warn/muted/err)
- **Kontext-Hinweis**: „Gefiltert auf :company" als kleine
Sub-Zeile, falls Firma-Kontext aktiv (Test-kompatibel!)
- **Saved-Views-Tabs**: 6 Tabs (Alle, Veröffentlicht,
Entwürfe, In Prüfung, Abgelehnt, Archiv) mit `cnt`-Pille,
klicken setzt `statusFilter` via `setView()`
- **Filter-Sektion**: Suche + Portal-Select + Firma-Select
(letzteres nur wenn `hasGlobalCompanyContext`)
- **Active-Chips**: entfernbare Anzeige aller aktiven Filter
(Status, Portal, Firma, Suche), mit `Alle zurücksetzen`-Link
- **Tabelle**:
- Status-Spalte mit Hub-Badge + Inline-Action „Zur Prüfung →"
für Drafts (ruft `submitForReview` mit `wire:confirm`)
- Titel mit Hub-Style-Link + PM-{id}-Sub
- Portal-Pills (eine oder zwei, abhängig vom Portal-Enum-Wert)
- Firma als Hub-Link oder „— keine —" italic
- Datum: Mono-Font + Sub mit Status-Kontext
(„veröffentlicht · 09:12", „eingereicht · 17:48" …)
- Row-Tint via `is-row-warn` (review) / `is-row-err`
(rejected) — dezent beim Hover
- **3-fach Empty-State**:
- `empty-search` (Suche ohne Treffer)
- `empty-filter` (Filter ohne Treffer, warm-Icon-Box)
- `empty-none` (gar keine PMs, mit 3-Schritt-Onboarding
01-Firma · 02-Verfassen · 03-Zur Prüfung)
- **Status-Aktionen-Legende**: `panel-warm` mit 5-Spalten-
Grid (Entwurf, In Prüfung, Veröffentlicht, Abgelehnt,
Archiviert) und einer Action-Liste je Status
### Was bewusst NICHT umgesetzt wurde
- **Bulk-Selection**: weggelassen (keine Bulk-Actions im
Backend → wäre nur Dekoration ohne Funktion)
- **Inline-Action „Grund ansehen →"** für Rejected: keine
`rejection_reason`-Spalte in `press_releases`-Tabelle
(Grund wird nur via E-Mail an Autor versendet)
- **Spalten- & Export-Buttons** im Header: keine Backend-
Implementierung, weggelassen
- **Modals und Bestätigungs-Flows**: bleiben FluxUI
- **Volt-Logik außerhalb der Erweiterungen**: unangetastet
### Tests & Hygiene
- **Erst-Fail**: `CustomerCompanyContextTest:79` rot, weil
„Gefiltert auf Alpha GmbH" im neuen Layout vom Counter-Strip
verdrängt wurde
- **Fix**: Kontext-Hinweis als zusätzliche kleine Sub-Zeile
unter dem Counter-Strip, immer sichtbar wenn Firma-Kontext
- **PR + Customer Tests**: 50/50 grün (199 Assertions)
- **Volle Suite**: 230 grün (1212 Assertions), 3 skipped,
1 fail = pre-existing `ApiDocumentationTest` (kein Bezug zu UI)
- **Build**: `npm run build:portal` clean
- **Pint**: `vendor/bin/pint --dirty` → `passed`
- **Lints**: keine Errors
### Status
- Plan-Status: ✅ Phase 4H **abgeschlossen**
- 03-WEITERE-PHASEN.md: 4H ergänzt als ✅
- Match zum Mockup: ≥ 90 %
### Übertragbar auf
- `admin/press-releases/index.blade.php` (Phase 4I als
natürliche Folgephase)
- `admin/users.blade.php`, `admin/contacts/index.blade.php`,
`admin/companies/index.blade.php` (Counter-Strip,
Saved-Views-Tabs, Filter-Chips wären überall sinnvoll)
---
## 2026-05-20 · Phase 4F · Restliche Admin-Bereiche
- **Anlass**: User „4f weiter" nach 4G. Siebtes (und letztes
großes) Päckchen aus Phase 4. Ziel: alle übrigen Admin-Pages
auf Hub-Stil, damit die komplette interne Strecke visuell
abgeschlossen ist.
- **Plan-Dokument**: `13-PHASE-4F-ADMIN-REST.md`.
Aufgrund des Umfangs (~7.500 Z. Blade) in 4 Sub-Päckchen
aufgeteilt.
### 4F-1 · Stammdaten & Switcher
- **`admin/presets/{index,create,edit}.blade.php`** +
`partials/form-fields.blade.php`: Page-Header
(„Admin Backend"-Pille, Eyebrow „Administration · Presets"),
Filter-Panel, Table-Panel mit Hub-Badges und Hub-Empty-State,
Forms in `article.panel`, Required-Marker auf
`text-[color:var(--color-err)]`.
- **`admin/categories/{index,create,edit}.blade.php`**:
Page-Header mit Aktion, KPI-Reihe mit
`
` (gesamt, aktiv, mit/ohne PMs),
Filter & Sort Panel, Category-Cards als `article.panel`,
Hub-Badges, Hub-Style innere Items, Danger-Zone mit linkem
roten Strip.
- **`admin/portal-switcher.blade.php`** (Sidebar):
Token-basierte Button-Farben mit `--color-bg-elev`,
`--color-bg-rule`, `--color-ink`, `--color-ink-2`,
`--color-ink-3`.
- **Tests**: `CategoryIndexPerformanceTest`,
`AdminCategoryManagementTest`,
`AdminPresetManagementTest` — alle grün.
### 4F-2 · Pressekontakte
- **`admin/contacts/index.blade.php`** (729 Z.): Page-Header
mit Action, KPI-Reihe (``),
Filter-Panel, Preset-Panel, Table-Panel mit Hub-Badges und
Hub-Empty-State, Hub-Style Flash-Boxen.
- **`admin/contacts/create.blade.php`** (275 Z.):
Page-Header mit „prefilled company"-Badge, Forms in
`article.panel`.
- **`admin/contacts/edit.blade.php`** (352 Z.):
Page-Header mit ID + Portal-Badge, Forms in
`article.panel`, Danger-Zone mit linkem roten Strip.
### 4F-3 · Operations & Finance
- **`admin/footer-codes/{index,create,edit}.blade.php`**:
Page-Header, KPI-Reihe, Filter-Panel, Table-Panel mit
Hub-Badges, Forms in `article.panel`, Category-Checkboxes
Hub-styled, Danger-Zone.
- **`admin/reports/slow-requests.blade.php`** +
`slow-requests-table.blade.php`: Page-Header,
Filter-Panel mit Reset-Button, KPI-Reihe, Top Routes/Paths
Panels, Slowest-Requests-Table, Frequent Slow Queries Table,
EXPLAIN Top Slow Queries Panel — alles Hub-styled.
- **`admin/invoices/index.blade.php`** (Legacy-Archiv):
Page-Header mit Archive-Badge, Warning-Box für „unmapped",
KPI-Reihe, Filter-Panel, Table-Panel mit Hub-Badges +
Pagination.
- **`admin/coupons/index.blade.php`** (Stub): Page-Header
„Vertagt"-Badge, Info-Panel mit Hub-Style List-Items.
- **`admin/payments/index.blade.php`** (Stub): Page-Header
„In Vorbereitung"-Badge, Info-Panel mit Hub-Style
List-Items + Rules.
- **Tests**: `AdminFooterCodeManagementTest`,
`AdminSlowRequestReportTest`,
`AdminSlowRequestLoggingTest`,
`AdminLegacyInvoiceArchiveTest` — alle grün.
### 4F-4 · User-Verwaltung
- **`admin/roles/{index,create,edit}.blade.php`**:
Page-Header (mit ID + System-Role-Badges in edit),
Warning-Box für System-Rollen, Forms in `article.panel`,
Table-Panel mit Hub-Badges + Empty-State.
- **`admin/newsletter/sync.blade.php`** (171 Z.):
Page-Header mit Sync-Status-Badge (active/deactivated),
Action-Buttons (Dry Run, Test-Sync) im Header, Hub-Style
Info/Success-Pillen für Notifications, KPI-Reihe mit
`` (gesamt, bestätigt, ausstehend,
abgemeldet), Config-Details (Provider, Timeout, Endpoint)
als Definition-List in `article.panel`.
- **`admin/users.blade.php`** (939 Z.): Page-Header mit
Action „Benutzer anlegen", KPI-Reihe (gesamt, aktiv,
inaktiv), Filter-Panel mit Reset-Button, Table-Wrapper
als `article.panel` mit Hub-Empty-State. **Modal**
und alle Tabellen-Inhalte bewusst unangetastet — wegen
Test-Strings + Komplexität.
- **`admin/users/show.blade.php`** (239 Z.): Hub-Header mit
ID + Status-Badges, KPI-Reihe (Portal, Typ, Status, Login),
Rollen-Panel, Rechnungsadresse-Panel,
„Verknüpfte Firmen & Kontakte"-Panel als verschachtelte
Hub-Boxes.
- **`admin/users/create.blade.php`** (421 Z.): Hub-Header,
Forms in `article.panel` (Basisdaten, Rollenzuweisung,
Firmenverknüpfung, Rechnungsadresse), Action-Panel
am Ende.
- **`admin/users/edit.blade.php`** (1.224 Z.): Hub-Header
mit ID/Portal/Status-Badges, Notification als
Hub-Style Ok-Pill, Quick-Nav als Token-Pillen mit
Hover auf Hub-Blue, KPI-Reihe (Account, Legacy-Profil,
Verknüpfungen, Rechnungsadresse). Innere Sektionen
(`#account`, `#legacy-profile`, `#roles`,
`#company-links`, `#contact-links`, `#billing-address`)
bleiben `flux:card` (IDs für Quick-Nav, sehr großes File).
Footer-Action-Panel auf Hub umgestellt.
- **Tests**: `UserManagementTest`, `UserImpersonationTest`,
`UserList*Test` — 29 Tests / 270 Assertions grün.
### Bauplatz-Hygiene
- **Build**: `npm run build:portal` — sauber durch.
- **Pint**: `vendor/bin/pint --dirty` — `passed`.
- **Lints**: keine Linter-Errors in den editierten Blade-Files.
- **Pre-existing**: `ApiDocumentationTest` weiterhin rot, kein
Bezug zu UI-Styling (siehe frühere Phasen).
### Abgrenzung — was bewusst NICHT angefasst wurde
- Volt-Logik in allen Dateien (PHP, `mount`, `save`,
`with`, …).
- ``, ``, ``,
``, ``, ``,
``, ``, ``.
- Innere Sektionen von `users/edit.blade.php` mit ID-Ankern
(Quick-Nav-Targets) — diese bleiben `flux:card`, da
Footnote-Logik daran hängt und das File 1.224 Z. groß ist.
- Modal in `users.blade.php` und alle internen Bestätigungs-
Flows (Test-Strings).
- Test-relevante Strings überall.
### Status
- Plan-Status: ✅ Phase 4F **abgeschlossen**.
- 03-WEITERE-PHASEN.md: 4F auf ✅ aktualisiert.
---
## 2026-05-20 · Phase 4G · Customer Portal (Mein Bereich)
- **Anlass**: User „weiter 4G" nach 4E. Sechstes Päckchen aus
Phase 4: alle übrigen Customer-Pages auf Hub-Stil bringen,
damit die komplette User-sichtbare Strecke (Mein Bereich)
visuell abgeschlossen ist.
- **Plan-Dokument**: `12-PHASE-4G-CUSTOMER-PORTAL.md`.
- **Was umgebaut wurde**:
- **`customer/company-switcher.blade.php`** (Sidebar-Helper,
91 Z.): „Aktive Firma"-Label als `.badge hub dot`,
Portal-Suffix als Token-Eyebrow, „Keine Firma zugeordnet"
als `.badge warn`. ``, `Firma öffnen`-Button
und `route('me.press-kits.show', …)` bleiben — alles, was
der `CustomerCompanyContextTest` assertiert, ist erhalten.
- **`customer/bookings.blade.php`** (Coming-Soon, 52 Z.):
Hub-Page-Header („User Backend"-Pille,
„Mein Bereich · Finanzen"-Eyebrow, Warn-Pille
„In Vorbereitung"). Info-Box auf Hub-Soft-Token,
3 Feature-Panels mit Eyebrow + Beschreibung.
- **`customer/invoices.blade.php`** (194 Z.): Page-Header
mit Aktion „Rechnungsadresse im Profil pflegen". Hinweis
in eigenes `.panel`. 4 KPI-Cards (primary/muted/ok/warn).
Filter-Panel, Tabellen-Panel mit Hub-Badges (`ok dot`
für bezahlt, `warn dot` für offen), Empty-State als
Icon-Box. Pagination am Boden im Panel mit Top-Border.
Notification als Hub-Warn-Pille mit Icon.
- **`customer/tokens.blade.php`** (212 Z.): Hub-Page-Header
mit „API-Dokumentation"-Aktion. Flash-Boxen (success/warn)
in Token-Style. „Neuer Token"-Anzeige als eigenes Panel
mit linkem Warn-Strip (`border-left:3px solid
--color-warn`) + `.badge warn`-„Nur jetzt sichtbar". Form
in Panel mit Border-Top-getrenntem Submit-Bereich.
Tabelle in Panel mit Counter, Berechtigungen als
`.badge hub` (statt `flux:badge`), Empty-State als
Icon-Box.
- **`customer/press-kits/index.blade.php`** (119 Z.):
Hub-Page-Header. Filter-Panel. Karten-Grid mit
`.panel`-Karten: `.panel-head` mit Status-Badge
(`ok dot` / `err dot`), Body mit Slug, Portal/Rolle/
Footer-Badges, KPI-Boxen (Border + bg-elev), Footer
mit Border-Top + „Firma öffnen"-Button.
Empty-State als full-width Panel mit Hub-Icon-Box.
- **`customer/press-kits/show.blade.php`** (734 Z. → Polish):
Großes Detail-Cockpit komplett auf Hub:
- **Header**: Pillen-Reihe (User-Backend, Mein
Bereich · Firma, Aktiv/Inaktiv, Portal, Rolle, ggf.
Footer-Code-aus) + Logo-Box (oder Hub-Icon-Box) + H1
+ Slug. Aktionen rechts: Zurück, Stammdaten bearbeiten,
Neue PM.
- **Quick-Nav**: Anker-Links als pillen-artige
Hover-Buttons mit Bottom-Border.
- **4 KPI-Cards**: PMs (primary), Pressekontakte (ok),
Portal (muted), Deine Rolle (muted) — mit
`canManageCompany`-abhängiger Trend.
- **Stammdaten-Panel**: `.panel-head` mit Bearbeiten-
Button. Inline-Form als `bg-elev`-Block mit
Border-Top-getrennten Sections (Logo / Aktionen).
Daten-Liste als `` mit Token-Labels + Werten,
Website als Hub-Underline-Link.
- **Pressekontakte-Panel**: `.panel-head` mit Counter.
Inline-Form analog Stammdaten. Kontakt-Items als
`bg-elev`-Boxen mit Aktionen rechts. Empty-State als
gestrichelte Box. Flash-Messages
(„Pressekontakt wurde angelegt./aktualisiert./
gelöscht.") in Token-Success-Pille.
- **Pressemitteilungen-Panel**: Tabelle mit Hub-Status-
Badges (ok/warn/err/hub). Empty-State Hub-Icon-Box.
- **Abrechnung & Statistik**: 2 Panels nebeneinander
mit „In Vorbereitung"/„Später"-Warn-Pillen. Abrechnung
mit gestrichelter Hint-Box. Statistik mit
2 Token-Mini-Stats.
- **Was bewusst unverändert blieb**:
- Volt-PHP-Logik in allen Dateien (mount, saveCompany,
saveContact, deleteContact etc.).
- Flash-Strings („Stammdaten wurden gespeichert.",
„Pressekontakt wurde angelegt./aktualisiert./gelöscht.",
„Token wurde erstellt", „Token wurde widerrufen.",
„API-Tokens werden erst freigeschaltet" etc.) —
bleiben in Volt-PHP wie zuvor und erscheinen in den
neuen Hub-Pillen.
- Section-Headings „Abrechnung" und „Statistik" — Tests
assertieren genau diese Strings.
- Strings im Header („Alpha GmbH", „Firma öffnen",
`route('me.press-kits.show', …)`).
- FluxUI-Form-Komponenten (`flux:input`, `flux:select`,
`flux:textarea`, `flux:checkbox`, `flux:field`,
`flux:error`, `flux:table*`) — nur Wrapper-Markup
verändert.
- **Verifikation**:
- `php artisan view:clear` ✓
- `npm run build:portal` ✓ — 418.11 kB CSS / 44.38 kB JS
(keine Größenänderung gegenüber 4E).
- `php artisan test --compact tests/Feature/{
CustomerPortalTest, CustomerCompanyContextTest,
PanelConsolidationTest}.php` →
**29 passed, 131 assertions**.
- Volle Suite: **230 passed, 3 skipped, 1 pre-existing
fail** (`ApiDocumentationTest` — fehlende
`docs/api/v1.yml`, war auch vor 4G/4E/4D rot).
- `vendor/bin/pint --dirty --format agent` → `passed`.
- **Resultat**:
- Mein-Bereich des Users ist visuell **vollständig** auf
Hub-Sprache.
- Sidebar-Nav (presse-kits, invoices, tokens, bookings)
läuft jetzt durchgängig im selben Vokabular wie Dashboard
+ Press-Releases.
- Detail-Cockpit `press-kits/show` ist das visuell
aufwendigste Customer-Page und stimmt jetzt mit Admin-
Detail-Show überein (Pillen-Header, KPI-Reihe, Panels,
Quick-Nav, Tabellen).
- **Nächste mögliche Päckchen**:
- **4F** Restliche Admin-Bereiche (contacts, categories,
presets, footer-codes, slow-requests, users).
- **press-release-images-manager** Komponente (kleiner
Cleanup aus 4C-Resten).
- **Phase 5** Dark-Mode-Konsolidierung.
---
## 2026-05-20 · Phase 4E · Profile & Settings
- **Anlass**: User „okay weiter" nach 4D. Fünftes Päckchen aus
Phase 4: alle Settings-Pages (Admin + Customer) auf Hub-Stil.
- **Plan-Dokument**: `11-PHASE-4E-PROFILE-SETTINGS.md`.
- **Zentraler Trick — Wrapper umgebaut**:
- **`resources/views/partials/settings-heading.blade.php`**:
Komplett neu als Hub-Page-Header (Pille „Admin Backend",
Eyebrow „Mein Konto · Einstellungen", H1 „Settings",
Subtitle).
- **`resources/views/components/settings/layout.blade.php`**:
Komplett neu als 2-Spalten-Grid mit Sidebar-Nav-`.panel`
(„Mein Konto"-Eyebrow + FluxUI-Navlist drin) und
Content-`.panel` mit `.panel-head` für Page-Heading +
Subheading im Body. Heading/Subheading-Slots der einzelnen
Settings-Pages werden so automatisch im Hub-Look gerendert.
- **Effekt**: `settings/appearance.blade.php` musste
**gar nicht** angefasst werden — übernimmt den Hub-Look
via Wrapper. Die anderen beiden brauchen nur
Save-Bar-Polish.
- **Was umgebaut wurde**:
- **`settings/profile.blade.php`**: Verification-Hinweis von
``-Link auf Hub-Warn-Box (gelber Linker Strip,
Icon, Hub-Link für „re-send the verification email").
Save-Bar mit Border-Top + Token-`Saved.`-Pill.
Delete-Button-Section visuell durch Border-Top abgetrennt.
- **`settings/password.blade.php`**: Save-Bar gleicher Polish.
- **`settings/delete-user-form.blade.php`**: Das `mt-10`-Card
durch Hub-Danger-Box mit `border-l-[3px]
border-l-[color:var(--color-err)]`, „Danger Zone"-Eyebrow,
H3 + Subtitle + Trash-Button. Modal-Markup komplett
unverändert (Confirm-Password-Modal kommt aus FluxUI-Std.).
- **`customer/profile.blade.php`**: Page-Header („User
Backend"-Pille, „Mein Bereich · Profil"-Eyebrow,
„Mein Profil"-H1). Form in 3 Panels + Aktions-Panel:
Konto (Name/E-Mail/Sprache) · Profil (Anrede,
Vor-/Nachname, Telefon, Backlink, Checkboxen) ·
Rechnungsadresse (mit Warn-Hub-Box, wenn unvollständig).
Zugeordnete-Firmen als eigenes `.panel` mit Hub-Badges
(`ok` für Eigentümer, `hub` für Portal/Rolle).
- **`customer/security.blade.php`**: Page-Header. 4-spaltige
KPI-Reihe mit `.panel` + uppercase-Eyebrow + großer Wert +
Hub-Badge (E-Mail bestätigt? · 2FA aktiv? · Letzter Login +
IP · Sessions-Count). 2-Spalten-Grid für Passwort + E-Mail
in `.panel` mit `.panel-head`. 2FA-`.panel` mit
ok-Badge im Header wenn aktiv, Recovery-Codes mit
Hub-Bg-Boxes. Sessions-`.panel` mit Eintrags-Counter,
Empty-State als Hub-Icon-Box. **Alle Test-Strings
erhalten**: „Konto-Sicherheit", „Letzter Login",
„Aktive Sessions", „Passwort ändern", „E-Mail-Adresse
ändern", „Zwei-Faktor-Authentifizierung",
„Rechnungsadresse".
- **Tests**:
- Smoke: `Settings|CustomerProfileSecurity|
CustomerCompanyContext` → 33 passed (146 assertions).
- Volle Suite: 230 passed / 3 skipped /
1 pre-existing `ApiDocumentationTest`-Fail.
- **Build / Pint**: `npm run build:portal` ✓ (418 kB CSS),
`pint --dirty` ✓, keine Linter-Errors.
- **Bewusst NICHT angefasst**:
- Volt-Logik in allen Dateien.
- Confirm-User-Deletion-Modal-Markup
(`settings/delete-user-form.blade.php`).
- Fortify-2FA-Logik (Enable / Disable / Recovery-Codes-
Regenerate / QR-Generation).
- `` Component-Wrapper — nur Slot-Inhalt.
- **Nächster Schritt** — Vorschlag:
- **4G** Customer-Bereiche (invoices, tokens, bookings,
company-switcher, me/press-kits/*) — Tests fordern
Strings, aber alle gut greifbar.
- **4F** Restliche Admin-Bereiche (contacts, categories,
presets, footer-codes, slow-requests, users) — größeres
Päckchen, sollte weiter unterteilt werden.
---
## 2026-05-20 · Phase 4D · Companies (admin)
- **Anlass**: User „okay weiter" nach 4C. Viertes Päckchen aus
Phase 4: alle vier Admin-Companies-Pages auf Hub-Stil.
- **Plan-Dokument**: `10-PHASE-4D-COMPANIES.md`.
- **Was umgebaut wurde**:
- **`admin/companies/index.blade.php`**: Hub-Page-Header
(„Admin Backend"-Pille, Eyebrow „Stammdaten · Firmen",
H1 „Firmen", Subtitle, CTA „Neue Firma" rechts) →
3 `` (Gesamt/Aktiv/Inaktiv) →
Filter-`.panel` mit Combobox-Selects unverändert in der
Logik, nur Hülle getauscht → Tabelle in `.panel
overflow-hidden` mit `.panel-head` „Alle Firmen" +
Eintrags-Counter. Tabellen-Status/Portal/Count-Badges
auf Hub-Klassen (`badge ok|err|hub` + Dot) gesetzt.
Empty-State als Hub-Icon-Box.
- **`admin/companies/show.blade.php`**: Header mit
Status-, Portal- und ID-Pille; Logo-Box neben H1. KPI-Reihe
(3 stat-cards). Tabs „Überblick" / „Kontakte" als schlankes
Bottom-Border-Pattern (kein FluxUI-Tabs-Group nötig). Beide
Tab-Inhalte komplett in `.panel`-Sektionen mit `dl`-Layouts
bzw. Kontakt-Karten. Existing-Contact-Combobox bleibt
FluxUI; Wrapper auf Hub-`bg-elev`. Flash-Boxen
(success/error/info) auf Token-Pillen.
- **`admin/companies/edit.blade.php`**: Page-Header
(„ID"-Pille), 5 Form-Panels (Basisinformationen, Adresse,
Rechtliche Daten, Logo & Status, Aktionen). Required-Marker
auf `text-[color:var(--color-err)]`. Logo-Vorschau-Bild
nutzt Hub-Token-Border. „Logo wird beim Speichern entfernt"
auf Hub-Warn-Box (statt `flux:callout`).
**Delete-Confirm-Modal komplett unverändert.**
- **`admin/companies/create.blade.php`**: gleiches Schema
wie Edit, ohne Status-Pille und ohne Delete-Button. Forms
in 5 Panels strukturiert.
- **Tests**:
- Companies-Smoke: `UserManagement|PortalAssetManifest`
→ 25 passed (227 assertions).
- Volle Suite: 230 passed / 3 skipped /
1 vorbestehender Fail (`ApiDocumentationTest` —
fehlende Datei `docs/api/v1.yml`, nicht durch Phase 4D
verursacht).
- **Build / Pint**: `npm run build:portal` ✓ (418 kB CSS,
44 kB JS), `vendor/bin/pint --dirty --format agent` ✓.
- **Bewusst NICHT angefasst**:
- Volt-Logik in allen vier Dateien.
- `deleteCompany`-Methode und ihr Confirm-Modal-Markup
(Test `UserManagementTest::admin can delete company`
prüft Redirect-Verhalten, nicht UI).
- `` (Kontakt-/User-Lookup)
und alle anderen `flux:field`/`flux:input`-Bausteine —
Token-Bridging trägt.
- Test-relevante Strings: „Firmen", „Portal", „Alle Portale",
„Presseecho", „Businessportal24", „/admin/companies/…".
- **Nächster Schritt (Phase 4E oder 4F)**:
- **4E** = Profile/Settings (`settings.*`, `me.profile`,
`me.security`) — eher klein, viele kleine Panels.
- **4F** = Restliche Admin-Bereiche (contacts/, categories/,
presets/, footer-codes/, slow-requests, …) — Päckchen-Größe.
---
## 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 (``,
``, ``, ``,
`` inkl. Combobox-Variant, ``,
``) — 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.
- **``** —
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
`` mit `@class([])`-Syntax.
- **Customer-Show-spezifisch**:
- **Rejection-Hinweis** als roter `.panel` mit linker
Akzent-Border (`border-left-width:3px`) und Icon-Box —
statt ``.
- **Review-Pending-Hinweis** als warner `.panel` mit
Akzent-Border und Clock-Icon-Box — statt ``.
- **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
(~3–5 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: `` 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-`` bleibt — das
Zinc-→Hub-Mapping aus Phase 1 zieht hier perfekt.
- **Status-Badges**: ``
ersetzt durch `` 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 `` (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 ``):
- 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`
+ ``-Investition zahlt sich ab Phase 3 deutlich aus.
- Der `` 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.appearance` ist FluxUIs Magic-Object — LocalStorage-persistent,
`@fluxAppearance`-Script setzt `class="dark"` auf ``.
- 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 ``-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/`:
- ``
mit Slots `meta` (oben rechts) und `trend` (unten).
- ``
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 ``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 `` 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).
- ``-Extraktion (Brand-Bridge bleibt inline, bis
sie an mehr Stellen gebraucht wird).
- **Lessons learned**:
- PHPDoc in Blade-Components darf KEINE ``-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 `` injiziert `@fluxScripts` (sidebar.blade.php Zeile
nahe ``) **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
``, 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 ``-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 (``) 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 `` entfernt
* `` jetzt `bg-bg text-ink antialiased` (Hub-Buchpapier)
* `` ersetzt durch `` + 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 (+/- 5–10 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 2–6
- `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
``)
- 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]
```