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>
This commit is contained in:
Kevin Adametz 2026-05-19 16:36:13 +00:00
parent 092ee0e918
commit 0a3e52d603
112 changed files with 8464 additions and 1649 deletions

View file

@ -1,5 +1,5 @@
@props([
'brand' => 'presseportale',
'brand' => 'pressekonto',
'variant' => 'auto',
'serif' => true,
])
@ -9,47 +9,66 @@
* Zentrale Brand-Wortmarke für alle drei Marken der Verlags-Familie.
*
* Schreibweise (verbindlich):
* - presseecho "presse" + "echo" (echo ist die Akzentfarbe)
* - businessportal24 "businessportal" + "24" (24 ist orange)
* - presseportale "presse" + "portale" (portale ist Bernstein)
* - presseecho "presse" + "echo" (echo grün)
* - businessportal24 "businessportal" + "24" (24 orange)
* - pressekonto "presse" + "konto" (konto bernstein)
*
* Keine TLD-Endung (".de", ".com") direkt am Markennamen. Diese gehören
* falls überhaupt getrennt in den juristischen Bereich (Impressum, Kontakt).
*
* Schriftart:
* - Standard `font-serif` (Source Serif 4) passt zum Editorial-Charakter
* von Presseecho und BusinessPortal24. Der Hub lädt Source Serif 4
* ebenfalls mit, damit Markennennungen typografisch konsistent bleiben.
* aller drei Portale.
* - `:serif="false"` schaltet auf font-sans (Inter Tight) etwa für die
* Top-Utility-Bar, in der die Marken sehr klein erscheinen.
*
* Variant:
* - `auto` Akzentfarbe = Theme-Default (Orange / Grün / Bernstein)
* - `on-dark` hellere/wärmere Akzentfarbe (für dunkle Hub-Panels)
* - `mono` Akzent identisch zum Basis-Ton (z. B. wenn beides weiß sein soll)
* - `auto` Name + Akzent in den Marken-Standardfarben (auf hellem Grund)
* - `on-dark` Name in Weiß (Negativ), Akzent in der dunkel-tauglichen Variante
* - `mono` Name + Akzent erben vom Parent (z. B. wenn beides weiß sein soll)
*
* Logo-Farben (siehe Brand-Manual):
* - businessportal: #232A33 (auf hell) / #FFFFFF (negativ)
* - presse (Echo): #1B2417 (auf hell) / #FFFFFF (negativ)
* - presse (Konto): #1A2540 (auf hell) / #FFFFFF (negativ)
* - 24: #C84A1E immer
* - echo: #345636 (auf hell) / #9BD5B2 (negativ)
* - konto: #B07A3A immer
*/
$marks = [
'presseecho' => [
'name' => 'presse',
'accent' => 'echo',
'name_color_auto' => '#1B2417',
'name_color_on_dark' => '#FFFFFF',
'accent_color_auto' => '#345636',
'accent_color_on_dark' => '#9BD5B2',
],
'businessportal24' => [
'name' => 'businessportal',
'accent' => '24',
'name_color_auto' => '#232A33',
'name_color_on_dark' => '#FFFFFF',
'accent_color_auto' => '#C84A1E',
'accent_color_on_dark' => '#C84A1E',
],
'presseportale' => [
'pressekonto' => [
'name' => 'presse',
'accent' => 'portale',
'accent' => 'konto',
'name_color_auto' => '#1A2540',
'name_color_on_dark' => '#FFFFFF',
'accent_color_auto' => '#B07A3A',
'accent_color_on_dark' => '#B07A3A',
],
];
$mark = $marks[$brand] ?? $marks['presseportale'];
$mark = $marks[$brand] ?? $marks['pressekonto'];
$nameColor = match ($variant) {
'on-dark' => $mark['name_color_on_dark'],
'mono' => 'inherit',
default => $mark['name_color_auto'],
};
$accentColor = match ($variant) {
'on-dark' => $mark['accent_color_on_dark'],
@ -62,5 +81,6 @@
$baseAttributes = $attributes->merge(['class' => $fontClass]);
@endphp
<span {{ $baseAttributes }}>{{ $mark['name'] }}<span
<span {{ $baseAttributes }}><span
style="color: {{ $nameColor }};">{{ $mark['name'] }}</span><span
style="color: {{ $accentColor }};">{{ $mark['accent'] }}</span></span>

View file

@ -3,19 +3,19 @@
])
@php
$themeKey = config('app.theme', 'presseportale');
$themeKey = config('app.theme', 'pressekonto');
$brand = $brand ?? config('domains.domains.' . $themeKey . '.brand', []);
$brandTagline = $brand['tagline_short'] ?? 'Publisher · Hub';
$brandTaglineLong = $brand['tagline_long'] ?? 'Der gemeinsame Publisher-Bereich für presseecho und businessportal24.';
$footerLegal = str_replace(':year', (string) now()->year, $brand['footer_legal'] ?? '© ' . now()->year . ' presseportale');
$footerLegal = str_replace(':year', (string) now()->year, $brand['footer_legal'] ?? '© ' . now()->year . ' pressekonto');
@endphp
<footer class="bg-hub-grad-2 text-ink-on-dark">
<div class="max-w-layout mx-auto px-8 py-14 grid gap-10" style="grid-template-columns:1.5fr 1fr 1fr 1fr;">
<div>
<div class="text-[24px] font-bold leading-none tracking-[-0.5px] text-white">
<x-web.brand-mark brand="presseportale" :serif="false" />
<div class="text-[24px] font-bold leading-none tracking-[-0.5px]">
<x-web.brand-mark brand="pressekonto" variant="on-dark" :serif="false" />
</div>
<div class="eyebrow on-dark mt-2 text-[9.5px] tracking-[0.22em]">
{{ $brandTagline }}

