presseportale/dev/frontend/ENTWICKLUNGSKONZEPT-BusinessPortal24-Frontend.md
Kevin Adametz 0a3e52d603 19-05-2026 Rebrand Pressekonto, Hub-Flux UI und Legacy-Media-Migration
Umbenennung presseportale → pressekonto in Domains, Themes und Dokumentation.
Design-Tokens, Portal-Shell, Customer-Dashboard, Auth- und Admin-PM-Views.
Artisan-Befehl migrate:legacy-media mit Tests und Hub-Flux-Entwicklungsdocs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-19 16:36:13 +00:00

41 KiB
Raw Blame History

Entwicklungskonzept BusinessPortal24, Presseecho & pressekonto-Hub Frontend

Stand: 13. Mai 2026 Domains: businessportal24.test / .com · presseecho.test / .de · pressekonto.test / .de (Hub) Theme-Slugs: businessportal24 (warm-rotes Editorial) · presseecho (grünes Editorial) · pressekonto (Hub-Blau · Publisher-Landing) Assets-Dir (geteilt): public/build/web/ Ziel: Editoriales DACH-Pressemitteilungs-Ökosystem mit 1:1-Mockup-Umsetzung. Presseecho nutzt die gleiche Komponenten-Architektur wie BP24, der Hub pressekonto.de ist eine eigenständige Publisher-Landing mit klar abgegrenztem Charakter (Hub-Blau + Bernstein, kein Editorial-Feed).

Dieses Dokument beschreibt den aktuellen Stand und die wichtigsten Architektur­entscheidungen der BusinessPortal24-, Presseecho- und pressekonto-Hub-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.

