# 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 (``, ``, ``, ``, `` 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] ```