View file

@ -4,12 +4,12 @@
])
@php
$themeKey = config('app.theme', 'presseportale');
$themeKey = config('app.theme', 'pressekonto');
$brand =
$brand ??
config('domains.domains.' . $themeKey . '.brand', [
'name' => 'presse',
'accent' => 'portale',
'accent' => 'konto',
'tagline_short' => 'Publisher · Hub',
]);
$brandTagline = $brand['tagline_short'] ?? 'Publisher · Hub';
@ -27,9 +27,9 @@
<div class="max-w-layout mx-auto px-8 py-[18px] grid items-center gap-6" style="grid-template-columns:auto 1fr auto;">
<a href="{{ route('home') }}" class="flex items-baseline gap-2.5 cursor-pointer group"
aria-label="presseportale Startseite">
aria-label="pressekonto Startseite">
<span class="text-[24px] font-bold tracking-[-0.5px] leading-none text-hub">
<x-web.brand-mark brand="presseportale" :serif="false" />
<x-web.brand-mark brand="pressekonto" :serif="false" />
</span>
<span class="hidden md:inline-block w-px h-[18px] bg-bg-rule"></span>
<span class="eyebrow muted text-[9.5px] tracking-[0.22em]">{{ $brandTagline }}</span>

View file

@ -25,8 +25,8 @@
<div class="max-w-layout mx-auto px-8 py-12 grid gap-10 grid-cols-1 md:grid-cols-2 lg:grid-cols-[1.4fr_1fr_1fr_1fr]">
<div>
<a href="{{ route('home') }}" class="block cursor-pointer group" aria-label="{{ $brandName }}{{ $brandAccent }} Startseite">
<div class="font-serif text-[24px] font-semibold leading-none tracking-[-0.5px] text-white group-hover:text-white/80 transition-colors">
{{ $brandName }}@if ($brandAccent)<span class="text-brand">{{ $brandAccent }}</span>@endif
<div class="text-[24px] font-semibold leading-none tracking-[-0.5px]">
<x-web.brand-mark :brand="$themeKey" variant="on-dark" />
</div>
<div class="eyebrow mt-2 text-[9.5px] tracking-[0.18em] text-ink-on-dark-muted">
{{ $brandTagline }}

View file

@ -102,8 +102,8 @@
@keydown.escape.window="searchOpen = false">
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 py-3 lg:py-[18px] flex items-center gap-3 sm:gap-4 lg:gap-6">
<a href="{{ route('home') }}" class="block cursor-pointer group flex-shrink-0" aria-label="{{ $brandName }}{{ $brandAccent }} Startseite">
<div class="font-serif text-[22px] sm:text-[24px] lg:text-[28px] font-semibold leading-none tracking-[-0.5px] text-ink group-hover:text-brand transition-colors">
{{ $brandName }}@if ($brandAccent)<span class="text-brand">{{ $brandAccent }}</span>@endif
<div class="text-[22px] sm:text-[24px] lg:text-[28px] font-semibold leading-none tracking-[-0.5px]">
<x-web.brand-mark :brand="$themeKey" />
</div>
<div class="eyebrow muted mt-1 text-[9.5px] tracking-[0.18em] hidden sm:block">
{{ $brandTagline }}