26 KiB
Entwicklungskonzept – BusinessPortal24 & Presseecho Frontend
Stand: 12. Mai 2026 Domains:
businessportal24.test/businessportal24.com·presseecho.test/presseecho.comTheme-Slugs:businessportal24(warm-rotes Editorial) ·presseecho(grünes Editorial) Assets-Dir (geteilt):public/build/web/Ziel: Editoriales DACH-Pressemitteilungs-Portal mit 1:1-Mockup-Umsetzung. Presseecho nutzt die gleiche Komponenten-Architektur wie BP24 und unterscheidet sich nur via Theme-Tokens + Brand-Konfiguration.
Dieses Dokument beschreibt den aktuellen Stand und die wichtigsten Architekturentscheidungen der BusinessPortal24- und Presseecho-Frontend-Entwicklung. Es ist die zentrale Anlaufstelle für alle, die im Frontend weiterarbeiten oder neue Seiten ergänzen.
1. Zielbild & Designreferenzen
Das Portal folgt einer editorial-zeitungs-orientierten Ästhetik mit ruhiger Beige-Surface, klarer Hierarchie über Typografie statt Cards und einer einzigen warm-roten Akzentfarbe.
| Datei | Zweck |
|---|---|
dev/frontend/Pass B _ _ Deutschland _aktiv.png |
Visuelle Referenz Desktop |
dev/frontend/Pass B _ _ Deutschland _aktiv.html |
Roh-HTML-Export aus Figma (für strukturelle Analyse) |
dev/frontend/Mobile _ Startseite.png |
Visuelle Referenz Mobile |
dev/frontend/tailwind_v3/Startseite Tailwind.html |
Master-Vorlage der Implementierung (Tailwind v3 Export – sauberer, ohne Embedded-Bilder) |
dev/frontend/tailwind_v3/Branchenseite Tailwind.html |
Vorlage Branchenseite (offen) |
dev/frontend/tailwind_v3/Detailseite Tailwind.html |
Vorlage Detailseite Pressemitteilung (offen) |
dev/frontend/tailwind_v3/Veröffentlichen Tailwind.html |
Vorlage Veröffentlichen-Landing (offen) |
dev/frontend/Branchenseite _ Energie _ Klima _aktiv.png / .html |
Hochauflösende Branchen-Vorlage |
dev/frontend/Detailseite _ Pressemitteilung _aktiv.png / .html |
Hochauflösende Detailseite-Vorlage |
dev/frontend/Ver_ffentlichen _ Variante A _aktiv_.png / .html |
Veröffentlichen-Vorlage |
dev/frontend/Umsetzungskonzept - Frontend BusinessPortal24 Startseite.md |
Historisches Detailkonzept zur Startseite |
Verbindlich: Die tailwind_v3-Exports sind die normative Referenz – sie enthalten alle Spacings, Schriftgrößen, Tracking-Werte und Farbtöne in Klartext. Das .png dient als visuelle Bestätigung.
2. Tech-Stack
- Framework: Laravel 12 (PHP 8.4)
- UI: Livewire 4 + Volt 1 (single-file components)
- CSS: Tailwind CSS v4 mit
@theme-Tokens und scoped Layer-Komponenten - Build: Vite 6 (dualer Setup:
vite.web.config.jsPort 5178 /vite.portal.config.jsPort 5177) - Interaktivität: Alpine.js v3 (initialisiert in
resources/js/app.js) - Icons: Inline-SVG (Bunny-Fonts-Icons werden bewusst NICHT genutzt, um Render-konsistent zu bleiben)
- Fonts (Bunny.net):
Inter Tight(Sans),Source Serif 4(Serif),JetBrains Mono(Mono) - Tests: Pest 3 + PHPUnit 11
- Lint/Format: Laravel Pint (
vendor/bin/pint --dirty --format agent)
3. Domain-Routing
Das Portal nutzt das bestehende ThemeServiceProvider-System aus CLAUDE.md. Beide Domains teilen sich build/web/-Assets und unterscheiden sich nur in der geladenen Theme-CSS-Datei:
Request (Host: businessportal24.test)
→ ThemeServiceProvider erkennt Domain
→ /config/domains.php liefert assets_dir = "build/web", theme = "businessportal24"
→ routes/web.php · "/" gibt businessportal24.blade.php zurück, vorgeladen mit Daten aus $webHomeData(Portal::Businessportal24)
→ resources/views/web/layouts/web-master.blade.php lädt theme-businessportal24.css + app.js
Request (Host: presseecho.test)
→ /config/domains.php liefert theme = "presseecho"
→ routes/web.php · "/" gibt presseecho.blade.php zurück, vorgeladen mit Daten aus $webHomeData(Portal::Presseecho)
→ web-master.blade.php lädt theme-presseecho.css + app.js
Lokale Domain-Simulation:
.env:DEV_SIMULATE_DOMAIN=true,DEV_SIMULATED_DOMAIN=businessportal24.test|presseecho.test- Alternativ:
?theme=businessportal24|presseechoals Query-Parameter
3.1 Generischer Daten-Provider
Der Daten-Provider $webHomeData(Portal $primaryPortal) in routes/web.php ist portal-agnostisch und liefert für beide Domains die gleichen Variablen (leadRelease, sideReleases, mostReadReleases, activeNewsrooms, industryIndex, homeStats). Aufruf:
view('web.presseecho', $webHomeData(Portal::Presseecho));
view('web.businessportal24', $webHomeData(Portal::Businessportal24));
Die Trennung der Portale geschieht über whereIn('portal', [$primaryPortal->value, Portal::Both->value]).
3.2 Brand-Konfiguration
In config/domains.php liegt pro Domain ein brand-Block, der Komponenten dynamisch befüllt (Logo-Text, Tagline, Newsletter-Topics, Footer-Legal, Meta-Texte):
'presseecho' => [
'theme' => 'presseecho',
'brand' => [
'name' => 'presseecho',
'accent' => null, // kein Brand-Akzent (z.B. "24")
'tagline_short' => 'Pressemitteilungen · DACH',
'tagline_long' => 'Fachmeldungen aus Wirtschaft und Industrie ...',
'footer_legal' => '© :year presseecho.com · Alle Rechte vorbehalten',
'about_label' => 'Über presseecho',
'meta_title' => '... – presseecho',
'meta_description' => '...',
'newsletter_topics' => [ ... ],
],
],
'businessportal24' => [
'theme' => 'businessportal24',
'brand' => [
'name' => 'businessportal',
'accent' => '24', // markenrechtlicher Brand-Akzent
...
],
],
Komponenten (site-header, site-footer, newsletter-strip) lesen ihre Defaults aus config('domains.domains.'.config('app.theme').'.brand', [...]). Übergaben via :brand="..." überschreiben sie jederzeit.
4. Theme-System (Tailwind v4)
Datei: resources/css/web/theme-businessportal24.css
Alle Designtokens liegen in einem @theme-Block:
@theme {
/* Surfaces */
--color-bg: #f6f4ef;
--color-bg-elev: #fbfaf6;
--color-bg-rule: #e5e0d5;
--color-bg-rule-strong: #1c1a17;
--color-bg-card-warm: #f1ece2; /* Warm-beige Anzeigen-Karten */
--color-bg-card-warm-border: #d9cdb6;
--color-topbar: #1a1f26;
--color-topbar2: #232a33;
/* Ink (Text-Hierarchie) */
--color-ink: #1c1a17;
--color-ink-2: #3d3935;
--color-ink-3: #6e6862;
--color-ink-4: #9a958d;
--color-ink-on-dark: #f6f4ef;
--color-ink-on-dark-2: #b8b3aa;
/* Brand */
--color-brand: #c84a1e;
--color-brand-deep: #a23814;
--color-brand-soft: #f4e5dd;
--color-live: #e03a1a;
--color-gain: #2e8540;
--color-loss: #c8341e;
--color-ok: #2e8540;
/* Editorial-Akzente (auf dunklem Grund / in Card-Warm) */
--color-accent-warm: #ff8b6f; /* Eyebrows auf TopBar/Hero/Newsletter */
--color-ink-on-dark-muted: #8a847b; /* gedämpfter Text auf Dunkel */
--color-ink-on-dark-rule: #2a2723; /* feiner Trenner auf Dunkel */
--color-bg-card-warm-hover: #ece5d5;
--color-bg-card-warm-rule: #c8bda8; /* Hairline „Anzeige" innerhalb Card-Warm */
--color-card-warm-cat: #6e6862;
--color-card-warm-title: #3a332b;
--color-feature-line: #a8c8a8; /* Decor-Linien im Feature-Bild-Fallback */
--color-feature-dot: #c4dcc4;
/* Typo & Layout */
--font-sans: "Inter Tight", "Söhne", Inter, system-ui, sans-serif;
--font-serif: "Source Serif 4", "Source Serif Pro", Charter, Georgia, serif;
--font-mono: "JetBrains Mono", "SF Mono", ui-monospace, monospace;
--container-layout: 1280px;
}
Daraus stehen Klassen wie bg-bg, text-ink-3, border-bg-rule, text-brand, text-accent-warm, bg-card-warm-hover, max-w-layout, font-serif automatisch zur Verfügung.
Wichtig: Komponenten dürfen keine Hex-Werte mehr enthalten. Stattdessen die Tokens nutzen (
text-accent-warm,border-ink-on-dark-rule,text-card-warm-cat, …). So bleibt der Theme-Wechsel zwischen BP24 und Presseecho ein reiner CSS-Switch.
Wiederkehrende Komponenten-Klassen (in @layer components)
| Klasse | Verwendung |
|---|---|
.eyebrow / .eyebrow.muted / .eyebrow.on-dark |
11px-Vor-Label uppercase (Brand-Farbe / Grau / accent-warm für Dunkel-Sektionen) |
.bp-cat |
Kategoriekürzel 11px uppercase brand |
.bp-tag |
Solid-Brand-Tag (z. B. „TOP-MELDUNG", „Top-Meldung") |
.rule-strong |
1 px-Hairline auf --color-bg-rule-strong |
.rule |
1 px-Hairline auf --color-bg-rule |
.bg-topbar-grad |
135°-Gradient TopBar → Topbar2 (TopBar, CTA, Footer, Newsletter) |
.bg-feature-grad |
135°-Gradient (Featured-Top-Bild-Fallback) |
.bg-hero-grad |
135°-Gradient (Hero-Bild-Fallback) |
.ticker-marquee-track |
Endlos-Laufband (CSS-Keyframe bp-ticker-marquee, Dauer per --bp-ticker-duration, default 42 s; respektiert prefers-reduced-motion) |
Utility-Klassen (in @layer utilities)
.pulse-dot– 1.6 s ease-in-out Animation (Live-Ticker, „heute aktiv"-Badge).tabular-nums–font-variant-numeric: tabular-nums
Plus eine globale Regel:
[x-cloak] { display: none !important; } /* Alpine.js Init-Schutz */
5. Komponenten-Architektur
5.1 Layout
resources/views/web/layouts/web-master.blade.php
└── @yield('content')
Das Layout lädt das theme-spezifische CSS via @vite. Domain-spezifische Fonts werden nur für businessportal24 von bunny.net gezogen.
5.2 Startseite
resources/views/web/businessportal24.blade.php
├── <x-web.site-header /> ← TopBar + Header + Nav + Live-Ticker
├── <main>
│ ├── <x-web.focus-hero /> ← „Im Fokus" Hero + Sidebar „Was sonst zählt"
│ ├── <section> 1.7fr/1fr Grid
│ │ ├── <livewire:web.press-release-feed />
│ │ └── <aside>
│ │ ├── <x-web.most-read />
│ │ ├── <x-web.publisher-cta />
│ │ └── <x-web.active-newsrooms />
│ ├── <x-web.industry-spotlight />
│ ├── <x-web.events-week />
│ ├── <x-web.industry-index />
│ ├── <x-web.newsletter-strip />
│ └── <x-web.quality-summary />
└── <x-web.site-footer />
5.3 Komponenten-Übersicht
| Datei | Rolle | Datenquelle |
|---|---|---|
site-header.blade.php |
Top-Utility-Bar (Datum + Ausgabe-Tabs + Sprache/Links), Brand-Header (Logo + Suche + Anmelden + Veröffentlichen), Unter-Nav. Inkl. Such-Overlay + Burger-Mobile-Nav via Alpine. | Statisch (Props) |
live-ticker.blade.php |
Dunkler AD-HOC-Streifen mit Ticker-Items + DAX-Sparkline. | Mock (Props ticker, marketIndex) |
focus-hero.blade.php |
Hauptmeldung (500 px Hero) + 4 Sidebar-Items „Was sonst zählt" + Anzeige. | echtes leadRelease, sideReleases → fallback Mockup |
focus-side-item.blade.php |
Einzelnes Sidebar-Item (Nummerierung 01-04, 64×64-Bild, Verifiziert-Icon). | release ODER mock |
focus-ad.blade.php |
Warm-beige Anzeigen-Karte mit Anzeige- + Ende-Anzeige-Hairlines. | Statisch / Props |
press-release-feed.blade.php (Volt) |
Featured-Top + Liste + In-Feed-Anzeige + „Weitere Meldungen"-Button. Tabs: Alle / Heute / Diese Woche. Pagination via WithPagination. Empty-State liefert Mock-Top + Mock-Liste + Anzeige. |
PressRelease mit withCount-Eager-Loading |
feed-top-item.blade.php |
Featured-Eintrag mit 240×160-Bild. | release ODER mock |
feed-item.blade.php |
Zeilen-Eintrag 60 px Zeit / 100 px Kat. / 1fr Titel. Optional „Empfehlung"-Badge. | release ODER mock |
feed-ad.blade.php |
Inline-Anzeige mit Anzeige- + Ende-Anzeige-Hairlines. | Statisch / Props |
most-read.blade.php |
Top 4 nach Hits mit horizontalem Brand-Balkenindikator. | releases → fallback Mockup |
publisher-cta.blade.php |
Dunkle Call-to-Action mit Brand-Button + Sekundärlink. | Statisch (Props submitHref, pricingHref) |
active-newsrooms.blade.php |
Newsroom-Liste mit Marken-Initial-Quadrat + Pulse-Badge „heute aktiv". | companies → fallback Mockup |
industry-spotlight.blade.php |
„Heute im Fokus · Energie & Klima" – 3-Spalten-Stat-Grid + 3 Meldungen + warme Studien-Karte mit Brand-Topborder. | Aktuell Mockup |
events-week.blade.php |
7-Spalten-Grid „Termine & Events" mit „Heute"-Highlight und Pulse-Dot. | Aktuell Mockup |
industry-index.blade.php |
„Branchen-Index" – 4×2 Grid mit Gain/Loss-Delta + Balkenindikator. | industries (Category-Counts) → fallback Mockup |
newsletter-strip.blade.php |
Dunkles Newsletter-Panel mit Email-Form + Topic-Checkboxen (links Topic-Auswahl). | Aktuell Mockup |
quality-summary.blade.php |
Warm-beige Card mit Schild-Icon zum Content-Score. | Statisch |
site-footer.blade.php |
4-Spalten-Footer + Bottom-Bar (AGB / Cookie / DSGVO). | Statisch |
Alle Komponenten haben konsistente Konventionen:
cursor-pointer+hover:-Variante +transition-colorsauf jedem klickbaren Element- Bei Bild-Containern:
group+group-hover:scale-105(subtiler Zoom) - Bei Listenelementen:
group+group-hover:text-brandfür den Titel - Alle Mockup-Inhalte sind als spätere Datenquellen markiert (Inline-Kommentare oder via Issue-Tracker)
6. Backend-Anbindung der Startseite
Datei: routes/web.php → Closure $businessportalHomeData
Liefert dem Blade-View folgende Variablen:
| Variable | Quelle | Verwendung |
|---|---|---|
$leadRelease |
Neueste veröffentlichte BP24-PM | focus-hero Hero |
$sideReleases |
Nächste 4 veröffentlichte PMs (ohne Lead) | focus-hero Sidebar |
$mostReadReleases |
Top 4 nach hits |
most-read |
$activeNewsrooms |
Companies mit Press-Releases letzte 7 Tage, sortiert nach heute-aktiv | active-newsrooms (Mapped Array, kein Model) |
$industryIndex |
Top-Level-Categories mit Recent/Previous-Count + Delta | industry-index (Mapped Array) |
$homeStats |
publishedCount, publishedToday, archiveSince | quality-summary |
SQLite-Kompatibilität: Die whereHas-Bedingung für activeNewsrooms wurde bewusst ohne HAVING geschrieben, weil SQLite keine HAVING-Clauses ohne Aggregat unterstützt. Das ist relevant für die Test-Datenbank (DB_DATABASE=testing).
7. Responsive Strategie
| Breakpoint | Verhalten |
|---|---|
< sm (< 640 px) |
Kompaktes Datum, mini-Edition-Tabs (DE/AT/CH/EN), Such-Icon → Overlay, „PM"-Button kurz, Logo-Untertitel ausgeblendet |
sm (≥ 640 px) |
Voller Logo-Untertitel, vollständige Buttons („Anmelden", „Veröffentlichen") |
md (≥ 768 px) |
„Ausgabe"-Label sichtbar, inline-Suchfeld statt Icon-Button |
lg (≥ 1024 px) |
Sprache „Deutsch" + Trennlinie + Newsletter/RSS/API sichtbar, horizontale Underline-Nav statt Burger, Live-Ticker DAX-Sparkline |
xl (≥ 1280 px) |
⌘K-Hinweis im Suchfeld |
Mobile Navigation
Bei < lg blendet sich die Underline-Nav aus und wird durch einen Burger-Trigger ersetzt, der die aktuelle Rubrik prominent anzeigt. Klick öffnet ein abgesetztes Dropdown (absolute z-40) mit allen Rubriken als vertikale Liste. Aktive Rubrik ist Brand-farben + Check-Icon. Esc-Taste, @click.outside und das ausgewählte Item schließen das Menü.
Such-Overlay
Such-Icon-Button öffnet einen modalen Layer (fixed inset-0 z-50 bg-ink/70 backdrop-blur-sm) mit großem Suchfeld, das via Alpine $watch + $refs automatisch fokussiert wird. Esc oder Klick auf Backdrop schließt.
8. Tests
Datei: tests/Feature/Web/Businessportal24HomeTest.php
Drei Test-Szenarien:
renders the editorial shell– Verifiziert Statik (Header, Sektionsüberschriften, Ticker, Newsletter, Quality-Summary). Stellt sicher, dass alte Marketing-Texte („führende Plattform", „maximale Reichweite", „Exklusiv-Interview") NICHT mehr erscheinen.feed only shows published businessportal content– Prüft Portal-Trennung (BP24 + Both sind sichtbar, Presseecho-Only und Drafts nicht).shows most read releases in the sidebar– Prüft Hits-Sortierung in dermost-read-Komponente.
Datei: tests/Feature/Web/PresseechoHomeTest.php
Drei spiegelbildliche Test-Szenarien:
renders the editorial shell– Identische Sektions-Checks, gegenpresseecho.test.feed only shows published presseecho content– Portal-Trennung gespiegelt: Presseecho + Both sichtbar, BP24-Only und Drafts nicht.shows most read releases in the sidebar– Hits-Sortierung.
Stand: 6 passed (48 Assertions, beide Test-Dateien zusammen). Gesamt-Suite 215/216 (der eine Fail ApiDocumentationTest ist vorbestehend wegen fehlender docs/api/v1.yml und nicht UI-bezogen).
9. Build & Workflow
Lokale Entwicklung
npm run dev:web # Vite Dev Server für Web-Domains (Port 5178)
npm run dev:portal # Vite Dev Server für Portal (Port 5177)
npm run dev:all # Beide parallel
Production-Build
NODE_OPTIONS="--max-old-space-size=4096" npm run build:web
⚠️ Build-Memory: Ohne --max-old-space-size=4096 bricht Vite mit Exit-Code 137 (OOM) ab, sobald Alpine.js + die volle Tailwind-v4-Pipeline kompiliert werden.
Tests
php artisan test --compact --filter=Businessportal24HomeTest
Lint
vendor/bin/pint --dirty --format agent
10. Entwicklungsschritte (chronologisch)
| # | Datum | Schritt | Status |
|---|---|---|---|
| 1 | 12.05.2026 | Umsetzungskonzept erstellt + offene Fragen geklärt | ✅ |
| 2 | 12.05.2026 | Mockup Pass B _ _ Deutschland _aktiv 1:1 in Blade/Volt überführt |
✅ |
| 3 | 12.05.2026 | Theme-CSS auf v3-Mockup-Werte migriert (vollständiges Surface/Ink/Brand-System, Gradient-Klassen, max-w-layout) |
✅ |
| 4 | 12.05.2026 | „Ende Anzeige"-Hairline für focus-ad ergänzt, In-Feed-Anzeigen im Feed auf eine reduziert (am Ende vor „Weitere Meldungen") |
✅ |
| 5 | 12.05.2026 | cursor-pointer + Hover-Effekte konsistent auf allen klickbaren Elementen (Tabs, Cards, Links, Buttons, Newsletter-Topics) |
✅ |
| 6 | 12.05.2026 | Responsive Header umgebaut: Burger-Mobile-Nav, Such-Overlay (Alpine.js), kompaktere TopBar, sichtbare Anmelden/Veröffentlichen-Buttons | ✅ |
| 7 | 12.05.2026 | Edition-Tabs (DE/AT/CH/EN) auch auf mobile sichtbar | ✅ |
| 8 | 12.05.2026 | Empty-State des Feeds liefert Mock-Top + Mock-Liste + Anzeige (analog Hero/Sidebar) | ✅ |
| 9 | 12.05.2026 | Live-Ticker-Animationen: Ad-Hoc-Meldungen als Endlos-Laufband (ticker-marquee-track, respektiert prefers-reduced-motion), rechte Kurszeile blättert via Alpine alle 5,2 s vertikal durch |
✅ |
| 10 | 12.05.2026 | Editorial-Akzente aus Hex-Hardcodings auf Theme-Tokens migriert (accent-warm, ink-on-dark-muted, ink-on-dark-rule, card-warm-*, feature-*) |
✅ |
| 11 | 12.05.2026 | Presseecho-Theme angelegt (theme-presseecho.css – grüner Brand, gleiche Token-Namen) und Presseecho-Startseite auf BP24-Komponenten umgestellt (presseecho.blade.php) |
✅ |
| 12 | 12.05.2026 | routes/web.php: Daten-Provider generalisiert zu $webHomeData(Portal) – beide Domains nutzen denselben Code-Pfad |
✅ |
| 13 | 12.05.2026 | Brand-Konfiguration in config/domains.php pro Domain (brand.name, brand.accent, brand.tagline_*, brand.newsletter_topics, brand.footer_legal, brand.about_label) – site-header, site-footer, newsletter-strip lesen daraus |
✅ |
| 14 | 12.05.2026 | press-release-feed-Volt-Component portal-agnostisch (Prop :portal); Aufruf vom View-Layer aus |
✅ |
| 15 | 12.05.2026 | PresseechoHomeTest analog zu Businessportal24HomeTest (3 Szenarien, RefreshDatabase) |
✅ |
| 16 | 12.05.2026 | Aktuell offen: Detailseite, Branchenseite, Veröffentlichen-Landing für beide Domains | 🟡 |
11. Roadmap & nächste Schritte
| Reihenfolge | Aufgabe | Vorlage | Status |
|---|---|---|---|
| 1 | Mobile-Feinschliff Startseite gegen dev/frontend/Mobile _ Startseite.png durchgehen, alle Sektionen testen (besonders 7-Spalten-Events und 4×2 Branchen-Index Stack-Behavior) |
Mobile _ Startseite.html |
🟡 noch nicht final geprüft |
| 2 | Detailseite Pressemitteilung umsetzen | tailwind_v3/Detailseite Tailwind.html + Detailseite _ Pressemitteilung _aktiv.png |
🔴 offen |
| 3 | Branchenseite Energie & Klima umsetzen (Template für alle Kategorien) | tailwind_v3/Branchenseite Tailwind.html + Branchenseite _ Energie _ Klima _aktiv.png |
🔴 offen |
| 4 | Veröffentlichen-Landing umsetzen (Variante A) | tailwind_v3/Veröffentlichen Tailwind.html + Ver_ffentlichen _ Variante A _aktiv_.png |
🔴 offen |
| 5 | Echte Datenquellen für aktuell statische Komponenten anbinden: Live-Ticker (Ad-Hoc-Meldungen), Events-Week, Newsletter-Topics, Industry-Spotlight-Studie | – | 🔴 offen |
| 6 | Legacy-URL-Mapping für Kategorien + Pressemitteilungen festlegen + Tests | siehe Umsetzungskonzept §13 | 🔴 offen |
| 7 | Presseecho-Ableitung als zweites Web-Theme aus stabiler BP24-Basis | – | 🔴 offen |
Reihenfolge-Begründung: Erst wenn Detailseite + Branchenseite + Veröffentlichen vorhanden sind, sind die wiederverwendbaren Bausteine klar genug abstrahiert. Eine zu frühe Abstraktion auf Basis nur der Startseite würde Re-Work erzeugen.
12. Konventionen & Do/Don't
✅ Do
- Mockup-Vorlage
tailwind_v3/...htmlals Quelle der Wahrheit nutzen. Spacings, Farben, Schriftgrößen 1:1 übernehmen. - Eigene Tailwind-v4-Tokens (
bg-bg,text-ink-3,border-bg-rule, …) statt fester Hex-Werte verwenden – Ausnahme: TopBar-spezifische#2A2723,#8A847B,#FF8B6F, die ausschließlich auf dunklem Hintergrund vorkommen. cursor-pointer+transition-colorsauf jedem klickbaren Element (Buttons brauchen das wegen Tailwind-Preflight explizit).- Mockup-Fallback in Komponenten konsequent unterstützen (
@if ($release) … @else … @endifoder Mock-Props), damit Empty-States nie „leer" wirken. - Volt für interaktive Komponenten, klassische Blade-Components für reine Darstellung.
- Tests bei jeder Änderung pflegen – mindestens 1 Assertion pro neue sichtbare Sektion in
Businessportal24HomeTest. - Pint nach jeder PHP-Änderung ausführen.
- Build mit
NODE_OPTIONS=--max-old-space-size=4096dokumentieren in Skripten / CI.
❌ Don't
- Keine FluxUI-Komponenten im Web-Bundle (nur im Portal verfügbar).
- Keine Marketing-Phrasen wie „führende Plattform", „maximale Reichweite", „Exklusiv-Interview" – das war Pass A, wir sind auf Pass B.
- Keine
HAVING-Clauses ohne Aggregat (SQLite-Test-DB bricht). - Keine festen Pixel-Container > 1280 px (Layout-Token).
- Keine Inline-
style="background-color:..."für Theme-Farben – stattdessen@theme-Token verwenden.
13. Wiederkehrende Snippets
Sektions-Header
<section class="max-w-layout mx-auto px-8 mt-16">
<header class="flex items-baseline justify-between mb-4 flex-wrap gap-3">
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">
Sektionstitel <span class="text-brand">· Subtitle</span>
</h2>
<div class="eyebrow muted">Meta-Information</div>
</header>
<hr class="rule-strong">
{{-- ... --}}
</section>
Feed-Listen-Item (60 / 100 / 1fr)
<a href="#" class="grid items-baseline gap-4 py-3.5 border-b border-bg-rule cursor-pointer hover:bg-bg-elev transition-colors group"
style="grid-template-columns: 60px 100px 1fr;">
<span class="font-mono text-[12px] text-ink-3">14:18</span>
<span class="bp-cat">Kategorie</span>
<div>
<div class="font-serif text-[15.5px] leading-[1.3] font-medium text-ink group-hover:text-brand transition-colors">
Titel der Meldung
</div>
<div class="text-[11px] text-ink-3 mt-1">Unternehmen · Stadt</div>
</div>
</a>
Anzeigen-Block (warm-beige)
<div class="-mx-4 my-2">
<div class="flex items-center gap-2.5 px-4">
<span class="h-px flex-1 bg-bg-card-warm-rule"></span>
<span class="text-[9px] font-bold tracking-[0.22em] uppercase text-ink-on-dark-muted">Anzeige</span>
<span class="h-px flex-1 bg-bg-card-warm-rule"></span>
</div>
<a href="#" rel="sponsored nofollow" class="block px-4 py-4 bg-bg-card-warm cursor-pointer hover:bg-bg-card-warm-hover transition-colors">
{{-- Titel: text-card-warm-title; Kategorie/Meta: text-card-warm-cat --}}
</a>
<div class="flex items-center gap-2.5 px-4">
<span class="h-px flex-1 bg-bg-card-warm-rule"></span>
<span class="text-[9px] font-bold tracking-[0.22em] uppercase text-ink-on-dark-muted">Ende Anzeige</span>
<span class="h-px flex-1 bg-bg-card-warm-rule"></span>
</div>
</div>
Dunkles Panel (Newsletter / CTA / Footer)
<section class="bg-topbar-grad text-ink-on-dark p-12">
<div class="eyebrow on-dark mb-3">Eyebrow</div>
<h2 class="font-serif text-[30px] font-semibold text-white leading-[1.18] tracking-[-0.4px]">Headline</h2>
{{-- ... --}}
</section>
14. Pflege dieses Dokuments
- Wer ein neues Feature umsetzt: Eintrag in Tabelle §10 ergänzen + ggf. §5.3 (Komponenten) und §11 (Roadmap) aktualisieren.
- Wer einen neuen Designtoken hinzufügt: §4 aktualisieren.
- Wer eine neue Seite/Route ergänzt: §3 (Routing) erweitern.
- Status-Indikator pflegen:
- ✅ erledigt und in Production-tauglichem Zustand
- 🟡 in Arbeit oder Feinschliff nötig
- 🔴 offen, noch nicht begonnen
Die tailwind_v3-Mockups sind die normative Quelle. Bei Konflikten zwischen .png, Roh-.html und tailwind_v3/...html gewinnt immer das tailwind_v3/-Pendant.