Presseecho übernimmt dieselbe Architektur, tauscht aber das Surface auf grünlich-getintetes Editorial-Off-White und ersetzt die warm-rote Akzentfarbe durch ein dunkles Forest-Green (Brand #345636). Die Editorial-Akzentfarbe für Eyebrows auf dunklem Grund bleibt warm-amber (accent-warm: #e8a95f) das hat sich in der Iteration als beste Lesbarkeit auf den dunklen Forest-Panels bewährt.

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.js Port 5178 / vite.portal.config.js Port 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, vor­geladen 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, vor­geladen 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|presseecho|pressekonto als Query-Parameter

Hub-Sonderfall (pressekonto.test): Diese Domain ist gleichzeitig Admin-Backend (Auth/Admin/Customer-Routen, theme = main, Build-Dir build/portal/) und öffentliche Hub-Landing (theme = pressekonto, Build-Dir build/web/). In config/domains.php existieren beide Einträge (portal und pressekonto) für dieselbe domain_name. Der ThemeServiceProvider matcht zuerst portal (Backend-Standard); für die öffentliche Landing schaltet routes/web.php per $applyWebDomainConfig('pressekonto') explizit auf das Hub-Theme um. Auth- und Admin-Routen bleiben unbeeinflusst.

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.1.1 Presseecho-Farbpalette (Stand 13.05.2026, finalisiert)

Damit das Theme für Presseecho dokumentiert ist, hier der verbindliche Token-Snapshot aus theme-presseecho.css:

@theme {
    /* Surfaces (grünlich-getintete Editorial-Vorlage) */
    --color-bg:                  #f2f4ed;
    --color-bg-elev:             #fafbf7;
    --color-bg-rule:             #dde2d3;
    --color-bg-rule-strong:      #1b2417;
    --color-bg-card-warm:        #ecefe3;
    --color-bg-card-warm-border: #c7cfb6;

    /* Dunkle Editorial-Panels (Topbar, CTA, Newsletter, Footer) */
    --color-topbar:  #1a3d2e;   /* linear-gradient(135deg, #1a3d2e 0%, #122d22 100%) */
    --color-topbar2: #122d22;

    /* Ink (warm-grün, gedämpft) */
    --color-ink:           #1b2417;
    --color-ink-2:         #324132;
    --color-ink-3:         #6a7766;
    --color-ink-4:         #98a294;
    --color-ink-on-dark:   #f0f4eb;
    --color-ink-on-dark-2: #b1b9ab;

    /* Brand: dunkles Forest-Green */
    --color-brand:      #345636;
    --color-brand-deep: #243c25;
    --color-brand-soft: #dbe7d3;

    /* Editorial-Akzente */
    --color-accent-warm:         #e8a95f;   /* warmer Bernstein für Eyebrows auf Dunkel */
    --color-ink-on-dark-muted:   #859485;
    --color-ink-on-dark-rule:    #28332b;
    --color-bg-card-warm-hover:  #dde3cc;
    --color-bg-card-warm-rule:   #b7c0a2;
    --color-card-warm-cat:       #5f6a52;
    --color-card-warm-title:     #2e3826;
    --color-feature-line:        #a8c8a8;
    --color-feature-dot:         #c4dcc4;
}

/* Gradient-Komponenten-Klassen */
.bg-feature-grad { background-image: linear-gradient(135deg, #2c4733, #15281c); }
.bg-hero-grad    { background-image: linear-gradient(135deg, #2c4733, #1a2a1f); }

Iteration des Topbar-Gradients:

Versuch Werte Bewertung
Startwert #1b2a1f → #25342a zu dunkel/zu neutral
Erste Variante #1f4d3a → #163a2c zu hell
Final #1a3d2e → #122d22 abgenommen

3.1.2 pressekonto-Hub-Palette (Stand 13.05.2026)

Der Hub ist bewusst eigenständig positioniert: er ist kein Editorial-Feed, sondern eine reine Publisher-Landing („Ein Konto zwei Reichweiten"). Er bekommt daher einen ganz eigenen Charakter:

  • Surface: warmes Buchpapier wie bei BP24/Presseecho (--color-bg: #f6f4ef) signalisiert Familien-Zugehörigkeit.
  • Primary: Hub-Blau #1A2540 mit Gradient nach #243152 (Topbar, CTAs, alle „Hub"-Akzente).
  • Akzent: gedecktes Bernstein #B07A3A bewusst gewählt, weil weder Orange (BP24) noch Grün (Presseecho). Der Hub steht visuell „zwischen" den beiden Brands.
  • Schrift: Inter Tight (Standardtext) + JetBrains Mono (Mono) + Source Serif 4 (nur für Marken-Mentions der Tochter-Portale, damit typografische Konsistenz zur jeweiligen Brand-Landing erhalten bleibt; im Hub-Fließtext nicht verwendet).

Token-Snapshot aus resources/css/web/theme-pressekonto.css:

@theme {
    /* Surfaces  gleiche Familie wie BP24/Presseecho */
    --color-bg:              #f6f4ef;
    --color-bg-elev:         #fbfaf6;
    --color-bg-rule:         #e2ddd0;
    --color-bg-card:         #ffffff;
    --color-bg-card-warm:    #efeadc;

    /* Hub-Blau  Primary */
    --color-hub:        #1a2540;
    --color-hub-2:      #243152;
    --color-hub-3:      #2e3d66;
    --color-hub-soft:   #e5e9f1;
    --color-hub-soft-2: #cfd6e4;
    --color-hub-line:   #7b8fbf;
    --color-topbar:     #1a2540;
    --color-topbar2:    #243152;

    /* Bernstein-Akzent  bewusst NICHT BP24-Orange, NICHT Presseecho-Grün */
    --color-accent:        #b07a3a;
    --color-accent-deep:   #8a5e27;
    --color-accent-soft:   #f1e6d3;

    /* Ink, Brand-Aliase (für Komponenten, die brand-Tokens nutzen) */
    --color-brand:         #1a2540;
    --color-brand-deep:    #0f1729;
    --color-brand-soft:    #e5e9f1;

    /* Schrift: Inter Tight + JetBrains Mono für Hub-Inhalte,
       Source Serif 4 wird mitgeladen, aber nur für Marken-Mentions per
       <x-web.brand-mark> aktiviert. */
    --font-sans:  "Inter Tight", 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;
}

Hub-spezifische Komponenten-Klassen (alle in @layer components):

  • .bg-hub-grad → 135° #1a2540 → #243152 (Topbar, CTA, Architektur-Knoten)
  • .bg-hub-grad-2 → 180° #1a2540 → #0f1729 (Footer)
  • .bg-accent-grad → 135° #b07a3a → #8a5e27
  • .hero-grid → subtile 48×48 px Gitterlinien als Hero-Hintergrund
  • .section-eyebrow → Hub-Blau-Eyebrow mit Linien-Schwanz
  • .ribbon-recommend → „Empfohlen für Unternehmen"-Banner auf der Pro-Tarif-Karte
  • .faq-chev + details > summary → CSS-only Accordion (kein JS nötig)

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). name + accent ergeben zusammen den vollständigen Markennamen der accent-Teil wird im Header/Footer farbig hervorgehoben:

'presseecho' => [
    'theme' => 'presseecho',
    'brand' => [
        'name' => 'presse',                       // schwarz
        'accent' => 'echo',                       // grün (text-brand → #345636)
        'tagline_short' => 'Pressemitteilungen · DACH',
        'tagline_long' => 'Fachmeldungen aus Wirtschaft und Industrie ...',
        'footer_legal' => '© :year presseecho · Alle Rechte vorbehalten',
        'about_label' => 'Über presseecho',
        'meta_title' => '...  presseecho',
        'meta_description' => '...',
        'newsletter_topics' => [ ... ],
    ],
],
'businessportal24' => [
    'theme' => 'businessportal24',
    'brand' => [
        'name' => 'businessportal',               // schwarz
        'accent' => '24',                         // orange (text-brand → #C84A1E)
        'footer_legal' => '© :year businessportal24 · Alle Rechte vorbehalten',
        ...
    ],
],
'pressekonto' => [                              // Hub-Variante (web)
    'theme' => 'pressekonto',
    'brand' => [
        'name' => 'presse',                       // hub-blau
        'accent' => 'konto',                      // bernstein
        'footer_legal' => '© :year pressekonto · Alle Rechte vorbehalten',
        ...
    ],
],

Komponenten (site-header, site-footer, newsletter-strip) lesen ihre Defaults aus config('domains.domains.'.config('app.theme').'.brand', [...]). Übergaben via :brand="..." überschreiben sie jederzeit.

3.3 Brand-Mark-Konvention (verbindlich, Stand 13.05.2026)

Die Schreibweise der drei Marken folgt einer einheitlichen Regel: keine TLD-Endung am Markennamen, Akzentteil farblich hervorgehoben. Domains (.de, .com) gehören ausschließlich in technische Felder (URLs, mailto-Adressen, Impressum) niemals in den Marken-Schriftzug.

Marke Wortmarke Akzentfarbe (auto) Akzentfarbe (on-dark)
presseecho presse·echo #345636 (Forest) #9BD5B2
businessportal24 businessportal·24 #C84A1E (Orange) #F4B098
pressekonto presse·konto #B07A3A (Bernstein) #B07A3A

Single Source of Truth: Die Komponente <x-web.brand-mark brand="…" /> rendert die Markenschreibung zentral inkl. Span-Splitting, Schriftart und Akzent­farbe. Sie wird überall verwendet, wo eine Marke als Fließtext-Mention erscheint:

  • Hub-Komponenten (hub/top-utility-bar, hub/site-header, hub/site-footer, hub/brand-context-banner)
  • Hub-View pressekonto.blade.php (Hero-Headline, Architektur-Diagramm, Tarif-Subline, Plattform-Familie, FAQ)
  • Cross-Brand-Mentions auf BP24-/Presseecho-Landings, falls ergänzt
{{-- Standard: font-serif (Source Serif 4), Auto-Akzent --}}
<x-web.brand-mark brand="presseecho" />

{{-- In Fließtext / kleinen Schrift­größen: font-sans (Inter Tight) --}}
<x-web.brand-mark brand="businessportal24" :serif="false" />

{{-- Auf dunklem Hintergrund (Topbar, Hub-Footer): hellere Akzentfarbe --}}
<x-web.brand-mark brand="presseecho" variant="on-dark" />

Die BP24-/Presseecho-Header und -Footer rendern ihren eigenen Markennamen weiterhin über das $brandName+$brandAccent-Pattern aus der brand-Config (die Config liefert dasselbe Splitting presse+echo), erscheinen also typografisch identisch.


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-colors auf jedem klickbaren Element
  • Bei Bild-Containern: group + group-hover:scale-105 (subtiler Zoom)
  • Bei Listenelementen: group + group-hover:text-brand für den Titel
  • Alle Mockup-Inhalte sind als spätere Datenquellen markiert (Inline-Kommentare oder via Issue-Tracker)

5.4 Hub-Komponenten (components/web/hub/)

Der Hub pressekonto.de hat einen eigenen, deutlich anderen Charakter als die beiden Brand-Portale (kein Editorial-Feed, sondern Publisher-Landing) und bekommt daher einen eigenen Komponenten-Namespace. Die Sektionen selbst (Hero, Features, How-it-works, Tarife, Plattform-Familie, Social-Proof, FAQ, CTA) sind als inline-Markup in resources/views/web/pressekonto.blade.php umgesetzt, weil sie page-spezifisch sind.

Datei Rolle
hub/top-utility-bar.blade.php Schmale Hub-Blau-Topbar mit Datum, „Publisher-Hub für …"-Brand-Family-Links (rendert <x-web.brand-mark variant="on-dark" :serif="false">), Status/Doku/Kontakt. Props: date, siblingPortals (jetzt Liste mit brand-Key statt fixer Strings).
hub/site-header.blade.php Wortmark presse·konto (über <x-web.brand-mark brand="pressekonto" :serif="false">) + Untertitel „Publisher · Hub", zentrale Primary-Nav (Tarife, So funktioniert es, …), Anmelden + Konto erstellen CTAs. Routes: login, register.
hub/brand-context-banner.blade.php Conditional Banner unter dem Header greift nur bei ?from=presseecho oder ?from=businessportal24 und zeigt: „Sie kommen von … Ihr Konto hier funktioniert für beide Portale". Markenname über Brand-Mark (font-serif), „Zurück zu …"-Link nutzt sans-Variante.
hub/site-footer.blade.php 4-Spaltiger Hub-Footer (Konto / Plattform / Rechtliches + Brand-Spalte mit Plattform-Familie-Links über Brand-Mark variant="on-dark"), Hub-Gradient linear-gradient(180deg,#1A2540,#0F1729). Brand-Block aus config/domains.php.

Hub-Sektionen als inline-Blade (in pressekonto.blade.php):

  1. Hero mit Architektur-Diagramm rechts (zentraler Hub-Knoten + Brand-Portal-Karten + Output-Boxen, alles SVG-only).
  2. Was Sie hier können 3-Karten-Grid (Veröffentlichen / Newsrooms / Reichweite).
  3. So funktioniert es 4-Step-Ol mit Differenzierungs-Highlight in Schritt 3 (Bernstein-Akzent für „Unsere Qualitätssicherung").
  4. Tarife 3 Karten (Starter / Standard / Pro mit .ribbon-recommend) + breiter Enterprise-Streifen in Hub-Blau.
  5. Hinter pressekonto.de 2-Spalten-Plattform-Familie mit den Original-Brand-Gradients der Tochter-Portale (#1F4D3A→#163A2C für Presseecho, #1A1F26→#232A33 für BP24).
  6. Aktive Newsrooms Prose-Auflistung statt Logo-Wall + kompakte Stats-Sidebar.
  7. FAQ CSS-only-Accordion (<details> + .faq-chev) mit 8 Fragen, eine offen by default.
  8. CTA-Wiederholung + Footer.

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:

  1. 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.
  2. feed only shows published businessportal content Prüft Portal-Trennung (BP24 + Both sind sichtbar, Presseecho-Only und Drafts nicht).
  3. shows most read releases in the sidebar Prüft Hits-Sortierung in der most-read-Komponente.

Datei: tests/Feature/Web/PresseechoHomeTest.php

Drei spiegelbildliche Test-Szenarien:

  1. renders the editorial shell Identische Sektions-Checks, gegen presseecho.test.
  2. feed only shows published presseecho content Portal-Trennung gespiegelt: Presseecho + Both sichtbar, BP24-Only und Drafts nicht.
  3. shows most read releases in the sidebar Hits-Sortierung.

Datei: tests/Feature/Web/PressekontoHubHomeTest.php

Fünf Test-Szenarien rund um die Hub-Landing:

  1. renders the publisher landing shell prüft alle Hauptsektionen sind sichtbar (Publisher-Hub, Was Sie hier können, So funktioniert es, Vier Schritte, Tarife, Starter, Standard, Pro, Enterprise, Hinter pressekonto.de, Plattform im Überblick, Häufige Fragen, Loslegen, Alle Systeme betriebsbereit).
  2. loads the hub theme assets, not portal admin stellt sicher, dass theme-pressekonto aus dem Manifest geladen wird (nicht theme-businessportal24 oder theme-presseecho).
  3. hides the brand-context banner without a from parameter Default-Aufruf zeigt keinen „Sie kommen von …"-Banner.
  4. shows the brand-context banner when arriving from presseecho ?from=presseecho triggert den Banner inkl. Link „Zurück zu presseecho.de".
  5. shows the brand-context banner when arriving from businessportal24 ?from=businessportal24 triggert den Banner für BP24.

Stand: 11 Web-Tests grün (BP24 3 + Presseecho 3 + Hub 5 = 79 Assertions). Gesamt-Suite: 220/221 (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. Entwicklungs­schritte (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 gleiche Token-Namen) und Presseecho-Startseite auf BP24-Komponenten umgestellt (presseecho.blade.php)
11a 13.05.2026 Editorial-Fonts-Loader im web-master.blade.php für presseecho freigeschaltet (Source Serif 4 + Inter Tight + JetBrains Mono via bunny.net, Montserrat nur noch für Portal/Legacy).
11b 13.05.2026 Presseecho-Farbpalette finalisiert (vom Design abgesegnet): grünlich-getintete Surfaces (--color-bg: #f2f4ed, Card-Warm #ecefe3/#c7cfb6), Brand bleibt dunkles Forest #345636 mit Deep #243c25 und Soft #dbe7d3. Topbar-Gradient nach Iteration auf linear-gradient(135deg, #1a3d2e 0%, #122d22 100%) festgelegt satter Forest-Ton, ohne zu hell zu wirken. Feature- und Hero-Gradient grün getintet (#2c4733 → #15281c / #2c4733 → #1a2a1f). Editorial-Akzent bleibt warm-amber (accent-warm: #e8a95f) für Eyebrows auf dunklem Grund.
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 13.05.2026 pressekonto-Hub-Landing live: neues Web-Theme pressekonto (Hub-Blau + Bernstein, theme-pressekonto.css), eigener Komponenten-Namespace components/web/hub/ (Top-Bar, Site-Header, Brand-Context-Banner, Site-Footer), Hub-View web/pressekonto.blade.php mit Hero/Architektur-Diagramm, Features, How-it-works, Tarife (Starter/Standard/Pro+Ribbon, Enterprise-Streifen), Plattform-Familie, Aktive-Newsrooms, FAQ-Accordion, CTA. routes/web.php schaltet für pressekonto.test auf das Hub-Theme um. Root-Route in routes/admin.php entfernt (Layout referenziert jetzt route('dashboard')).
17 13.05.2026 PressekontoHubHomeTest (5 Szenarien inkl. Brand-Context-Banner-Conditional). Vite-Config + ThemeHelper + web-master-Fonts (Inter Tight + JetBrains Mono ohne Serif) für pressekonto ergänzt.
18 13.05.2026 Brand-Mark-Konvention etabliert (Feintuning Marken-Schreibweise): keine TLD am Marken­schriftzug, Akzent farblich vom Basis-Wort abgesetzt. Single Source of Truth <x-web.brand-mark> (Marken-Tabelle inkl. Standard- und On-Dark-Akzentfarben, Serif/Sans-Switch). config/domains.php umgestellt (presseecho: name=presse/accent=echo; pressekonto: name=presse/accent=konto; Footer-Legal & Meta-Texte ohne TLD). Hub-Komponenten und Hub-View durchgehend auf Brand-Mark migriert (Top-Utility-Bar, Site-Header, Brand-Context-Banner, Site-Footer, Hero-Headline, Architektur-Diagramm, Tarif-Subline, Plattform-Familie, FAQ). Hub-Theme bekommt Source Serif 4 als --font-serif (für Marken-Mentions) Bunny-Font-Loader erweitert. +1 neuer Test uses the brand-mark splitting without TLDs; alle 12 Web-Tests grün.
19 12.05.2026 Aktuell offen: Detailseite, Branchenseite, Veröffentlichen-Landing für BP24 + Presseecho. Hub-Folgeseiten (Konto-Erstellen-Flow als Landing, Tarif-Detail, Doku-Hub) ebenfalls offen. 🟡

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 erledigt (13.05.2026) Startseite live über theme-presseecho.css + Brand-Config, gleiche Komponenten wie BP24
8 Detailseite/Branchenseite ebenfalls für Presseecho durchziehen, sobald BP24-Templates stehen (sollte ein reiner Theme-Switch werden) siehe oben 🔴 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. Presseecho profitiert dann automatisch davon (nur Token-Switch).


12. Konventionen & Do/Don't

Do

  • Mockup-Vorlage tailwind_v3/...html als 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-colors auf jedem klickbaren Element (Buttons brauchen das wegen Tailwind-Preflight explizit).
  • Mockup-Fallback in Komponenten konsequent unterstützen (@if ($release) … @else … @endif oder 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=4096 dokumentieren 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>
<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.