13-05-2026 Frontend DEV + HUB
This commit is contained in:
parent
5b8bdf4182
commit
092ee0e918
24 changed files with 3560 additions and 34 deletions
|
|
@ -16,6 +16,10 @@ class ThemeHelper
|
||||||
'positive' => 'img/logos/portal-logo-positive.svg',
|
'positive' => 'img/logos/portal-logo-positive.svg',
|
||||||
'negative' => 'img/logos/portal-logo-negative.svg',
|
'negative' => 'img/logos/portal-logo-negative.svg',
|
||||||
],
|
],
|
||||||
|
'presseportale' => [
|
||||||
|
'positive' => 'img/logos/portal-logo-positive.svg',
|
||||||
|
'negative' => 'img/logos/portal-logo-negative.svg',
|
||||||
|
],
|
||||||
'presseecho' => [
|
'presseecho' => [
|
||||||
'positive' => 'img/logos/presseecho-logo-positiv.svg',
|
'positive' => 'img/logos/presseecho-logo-positiv.svg',
|
||||||
'negative' => 'img/logos/presseecho-logo-negativ.svg',
|
'negative' => 'img/logos/presseecho-logo-negativ.svg',
|
||||||
|
|
@ -115,6 +119,7 @@ class ThemeHelper
|
||||||
|
|
||||||
$assetUrlMap = [
|
$assetUrlMap = [
|
||||||
'portal' => 'https://assets.presseportale.test',
|
'portal' => 'https://assets.presseportale.test',
|
||||||
|
'presseportale' => 'https://assets.presseportale.test',
|
||||||
'presseecho' => 'https://assets.presseecho.test',
|
'presseecho' => 'https://assets.presseecho.test',
|
||||||
'businessportal24' => 'https://assets.businessportal24.test',
|
'businessportal24' => 'https://assets.businessportal24.test',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,31 @@ return [
|
||||||
'font' => 'Montserrat',
|
'font' => 'Montserrat',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'presseportale' => [
|
||||||
|
'domain_name' => env('APP_PORTAL_NAME', 'presseportale.test'),
|
||||||
|
'url' => env('APP_PORTAL_URL', 'https://presseportale.test'),
|
||||||
|
'asset_url' => env('APP_PORTAL_ASSET_URL', 'https://assets.presseportale.test'),
|
||||||
|
'theme' => 'presseportale',
|
||||||
|
'view_prefix' => 'web',
|
||||||
|
'assets_dir' => 'build/web',
|
||||||
|
'description' => 'Hub-Landing presseportale.com (öffentlicher Publisher-Bereich)',
|
||||||
|
'color_scheme' => [
|
||||||
|
'primary' => '#1A2540',
|
||||||
|
'secondary' => '#B07A3A',
|
||||||
|
],
|
||||||
|
'font' => 'Inter Tight',
|
||||||
|
'brand' => [
|
||||||
|
'name' => 'presse',
|
||||||
|
'accent' => 'portale',
|
||||||
|
'tagline_short' => 'Publisher · Hub',
|
||||||
|
'tagline_long' => 'Der gemeinsame Publisher-Bereich für presseecho und businessportal24 – Pressemitteilungen schreiben, redaktionell prüfen lassen, auf beiden Reichweiten veröffentlichen.',
|
||||||
|
'footer_legal' => '© :year presseportale · Alle Rechte vorbehalten',
|
||||||
|
'about_label' => 'Über presseportale',
|
||||||
|
'meta_title' => 'presseportale – Publisher-Hub für presseecho und businessportal24',
|
||||||
|
'meta_description' => 'Ein Konto, zwei Reichweiten: Pressemitteilungen redaktionell geprüft auf presseecho und businessportal24 gleichzeitig veröffentlichen.',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
'presseecho' => [
|
'presseecho' => [
|
||||||
'domain_name' => env('APP_PRESSEECHO_NAME', 'presseecho.test'),
|
'domain_name' => env('APP_PRESSEECHO_NAME', 'presseecho.test'),
|
||||||
'url' => env('APP_PRESSEECHO_URL', 'https://presseecho.test'),
|
'url' => env('APP_PRESSEECHO_URL', 'https://presseecho.test'),
|
||||||
|
|
@ -51,11 +76,11 @@ return [
|
||||||
],
|
],
|
||||||
'font' => 'Montserrat',
|
'font' => 'Montserrat',
|
||||||
'brand' => [
|
'brand' => [
|
||||||
'name' => 'presseecho',
|
'name' => 'presse',
|
||||||
'accent' => null,
|
'accent' => 'echo',
|
||||||
'tagline_short' => 'Pressemitteilungen · DACH',
|
'tagline_short' => 'Pressemitteilungen · DACH',
|
||||||
'tagline_long' => 'Fachmeldungen aus Wirtschaft und Industrie. Redaktionell geprüft. Strukturiert distribuiert.',
|
'tagline_long' => 'Fachmeldungen aus Wirtschaft und Industrie. Redaktionell geprüft. Strukturiert distribuiert.',
|
||||||
'footer_legal' => '© :year presseecho.com · Alle Rechte vorbehalten',
|
'footer_legal' => '© :year presseecho · Alle Rechte vorbehalten',
|
||||||
'about_label' => 'Über presseecho',
|
'about_label' => 'Über presseecho',
|
||||||
'meta_title' => 'Aktuelle Pressemitteilungen aus Wirtschaft & Industrie – presseecho',
|
'meta_title' => 'Aktuelle Pressemitteilungen aus Wirtschaft & Industrie – presseecho',
|
||||||
'meta_description' => 'Redaktionell kuratierte Pressemitteilungen aus Wirtschaft und Industrie im DACH-Raum.',
|
'meta_description' => 'Redaktionell kuratierte Pressemitteilungen aus Wirtschaft und Industrie im DACH-Raum.',
|
||||||
|
|
@ -86,7 +111,7 @@ return [
|
||||||
'accent' => '24',
|
'accent' => '24',
|
||||||
'tagline_short' => 'Pressemitteilungen · DACH',
|
'tagline_short' => 'Pressemitteilungen · DACH',
|
||||||
'tagline_long' => 'Veröffentlichungs-Portal für redaktionell geprüfte Pressemitteilungen aus Deutschland, Österreich und der Schweiz.',
|
'tagline_long' => 'Veröffentlichungs-Portal für redaktionell geprüfte Pressemitteilungen aus Deutschland, Österreich und der Schweiz.',
|
||||||
'footer_legal' => '© :year businessportal24.com · Alle Rechte vorbehalten',
|
'footer_legal' => '© :year businessportal24 · Alle Rechte vorbehalten',
|
||||||
'about_label' => 'Über businessportal24',
|
'about_label' => 'Über businessportal24',
|
||||||
'meta_title' => 'Aktuelle Pressemitteilungen aus der deutschen Wirtschaft – businessportal24',
|
'meta_title' => 'Aktuelle Pressemitteilungen aus der deutschen Wirtschaft – businessportal24',
|
||||||
'meta_description' => 'Pressemitteilungen aus Deutschland, Österreich und der Schweiz. Redaktionell geprüft. Strukturiert distribuiert.',
|
'meta_description' => 'Pressemitteilungen aus Deutschland, Österreich und der Schweiz. Redaktionell geprüft. Strukturiert distribuiert.',
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
# Entwicklungskonzept – BusinessPortal24 & Presseecho Frontend
|
# Entwicklungskonzept – BusinessPortal24, Presseecho & presseportale-Hub Frontend
|
||||||
|
|
||||||
> **Stand:** 12. Mai 2026
|
> **Stand:** 13. Mai 2026
|
||||||
> **Domains:** `businessportal24.test` / `businessportal24.com` · `presseecho.test` / `presseecho.com`
|
> **Domains:** `businessportal24.test` / `.com` · `presseecho.test` / `.de` · `presseportale.test` / `.com` (Hub)
|
||||||
> **Theme-Slugs:** `businessportal24` (warm-rotes Editorial) · `presseecho` (grünes Editorial)
|
> **Theme-Slugs:** `businessportal24` (warm-rotes Editorial) · `presseecho` (grünes Editorial) · `presseportale` (Hub-Blau · Publisher-Landing)
|
||||||
> **Assets-Dir (geteilt):** `public/build/web/`
|
> **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.
|
> **Ziel:** Editoriales DACH-Pressemitteilungs-Ökosystem mit 1:1-Mockup-Umsetzung. Presseecho nutzt die **gleiche Komponenten-Architektur** wie BP24, der Hub `presseportale.com` 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 Architekturentscheidungen der BusinessPortal24- und Presseecho-Frontend-Entwicklung. Es ist die zentrale Anlaufstelle für alle, die im Frontend weiterarbeiten oder neue Seiten ergänzen.
|
Dieses Dokument beschreibt den aktuellen Stand und die wichtigsten Architekturentscheidungen der BusinessPortal24-, Presseecho- und presseportale-Hub-Frontend-Entwicklung. Es ist die zentrale Anlaufstelle für alle, die im Frontend weiterarbeiten oder neue Seiten ergänzen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -14,6 +14,8 @@ Dieses Dokument beschreibt den aktuellen Stand und die wichtigsten Architektur
|
||||||
|
|
||||||
Das Portal folgt einer **editorial-zeitungs-orientierten Ästhetik** mit ruhiger Beige-Surface, klarer Hierarchie über Typografie statt Cards und einer einzigen warm-roten Akzentfarbe.
|
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 |
|
| Datei | Zweck |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `dev/frontend/Pass B _ _ Deutschland _aktiv.png` | Visuelle Referenz Desktop |
|
| `dev/frontend/Pass B _ _ Deutschland _aktiv.png` | Visuelle Referenz Desktop |
|
||||||
|
|
@ -65,7 +67,9 @@ Request (Host: presseecho.test)
|
||||||
|
|
||||||
Lokale Domain-Simulation:
|
Lokale Domain-Simulation:
|
||||||
- `.env`: `DEV_SIMULATE_DOMAIN=true`, `DEV_SIMULATED_DOMAIN=businessportal24.test|presseecho.test`
|
- `.env`: `DEV_SIMULATE_DOMAIN=true`, `DEV_SIMULATED_DOMAIN=businessportal24.test|presseecho.test`
|
||||||
- Alternativ: `?theme=businessportal24|presseecho` als Query-Parameter
|
- Alternativ: `?theme=businessportal24|presseecho|presseportale` als Query-Parameter
|
||||||
|
|
||||||
|
> **Hub-Sonderfall (`presseportale.test`):** Diese Domain ist gleichzeitig **Admin-Backend** (Auth/Admin/Customer-Routen, theme = `main`, Build-Dir `build/portal/`) **und** öffentliche **Hub-Landing** (theme = `presseportale`, Build-Dir `build/web/`). In `config/domains.php` existieren beide Einträge (`portal` und `presseportale`) für dieselbe `domain_name`. Der `ThemeServiceProvider` matcht zuerst `portal` (Backend-Standard); für die öffentliche Landing schaltet **`routes/web.php` per `$applyWebDomainConfig('presseportale')` explizit auf das Hub-Theme** um. Auth- und Admin-Routen bleiben unbeeinflusst.
|
||||||
|
|
||||||
### 3.1 Generischer Daten-Provider
|
### 3.1 Generischer Daten-Provider
|
||||||
|
|
||||||
|
|
@ -78,19 +82,134 @@ view('web.businessportal24', $webHomeData(Portal::Businessportal24));
|
||||||
|
|
||||||
Die Trennung der Portale geschieht über `whereIn('portal', [$primaryPortal->value, Portal::Both->value])`.
|
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`:
|
||||||
|
|
||||||
|
```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 presseportale-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-presseportale.css`:
|
||||||
|
|
||||||
|
```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
|
### 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):
|
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:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
'presseecho' => [
|
'presseecho' => [
|
||||||
'theme' => 'presseecho',
|
'theme' => 'presseecho',
|
||||||
'brand' => [
|
'brand' => [
|
||||||
'name' => 'presseecho',
|
'name' => 'presse', // schwarz
|
||||||
'accent' => null, // kein Brand-Akzent (z.B. "24")
|
'accent' => 'echo', // grün (text-brand → #345636)
|
||||||
'tagline_short' => 'Pressemitteilungen · DACH',
|
'tagline_short' => 'Pressemitteilungen · DACH',
|
||||||
'tagline_long' => 'Fachmeldungen aus Wirtschaft und Industrie ...',
|
'tagline_long' => 'Fachmeldungen aus Wirtschaft und Industrie ...',
|
||||||
'footer_legal' => '© :year presseecho.com · Alle Rechte vorbehalten',
|
'footer_legal' => '© :year presseecho · Alle Rechte vorbehalten',
|
||||||
'about_label' => 'Über presseecho',
|
'about_label' => 'Über presseecho',
|
||||||
'meta_title' => '... – presseecho',
|
'meta_title' => '... – presseecho',
|
||||||
'meta_description' => '...',
|
'meta_description' => '...',
|
||||||
|
|
@ -100,8 +219,18 @@ In `config/domains.php` liegt pro Domain ein **`brand`-Block**, der Komponenten
|
||||||
'businessportal24' => [
|
'businessportal24' => [
|
||||||
'theme' => 'businessportal24',
|
'theme' => 'businessportal24',
|
||||||
'brand' => [
|
'brand' => [
|
||||||
'name' => 'businessportal',
|
'name' => 'businessportal', // schwarz
|
||||||
'accent' => '24', // markenrechtlicher Brand-Akzent
|
'accent' => '24', // orange (text-brand → #C84A1E)
|
||||||
|
'footer_legal' => '© :year businessportal24 · Alle Rechte vorbehalten',
|
||||||
|
...
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'presseportale' => [ // Hub-Variante (web)
|
||||||
|
'theme' => 'presseportale',
|
||||||
|
'brand' => [
|
||||||
|
'name' => 'presse', // hub-blau
|
||||||
|
'accent' => 'portale', // bernstein
|
||||||
|
'footer_legal' => '© :year presseportale · Alle Rechte vorbehalten',
|
||||||
...
|
...
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
@ -109,6 +238,35 @@ In `config/domains.php` liegt pro Domain ein **`brand`-Block**, der Komponenten
|
||||||
|
|
||||||
Komponenten (`site-header`, `site-footer`, `newsletter-strip`) lesen ihre Defaults aus `config('domains.domains.'.config('app.theme').'.brand', [...])`. Übergaben via `:brand="..."` überschreiben sie jederzeit.
|
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` |
|
||||||
|
| `presseportale` | **presse**·*portale* | `#B07A3A` (Bernstein) | `#B07A3A` |
|
||||||
|
|
||||||
|
**Single Source of Truth:** Die Komponente `<x-web.brand-mark brand="…" />` rendert die Markenschreibung zentral inkl. Span-Splitting, Schriftart und Akzentfarbe. 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 `presseportale.blade.php` (Hero-Headline, Architektur-Diagramm, Tarif-Subline, Plattform-Familie, FAQ)
|
||||||
|
* Cross-Brand-Mentions auf BP24-/Presseecho-Landings, falls ergänzt
|
||||||
|
|
||||||
|
```blade
|
||||||
|
{{-- Standard: font-serif (Source Serif 4), Auto-Akzent --}}
|
||||||
|
<x-web.brand-mark brand="presseecho" />
|
||||||
|
|
||||||
|
{{-- In Fließtext / kleinen Schriftgröß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)
|
## 4. Theme-System (Tailwind v4)
|
||||||
|
|
@ -257,6 +415,28 @@ Alle Komponenten haben **konsistente Konventionen**:
|
||||||
- Bei Listenelementen: `group` + `group-hover:text-brand` für den Titel
|
- 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)
|
- Alle Mockup-Inhalte sind als spätere Datenquellen markiert (Inline-Kommentare oder via Issue-Tracker)
|
||||||
|
|
||||||
|
### 5.4 Hub-Komponenten (`components/web/hub/`)
|
||||||
|
|
||||||
|
Der Hub `presseportale.com` 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/presseportale.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`·`portale` (über `<x-web.brand-mark brand="presseportale" :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 `presseportale.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 presseportale.com** – 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
|
## 6. Backend-Anbindung der Startseite
|
||||||
|
|
@ -316,7 +496,17 @@ Drei spiegelbildliche Test-Szenarien:
|
||||||
2. **`feed only shows published presseecho content`** – Portal-Trennung gespiegelt: Presseecho + Both sichtbar, BP24-Only und Drafts nicht.
|
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.
|
3. **`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).
|
### Datei: `tests/Feature/Web/PresseportaleHubHomeTest.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 presseportale.com, Plattform im Überblick, Häufige Fragen, Loslegen, Alle Systeme betriebsbereit).
|
||||||
|
2. **`loads the hub theme assets, not portal admin`** – stellt sicher, dass `theme-presseportale` 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).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -366,12 +556,17 @@ vendor/bin/pint --dirty --format agent
|
||||||
| 8 | 12.05.2026 | Empty-State des Feeds liefert Mock-Top + Mock-Liste + Anzeige (analog Hero/Sidebar) | ✅ |
|
| 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 | ✅ |
|
| 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-*`) | ✅ |
|
| 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`) | ✅ |
|
| 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 | ✅ |
|
| 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 | ✅ |
|
| 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 | ✅ |
|
| 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) | ✅ |
|
| 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 | 🟡 |
|
| 16 | 13.05.2026 | **presseportale-Hub-Landing live**: neues Web-Theme `presseportale` (Hub-Blau + Bernstein, `theme-presseportale.css`), eigener Komponenten-Namespace `components/web/hub/` (Top-Bar, Site-Header, Brand-Context-Banner, Site-Footer), Hub-View `web/presseportale.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 `presseportale.test` auf das Hub-Theme um. Root-Route in `routes/admin.php` entfernt (Layout referenziert jetzt `route('dashboard')`). | ✅ |
|
||||||
|
| 17 | 13.05.2026 | `PresseportaleHubHomeTest` (5 Szenarien inkl. Brand-Context-Banner-Conditional). Vite-Config + ThemeHelper + `web-master`-Fonts (Inter Tight + JetBrains Mono ohne Serif) für `presseportale` ergänzt. | ✅ |
|
||||||
|
| 18 | 13.05.2026 | **Brand-Mark-Konvention etabliert** (Feintuning Marken-Schreibweise): keine TLD am Markenschriftzug, 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`; `presseportale`: `name=presse`/`accent=portale`; 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. | 🟡 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -385,9 +580,10 @@ vendor/bin/pint --dirty --format agent
|
||||||
| 4 | **Veröffentlichen-Landing** umsetzen (Variante A) | `tailwind_v3/Veröffentlichen Tailwind.html` + `Ver_ffentlichen _ Variante A _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 |
|
| 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 |
|
| 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 |
|
| 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.
|
**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).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
1136
dev/frontend/tailwind_v3/Hub Landing presseportale-2.html
Normal file
1136
dev/frontend/tailwind_v3/Hub Landing presseportale-2.html
Normal file
File diff suppressed because it is too large
Load diff
301
dev/frontend/tailwind_v3/Login presseportale A3 Tailwind.html
Normal file
301
dev/frontend/tailwind_v3/Login presseportale A3 Tailwind.html
Normal file
|
|
@ -0,0 +1,301 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<title>presseportale.com — Anmelden</title>
|
||||||
|
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Inter+Tight:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet" />
|
||||||
|
|
||||||
|
<script src="https://cdn.tailwindcss.com?plugins=forms"></script>
|
||||||
|
<script>
|
||||||
|
tailwind.config = {
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
bg: "#F6F4EF",
|
||||||
|
"bg-elev": "#FBFAF6",
|
||||||
|
"bg-rule": "#E2DDD0",
|
||||||
|
"bg-rule-2": "#CFC8B5",
|
||||||
|
card: "#FFFFFF",
|
||||||
|
hub: "#1A2540",
|
||||||
|
"hub-2": "#243152",
|
||||||
|
"hub-soft": "#E5E9F1",
|
||||||
|
accent: "#B07A3A",
|
||||||
|
"accent-deep":"#8A5E27",
|
||||||
|
ink: "#1A1F1C",
|
||||||
|
"ink-2":"#3A413D",
|
||||||
|
"ink-3":"#5A6360",
|
||||||
|
"ink-4":"#8A918D",
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: ['"Inter Tight"','Inter','system-ui','sans-serif'],
|
||||||
|
mono: ['"JetBrains Mono"','"SF Mono"','ui-monospace','monospace'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style type="text/tailwindcss">
|
||||||
|
@layer components {
|
||||||
|
/* Field */
|
||||||
|
.field-input {
|
||||||
|
@apply w-full bg-white border border-bg-rule rounded-md
|
||||||
|
px-[13px] py-[11px] text-[14px] text-ink
|
||||||
|
outline-none transition-[border-color,box-shadow,background] duration-150;
|
||||||
|
}
|
||||||
|
.field-input::placeholder { color:#8A918D; }
|
||||||
|
.field-input:hover { @apply border-bg-rule-2; }
|
||||||
|
.field-input:focus {
|
||||||
|
@apply border-hub;
|
||||||
|
box-shadow: 0 0 0 3px rgba(26,37,64,0.10);
|
||||||
|
}
|
||||||
|
.field-label { @apply block text-[12.5px] font-semibold text-ink mb-1.5; }
|
||||||
|
|
||||||
|
/* Checkbox */
|
||||||
|
.check {
|
||||||
|
appearance:none; -webkit-appearance:none;
|
||||||
|
width:16px; height:16px;
|
||||||
|
border:1.5px solid #CFC8B5; border-radius:3px;
|
||||||
|
background:#FFFFFF; cursor:pointer; position:relative;
|
||||||
|
flex-shrink:0; transition: border-color .12s, background .12s;
|
||||||
|
margin:0;
|
||||||
|
}
|
||||||
|
.check:hover { border-color:#1A2540; }
|
||||||
|
.check:checked { background:#1A2540; border-color:#1A2540; }
|
||||||
|
.check:checked::before {
|
||||||
|
content:""; position:absolute;
|
||||||
|
left:4px; top:1px; width:5px; height:9px;
|
||||||
|
border:solid #fff; border-width:0 1.8px 1.8px 0;
|
||||||
|
transform:rotate(42deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.btn-primary {
|
||||||
|
@apply w-full inline-flex items-center justify-center gap-2
|
||||||
|
px-4 py-[11px] bg-hub text-white rounded-md
|
||||||
|
text-[14px] font-semibold transition-colors hover:bg-hub-2;
|
||||||
|
}
|
||||||
|
.btn-outline {
|
||||||
|
@apply w-full inline-flex items-center justify-center gap-2
|
||||||
|
px-4 py-[10px] bg-white text-ink rounded-md
|
||||||
|
border border-bg-rule text-[13px] font-semibold
|
||||||
|
transition-colors hover:bg-bg-elev hover:border-bg-rule-2;
|
||||||
|
}
|
||||||
|
.btn-sso {
|
||||||
|
@apply inline-flex items-center justify-center gap-2
|
||||||
|
px-3 py-[9px] bg-white text-ink rounded-md
|
||||||
|
border border-bg-rule text-[13px] font-semibold
|
||||||
|
transition-colors hover:bg-bg-elev hover:border-bg-rule-2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Eyebrow */
|
||||||
|
.eyebrow-hub {
|
||||||
|
@apply text-[10.5px] font-bold tracking-[0.22em] uppercase text-hub;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hub link */
|
||||||
|
.link-hub { @apply text-hub font-semibold no-underline hover:underline; text-underline-offset:3px; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body { margin:0; padding:0; }
|
||||||
|
body { background:#F6F4EF; }
|
||||||
|
|
||||||
|
/* Atmosphäre: Raster + konzentrische Kreise */
|
||||||
|
.hub-grid {
|
||||||
|
position:absolute; inset:0;
|
||||||
|
background-image:
|
||||||
|
linear-gradient(to right, rgba(26,37,64,0.045) 1px, transparent 1px),
|
||||||
|
linear-gradient(to bottom, rgba(26,37,64,0.045) 1px, transparent 1px);
|
||||||
|
background-size: 56px 56px;
|
||||||
|
pointer-events:none;
|
||||||
|
}
|
||||||
|
.from-banner {
|
||||||
|
background:#FFFFFF;
|
||||||
|
border:1px solid #E2DDD0;
|
||||||
|
border-left:2px solid #1A2540;
|
||||||
|
border-radius:4px;
|
||||||
|
padding:8px 14px;
|
||||||
|
font-size:12px; color:#3A413D;
|
||||||
|
}
|
||||||
|
.field-pw-wrap { position:relative; }
|
||||||
|
.field-affix {
|
||||||
|
position:absolute; top:50%; right:10px; transform:translateY(-50%);
|
||||||
|
color:#5A6360; font-size:11.5px; font-weight:600;
|
||||||
|
background:transparent; border:0; cursor:pointer;
|
||||||
|
padding:4px 6px; border-radius:3px;
|
||||||
|
font-family:inherit;
|
||||||
|
}
|
||||||
|
.field-affix:hover { color:#1A2540; background:#F6F4EF; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="font-sans text-ink antialiased">
|
||||||
|
|
||||||
|
<!-- Vollflächiger Screen 100vh; Atmosphäre liegt hinter allem -->
|
||||||
|
<div class="relative min-h-screen flex flex-col overflow-hidden bg-bg">
|
||||||
|
|
||||||
|
<!-- Atmosphäre: Raster -->
|
||||||
|
<div class="hub-grid" aria-hidden="true"></div>
|
||||||
|
<!-- Atmosphäre: konzentrische Kreise um die Bildmitte -->
|
||||||
|
<svg class="absolute inset-0 w-full h-full pointer-events-none" preserveAspectRatio="xMidYMid slice" viewBox="0 0 1280 880" aria-hidden="true">
|
||||||
|
<g opacity="0.09" stroke="#1A2540" fill="none" stroke-width="1">
|
||||||
|
<circle cx="640" cy="470" r="160"/>
|
||||||
|
<circle cx="640" cy="470" r="260"/>
|
||||||
|
<circle cx="640" cy="470" r="380"/>
|
||||||
|
<circle cx="640" cy="470" r="510"/>
|
||||||
|
<circle cx="640" cy="470" r="660"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<!-- 3px Hub-Blau-Streifen ganz oben -->
|
||||||
|
<div class="relative h-[3px] bg-hub z-10"></div>
|
||||||
|
|
||||||
|
<!-- Header -->
|
||||||
|
<header class="relative z-10 px-10 py-[22px] flex items-center justify-between">
|
||||||
|
<a href="#" class="flex items-baseline gap-2.5 no-underline">
|
||||||
|
<span class="text-[19px] font-bold tracking-[-0.4px] text-hub leading-none">
|
||||||
|
presseportale<span class="text-accent">.com</span>
|
||||||
|
</span>
|
||||||
|
<span class="inline-block w-px h-[14px] bg-bg-rule"></span>
|
||||||
|
<span class="text-[9.5px] font-bold tracking-[0.22em] uppercase text-ink-3">
|
||||||
|
Publisher · Hub
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<span class="text-[13px] text-ink-3">
|
||||||
|
Noch kein Konto? <a href="#" class="link-hub">Konto erstellen</a>
|
||||||
|
</span>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Center: Auth card -->
|
||||||
|
<main class="relative z-10 flex-1 flex items-center justify-center px-10 py-5">
|
||||||
|
<div class="w-full max-w-[440px]">
|
||||||
|
|
||||||
|
<!-- from=presseecho Banner -->
|
||||||
|
<div class="from-banner mb-3.5">
|
||||||
|
Ihr Konto funktioniert auch für <strong class="font-semibold text-ink">presseecho.de</strong>
|
||||||
|
und <strong class="font-semibold text-ink">businessportal24.com</strong>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="bg-card border border-bg-rule rounded-lg px-9 pt-[34px] pb-8"
|
||||||
|
style="box-shadow:0 1px 0 rgba(26,31,28,0.03), 0 20px 50px -32px rgba(26,37,64,0.28);">
|
||||||
|
|
||||||
|
<div class="eyebrow-hub mb-2.5">Anmeldung im Publisher-Hub</div>
|
||||||
|
<h1 class="text-[26px] font-bold tracking-[-0.5px] leading-[1.2] m-0 mb-7 text-ink">
|
||||||
|
Willkommen zurück
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<form onsubmit="event.preventDefault();" class="space-y-[18px]">
|
||||||
|
|
||||||
|
<!-- Email -->
|
||||||
|
<div>
|
||||||
|
<label class="field-label" for="email">E-Mail-Adresse</label>
|
||||||
|
<input id="email" type="email" autocomplete="username"
|
||||||
|
class="field-input"
|
||||||
|
placeholder="redaktion@ihr-unternehmen.de" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Password -->
|
||||||
|
<div>
|
||||||
|
<div class="flex items-baseline justify-between mb-1.5">
|
||||||
|
<label class="field-label !mb-0" for="pw">Passwort</label>
|
||||||
|
<a href="#" class="link-hub text-[12px]">Passwort vergessen?</a>
|
||||||
|
</div>
|
||||||
|
<div class="field-pw-wrap">
|
||||||
|
<input id="pw" type="password" autocomplete="current-password"
|
||||||
|
class="field-input pr-[72px]"
|
||||||
|
placeholder="••••••••••" />
|
||||||
|
<button type="button" class="field-affix" data-toggle-pw="pw">Anzeigen</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Remember -->
|
||||||
|
<label class="flex items-center gap-2.5 text-[12.5px] text-ink-2 cursor-pointer select-none">
|
||||||
|
<input type="checkbox" class="check" checked />
|
||||||
|
Angemeldet bleiben
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<!-- Primary -->
|
||||||
|
<button type="submit" class="btn-primary !mt-[22px]">Anmelden</button>
|
||||||
|
|
||||||
|
<!-- oder -->
|
||||||
|
<div class="flex items-center gap-3 !mt-[22px] !mb-[14px]">
|
||||||
|
<span class="flex-1 h-px bg-bg-rule"></span>
|
||||||
|
<span class="text-[11px] font-semibold tracking-[0.18em] uppercase text-ink-3">oder</span>
|
||||||
|
<span class="flex-1 h-px bg-bg-rule"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Magic-Link -->
|
||||||
|
<button type="button" class="btn-outline !mt-0">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
||||||
|
<rect x="2" y="3" width="12" height="10" stroke="currentColor" stroke-width="1.4"/>
|
||||||
|
<path d="M2.5 4l5.5 5 5.5-5" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
Magic-Link senden
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- SSO -->
|
||||||
|
<div class="grid grid-cols-2 gap-2.5 !mt-2.5">
|
||||||
|
<button type="button" class="btn-sso">
|
||||||
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||||
|
<path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.76h3.56c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/>
|
||||||
|
<path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.56-2.76c-.99.66-2.25 1.06-3.72 1.06-2.86 0-5.29-1.93-6.15-4.53H2.18v2.84A11 11 0 0012 23z" fill="#34A853"/>
|
||||||
|
<path d="M5.85 14.11A6.6 6.6 0 015.5 12c0-.73.13-1.44.35-2.11V7.05H2.18A11 11 0 001 12c0 1.78.43 3.46 1.18 4.95l3.67-2.84z" fill="#FBBC05"/>
|
||||||
|
<path d="M12 5.38c1.62 0 3.07.56 4.21 1.65l3.16-3.16C17.45 2.09 14.96 1 12 1 7.7 1 3.99 3.47 2.18 7.05l3.67 2.84C6.71 7.3 9.14 5.38 12 5.38z" fill="#EA4335"/>
|
||||||
|
</svg>
|
||||||
|
Google
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn-sso">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
||||||
|
<rect x="2" y="2" width="9" height="9" fill="#F25022"/>
|
||||||
|
<rect x="13" y="2" width="9" height="9" fill="#7FBA00"/>
|
||||||
|
<rect x="2" y="13" width="9" height="9" fill="#00A4EF"/>
|
||||||
|
<rect x="13" y="13" width="9" height="9" fill="#FFB900"/>
|
||||||
|
</svg>
|
||||||
|
Microsoft
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- Micro-Footer -->
|
||||||
|
<footer class="relative z-10 px-10 pt-[18px] pb-[26px] flex items-center justify-between text-[11.5px] text-ink-3">
|
||||||
|
<span>
|
||||||
|
SSL <span class="text-ink-4 mx-2">·</span>
|
||||||
|
Daten in DE <span class="text-ink-4 mx-2">·</span>
|
||||||
|
2-Faktor verfügbar
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<a href="#" class="text-ink-3 no-underline hover:text-ink">Impressum</a>
|
||||||
|
<span class="text-ink-4 mx-2">·</span>
|
||||||
|
<a href="#" class="text-ink-3 no-underline hover:text-ink">Datenschutz</a>
|
||||||
|
<span class="text-ink-4 mx-2">·</span>
|
||||||
|
<a href="#" class="text-ink-3 no-underline hover:text-ink">AGB</a>
|
||||||
|
<span class="text-ink-4 mx-2">·</span>
|
||||||
|
<a href="#" class="text-ink-3 no-underline hover:text-ink">Support</a>
|
||||||
|
</span>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Password show/hide
|
||||||
|
document.querySelectorAll('[data-toggle-pw]').forEach(btn => {
|
||||||
|
btn.addEventListener('click', () => {
|
||||||
|
const input = document.getElementById(btn.dataset.togglePw);
|
||||||
|
const isPw = input.type === 'password';
|
||||||
|
input.type = isPw ? 'text' : 'password';
|
||||||
|
btn.textContent = isPw ? 'Verbergen' : 'Anzeigen';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
0
dev:web
Normal file
0
dev:web
Normal file
|
|
@ -21,8 +21,8 @@
|
||||||
--color-bg-dark: #15201a;
|
--color-bg-dark: #15201a;
|
||||||
--color-bg-card-warm: #ecefe3;
|
--color-bg-card-warm: #ecefe3;
|
||||||
--color-bg-card-warm-border: #c7cfb6;
|
--color-bg-card-warm-border: #c7cfb6;
|
||||||
--color-topbar: #1b2a1f;
|
--color-topbar: #1a3d2e; /* moderat heller als #1b2a1f, aber dunkler als #1f4d3a */
|
||||||
--color-topbar2: #25342a;
|
--color-topbar2: #122d22; /* analog moderat heller als #25342a */
|
||||||
|
|
||||||
/* Ink */
|
/* Ink */
|
||||||
--color-ink: #1b2417;
|
--color-ink: #1b2417;
|
||||||
|
|
|
||||||
319
resources/css/web/theme-presseportale.css
Normal file
319
resources/css/web/theme-presseportale.css
Normal file
|
|
@ -0,0 +1,319 @@
|
||||||
|
/**
|
||||||
|
* Theme für den Publisher-Hub presseportale.com (presseportale.test)
|
||||||
|
*
|
||||||
|
* Eigener Charakter zwischen den beiden Brand-Portalen:
|
||||||
|
* - Surface: warmes Buchpapier (gleiche Familie wie BP24/Presseecho)
|
||||||
|
* - Primary: Hub-Blau (#1A2540) – seriös, plattform-neutral
|
||||||
|
* - Accent: gedecktes Bernstein (#B07A3A) – bewusst NICHT Orange (BP24) und NICHT Grün (Presseecho)
|
||||||
|
* - Schrift: Inter Tight + JetBrains Mono, OHNE Source Serif (Hub-Bezug, weniger editorial-redaktionell als die Brand-Portale)
|
||||||
|
*
|
||||||
|
* Token-Namen folgen wo möglich der BP24/Presseecho-Konvention (bg, bg-elev, bg-rule, ink-*),
|
||||||
|
* sodass viele Utility-Klassen identisch greifen. Hub-spezifische Tokens
|
||||||
|
* (hub, hub-2, hub-soft, accent-soft, hub-line) sind zusätzlich definiert.
|
||||||
|
*/
|
||||||
|
@import "./shared-styles.css";
|
||||||
|
|
||||||
|
@theme {
|
||||||
|
/* Surfaces — warmes Buchpapier, gleiche Familie wie die Brand-Portale */
|
||||||
|
--color-bg: #f6f4ef;
|
||||||
|
--color-bg-elev: #fbfaf6;
|
||||||
|
--color-bg-rule: #e2ddd0;
|
||||||
|
--color-bg-rule-strong: #1a1f1c;
|
||||||
|
--color-bg-dark: #15201a;
|
||||||
|
--color-bg-card: #ffffff;
|
||||||
|
--color-bg-card-warm: #efeadc;
|
||||||
|
--color-bg-card-warm-border: #d6cfbb;
|
||||||
|
|
||||||
|
/* Hub-Blau — Primary, plattform-neutral */
|
||||||
|
--color-hub: #1a2540;
|
||||||
|
--color-hub-2: #243152;
|
||||||
|
--color-hub-3: #2e3d66;
|
||||||
|
--color-hub-soft: #e5e9f1;
|
||||||
|
--color-hub-soft-2: #cfd6e4;
|
||||||
|
--color-hub-line: #7b8fbf;
|
||||||
|
|
||||||
|
/* Topbar (Alias für Hub-Gradient, damit shared base-Klassen passen) */
|
||||||
|
--color-topbar: #1a2540;
|
||||||
|
--color-topbar2: #243152;
|
||||||
|
--color-topbar-deep: #0f1729;
|
||||||
|
|
||||||
|
/* Akzent — gedecktes Bernstein (zwischen Orange und Beige) */
|
||||||
|
--color-accent: #b07a3a;
|
||||||
|
--color-accent-deep: #8a5e27;
|
||||||
|
--color-accent-soft: #f1e6d3;
|
||||||
|
--color-accent-warm: #b07a3a;
|
||||||
|
|
||||||
|
/* Ink — Anthrazit-Reihe */
|
||||||
|
--color-ink: #1a1f1c;
|
||||||
|
--color-ink-2: #3a413d;
|
||||||
|
--color-ink-3: #5a6360;
|
||||||
|
--color-ink-4: #8a918d;
|
||||||
|
--color-ink-on-dark: #f6f4ef;
|
||||||
|
--color-ink-on-dark-2: #b2b9c7;
|
||||||
|
--color-ink-on-dark-3: #7b8fbf;
|
||||||
|
--color-ink-on-dark-muted: #7b8fbf;
|
||||||
|
--color-ink-on-dark-rule: #2a3550;
|
||||||
|
|
||||||
|
/* Brand-Aliase, damit Komponenten, die brand-Tokens verwenden, funktionieren */
|
||||||
|
--color-brand: #1a2540;
|
||||||
|
--color-brand-deep: #0f1729;
|
||||||
|
--color-brand-soft: #e5e9f1;
|
||||||
|
--color-live: #c84a1e;
|
||||||
|
--color-gain: #2e8540;
|
||||||
|
--color-loss: #c8341e;
|
||||||
|
--color-ok: #2e8540;
|
||||||
|
|
||||||
|
/* Editorial-Akzente (für card-warm-Sektionen) */
|
||||||
|
--color-bg-card-warm-hover: #e6deca;
|
||||||
|
--color-bg-card-warm-rule: #c8bda3;
|
||||||
|
--color-card-warm-cat: #5a6360;
|
||||||
|
--color-card-warm-title: #2a302d;
|
||||||
|
--color-feature-line: #c0c8db;
|
||||||
|
--color-feature-dot: #d8dde9;
|
||||||
|
|
||||||
|
/* Fonts — Hub: Inter Tight + JetBrains Mono.
|
||||||
|
Source Serif 4 wird zusätzlich geladen, damit Markennennungen der
|
||||||
|
Tochter-Portale (presseecho, businessportal24) typografisch konsistent
|
||||||
|
erscheinen – im Hub-Standardtext kommt sie aber nicht zum Einsatz. */
|
||||||
|
--font-sans: "Inter Tight", Inter, system-ui, -apple-system,
|
||||||
|
BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||||
|
--font-serif: "Source Serif 4", "Source Serif Pro", Charter,
|
||||||
|
"Iowan Old Style", Georgia, serif;
|
||||||
|
--font-mono: "JetBrains Mono", "SF Mono", ui-monospace, SFMono-Regular,
|
||||||
|
Menlo, Consolas, monospace;
|
||||||
|
|
||||||
|
/* Layout */
|
||||||
|
--container-layout: 1280px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HSL-Variablen für Legacy-Komponenten (shared-styles) */
|
||||||
|
:root {
|
||||||
|
--font-primary: var(--font-sans);
|
||||||
|
--font-secondary: var(--font-sans);
|
||||||
|
|
||||||
|
--background: 40 30% 95%; /* #f6f4ef */
|
||||||
|
--foreground: 144 8% 11%;
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 144 8% 11%;
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 144 8% 11%;
|
||||||
|
|
||||||
|
/* Primary: #1A2540 -> hsl(222, 43%, 18%) */
|
||||||
|
--primary: 222 43% 18%;
|
||||||
|
--primary-foreground: 0 0% 100%;
|
||||||
|
--primary-50: 222 43% 96%;
|
||||||
|
--primary-100: 222 43% 92%;
|
||||||
|
--primary-200: 222 43% 85%;
|
||||||
|
--primary-300: 222 43% 75%;
|
||||||
|
--primary-400: 222 43% 60%;
|
||||||
|
--primary-500: 222 43% 45%;
|
||||||
|
--primary-600: 222 43% 36%;
|
||||||
|
--primary-700: 222 43% 28%;
|
||||||
|
--primary-800: 222 43% 22%;
|
||||||
|
--primary-900: 222 43% 18%;
|
||||||
|
--primary-950: 222 43% 12%;
|
||||||
|
|
||||||
|
--secondary: 224 30% 30%;
|
||||||
|
--secondary-foreground: 0 0% 100%;
|
||||||
|
|
||||||
|
--muted: 40 18% 90%;
|
||||||
|
--muted-foreground: 144 6% 38%;
|
||||||
|
--accent: 31 51% 46%;
|
||||||
|
--accent-foreground: 0 0% 100%;
|
||||||
|
--destructive: 0 84% 60%;
|
||||||
|
--destructive-foreground: 0 0% 100%;
|
||||||
|
--border: 38 23% 85%;
|
||||||
|
--input: 38 23% 85%;
|
||||||
|
--ring: 222 43% 18%;
|
||||||
|
--radius: 4px;
|
||||||
|
|
||||||
|
--shadow-card: 0 1px 2px 0 rgb(26 37 64 / 0.06);
|
||||||
|
--shadow-card-hover: 0 4px 12px -2px rgb(26 37 64 / 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #e8e4da;
|
||||||
|
color: var(--color-ink);
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-feature-settings: "ss01", "cv11";
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
color: inherit;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-mono {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-feature-settings: "tnum";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
/* Hub-Eyebrow — sperrgesetzt, in Hub-Blau */
|
||||||
|
.eyebrow {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.2em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--color-hub);
|
||||||
|
}
|
||||||
|
.eyebrow.muted {
|
||||||
|
color: var(--color-ink-3);
|
||||||
|
letter-spacing: 0.16em;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 10.5px;
|
||||||
|
}
|
||||||
|
.eyebrow.accent {
|
||||||
|
color: var(--color-accent-deep);
|
||||||
|
}
|
||||||
|
.eyebrow.on-dark {
|
||||||
|
color: var(--color-hub-line);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section-Eyebrow mit kurzem Linien-Schwanz */
|
||||||
|
.section-eyebrow {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.22em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--color-hub);
|
||||||
|
}
|
||||||
|
.section-eyebrow::after {
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
width: 42px;
|
||||||
|
height: 1px;
|
||||||
|
background: var(--color-hub);
|
||||||
|
opacity: 0.45;
|
||||||
|
}
|
||||||
|
.section-eyebrow.on-dark {
|
||||||
|
color: var(--color-hub-line);
|
||||||
|
}
|
||||||
|
.section-eyebrow.on-dark::after {
|
||||||
|
background: var(--color-hub-line);
|
||||||
|
opacity: 0.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rule {
|
||||||
|
height: 1px;
|
||||||
|
background: var(--color-bg-rule);
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.rule-strong {
|
||||||
|
height: 1px;
|
||||||
|
background: var(--color-bg-rule-strong);
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.rule-hub {
|
||||||
|
height: 2px;
|
||||||
|
background: var(--color-hub);
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subtile geometrische Hintergrundlinien fürs Hero */
|
||||||
|
.hero-grid {
|
||||||
|
background-image:
|
||||||
|
linear-gradient(
|
||||||
|
to right,
|
||||||
|
rgba(26, 37, 64, 0.04) 1px,
|
||||||
|
transparent 1px
|
||||||
|
),
|
||||||
|
linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
rgba(26, 37, 64, 0.04) 1px,
|
||||||
|
transparent 1px
|
||||||
|
);
|
||||||
|
background-size: 48px 48px;
|
||||||
|
background-position: -1px -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hub-Gradient-Klassen */
|
||||||
|
.bg-hub-grad {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
var(--color-hub) 0%,
|
||||||
|
var(--color-hub-2) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.bg-hub-grad-2 {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
var(--color-hub) 0%,
|
||||||
|
var(--color-topbar-deep) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.bg-accent-grad {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
var(--color-accent) 0%,
|
||||||
|
var(--color-accent-deep) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
.bg-topbar-grad {
|
||||||
|
background-image: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
var(--color-topbar) 0%,
|
||||||
|
var(--color-topbar2) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empfohlen-Ribbon auf Tarif-Karten */
|
||||||
|
.ribbon-recommend {
|
||||||
|
position: absolute;
|
||||||
|
top: -1px;
|
||||||
|
left: -1px;
|
||||||
|
right: -1px;
|
||||||
|
background: var(--color-hub);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 10.5px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.18em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accordion-Pfeil (FAQ) */
|
||||||
|
details > summary {
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
details > summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
details[open] .faq-chev {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.faq-chev {
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
.tabular-nums {
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[x-cloak] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
66
resources/views/components/web/brand-mark.blade.php
Normal file
66
resources/views/components/web/brand-mark.blade.php
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
@props([
|
||||||
|
'brand' => 'presseportale',
|
||||||
|
'variant' => 'auto',
|
||||||
|
'serif' => true,
|
||||||
|
])
|
||||||
|
|
||||||
|
@php
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* - `: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)
|
||||||
|
*/
|
||||||
|
$marks = [
|
||||||
|
'presseecho' => [
|
||||||
|
'name' => 'presse',
|
||||||
|
'accent' => 'echo',
|
||||||
|
'accent_color_auto' => '#345636',
|
||||||
|
'accent_color_on_dark' => '#9BD5B2',
|
||||||
|
],
|
||||||
|
'businessportal24' => [
|
||||||
|
'name' => 'businessportal',
|
||||||
|
'accent' => '24',
|
||||||
|
'accent_color_auto' => '#C84A1E',
|
||||||
|
'accent_color_on_dark' => '#C84A1E',
|
||||||
|
],
|
||||||
|
'presseportale' => [
|
||||||
|
'name' => 'presse',
|
||||||
|
'accent' => 'portale',
|
||||||
|
'accent_color_auto' => '#B07A3A',
|
||||||
|
'accent_color_on_dark' => '#B07A3A',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$mark = $marks[$brand] ?? $marks['presseportale'];
|
||||||
|
|
||||||
|
$accentColor = match ($variant) {
|
||||||
|
'on-dark' => $mark['accent_color_on_dark'],
|
||||||
|
'mono' => 'inherit',
|
||||||
|
default => $mark['accent_color_auto'],
|
||||||
|
};
|
||||||
|
|
||||||
|
$fontClass = $serif ? 'font-serif' : 'font-sans';
|
||||||
|
|
||||||
|
$baseAttributes = $attributes->merge(['class' => $fontClass]);
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<span {{ $baseAttributes }}>{{ $mark['name'] }}<span
|
||||||
|
style="color: {{ $accentColor }};">{{ $mark['accent'] }}</span></span>
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
@props([
|
||||||
|
'from' => null,
|
||||||
|
])
|
||||||
|
|
||||||
|
@php
|
||||||
|
$brandMap = [
|
||||||
|
'presseecho' => [
|
||||||
|
'brand' => 'presseecho',
|
||||||
|
'url' => config('domains.domain_presseecho_url'),
|
||||||
|
],
|
||||||
|
'businessportal24' => [
|
||||||
|
'brand' => 'businessportal24',
|
||||||
|
'url' => config('domains.domain_businessportal_url'),
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$context = $brandMap[$from] ?? null;
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
@if ($context)
|
||||||
|
<div class="bg-hub-soft border-b border-hub-soft-2">
|
||||||
|
<div class="max-w-layout mx-auto px-8 py-3 flex items-center gap-4">
|
||||||
|
<span class="inline-flex items-center justify-center w-6 h-6 rounded-full bg-hub text-white flex-shrink-0">
|
||||||
|
<svg width="11" height="11" viewBox="0 0 12 12" fill="none">
|
||||||
|
<path d="M7.5 2.5L4 6l3.5 3.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<div class="text-[12.5px] text-ink-2 leading-[1.45]">
|
||||||
|
Sie kommen von
|
||||||
|
<a class="font-semibold underline underline-offset-[3px] decoration-hub/30 hover:decoration-hub" href="{{ $context['url'] }}">
|
||||||
|
<x-web.brand-mark :brand="$context['brand']" />
|
||||||
|
</a>.
|
||||||
|
Ihr Konto hier funktioniert für <strong class="text-hub font-semibold">beide Portale</strong> —
|
||||||
|
<x-web.brand-mark brand="presseecho" /> und <x-web.brand-mark brand="businessportal24" />.
|
||||||
|
</div>
|
||||||
|
<span class="flex-1"></span>
|
||||||
|
<a href="{{ $context['url'] }}" class="inline-flex items-center gap-1.5 text-[12px] font-medium text-ink-3 hover:text-hub transition-colors">
|
||||||
|
<svg width="10" height="10" viewBox="0 0 12 12" fill="none">
|
||||||
|
<path d="M7.5 2.5L4 6l3.5 3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
Zurück zu <x-web.brand-mark :brand="$context['brand']" :serif="false" class="font-medium" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
81
resources/views/components/web/hub/site-footer.blade.php
Normal file
81
resources/views/components/web/hub/site-footer.blade.php
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
@props([
|
||||||
|
'brand' => null,
|
||||||
|
])
|
||||||
|
|
||||||
|
@php
|
||||||
|
$themeKey = config('app.theme', 'presseportale');
|
||||||
|
$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');
|
||||||
|
@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>
|
||||||
|
<div class="eyebrow on-dark mt-2 text-[9.5px] tracking-[0.22em]">
|
||||||
|
{{ $brandTagline }}
|
||||||
|
</div>
|
||||||
|
<p class="text-[12.5px] text-white/65 leading-[1.65] mt-4 max-w-[340px]">
|
||||||
|
{{ $brandTaglineLong }}
|
||||||
|
</p>
|
||||||
|
<div class="mt-5 pt-5 border-t border-white/15 text-[12px] text-white/65">
|
||||||
|
Brand-Familie:
|
||||||
|
<a class="font-semibold underline underline-offset-[3px] decoration-white/30 ml-1" href="{{ config('domains.domain_presseecho_url') }}">
|
||||||
|
<x-web.brand-mark brand="presseecho" variant="on-dark" />
|
||||||
|
</a>
|
||||||
|
<span class="mx-2 text-white/30">·</span>
|
||||||
|
<a class="font-semibold underline underline-offset-[3px] decoration-white/30" href="{{ config('domains.domain_businessportal_url') }}">
|
||||||
|
<x-web.brand-mark brand="businessportal24" variant="on-dark" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="eyebrow on-dark mb-3.5">Konto</div>
|
||||||
|
<ul class="space-y-2 text-[13px] text-white/75 list-none p-0 m-0">
|
||||||
|
<li><a href="{{ route('login') }}" class="hover:text-white transition-colors">Anmelden</a></li>
|
||||||
|
<li><a href="{{ route('register') }}" class="hover:text-white transition-colors">Konto erstellen</a></li>
|
||||||
|
<li><a href="#tarife" class="hover:text-white transition-colors">Tarife</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Vertrieb kontaktieren</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Status</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="eyebrow on-dark mb-3.5">Plattform</div>
|
||||||
|
<ul class="space-y-2 text-[13px] text-white/75 list-none p-0 m-0">
|
||||||
|
<li><a href="#funktion" class="hover:text-white transition-colors">So funktioniert es</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Redaktionsrichtlinien</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Dokumentation</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">API-Referenz</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Changelog</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="eyebrow on-dark mb-3.5">Rechtliches</div>
|
||||||
|
<ul class="space-y-2 text-[13px] text-white/75 list-none p-0 m-0">
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Impressum</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">AGB</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Datenschutz</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">DPA / AV</a></li>
|
||||||
|
<li><a href="#" class="hover:text-white transition-colors">Cookie-Einstellungen</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border-t border-white/15">
|
||||||
|
<div class="max-w-layout mx-auto px-8 py-5 flex items-center justify-between gap-4 text-[11.5px] text-white/55">
|
||||||
|
<span>{{ $footerLegal }}</span>
|
||||||
|
<span class="flex items-center gap-2 font-mono text-[10.5px]">
|
||||||
|
<span class="inline-block w-1.5 h-1.5 rounded-full bg-ok"></span>
|
||||||
|
Alle Systeme betriebsbereit
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
60
resources/views/components/web/hub/site-header.blade.php
Normal file
60
resources/views/components/web/hub/site-header.blade.php
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
@props([
|
||||||
|
'navigation' => null,
|
||||||
|
'brand' => null,
|
||||||
|
])
|
||||||
|
|
||||||
|
@php
|
||||||
|
$themeKey = config('app.theme', 'presseportale');
|
||||||
|
$brand =
|
||||||
|
$brand ??
|
||||||
|
config('domains.domains.' . $themeKey . '.brand', [
|
||||||
|
'name' => 'presse',
|
||||||
|
'accent' => 'portale',
|
||||||
|
'tagline_short' => 'Publisher · Hub',
|
||||||
|
]);
|
||||||
|
$brandTagline = $brand['tagline_short'] ?? 'Publisher · Hub';
|
||||||
|
|
||||||
|
$navigation = $navigation ?? [
|
||||||
|
['label' => 'Tarife', 'href' => '#tarife'],
|
||||||
|
['label' => 'So funktioniert es', 'href' => '#funktion'],
|
||||||
|
['label' => 'Plattform-Familie', 'href' => '#familie'],
|
||||||
|
['label' => 'FAQ', 'href' => '#faq'],
|
||||||
|
['label' => 'Dokumentation', 'href' => '#'],
|
||||||
|
];
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<header class="bg-bg-elev border-b border-bg-rule">
|
||||||
|
<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">
|
||||||
|
<span class="text-[24px] font-bold tracking-[-0.5px] leading-none text-hub">
|
||||||
|
<x-web.brand-mark brand="presseportale" :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>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<nav class="hidden lg:flex items-center justify-center gap-1 text-[13.5px] font-medium">
|
||||||
|
@foreach ($navigation as $item)
|
||||||
|
<a href="{{ $item['href'] }}"
|
||||||
|
class="px-3.5 py-2 text-ink-2 hover:text-hub transition-colors">{{ $item['label'] }}</a>
|
||||||
|
@endforeach
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<a href="{{ route('login') }}"
|
||||||
|
class="inline-flex items-center gap-2 px-4 py-2.5 text-[13px] font-semibold text-ink rounded-[4px] hover:bg-bg transition-colors">
|
||||||
|
Anmelden
|
||||||
|
</a>
|
||||||
|
<a href="{{ route('register') }}"
|
||||||
|
class="inline-flex items-center gap-2 px-[18px] py-2.5 text-[13px] font-semibold text-white bg-hub hover:bg-hub-2 rounded-[4px] transition-colors">
|
||||||
|
Konto erstellen
|
||||||
|
<svg width="11" height="11" viewBox="0 0 12 12" fill="none">
|
||||||
|
<path d="M3 9L9 3M9 3H4M9 3v5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
55
resources/views/components/web/hub/top-utility-bar.blade.php
Normal file
55
resources/views/components/web/hub/top-utility-bar.blade.php
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
@props([
|
||||||
|
'date' => null,
|
||||||
|
'siblingPortals' => [
|
||||||
|
['brand' => 'presseecho', 'url' => null],
|
||||||
|
['brand' => 'businessportal24', 'url' => null],
|
||||||
|
],
|
||||||
|
])
|
||||||
|
|
||||||
|
@php
|
||||||
|
$displayDate = $date ?? now()->locale('de')->isoFormat('dddd, D. MMMM YYYY');
|
||||||
|
|
||||||
|
$defaultUrls = [
|
||||||
|
'presseecho' => config('domains.domain_presseecho_url'),
|
||||||
|
'businessportal24' => config('domains.domain_businessportal_url'),
|
||||||
|
];
|
||||||
|
@endphp
|
||||||
|
|
||||||
|
<div class="bg-hub-grad text-ink-on-dark-2 border-b border-black/40">
|
||||||
|
<div class="max-w-layout mx-auto px-8 flex items-stretch text-[11.5px] tracking-wide">
|
||||||
|
|
||||||
|
<span class="flex items-center pr-4 py-2.5 whitespace-nowrap border-r border-white/10">
|
||||||
|
{{ $displayDate }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="flex items-center gap-2.5 px-4 py-2.5 whitespace-nowrap text-white/70">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 16 16" fill="none" class="opacity-65">
|
||||||
|
<rect x="2" y="2" width="5.5" height="5.5" stroke="currentColor" stroke-width="1.2" />
|
||||||
|
<rect x="8.5" y="2" width="5.5" height="5.5" stroke="currentColor" stroke-width="1.2" />
|
||||||
|
<rect x="2" y="8.5" width="12" height="5.5" stroke="currentColor" stroke-width="1.2" />
|
||||||
|
</svg>
|
||||||
|
<span>Publisher-Hub für</span>
|
||||||
|
@foreach ($siblingPortals as $index => $portal)
|
||||||
|
@php
|
||||||
|
$brandKey = $portal['brand'] ?? 'presseecho';
|
||||||
|
$portalUrl = $portal['url'] ?? ($defaultUrls[$brandKey] ?? '#');
|
||||||
|
@endphp
|
||||||
|
<a href="{{ $portalUrl }}" class="text-white font-semibold hover:underline">
|
||||||
|
<x-web.brand-mark :brand="$brandKey" variant="on-dark" :serif="false" />
|
||||||
|
</a>
|
||||||
|
@if (! $loop->last)
|
||||||
|
<span class="text-white/30">·</span>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="flex-1"></span>
|
||||||
|
|
||||||
|
<span class="flex items-center gap-4 py-2.5 whitespace-nowrap text-white/65">
|
||||||
|
<a href="#" class="hover:text-white">Status</a>
|
||||||
|
<a href="#" class="hover:text-white">Dokumentation</a>
|
||||||
|
<a href="#" class="hover:text-white">Kontakt</a>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
'accent' => '24',
|
'accent' => '24',
|
||||||
'tagline_short' => 'Pressemitteilungen · DACH',
|
'tagline_short' => 'Pressemitteilungen · DACH',
|
||||||
'tagline_long' => 'Veröffentlichungs-Portal für redaktionell geprüfte Pressemitteilungen aus Deutschland, Österreich und der Schweiz.',
|
'tagline_long' => 'Veröffentlichungs-Portal für redaktionell geprüfte Pressemitteilungen aus Deutschland, Österreich und der Schweiz.',
|
||||||
'footer_legal' => '© :year businessportal24.com · Alle Rechte vorbehalten',
|
'footer_legal' => '© :year businessportal24 · Alle Rechte vorbehalten',
|
||||||
'about_label' => 'Über businessportal24',
|
'about_label' => 'Über businessportal24',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
<!-- Sidebar Navigation -->
|
<!-- Sidebar Navigation -->
|
||||||
<aside class="w-64 bg-white dark:bg-gray-800 shadow-md hidden md:block">
|
<aside class="w-64 bg-white dark:bg-gray-800 shadow-md hidden md:block">
|
||||||
<div class="p-6">
|
<div class="p-6">
|
||||||
<a href="{{ route('admin.home') }}" class="text-xl font-bold text-gray-900 dark:text-white">
|
<a href="{{ route('dashboard') }}" class="text-xl font-bold text-gray-900 dark:text-white">
|
||||||
{{ $domainName ?? config('app.name') . ' Admin' }}
|
{{ $domainName ?? config('app.name') . ' Admin' }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
0
resources/views/web/brand-mark.blade.php
Normal file
0
resources/views/web/brand-mark.blade.php
Normal file
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
@vite([\App\Helpers\ThemeHelper::getThemeCssPath(), 'resources/js/app.js'], $domainConfig['assets_dir'] ?? 'build/web')
|
@vite([\App\Helpers\ThemeHelper::getThemeCssPath(), 'resources/js/app.js'], $domainConfig['assets_dir'] ?? 'build/web')
|
||||||
|
|
||||||
@if (($theme ?? null) === 'businessportal24')
|
@if (in_array(($theme ?? null), ['businessportal24', 'presseecho', 'presseportale'], true))
|
||||||
<link rel="preconnect" href="https://fonts.bunny.net" crossorigin>
|
<link rel="preconnect" href="https://fonts.bunny.net" crossorigin>
|
||||||
<link href="https://fonts.bunny.net/css?family=inter-tight:400,500,600,700|source-serif-4:400,500,600,700|jetbrains-mono:400,500,600" rel="stylesheet" />
|
<link href="https://fonts.bunny.net/css?family=inter-tight:400,500,600,700|source-serif-4:400,500,600,700|jetbrains-mono:400,500,600" rel="stylesheet" />
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -72,7 +72,7 @@
|
||||||
@stack('styles')
|
@stack('styles')
|
||||||
|
|
||||||
<!-- Domain-spezifische Fonts -->
|
<!-- Domain-spezifische Fonts -->
|
||||||
@if (($theme ?? null) !== 'businessportal24')
|
@if (! in_array(($theme ?? null), ['businessportal24', 'presseecho', 'presseportale'], true))
|
||||||
<link href="https://fonts.bunny.net/css?family=montserrat:400,500,600,700" rel="stylesheet" />
|
<link href="https://fonts.bunny.net/css?family=montserrat:400,500,600,700" rel="stylesheet" />
|
||||||
@endif
|
@endif
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
1143
resources/views/web/presseportale.blade.php
Normal file
1143
resources/views/web/presseportale.blade.php
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,7 @@
|
||||||
## Aktive Routen
|
## Aktive Routen
|
||||||
|
|
||||||
### Basis
|
### Basis
|
||||||
- `GET /` → `admin.home`
|
- `GET /` → öffentliche Publisher-Landing (`web/presseportale.blade.php`, Hub-Theme); eingeloggte Admins werden nach Login direkt nach `/dashboard` geleitet.
|
||||||
- `GET /dashboard` → `dashboard`
|
- `GET /dashboard` → `dashboard`
|
||||||
- `GET /settings` (Redirect) → `settings/profile`
|
- `GET /settings` (Redirect) → `settings/profile`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,10 @@ use App\Http\Middleware\LogSlowAdminRequests;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Livewire\Volt\Volt;
|
use Livewire\Volt\Volt;
|
||||||
|
|
||||||
// Admin-Startseite → Dashboard
|
// Hinweis: Die Root-Route (`/`) auf der Portal-Domain rendert seit dem
|
||||||
Route::get('/', function () {
|
// Hub-Launch die öffentliche Publisher-Landing (web/presseportale.blade.php).
|
||||||
return redirect()->route('dashboard');
|
// Eingeloggte Admins werden über die Auth-Pipeline direkt nach /dashboard
|
||||||
})->name('admin.home');
|
// geleitet (siehe FORTIFY_HOME / LoginResponseContract).
|
||||||
|
|
||||||
Route::get('dashboard', DashboardController::class)
|
Route::get('dashboard', DashboardController::class)
|
||||||
->middleware(['auth', 'verified', EnsureUserIsAdmin::class, LogSlowAdminRequests::class])
|
->middleware(['auth', 'verified', EnsureUserIsAdmin::class, LogSlowAdminRequests::class])
|
||||||
->name('dashboard');
|
->name('dashboard');
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,10 @@ Route::get('/', function () use ($applyWebDomainConfig, $webHomeData) {
|
||||||
$applyWebDomainConfig('businessportal24');
|
$applyWebDomainConfig('businessportal24');
|
||||||
|
|
||||||
return view('web.businessportal24', $webHomeData(Portal::Businessportal24));
|
return view('web.businessportal24', $webHomeData(Portal::Businessportal24));
|
||||||
|
} elseif (str_contains($domain, 'presseportale')) {
|
||||||
|
$applyWebDomainConfig('presseportale');
|
||||||
|
|
||||||
|
return view('web.presseportale');
|
||||||
}
|
}
|
||||||
|
|
||||||
$applyWebDomainConfig('businessportal24');
|
$applyWebDomainConfig('businessportal24');
|
||||||
|
|
|
||||||
88
tests/Feature/Web/PresseportaleHubHomeTest.php
Normal file
88
tests/Feature/Web/PresseportaleHubHomeTest.php
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
test('presseportale hub homepage renders the publisher landing shell', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$this->get('https://presseportale.test/')
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertSee('presse', false)
|
||||||
|
->assertSee('portale', false)
|
||||||
|
->assertSeeText('Publisher-Hub')
|
||||||
|
->assertSeeText('Ein Konto.')
|
||||||
|
->assertSeeText('Was Sie hier können')
|
||||||
|
->assertSeeText('So funktioniert es')
|
||||||
|
->assertSeeText('Vier Schritte')
|
||||||
|
->assertSeeText('Tarife')
|
||||||
|
->assertSeeText('Starter')
|
||||||
|
->assertSeeText('Standard')
|
||||||
|
->assertSeeText('Pro')
|
||||||
|
->assertSeeText('Enterprise')
|
||||||
|
->assertSeeText('Hinter presseportale')
|
||||||
|
->assertSeeText('Plattform im Überblick')
|
||||||
|
->assertSeeText('Häufige Fragen')
|
||||||
|
->assertSeeText('Loslegen')
|
||||||
|
->assertSeeText('Alle Systeme betriebsbereit');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('presseportale hub homepage uses the brand-mark splitting without TLDs', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$response = $this->get('https://presseportale.test/');
|
||||||
|
|
||||||
|
$content = $response->getContent();
|
||||||
|
|
||||||
|
$response->assertSuccessful();
|
||||||
|
|
||||||
|
// Markennamen erscheinen ausschliesslich gesplittet (presse|echo, businessportal|24, presse|portale).
|
||||||
|
expect($content)
|
||||||
|
->not->toContain('presseecho.de')
|
||||||
|
->not->toContain('businessportal24.com')
|
||||||
|
->toContain('businessportal')
|
||||||
|
->toContain('>24<')
|
||||||
|
->toContain('>echo<')
|
||||||
|
->toContain('>portale<');
|
||||||
|
|
||||||
|
// presseportale darf ausschliesslich in der Vertriebs-Mailto-Adresse als Domain auftauchen,
|
||||||
|
// niemals als Marken-Schreibweise im Lese-Text.
|
||||||
|
expect(substr_count($content, 'presseportale.com'))
|
||||||
|
->toBe(substr_count($content, 'vertrieb@presseportale.com'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('presseportale hub homepage loads the hub theme assets, not portal admin', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$response = $this->get('https://presseportale.test/');
|
||||||
|
|
||||||
|
$response
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertSee('theme-presseportale', false)
|
||||||
|
->assertDontSee('theme-businessportal24', false)
|
||||||
|
->assertDontSee('theme-presseecho', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('presseportale hub homepage hides the brand-context banner without a from parameter', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$this->get('https://presseportale.test/')
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertDontSeeText('Sie kommen von');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('presseportale hub homepage shows the brand-context banner when arriving from presseecho', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$response = $this->get('https://presseportale.test/?from=presseecho')
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertSeeText('Sie kommen von')
|
||||||
|
->assertSeeText('Zurück zu');
|
||||||
|
|
||||||
|
// Brand-Mark rendert "presse" + farbiger Akzent "echo" – TLD darf nicht auftauchen.
|
||||||
|
$response->assertDontSee('presseecho.de', false);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('presseportale hub homepage shows the brand-context banner when arriving from businessportal24', function () {
|
||||||
|
/** @var TestCase $this */
|
||||||
|
$response = $this->get('https://presseportale.test/?from=businessportal24')
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertSeeText('Sie kommen von')
|
||||||
|
->assertSeeText('Zurück zu');
|
||||||
|
|
||||||
|
$response->assertDontSee('businessportal24.com', false);
|
||||||
|
});
|
||||||
0
vite
Normal file
0
vite
Normal file
|
|
@ -19,6 +19,7 @@ export default defineConfig({
|
||||||
// Web Theme CSS Dateien
|
// Web Theme CSS Dateien
|
||||||
"resources/css/web/theme-businessportal24.css",
|
"resources/css/web/theme-businessportal24.css",
|
||||||
"resources/css/web/theme-presseecho.css", // Neu: CSS für presseecho hinzugefügt, um beide Themes vorab zu kompilieren
|
"resources/css/web/theme-presseecho.css", // Neu: CSS für presseecho hinzugefügt, um beide Themes vorab zu kompilieren
|
||||||
|
"resources/css/web/theme-presseportale.css", // Hub-Landing presseportale.com
|
||||||
"resources/js/app.js",
|
"resources/js/app.js",
|
||||||
],
|
],
|
||||||
refresh: ["resources/views/web/**/*.blade.php"],
|
refresh: ["resources/views/web/**/*.blade.php"],
|
||||||
|
|
@ -44,6 +45,8 @@ export default defineConfig({
|
||||||
"businessportal24.test",
|
"businessportal24.test",
|
||||||
"assets.presseecho.test", // Neu: presseecho-Host hinzugefügt
|
"assets.presseecho.test", // Neu: presseecho-Host hinzugefügt
|
||||||
"presseecho.test", // Neu: presseecho-Host hinzugefügt
|
"presseecho.test", // Neu: presseecho-Host hinzugefügt
|
||||||
|
"assets.presseportale.test", // Hub-Landing presseportale.com
|
||||||
|
"presseportale.test", // Hub-Landing presseportale.com
|
||||||
"localhost",
|
"localhost",
|
||||||
"0.0.0.0",
|
"0.0.0.0",
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue