Spoke-Frontend-Audit: Fake-Inhalte raus, Newsletter-Rueckbau, echte Boersendaten, EN-Lokalisierung

Frontend-Umbau (Kevin, 06.07.2026), Ergebnis des businessportal24-Audits:

- Fake-Anzeigen und Mock-/Fallback-Daten entfernt (focus-ad, feed-ad,
  highlight-card, press-release-card, featured-releases, press-releases-grid);
  Sektionen rendern nur noch mit echten Daten oder gar nicht
- Newsletter-Strip und Newsletter-Box zurueckgebaut (Feature nachgelagert,
  vor Reaktivierung DOI-Flow noetig)
- Echte Boersendaten: MarketDataService (Yahoo-Finance-Quotes, config/market.php,
  Cache) + market:refresh alle 15 Min. im Scheduler; live-ticker blendet sich
  ohne Daten aus
- EN-Lokalisierung der Kern-Seiten via lang/de/web.php + lang/en/web.php;
  Carbon-Locale folgt app()->getLocale()
- Web-Tests auf den neuen Frontend-Stand nachgezogen (Suite: 993 gruen)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-06 13:36:23 +00:00
parent 3320aaaa85
commit bfad13af7d
67 changed files with 1735 additions and 1521 deletions

View file

@ -4,8 +4,13 @@
$brand = config('domains.domains.businessportal24.brand', []);
@endphp
@section('title', $brand['meta_title'] ?? 'Aktuelle Pressemitteilungen aus der deutschen Wirtschaft – businessportal24')
@section('meta_description', $brand['meta_description'] ?? 'Pressemitteilungen aus Deutschland, Österreich und der Schweiz. Redaktionell geprüft. Strukturiert distribuiert.')
{{-- DE-Meta kommt brand-spezifisch aus config/domains.php, EN aus den Übersetzungsdateien. --}}
@section('title', app()->getLocale() === 'de'
? ($brand['meta_title'] ?? 'Aktuelle Pressemitteilungen aus der deutschen Wirtschaft – businessportal24')
: __('web.meta.home_title', ['brand' => ($brand['name'] ?? 'businessportal').($brand['accent'] ?? '')]))
@section('meta_description', app()->getLocale() === 'de'
? ($brand['meta_description'] ?? 'Pressemitteilungen aus Deutschland, Österreich und der Schweiz. Qualitätsgeprüft. Strukturiert distribuiert.')
: __('web.meta.home_description'))
@section('hreflang')
<link rel="alternate" hreflang="de" href="{{ url('/de') }}">
@ -14,7 +19,7 @@
@endsection
@section('content')
<x-web.site-header :ticker="$tickerItems ?? []" />
<x-web.site-header />
<main class="bg-bg text-ink">
<x-web.focus-hero
@ -42,7 +47,9 @@
<x-web.pricing-teaser />
<x-web.newsletter-strip />
{{-- Newsletter-Sektion bewusst entfernt (Double-Opt-in nachgelagert,
siehe dev/release/entwicklungsplan-release.md) — stattdessen Veröffentlichen-CTA. --}}
<x-web.publish-band />
<x-web.quality-summary :stats="$homeStats ?? []" />
</main>

View file

@ -36,7 +36,7 @@
[
'title' => 'Pressemitteilungen & Inhalte',
'items' => [
['q' => 'Welche Dateiformate werden unterstützt?', 'a' => 'Bilder: JPG, PNG, WebP (max. 16 MB). Anhänge: PDF, Word, Excel, PowerPoint, ZIP und TXT (max. 25 MB je Datei).'],
['q' => 'Welche Dateiformate werden unterstützt?', 'a' => 'Bilder: JPG, PNG, WebP (max. 16 MB im Editor; über die API max. 8 MB). Anhänge: PDF, Word, Excel, PowerPoint, ZIP und TXT (max. 25 MB je Datei).'],
['q' => 'Kann ich eine Pressemitteilung nach Veröffentlichung korrigieren?', 'a' => 'Ja — wir korrigieren statt zu löschen: Die URL Ihrer Mitteilung bleibt erhalten, Verweise und Verlinkungen bestehen weiter. Wenden Sie sich mit Korrekturwünschen an unseren Support.'],
['q' => 'Wie optimiere ich meine Pressemitteilung für SEO?', 'a' => 'Nutzen Sie aussagekräftige Headlines, integrieren Sie relevante Keywords natürlich, hinterlegen Sie Bildtitel und strukturieren Sie den Text mit Zwischenüberschriften.'],
['q' => 'Was passiert, wenn eine Mitteilung abgelehnt wird?', 'a' => 'Sie erhalten die Ablehnung mit Begründung und können die Mitteilung überarbeiten und erneut einreichen. Ein abgelehnter Beitrag verbraucht kein Kontingent.'],

View file

@ -3,16 +3,14 @@
@php
use Illuminate\Support\Str;
\Carbon\Carbon::setLocale('de');
$catTranslation = $category->translations->firstWhere('locale', 'de') ?? $category->translations->first();
$catName = $catTranslation?->name ?? 'Branche';
$catTranslation = $category->translations->firstWhere('locale', app()->getLocale()) ?? $category->translations->first();
$catName = $catTranslation?->name ?? __('web.category.fallback_name');
$catSlug = $catTranslation?->slug;
$catDescription = filled($catTranslation?->description)
? $catTranslation->description
: 'Aktuelle Pressemitteilungen aus dem Bereich '.$catName.' – redaktionell geprüft und strukturiert distribuiert im DACH-Raum.';
: __('web.category.default_description', ['category' => $catName]);
$parentTranslation = $category->parent?->translations->firstWhere('locale', 'de') ?? $category->parent?->translations->first();
$parentTranslation = $category->parent?->translations->firstWhere('locale', app()->getLocale()) ?? $category->parent?->translations->first();
$parentName = $parentTranslation?->name;
$parentHref = $parentTranslation?->slug ? route('kategorie', ['slug' => $parentTranslation->slug]) : null;
@ -25,7 +23,7 @@
$leadImage = $leadRelease?->images->first();
$leadImageUrl = $leadImage?->variantUrl('detail') ?? $leadImage?->variantUrl('card') ?? $leadImage?->url();
$leadCat = $leadRelease?->category?->translations->firstWhere('locale', 'de') ?? $leadRelease?->category?->translations->first();
$leadCat = $leadRelease?->category?->translations->firstWhere('locale', app()->getLocale()) ?? $leadRelease?->category?->translations->first();
$leadCompany = $leadRelease?->company?->name;
$leadLead = $leadRelease
? (filled($leadRelease->subtitle)
@ -36,7 +34,7 @@
$leadReadTime = max(1, (int) round($leadWords / 200));
@endphp
@section('title', 'Pressemitteilungen ' . $catName . ' – ' . config('app.name'))
@section('title', __('web.category.meta_title', ['category' => $catName, 'brand' => config('app.name')]))
@section('meta_description', Str::limit(strip_tags($catDescription), 155))
@section('content')
@ -46,7 +44,7 @@
{{-- Breadcrumb --}}
<div class="border-b border-bg-rule">
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 py-2.5 flex items-center gap-2 text-[11.5px] text-ink-3">
<a href="{{ route('web.home') }}" class="hover:text-ink transition-colors">Startseite</a>
<a href="{{ route('web.home') }}" class="hover:text-ink transition-colors">{{ __('web.nav.home') }}</a>
@if ($parentName)
<span class="text-ink-4" aria-hidden="true">/</span>
<a href="{{ $parentHref }}" class="hover:text-ink transition-colors">{{ $parentName }}</a>
@ -59,10 +57,10 @@
{{-- Masthead --}}
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 pt-8 lg:pt-9">
<div class="flex items-center justify-between gap-4 mb-4">
<div class="eyebrow">Branche</div>
<a href="{{ route('web.home') }}" class="inline-flex items-center gap-1.5 text-[12px] font-semibold text-ink-3 hover:text-ink transition-colors whitespace-nowrap" aria-label="Zurück zu allen Meldungen">
<div class="eyebrow">{{ __('web.category.eyebrow') }}</div>
<a href="{{ route('web.home') }}" class="inline-flex items-center gap-1.5 text-[12px] font-semibold text-ink-3 hover:text-ink transition-colors whitespace-nowrap" aria-label="{{ __('web.category.back_aria') }}">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M15 19l-7-7 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
Alle Meldungen
{{ __('web.category.all_releases') }}
</a>
</div>
@ -72,12 +70,12 @@
<p class="font-serif text-[16px] leading-[1.55] m-0 mt-4 max-w-[680px] text-ink-2">{{ $catDescription }}</p>
<div class="mt-4 text-[11.5px] text-ink-3 flex items-center gap-2.5 flex-wrap">
<span class="w-1.5 h-1.5 rounded-full bg-brand pulse-dot"></span>
{{ $fmt($categoryStats['month'] ?? 0) }} Meldungen in den letzten 30 Tagen · {{ $fmt($categoryStats['today'] ?? 0) }} am {{ $referenceNow->translatedFormat('j. M Y') }}
{{ __('web.category.month_stat', ['count' => $fmt($categoryStats['month'] ?? 0), 'today' => $fmt($categoryStats['today'] ?? 0), 'date' => $referenceNow->translatedFormat('j. M Y')]) }}
</div>
@if ($subCategories->isNotEmpty())
<div class="flex flex-wrap items-center gap-2 mt-5 pt-5 border-t border-bg-rule">
<span class="eyebrow muted text-[10px] mr-1.5">Sub-Themen</span>
<span class="eyebrow muted text-[10px] mr-1.5">{{ __('web.category.sub_topics') }}</span>
@foreach ($subCategories as $sub)
<a href="{{ $sub['href'] }}" class="inline-flex items-baseline gap-[7px] px-3 py-1.5 text-[12px] font-medium border border-bg-rule-strong bg-bg text-ink hover:bg-white hover:border-brand transition-colors">
{{ $sub['name'] }}
@ -93,26 +91,26 @@
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-6">
<div class="grid grid-cols-2 lg:grid-cols-4 border-y border-bg-rule">
<div class="px-6 py-5 border-r border-bg-rule">
<div class="eyebrow muted text-[10px] mb-2.5">Meldungen aktueller Tag</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.category.stat_today') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($categoryStats['today'] ?? 0) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">Stand {{ $referenceNow->translatedFormat('j. M Y') }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.spotlight.stat_window_sub', ['date' => $referenceNow->translatedFormat('j. M Y')]) }}</div>
</div>
<div class="px-6 py-5 lg:border-r border-bg-rule">
<div class="eyebrow muted text-[10px] mb-2.5">Letzte 7 Tage</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.industry_index.window') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($categoryStats['week'] ?? 0) }}</div>
<div class="text-[11.5px] mt-2 {{ $weekDelta >= 0 ? 'text-gain' : 'text-loss' }} font-semibold">
{{ $weekDelta >= 0 ? '+' : '' }}{{ $fmt(abs($weekDelta)) }}@if ($weekDeltaPct !== null) ({{ $weekDelta >= 0 ? '+' : '-' }}{{ abs($weekDeltaPct) }} %)@endif <span class="text-ink-3 font-normal">ggü. Vorwoche</span>
{{ $weekDelta >= 0 ? '+' : '' }}{{ $fmt(abs($weekDelta)) }}@if ($weekDeltaPct !== null) ({{ $weekDelta >= 0 ? '+' : '-' }}{{ abs($weekDeltaPct) }} %)@endif <span class="text-ink-3 font-normal">{{ __('web.category.vs_previous_week') }}</span>
</div>
</div>
<div class="px-6 py-5 border-r border-bg-rule border-t lg:border-t-0">
<div class="eyebrow muted text-[10px] mb-2.5">Aktive Unternehmen</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.spotlight.stat_companies') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($categoryStats['activeCompanies'] ?? 0) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">in den letzten 7 Tagen</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.category.last_7_days') }}</div>
</div>
<div class="px-6 py-5 border-t lg:border-t-0">
<div class="eyebrow muted text-[10px] mb-2.5">Im Archiv</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.spotlight.stat_archive') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($categoryStats['total'] ?? 0) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">Meldungen gesamt</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.spotlight.stat_archive_sub') }}</div>
</div>
</div>
</section>
@ -123,12 +121,15 @@
<div class="grid gap-9 lg:grid-cols-[1.7fr_1fr]">
<article>
<a href="{{ route('release.detail', ['slug' => $leadRelease->slug]) }}" class="block group">
<div class="relative overflow-hidden bg-hero-grad hatch-dark" style="aspect-ratio: 16 / 10;">
{{-- Kein hatch-dark: dessen background-image würde den bg-hero-grad-Verlauf überschreiben. --}}
<div class="relative overflow-hidden bg-hero-grad" style="aspect-ratio: 16 / 10;">
@if ($leadImageUrl)
<img src="{{ $leadImageUrl }}" alt="{{ $leadRelease->title }}" class="absolute inset-0 w-full h-full object-cover" loading="lazy">
@else
<x-web.hero-fallback />
@endif
<div class="absolute top-5 left-5 flex gap-2">
<span class="bp-tag">Top-Meldung</span>
<span class="bp-tag">{{ __('web.hero.top_story') }}</span>
</div>
<div class="absolute left-0 right-0 bottom-0 px-6 sm:px-9 pb-8 pt-[70px] text-white" style="background:linear-gradient(180deg,transparent,rgba(0,0,0,0.92));">
@if ($leadCat)
@ -152,7 +153,7 @@
<span class="font-mono">{{ $leadRelease->published_at->translatedFormat('d.m.Y · H:i') }}</span>
<span aria-hidden="true">·</span>
@endif
<span>{{ $leadReadTime }} Min. Lesezeit</span>
<span>{{ __('web.shared.read_time', ['minutes' => $leadReadTime]) }}</span>
</div>
</div>
</div>
@ -160,10 +161,10 @@
</article>
<aside>
<div class="eyebrow muted mb-3.5">Weitere Top-Meldungen</div>
<div class="eyebrow muted mb-3.5">{{ __('web.category.more_top') }}</div>
@forelse ($topReleases as $top)
@php
$topCat = $top->category?->translations->firstWhere('locale', 'de') ?? $top->category?->translations->first();
$topCat = $top->category?->translations->firstWhere('locale', app()->getLocale()) ?? $top->category?->translations->first();
@endphp
<article class="py-[18px] {{ $loop->first ? 'border-t border-bg-rule-strong' : '' }} border-b border-bg-rule">
<a href="{{ route('release.detail', ['slug' => $top->slug]) }}" class="block group">
@ -181,7 +182,7 @@
</a>
</article>
@empty
<p class="text-[12.5px] text-ink-3 py-4 border-t border-bg-rule">Aktuell keine weiteren Top-Meldungen.</p>
<p class="text-[12.5px] text-ink-3 py-4 border-t border-bg-rule">{{ __('web.category.no_more_top') }}</p>
@endforelse
<div class="mt-[22px]">
@ -196,7 +197,7 @@
<div>
<header class="flex items-baseline justify-between mb-4 min-h-[34px] flex-wrap gap-3">
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">
Aktuelle Meldungen <span class="text-[14px] text-ink-3 font-normal ml-1.5">· {{ $catName }}</span>
{{ __('web.feed.title') }} <span class="text-[14px] text-ink-3 font-normal ml-1.5">· {{ $catName }}</span>
</h2>
</header>
<hr class="rule-strong">
@ -204,12 +205,12 @@
@forelse ($feedReleases as $release)
<x-web.feed-item :release="$release" :recommended="$release->content_score !== null && $release->content_score >= 80" />
@empty
<p class="text-[13px] text-ink-3 py-6">Aktuell keine weiteren Meldungen in dieser Branche.</p>
<p class="text-[13px] text-ink-3 py-6">{{ __('web.category.no_more_releases') }}</p>
@endforelse
<div class="flex justify-between items-center mt-7 flex-wrap gap-3">
<span class="text-[11.5px] text-ink-3">{{ $fmt($categoryStats['week'] ?? 0) }} Meldungen in den letzten 7 Tagen</span>
<a href="{{ route('suche') }}" class="px-3.5 py-2.5 text-[13px] font-semibold border border-bg-rule-strong bg-white text-ink hover:bg-bg-elev transition-colors">Im Archiv suchen →</a>
<span class="text-[11.5px] text-ink-3">{{ __('web.category.week_stat', ['count' => $fmt($categoryStats['week'] ?? 0)]) }}</span>
<a href="{{ route('suche') }}" class="px-3.5 py-2.5 text-[13px] font-semibold border border-bg-rule-strong bg-white text-ink hover:bg-bg-elev transition-colors">{{ __('web.category.search_archive') }} →</a>
</div>
</div>
@ -221,8 +222,8 @@
@else
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-12 mb-4">
<div class="border border-bg-rule bg-bg-elev px-6 py-10 text-center">
<h2 class="font-serif text-[22px] font-semibold text-ink m-0 mb-2">Noch keine Meldungen in {{ $catName }}</h2>
<p class="text-[13px] text-ink-3 m-0">Sobald Pressemitteilungen in dieser Branche veröffentlicht werden, erscheinen sie hier.</p>
<h2 class="font-serif text-[22px] font-semibold text-ink m-0 mb-2">{{ __('web.category.empty_title', ['category' => $catName]) }}</h2>
<p class="text-[13px] text-ink-3 m-0">{{ __('web.category.empty_text') }}</p>
</div>
</section>
@endif
@ -230,8 +231,8 @@
@if ($subCategories->isNotEmpty())
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-16">
<header class="flex items-baseline justify-between mb-4 flex-wrap gap-3">
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">Sub-Branchen <span class="text-[14px] text-ink-3 font-normal ml-1.5">· Volumen letzte 30 Tage</span></h2>
<span class="eyebrow muted">7-Tage-Trend</span>
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">{{ __('web.category.sub_industries') }} <span class="text-[14px] text-ink-3 font-normal ml-1.5">· {{ __('web.category.volume_30_days') }}</span></h2>
<span class="eyebrow muted">{{ __('web.category.trend_7_days') }}</span>
</header>
<hr class="rule-strong">
@php $subMax = max(1, (int) $subCategories->max('total')); @endphp
@ -244,7 +245,7 @@
</div>
<div class="flex items-baseline gap-2 mb-2.5">
<span class="font-serif text-[24px] font-semibold tracking-[-0.3px] text-ink">{{ $fmt($sub['total']) }}</span>
<span class="text-[11px] text-ink-3">Meldungen</span>
<span class="text-[11px] text-ink-3">{{ __('web.industry_index.releases') }}</span>
</div>
<div class="h-[3px] bg-bg-rule"><div class="h-full {{ $sub['delta'] >= 0 ? 'bg-gain' : 'bg-brand' }}" style="width: {{ max(8, (int) round($sub['total'] / $subMax * 100)) }}%;"></div></div>
</a>
@ -255,7 +256,7 @@
@if ($relatedCategories->isNotEmpty())
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-16">
<header class="mb-4"><h2 class="font-serif text-[22px] font-semibold m-0 tracking-[-0.2px] text-ink">Verwandte Branchen</h2></header>
<header class="mb-4"><h2 class="font-serif text-[22px] font-semibold m-0 tracking-[-0.2px] text-ink">{{ __('web.category.related') }}</h2></header>
<hr class="rule mb-5">
<div class="flex flex-wrap gap-2.5">
@foreach ($relatedCategories as $related)
@ -273,13 +274,13 @@
<div class="bg-topbar-grad text-ink-on-dark p-6 sm:p-9">
<div class="grid gap-9 lg:grid-cols-[1.4fr_1fr] lg:items-center">
<div>
<div class="eyebrow on-dark mb-2.5">Für Unternehmen aus {{ $catName }}</div>
<h3 class="font-serif text-[24px] sm:text-[28px] font-semibold m-0 mb-2.5 leading-[1.15] text-white tracking-[-0.3px]">Veröffentlichen Sie Ihre Pressemitteilung gezielt in {{ $catName }}.</h3>
<p class="text-[14px] leading-[1.55] m-0 max-w-[540px] text-white/80">Reichweite über aktive Newsrooms · Distribution an Fach- und Wirtschaftsredaktionen · Redaktionell geprüft.</p>
<div class="eyebrow on-dark mb-2.5">{{ __('web.category.cta_eyebrow', ['category' => $catName]) }}</div>
<h3 class="font-serif text-[24px] sm:text-[28px] font-semibold m-0 mb-2.5 leading-[1.15] text-white tracking-[-0.3px]">{{ __('web.category.cta_title', ['category' => $catName]) }}</h3>
<p class="text-[14px] leading-[1.55] m-0 max-w-[540px] text-white/80">{{ __('web.category.cta_text') }}</p>
</div>
<div class="flex flex-col gap-2.5">
<a href="{{ route('veroeffentlichen') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3.5 text-[14px] font-semibold bg-brand text-white hover:bg-brand-deep transition-colors">Pressemitteilung einreichen →</a>
<a href="{{ route('preise') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3 text-[14px] font-semibold text-white border border-white/30 hover:bg-white/10 transition-colors">Tarife &amp; Branchen-Pakete ansehen</a>
<a href="{{ route('veroeffentlichen') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3.5 text-[14px] font-semibold bg-brand text-white hover:bg-brand-deep transition-colors">{{ __('web.category.cta_submit') }} →</a>
<a href="{{ route('preise') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3 text-[14px] font-semibold text-white border border-white/30 hover:bg-white/10 transition-colors">{{ __('web.category.cta_pricing') }}</a>
</div>
</div>
</div>

View file

@ -8,8 +8,10 @@
@php
$siteName = $domainName ?? config('app.name', 'Laravel');
$pageTitle = trim($__env->yieldContent('title')) ?: $siteName;
$pageDescription = trim($__env->yieldContent('meta_description')) ?: $siteName;
// Inline-@section('title', …)-Werte kommen von Blade bereits escaped an —
// einmal dekodieren, damit {{ }} unten nicht doppelt escapt („&amp;amp;").
$pageTitle = html_entity_decode(trim($__env->yieldContent('title')), ENT_QUOTES, 'UTF-8') ?: $siteName;
$pageDescription = html_entity_decode(trim($__env->yieldContent('meta_description')), ENT_QUOTES, 'UTF-8') ?: $siteName;
// Self-Canonical als Default aus der Portal-URL + Request-Pfad (ohne Query):
// pro Portal/Domain getrennt und unabhängig von URL::forceRootUrl – verhindert Cross-Portal-Duplicate.
$portalBase = rtrim($domainUrl ?? config('app.url'), '/');

View file

@ -35,7 +35,7 @@
@endphp
@section('title', $company->name.' – Newsroom · '.$brandName.$brandAccent)
@section('meta_description', Str::limit($boilerplate ?? ('Newsroom von '.$company->name.': alle redaktionell geprüften Pressemitteilungen gebündelt an einem Ort.'), 155))
@section('meta_description', Str::limit($boilerplate ?? __('web.newsroom_page.meta_description', ['company' => $company->name]), 155))
@section('og_type', 'profile')
@section('hreflang')
@ -51,7 +51,7 @@
{{-- Breadcrumb --}}
<div class="border-b border-bg-rule">
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 py-2.5 flex items-center gap-2 text-[11.5px] text-ink-3">
<a href="{{ route('web.home') }}" class="hover:text-ink transition-colors">Startseite</a>
<a href="{{ route('web.home') }}" class="hover:text-ink transition-colors">{{ __('web.nav.home') }}</a>
<span class="text-ink-4" aria-hidden="true">/</span>
<a href="{{ route('newsrooms') }}" class="hover:text-ink transition-colors">Newsrooms</a>
<span class="text-ink-4" aria-hidden="true">/</span>
@ -63,9 +63,9 @@
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 pt-8 lg:pt-9">
<div class="flex items-center justify-between gap-4 mb-4">
<div class="eyebrow">Newsroom</div>
<a href="{{ route('newsrooms') }}" class="inline-flex items-center gap-1.5 text-[12px] font-semibold text-ink-3 hover:text-ink transition-colors whitespace-nowrap" aria-label="Zurück zu allen Newsrooms">
<a href="{{ route('newsrooms') }}" class="inline-flex items-center gap-1.5 text-[12px] font-semibold text-ink-3 hover:text-ink transition-colors whitespace-nowrap" aria-label="{{ __('web.newsroom_page.back_aria') }}">
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M15 19l-7-7 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
Alle Newsrooms
{{ __('web.newsroom_page.all_newsrooms') }}
</a>
</div>
@ -91,11 +91,11 @@
@endif
<span class="inline-flex items-center gap-1.5">
<span class="w-1.5 h-1.5 rounded-full bg-brand pulse-dot"></span>
{{ $fmt($newsroomStats['recent'] ?? 0) }} Meldungen in den letzten 30 Tagen
{{ __('web.newsroom_page.recent_stat', ['count' => $fmt($newsroomStats['recent'] ?? 0)]) }}
</span>
@if (! empty($newsroomStats['sinceYear']))
<span class="text-ink-4" aria-hidden="true">·</span>
<span>Newsroom seit {{ $newsroomStats['sinceYear'] }}</span>
<span>{{ __('web.newsroom_page.since', ['year' => $newsroomStats['sinceYear']]) }}</span>
@endif
</div>
</div>
@ -107,7 +107,7 @@
@if ($categories->isNotEmpty())
<div class="flex flex-wrap items-center gap-2 mt-5 pt-5 border-t border-bg-rule">
<span class="eyebrow muted text-[10px] mr-1.5">Branchen</span>
<span class="eyebrow muted text-[10px] mr-1.5">{{ __('web.newsroom_page.industries') }}</span>
@foreach ($categories as $cat)
<a href="{{ $cat['href'] }}" class="inline-flex items-baseline gap-[7px] px-3 py-1.5 text-[12px] font-medium border border-bg-rule-strong bg-bg text-ink hover:bg-white hover:border-brand transition-colors">
{{ $cat['name'] }}
@ -123,24 +123,24 @@
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-6">
<div class="grid grid-cols-2 lg:grid-cols-4 border-y border-bg-rule">
<div class="px-6 py-5 border-r border-bg-rule">
<div class="eyebrow muted text-[10px] mb-2.5">Meldungen aktueller Tag</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.category.stat_today') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($newsroomStats['today'] ?? 0) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">Stand {{ $referenceNow->translatedFormat('j. M Y') }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.spotlight.stat_window_sub', ['date' => $referenceNow->translatedFormat('j. M Y')]) }}</div>
</div>
<div class="px-6 py-5 lg:border-r border-bg-rule">
<div class="eyebrow muted text-[10px] mb-2.5">Letzte 30 Tage</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.newsroom_page.last_30_days') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($newsroomStats['recent'] ?? 0) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">veröffentlichte Meldungen</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.newsroom_page.published_releases') }}</div>
</div>
<div class="px-6 py-5 border-r border-bg-rule border-t lg:border-t-0">
<div class="eyebrow muted text-[10px] mb-2.5">Im Archiv</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.spotlight.stat_archive') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($newsroomStats['total'] ?? 0) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">Meldungen gesamt</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.spotlight.stat_archive_sub') }}</div>
</div>
<div class="px-6 py-5 border-t lg:border-t-0">
<div class="eyebrow muted text-[10px] mb-2.5">Aufrufe gesamt</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.newsroom_page.total_hits') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($newsroomStats['totalHits'] ?? 0) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">über alle Meldungen</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.newsroom_page.total_hits_sub') }}</div>
</div>
</div>
</section>
@ -150,12 +150,15 @@
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-10">
<article>
<a href="{{ route('release.detail', ['slug' => $leadRelease->slug]) }}" class="block group">
<div class="relative overflow-hidden bg-hero-grad hatch-dark" style="aspect-ratio: 16 / 9;">
{{-- Kein hatch-dark: dessen background-image würde den bg-hero-grad-Verlauf überschreiben. --}}
<div class="relative overflow-hidden bg-hero-grad" style="aspect-ratio: 16 / 9;">
@if ($leadImageUrl)
<img src="{{ $leadImageUrl }}" alt="{{ $leadRelease->title }}" class="absolute inset-0 w-full h-full object-cover" loading="lazy">
@else
<x-web.hero-fallback />
@endif
<div class="absolute top-5 left-5 flex gap-2">
<span class="bp-tag">Aktuellste Meldung</span>
<span class="bp-tag">{{ __('web.newsroom_page.latest') }}</span>
</div>
<div class="absolute left-0 right-0 bottom-0 px-6 sm:px-9 pb-8 pt-[70px] text-white" style="background:linear-gradient(180deg,transparent,rgba(0,0,0,0.92));">
@if ($leadCat)
@ -172,7 +175,7 @@
<span class="font-mono">{{ $leadRelease->published_at->translatedFormat('d.m.Y · H:i') }}</span>
<span aria-hidden="true">·</span>
@endif
<span>{{ $leadReadTime }} Min. Lesezeit</span>
<span>{{ __('web.shared.read_time', ['minutes' => $leadReadTime]) }}</span>
</div>
</div>
</div>
@ -186,7 +189,7 @@
<div>
<header class="flex items-baseline justify-between mb-4 min-h-[34px] flex-wrap gap-3">
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">
Alle Meldungen <span class="text-[14px] text-ink-3 font-normal ml-1.5">· {{ $fmt($newsroomStats['total'] ?? 0) }}</span>
{{ __('web.category.all_releases') }} <span class="text-[14px] text-ink-3 font-normal ml-1.5">· {{ $fmt($newsroomStats['total'] ?? 0) }}</span>
</h2>
</header>
<hr class="rule-strong">
@ -194,7 +197,7 @@
@forelse ($releases as $release)
<x-web.feed-item :release="$release" />
@empty
<p class="text-[13px] text-ink-3 py-6">Aktuell keine weiteren Meldungen in diesem Newsroom.</p>
<p class="text-[13px] text-ink-3 py-6">{{ __('web.newsroom_page.empty') }}</p>
@endforelse
<x-web.pagination :paginator="$releases" />
@ -205,16 +208,16 @@
{{-- Eigenen Newsroom starten --}}
<section class="border border-bg-rule-strong bg-bg-elev p-6">
<div class="eyebrow mb-2">Für Unternehmen</div>
<div class="eyebrow mb-2">{{ __('web.publisher_cta.eyebrow') }}</div>
<h3 class="font-serif text-[20px] font-semibold m-0 mb-2 tracking-[-0.2px] leading-[1.2] text-ink">
Eigenen Newsroom starten
{{ __('web.newsroom_page.own_title') }}
</h3>
<p class="text-[12.5px] leading-[1.5] m-0 mb-4 text-ink-2">
Bündeln Sie alle Ihre Pressemitteilungen unter einer eigenen Marken-URL – mit Logo, Branchen-Zuordnung und SEO-Vorteil.
{{ __('web.newsroom_page.own_text') }}
</p>
<a href="{{ route('veroeffentlichen') }}"
class="w-full inline-flex items-center justify-center gap-2 px-[18px] py-2.5 text-[13px] font-semibold bg-white border border-bg-rule-strong text-ink rounded-[2px] cursor-pointer hover:border-brand hover:text-brand transition-colors">
Newsroom anlegen →
{{ __('web.newsroom_page.own_cta') }} →
</a>
</section>

View file

@ -13,8 +13,8 @@
$fmt = fn ($value) => number_format((int) $value, 0, ',', '.');
@endphp
@section('title', 'Newsrooms – '.$brandName.$brandAccent)
@section('meta_description', 'Alle aktiven Unternehmens-Newsrooms im Überblick – redaktionell geprüfte Pressemitteilungen je Unternehmen, gebündelt und dauerhaft auffindbar im DACH-Raum.')
@section('title', __('web.newsrooms_page.meta_title', ['brand' => $brandName.$brandAccent]))
@section('meta_description', __('web.newsrooms_page.meta_description'))
@section('hreflang')
<link rel="alternate" hreflang="de" href="{{ url('/de/newsrooms') }}">
@ -38,31 +38,31 @@
{{-- Masthead --}}
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 pt-8 lg:pt-10">
<div class="max-w-[680px]">
<div class="eyebrow mb-3">Unternehmens-Newsrooms</div>
<div class="eyebrow mb-3">{{ __('web.newsrooms_page.eyebrow') }}</div>
<h1 class="font-serif text-[36px] sm:text-[46px] lg:text-[50px] font-semibold m-0 mb-4 leading-[1.05] tracking-[-1px] text-ink text-balance">
Newsrooms
</h1>
<p class="font-serif text-[16px] leading-[1.55] m-0 text-ink-2">
Alle aktiven Unternehmen mit ihren redaktionell geprüften Pressemitteilungen – gebündelt an einem Ort.
{{ __('web.newsrooms_page.intro') }}
</p>
</div>
{{-- Stat strip --}}
<div class="grid grid-cols-2 lg:grid-cols-3 border-y border-bg-rule mt-8">
<div class="px-6 py-5 border-r border-bg-rule">
<div class="eyebrow muted text-[10px] mb-2.5">Aktive Newsrooms</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.newsrooms.title') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($totalNewsrooms) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">mit veröffentlichten Meldungen</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.newsrooms_page.stat_total_sub') }}</div>
</div>
<div class="px-6 py-5 lg:border-r border-bg-rule">
<div class="eyebrow muted text-[10px] mb-2.5">Aktiv (30 Tage)</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.newsrooms_page.stat_active') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($activeNewsroomsCount) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">Stand {{ $referenceNow->translatedFormat('j. M Y') }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.spotlight.stat_window_sub', ['date' => $referenceNow->translatedFormat('j. M Y')]) }}</div>
</div>
<div class="px-6 py-5 border-t lg:border-t-0">
<div class="eyebrow muted text-[10px] mb-2.5">Meldungen im Archiv</div>
<div class="eyebrow muted text-[10px] mb-2.5">{{ __('web.newsrooms_page.stat_archive') }}</div>
<div class="font-serif text-[32px] sm:text-[36px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $fmt($archiveTotal) }}</div>
<div class="text-[11.5px] text-ink-3 mt-2">redaktionell geprüft</div>
<div class="text-[11.5px] text-ink-3 mt-2">{{ __('web.newsrooms_page.stat_archive_sub') }}</div>
</div>
</div>
</section>
@ -70,18 +70,18 @@
{{-- Suche + Verzeichnis --}}
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-8 mb-16">
<form action="{{ route('newsrooms') }}" method="get" class="mb-7 max-w-[520px]">
<label class="sr-only" for="newsroom-search">Newsroom suchen</label>
<label class="sr-only" for="newsroom-search">{{ __('web.newsrooms_page.search_label') }}</label>
<div class="flex items-center gap-3 px-4 py-3 border border-bg-rule-strong bg-bg-elev focus-within:border-brand transition-colors">
<svg width="18" height="18" viewBox="0 0 16 16" fill="none" class="flex-shrink-0 text-ink-3" aria-hidden="true">
<circle cx="7" cy="7" r="5" stroke="currentColor" stroke-width="1.5" />
<path d="M11 11l3 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
</svg>
<input id="newsroom-search" type="search" name="q" value="{{ $term }}"
placeholder="Unternehmen suchen…"
placeholder="{{ __('web.newsrooms_page.search_placeholder') }}"
autocomplete="off"
class="flex-1 bg-transparent border-0 p-0 text-[14px] text-ink placeholder:text-ink-3 focus:outline-none focus:ring-0 min-w-0">
<button type="submit" class="flex-shrink-0 px-3.5 py-1.5 text-[12.5px] font-semibold bg-brand text-white rounded-[2px] hover:bg-brand-deep transition-colors">
Suchen
{{ __('web.header.search_submit') }}
</button>
</div>
</form>
@ -91,11 +91,11 @@
{{ $fmt($newsrooms->total()) }}
{{ $newsrooms->total() === 1 ? 'Newsroom' : 'Newsrooms' }}
@if ($term !== '')
<span class="text-ink-3 font-normal">für „{{ $term }}"</span>
<span class="text-ink-3 font-normal">{{ __('web.search.for_term', ['term' => $term]) }}</span>
@endif
</h2>
@if ($term !== '')
<a href="{{ route('newsrooms') }}" class="text-[12.5px] text-brand font-semibold hover:text-brand-deep transition-colors">Filter zurücksetzen</a>
<a href="{{ route('newsrooms') }}" class="text-[12.5px] text-brand font-semibold hover:text-brand-deep transition-colors">{{ __('web.newsrooms_page.reset_filter') }}</a>
@endif
</header>
<hr class="rule-strong mb-6">
@ -123,18 +123,18 @@
<div class="min-w-0 flex-1">
<h3 class="font-serif text-[16px] font-semibold leading-[1.25] text-ink group-hover:text-brand transition-colors truncate">{{ $company->name }}</h3>
@if ($latest)
<div class="text-[11px] text-ink-3 mt-1">Letzte Meldung {{ $latest->translatedFormat('j. M Y') }}</div>
<div class="text-[11px] text-ink-3 mt-1">{{ __('web.newsrooms_page.latest_release', ['date' => $latest->translatedFormat('j. M Y')]) }}</div>
@endif
</div>
</div>
<div class="mt-auto flex items-center justify-between pt-3 border-t border-bg-rule">
<span class="text-[12px] text-ink-2">
<span class="font-mono font-semibold text-ink">{{ $fmt($company->releases_count ?? 0) }}</span> Meldungen
<span class="font-mono font-semibold text-ink">{{ $fmt($company->releases_count ?? 0) }}</span> {{ __('web.industry_index.releases') }}
</span>
@if ($isRecentlyActive)
<span class="inline-flex items-center gap-1.5 text-[10.5px] font-semibold text-ink-2 px-2 py-0.5 bg-brand/[0.06] border border-brand/20 rounded-[2px]">
<span class="w-1.5 h-1.5 rounded-full bg-brand"></span>
{{ $fmt($company->recent_count) }} / 30 Tage
{{ $fmt($company->recent_count) }} / {{ __('web.newsrooms_page.days_30') }}
</span>
@endif
</div>
@ -145,17 +145,17 @@
<x-web.pagination :paginator="$newsrooms" />
@else
<div class="border border-bg-rule bg-bg-elev px-6 py-12 text-center">
<h3 class="font-serif text-[20px] font-semibold text-ink m-0 mb-2">Keine Newsrooms gefunden</h3>
<h3 class="font-serif text-[20px] font-semibold text-ink m-0 mb-2">{{ __('web.newsrooms_page.none_found') }}</h3>
<p class="text-[13px] text-ink-3 m-0 mb-5 max-w-md mx-auto">
@if ($term !== '')
Für „{{ $term }}" gibt es derzeit keinen passenden Newsroom. Versuchen Sie einen anderen Suchbegriff.
{{ __('web.newsrooms_page.none_found_term', ['term' => $term]) }}
@else
Aktuell sind keine aktiven Newsrooms verfügbar.
{{ __('web.newsrooms_page.none_available') }}
@endif
</p>
@if ($term !== '')
<a href="{{ route('newsrooms') }}" class="inline-flex items-center gap-2 px-4 py-2.5 text-[13px] font-semibold border border-bg-rule-strong bg-white text-ink hover:bg-bg-elev transition-colors">
Alle Newsrooms anzeigen
{{ __('web.newsrooms.all') }}
</a>
@endif
</div>
@ -167,13 +167,13 @@
<div class="bg-topbar-grad text-ink-on-dark p-6 sm:p-9">
<div class="grid gap-9 lg:grid-cols-[1.4fr_1fr] lg:items-center">
<div>
<div class="eyebrow on-dark mb-2.5">Eigener Newsroom</div>
<h3 class="font-serif text-[24px] sm:text-[28px] font-semibold m-0 mb-2.5 leading-[1.15] text-white tracking-[-0.3px]">Bündeln Sie Ihre Pressemitteilungen im eigenen Newsroom.</h3>
<p class="text-[14px] leading-[1.55] m-0 max-w-[540px] text-white/80">Eigene Marken-URL · alle Meldungen zentral · SEO-Vorteil für Ihr Unternehmen · redaktionell geprüft.</p>
<div class="eyebrow on-dark mb-2.5">{{ __('web.newsrooms_page.cta_eyebrow') }}</div>
<h3 class="font-serif text-[24px] sm:text-[28px] font-semibold m-0 mb-2.5 leading-[1.15] text-white tracking-[-0.3px]">{{ __('web.newsrooms_page.cta_title') }}</h3>
<p class="text-[14px] leading-[1.55] m-0 max-w-[540px] text-white/80">{{ __('web.newsrooms_page.cta_text') }}</p>
</div>
<div class="flex flex-col gap-2.5">
<a href="{{ route('veroeffentlichen') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3.5 text-[14px] font-semibold bg-brand text-white hover:bg-brand-deep transition-colors">Pressemitteilung einreichen →</a>
<a href="{{ route('preise') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3 text-[14px] font-semibold text-white border border-white/30 hover:bg-white/10 transition-colors">Tarife &amp; Pakete ansehen</a>
<a href="{{ route('veroeffentlichen') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3.5 text-[14px] font-semibold bg-brand text-white hover:bg-brand-deep transition-colors">{{ __('web.category.cta_submit') }} →</a>
<a href="{{ route('preise') }}" class="w-full inline-flex items-center justify-center px-[18px] py-3 text-[14px] font-semibold text-white border border-white/30 hover:bg-white/10 transition-colors">{{ __('web.publisher_cta.pricing') }}</a>
</div>
</div>
</div>

View file

@ -285,8 +285,8 @@
</div>
</section>
{{-- Abschluss mit vorhandener Editorial-Komponente. --}}
<x-web.newsletter-strip />
{{-- Newsletter-Sektion bewusst entfernt: kommt nachgelagert mit echtem
Double-Opt-in (siehe dev/release/entwicklungsplan-release.md). --}}
</main>
<x-web.site-footer />

View file

@ -4,8 +4,13 @@
$brand = config('domains.domains.presseecho.brand', []);
@endphp
@section('title', $brand['meta_title'] ?? 'Aktuelle Pressemitteilungen aus Wirtschaft & Industrie – presseecho')
@section('meta_description', $brand['meta_description'] ?? 'Redaktionell kuratierte Pressemitteilungen aus Wirtschaft und Industrie im DACH-Raum.')
{{-- DE-Meta kommt brand-spezifisch aus config/domains.php, EN aus den Übersetzungsdateien. --}}
@section('title', app()->getLocale() === 'de'
? ($brand['meta_title'] ?? 'Aktuelle Pressemitteilungen aus Wirtschaft & Industrie – presseecho')
: __('web.meta.home_title', ['brand' => ($brand['name'] ?? 'presseecho').($brand['accent'] ?? '')]))
@section('meta_description', app()->getLocale() === 'de'
? ($brand['meta_description'] ?? 'Qualitätsgeprüfte Pressemitteilungen aus Wirtschaft und Industrie im DACH-Raum.')
: __('web.meta.home_description'))
@section('hreflang')
<link rel="alternate" hreflang="de" href="{{ url('/de') }}">
@ -14,7 +19,7 @@
@endsection
@section('content')
<x-web.site-header :ticker="$tickerItems ?? []" />
<x-web.site-header />
<main class="bg-bg text-ink">
<x-web.focus-hero
@ -42,7 +47,9 @@
<x-web.pricing-teaser />
<x-web.newsletter-strip />
{{-- Newsletter-Sektion bewusst entfernt (Double-Opt-in nachgelagert,
siehe dev/release/entwicklungsplan-release.md) — stattdessen Veröffentlichen-CTA. --}}
<x-web.publish-band />
<x-web.quality-summary :stats="$homeStats ?? []" />
</main>

View file

@ -39,7 +39,7 @@
<p class="text-[16px] lg:text-[17px] leading-[1.55] text-ink-2 mt-7 m-0 max-w-[560px]">
<x-web.brand-mark brand="pressekonto" :serif="false" /> ist der gemeinsame Publisher-Bereich für
unsere beiden Pressefachportale. Pressemitteilungen schreiben, redaktionell prüfen lassen, auf
unsere beiden Pressefachportale. Pressemitteilungen schreiben, automatisiert prüfen lassen, auf
beiden Reichweiten veröffentlichen — und Mitteilungen, Newsrooms und Abrechnung an einem Ort
verwalten.
</p>
@ -234,7 +234,7 @@
Pressemitteilungen auf beiden Portalen
</h3>
<p class="text-[13.5px] leading-[1.6] text-ink-2 mt-3 m-0">
Eine Mitteilung schreiben, redaktionell prüfen lassen, auf <x-web.brand-mark brand="presseecho"
Eine Mitteilung schreiben, Inhaltsprüfung durchlaufen lassen, auf <x-web.brand-mark brand="presseecho"
:serif="false" /> und <x-web.brand-mark brand="businessportal24" :serif="false" />
gleichzeitig veröffentlichen. Vorschau und Qualitäts-Checkliste inklusive.
</p>
@ -291,7 +291,7 @@
Aufrufe, Status und Abrechnung zentral
</h3>
<p class="text-[13.5px] leading-[1.6] text-ink-2 mt-3 m-0">
Aufrufe je Mitteilung über beide Portale. Prüf-Status und redaktionelles Feedback direkt an der
Aufrufe je Mitteilung über beide Portale. Prüf-Status und Feedback direkt an der
Mitteilung, Buchungen und Rechnungen zentral im Konto.
</p>
<ul class="mt-5 space-y-1.5 text-[12.5px] text-ink-3 list-none p-0">
@ -326,8 +326,9 @@
</div>
<div class="text-[16.5px] font-semibold text-ink tracking-[-0.2px] mb-2">Registrieren</div>
<p class="text-[12.5px] text-ink-2 leading-[1.55] m-0">
Konto in unter zwei Minuten anlegen — mit E-Mail und Passwort oder Google-Konto. Nach
Bestätigung Ihrer E-Mail-Adresse ist das Konto für beide Portale freigeschaltet.
Konto in unter zwei Minuten anlegen — mit E-Mail und Passwort, Anmeldung wahlweise
auch passwortlos per Magic-Link. Nach Bestätigung Ihrer E-Mail-Adresse ist das Konto
für beide Portale freigeschaltet.
</p>
</li>
<li class="relative px-7 py-7 border-r border-b lg:border-b-0 border-bg-rule">
@ -539,7 +540,7 @@
</h2>
<p class="text-[14.5px] text-ink-2 leading-[1.55] m-0 mt-4 max-w-[760px]">
<x-web.brand-mark brand="pressekonto" :serif="false" /> ist nicht „irgendein Tool" — es ist die
zentrale Plattform für unsere beiden redaktionell geführten Pressefachportale. Jedes Portal hat einen
zentrale Plattform für unsere beiden Pressefachportale. Jedes Portal hat einen
eigenen Charakter, eigene Leserschaft und eigene Themen-Schwerpunkte.
</p>
</header>
@ -564,7 +565,7 @@
<div class="px-7 py-7">
<p class="text-[13.5px] leading-[1.6] text-ink-2 m-0">
Themen-Sammlung und Langzeit-Archiv für Pressemitteilungen aus DACH. Editorial-Charakter,
Themen-Tiefe, redaktionell erschlossen — der Ort, an dem eine Mitteilung über Jahre auffindbar
Themen-Tiefe, nach Branchen erschlossen — der Ort, an dem eine Mitteilung über Jahre auffindbar
bleibt.
</p>
<hr class="rule my-5" />
@ -577,7 +578,7 @@
<div>
<div class="font-mono text-[18px] font-semibold text-ink leading-none tabular-nums">
{{ $fmtCount($hubStats['categories']) }} Branchen</div>
<div class="text-[11px] text-ink-3 mt-1">redaktionell erschlossen</div>
<div class="text-[11px] text-ink-3 mt-1">nach Branchen erschlossen</div>
</div>
</div>
<a href="{{ config('domains.domain_presseecho_url') }}"
@ -797,7 +798,7 @@
</svg>
</summary>
<div class="pb-5 text-[13.5px] text-ink-2 leading-[1.65] max-w-[640px]">
Nach der redaktionellen Freigabe geht Ihre Mitteilung sofort live — werktags in der Regel
Nach bestandener Inhaltsprüfung geht Ihre Mitteilung sofort live — werktags in der Regel
noch am selben Tag. Alternativ legen Sie einen Wunschtermin fest: Dann erscheint die
Mitteilung automatisch zum geplanten Zeitpunkt, geprüft und freigegeben ist sie bereits davor.
</div>

View file

@ -3,17 +3,15 @@
@php
use Illuminate\Support\Str;
\Carbon\Carbon::setLocale('de');
$company = $release->company;
$categoryTranslation = $release->category?->translations?->firstWhere('locale', 'de')
$categoryTranslation = $release->category?->translations?->firstWhere('locale', app()->getLocale())
?? $release->category?->translations?->first();
$categoryName = $categoryTranslation?->name;
$categorySlug = $categoryTranslation?->slug;
$categoryHref = $categorySlug ? route('kategorie', ['slug' => $categorySlug]) : route('web.home');
$parentTranslation = $release->category?->parent?->translations?->firstWhere('locale', 'de')
$parentTranslation = $release->category?->parent?->translations?->firstWhere('locale', app()->getLocale())
?? $release->category?->parent?->translations?->first();
$parentName = $parentTranslation?->name;
$parentSlug = $parentTranslation?->slug;
@ -38,9 +36,9 @@
$companyName = $company?->name;
$companyInitial = $companyName ? mb_strtoupper(mb_substr($companyName, 0, 1)) : '·';
$companyHref = $company?->slug ? route('newsrooms').'#'.$company->slug : route('newsrooms');
$companyHref = $company?->slug ? route('newsroom', ['slug' => $company->slug]) : route('newsrooms');
$countryNames = ['DE' => 'Deutschland', 'AT' => 'Österreich', 'CH' => 'Schweiz'];
$countryNames = ['DE' => __('web.countries.de'), 'AT' => __('web.countries.at'), 'CH' => __('web.countries.ch')];
$companyCountry = $company?->country_code ? ($countryNames[strtoupper($company->country_code)] ?? null) : null;
$boilerplate = filled($release->boilerplate_override) ? $release->boilerplate_override : $company?->boilerplate;
@ -84,8 +82,8 @@
<article>
{{-- Breadcrumbs --}}
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 pt-7">
<nav class="flex flex-wrap gap-2 text-[11.5px] text-ink-3 mb-2 font-mono tracking-wide" aria-label="Brotkrumen">
<a href="{{ route('web.home') }}" class="cursor-pointer hover:text-ink transition-colors">Startseite</a>
<nav class="flex flex-wrap gap-2 text-[11.5px] text-ink-3 mb-2 font-mono tracking-wide" aria-label="{{ __('web.detail.breadcrumbs') }}">
<a href="{{ route('web.home') }}" class="cursor-pointer hover:text-ink transition-colors">{{ __('web.nav.home') }}</a>
<span aria-hidden="true">/</span>
@if ($parentName)
<a href="{{ $parentHref }}" class="cursor-pointer hover:text-ink transition-colors">{{ $parentName }}</a>
@ -95,7 +93,7 @@
<a href="{{ $categoryHref }}" class="cursor-pointer text-brand hover:text-brand-deep transition-colors">{{ $categoryName }}</a>
<span aria-hidden="true">/</span>
@endif
<span class="text-ink-2">Pressemitteilung</span>
<span class="text-ink-2">{{ __('web.detail.press_release') }}</span>
</nav>
</div>
@ -105,7 +103,7 @@
@if ($embargoAt)
<div class="flex items-center gap-2.5 mb-3.5 flex-wrap">
<span class="text-[9.5px] font-bold tracking-[0.18em] uppercase text-brand px-2.5 py-[3px] border border-brand font-mono">
● Embargo aufgehoben
● {{ __('web.detail.embargo_lifted') }}
</span>
<span class="text-[11px] text-ink-3 font-mono">{{ $embargoAt->translatedFormat('j. F Y, H:i') }}</span>
</div>
@ -116,7 +114,7 @@
<a href="{{ $categoryHref }}" class="bp-cat cursor-pointer hover:text-brand-deep transition-colors">{{ $categoryName }}</a>
<span class="w-1 h-1 rounded-full bg-ink-4" aria-hidden="true"></span>
@endif
<span class="text-[11px] text-ink-3 italic font-serif">Für Wirtschaftsjournalisten</span>
<span class="text-[11px] text-ink-3 italic font-serif">{{ __('web.detail.audience') }}</span>
</div>
<h1 class="font-serif text-[32px] sm:text-[40px] lg:text-[48px] font-semibold m-0 mb-[22px] tracking-[-0.8px] leading-[1.1] max-w-[980px]" style="text-wrap:balance;">
@ -139,10 +137,10 @@
@endif
@if ($publishedAt)
<time datetime="{{ $publishedAt->toIso8601String() }}" class="font-mono text-[11.5px] text-ink-3">
{{ $publishedAt->translatedFormat('j. F Y') }} · {{ $publishedAt->format('H:i') }} Uhr
{{ $publishedAt->translatedFormat('j. F Y') }} · {{ __('web.detail.time_at', ['time' => $publishedAt->format('H:i')]) }}
</time>
@endif
<span class="font-mono text-[11.5px] text-ink-3">{{ $readTime }} Min. Lesezeit · {{ number_format($wordCount, 0, ',', '.') }} Wörter</span>
<span class="font-mono text-[11.5px] text-ink-3">{{ __('web.shared.read_time', ['minutes' => $readTime]) }} · {{ __('web.detail.words', ['count' => number_format($wordCount, 0, ',', '.')]) }}</span>
@if ($companyCountry)
<span class="inline-flex items-center gap-1.5 font-mono text-[11.5px] text-ink-3">
<svg width="11" height="11" viewBox="0 0 14 14" fill="none" aria-hidden="true"><path d="M7 1a5 5 0 015 5c0 4-5 7-5 7s-5-3-5-7a5 5 0 015-5z" stroke="currentColor" stroke-width="1.3" fill="none" /><circle cx="7" cy="6" r="1.5" fill="currentColor" /></svg>
@ -152,12 +150,12 @@
@if ($isRecommended)
<span class="inline-flex items-center gap-1.5 px-2 py-[3px] text-[9.5px] font-bold tracking-[0.14em] uppercase text-brand bg-brand/[0.04] border border-brand/30 font-mono cursor-help"
title="Diese Pressemitteilung wurde von der Redaktion empfohlen — basierend auf Quellenqualität, Verifizierungsstatus und redaktioneller Relevanz.">
title="{{ __('web.detail.recommended_hint') }}">
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M12 2l9 4v6c0 5-3.5 9-9 10-5.5-1-9-5-9-10V6z" stroke="currentColor" stroke-width="2" fill="none" />
<path d="M8 12l3 3 5-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
Redaktionsempfehlung
{{ __('web.detail.recommended') }}
</span>
@endif
</div>
@ -172,13 +170,13 @@
class="absolute inset-0 h-full w-full object-cover" loading="eager">
@else
<span class="relative text-[10px] font-mono tracking-wider uppercase text-white/50">
{{ $companyName ? 'Bild · Pressefoto '.$companyName : 'Bild · Pressefoto' }} (16:9)
{{ $companyName ? __('web.detail.image_placeholder_company', ['company' => $companyName]) : __('web.detail.image_placeholder') }} (16:9)
</span>
@endif
</div>
@if ($imageCaption || $imageCredit)
<div class="text-[11.5px] text-ink-3 mt-2.5 italic max-w-[720px]">
{{ $imageCaption }}@if ($imageCaption && $imageCredit) · @endif@if ($imageCredit)<span class="not-italic">Foto: {{ $imageCredit }}</span>@endif
{{ $imageCaption }}@if ($imageCaption && $imageCredit) · @endif@if ($imageCredit)<span class="not-italic">{{ __('web.detail.photo') }}: {{ $imageCredit }}</span>@endif
</div>
@endif
</section>
@ -193,45 +191,20 @@
@if (filled($boilerplate))
<div class="mt-9 pt-5 border-t border-bg-rule-strong max-w-[680px]">
<div class="eyebrow muted text-[9.5px] mb-2.5">Über das Unternehmen</div>
<div class="eyebrow muted text-[9.5px] mb-2.5">{{ __('web.detail.about_company') }}</div>
<p class="text-[13px] leading-[1.6] text-ink-3 m-0 max-w-[620px]">{{ $boilerplate }}</p>
</div>
@endif
{{-- Inline Ad --}}
<div class="my-8 max-w-[680px]">
<div class="flex items-center gap-2.5 mb-2.5">
<span class="h-px bg-bg-rule-strong flex-1"></span>
<span class="text-[9px] font-bold tracking-[0.22em] text-ink-on-dark-muted uppercase font-mono">Anzeige</span>
<span class="h-px bg-bg-rule-strong flex-1"></span>
</div>
<a href="#" rel="sponsored nofollow" class="grid px-[22px] py-5 bg-bg-card-warm items-center gap-[22px] cursor-pointer hover:bg-bg-card-warm-hover transition-colors" style="grid-template-columns:120px 1fr;">
<div class="aspect-square bg-white hatch-light flex items-center justify-center text-[9px] text-ink-on-dark-muted font-mono">LOGO</div>
<div>
<div class="text-[9.5px] font-bold tracking-[0.16em] uppercase mb-1.5 text-card-warm-cat">Partner · Branchen-Whitepaper</div>
<h3 class="font-serif text-[18px] leading-[1.3] m-0 mb-2 font-semibold tracking-[-0.2px] text-card-warm-title">
CO₂-Reporting nach CSRD: Was Industriebetriebe jetzt automatisieren müssen
</h3>
<div class="text-[12px] leading-[1.5] mb-2.5 text-card-warm-cat">Whitepaper · 32 Seiten · Praxisleitfaden für Mittelstand und Konzerne</div>
<span class="text-[12px] font-semibold underline text-card-warm-title">Studie kostenfrei anfordern →</span>
</div>
</a>
<div class="flex items-center gap-2.5 mt-2.5">
<span class="h-px bg-bg-rule-strong flex-1"></span>
<span class="text-[9px] font-bold tracking-[0.22em] text-ink-on-dark-muted uppercase font-mono">Ende Anzeige</span>
<span class="h-px bg-bg-rule-strong flex-1"></span>
</div>
</div>
{{-- Pressekontakt --}}
@if ($contact)
<div class="mt-8 px-5 sm:px-7 py-6 bg-white border border-bg-rule-strong max-w-[680px]">
<div class="eyebrow mb-3 text-[10.5px]">Pressekontakt</div>
<div class="eyebrow mb-3 text-[10.5px]">{{ __('web.detail.press_contact') }}</div>
<div class="flex gap-1.5 items-center mb-1 flex-wrap">
<strong class="font-serif text-[19px] font-semibold tracking-[-0.2px]">{{ $contactName ?: $companyName }}</strong>
@if ($publisherVerified)
<span title="Verifizierter Publisher — Identität und Domain bestätigt" class="inline-flex items-center text-verify-border flex-shrink-0">
<span title="{{ __('web.detail.verified_hint') }}" class="inline-flex items-center text-verify-border flex-shrink-0">
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M12 1l2.5 3 3.8-.4-.5 3.8L21 9l-2.6 2.5L19 15l-3.8.4L12 19l-2.5-3.6L5.7 15 5.6 11.4 3 9l2.5-1.6L4.7 4 8.5 4z" fill="currentColor" />
<path d="M7.5 12l3 3 6-6" stroke="white" stroke-width="2.2" fill="none" stroke-linecap="round" stroke-linejoin="round" />
@ -277,16 +250,16 @@
{{-- Inhalt melden (T13): sichtbar an jeder Mitteilung, nicht nur in der Sidebar --}}
<div class="mt-8 pt-4 border-t border-bg-rule flex flex-wrap items-center gap-x-4 gap-y-1.5 text-[11.5px] text-ink-3">
<span>Sie haben ein rechtliches Anliegen zu dieser Mitteilung?</span>
<span>{{ __('web.detail.legal_question') }}</span>
<a href="{{ route('legal-request.create', ['slug' => $release->slug, 'type' => 'report']) }}" class="inline-flex items-center gap-1.5 text-ink-2 underline underline-offset-2 hover:text-ink transition-colors">
<svg width="12" height="12" viewBox="0 0 14 14" class="flex-shrink-0" aria-hidden="true"><circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-width="1.3" fill="none" /><path d="M7 4v3.5M7 9.5v.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" /></svg>
Inhalt melden
{{ __('web.detail.report_content') }}
</a>
<a href="{{ route('legal-request.create', ['slug' => $release->slug, 'type' => 'dsgvo']) }}" class="inline-flex items-center gap-1.5 text-ink-2 underline underline-offset-2 hover:text-ink transition-colors">
<svg width="12" height="12" viewBox="0 0 14 14" class="flex-shrink-0" aria-hidden="true"><path d="M7 1l5 2v4c0 3-2.2 5.2-5 6-2.8-.8-5-3-5-6V3z" stroke="currentColor" stroke-width="1.3" fill="none" stroke-linejoin="round" /></svg>
Eigene Daten entfernen
{{ __('web.detail.remove_data') }}
</a>
<span class="text-ink-4">Meldungen sind kostenlos.</span>
<span class="text-ink-4">{{ __('web.detail.reports_free') }}</span>
</div>
</div>
@ -295,7 +268,7 @@
{{-- Publisher --}}
@if ($companyName)
<div class="p-4 bg-white border border-bg-rule-strong">
<div class="eyebrow muted text-[9.5px] mb-3">Veröffentlicht von</div>
<div class="eyebrow muted text-[9.5px] mb-3">{{ __('web.detail.published_by') }}</div>
<div class="flex gap-3 items-start mb-3">
<span class="w-11 h-11 bg-black text-white inline-flex items-center justify-center text-[20px] font-bold font-serif flex-shrink-0">{{ $companyInitial }}</span>
<div class="min-w-0">
@ -308,18 +281,17 @@
@if ($publisherVerified)
<div class="flex items-center gap-2 px-2.5 py-2 mb-3 bg-verify-bg border border-verify-border text-verify-ink cursor-help"
title="Identität und Domain durch {{ $brandLabel }} bestätigt">
title="{{ __('web.detail.verified_by', ['brand' => $brandLabel]) }}">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" class="text-verify-border flex-shrink-0" aria-hidden="true">
<path d="M12 1l2.5 3 3.8-.4-.5 3.8L21 9l-2.6 2.5L19 15l-3.8.4L12 19l-2.5-3.6L5.7 15 5.6 11.4 3 9l2.5-1.6L4.7 4 8.5 4z" fill="currentColor" />
<path d="M7.5 12l3 3 6-6" stroke="white" stroke-width="2.2" fill="none" stroke-linecap="round" stroke-linejoin="round" />
</svg>
<span class="text-[11.5px] font-semibold">Verifizierter Publisher</span>
<span class="text-[11.5px] font-semibold">{{ __('web.detail.verified_publisher') }}</span>
</div>
@endif
<div class="pt-3 border-t border-bg-rule flex flex-col gap-2">
<button type="button" class="px-2.5 py-2 text-[11.5px] font-semibold bg-ink text-white hover:bg-black transition-colors cursor-pointer">+ Newsroom folgen</button>
<a href="{{ $companyHref }}" class="text-[11.5px] text-ink-2 text-center py-1.5 underline underline-offset-2 cursor-pointer hover:text-ink transition-colors">Alle Mitteilungen →</a>
<a href="{{ $companyHref }}" class="px-2.5 py-2 text-center text-[11.5px] font-semibold bg-ink text-white hover:bg-black transition-colors cursor-pointer">{{ __('web.detail.to_newsroom') }} →</a>
</div>
</div>
@endif
@ -331,7 +303,7 @@
copied: false,
copy() { navigator.clipboard?.writeText(this.url).then(() => { this.copied = true; setTimeout(() => this.copied = false, 2000); }); }
}">
<div class="eyebrow muted text-[9.5px] mb-2.5">Teilen</div>
<div class="eyebrow muted text-[9.5px] mb-2.5">{{ __('web.detail.share') }}</div>
<div class="grid grid-cols-2 gap-1.5">
<a :href="`https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`" target="_blank" rel="noopener" class="inline-flex items-center gap-[7px] px-2.5 py-2 text-[11.5px] font-medium bg-white border border-bg-rule-strong text-ink hover:bg-bg-elev transition-colors cursor-pointer">
<svg width="13" height="13" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 6h2.5v8H3V6zm1.25-3a1.25 1.25 0 110 2.5 1.25 1.25 0 010-2.5zM7 6h2.4v1.1c.4-.7 1.3-1.3 2.6-1.3 2.7 0 3 1.7 3 3.9V14h-2.5v-3.7c0-.9 0-2-1.3-2s-1.5 1-1.5 2V14H7V6z" fill="currentColor" /></svg>
@ -343,11 +315,11 @@
</a>
<a :href="`mailto:?subject=${encodeURIComponent(title)}&body=${encodeURIComponent(url)}`" class="inline-flex items-center gap-[7px] px-2.5 py-2 text-[11.5px] font-medium bg-white border border-bg-rule-strong text-ink hover:bg-bg-elev transition-colors cursor-pointer">
<svg width="13" height="13" viewBox="0 0 16 16" aria-hidden="true"><rect x="2" y="3" width="12" height="10" stroke="currentColor" stroke-width="1.3" fill="none" /><path d="M2 4l6 4 6-4" stroke="currentColor" stroke-width="1.3" fill="none" /></svg>
E-Mail
{{ __('web.detail.email') }}
</a>
<button type="button" @click="copy()" class="inline-flex items-center gap-[7px] px-2.5 py-2 text-[11.5px] font-medium bg-white border border-bg-rule-strong text-ink hover:bg-bg-elev transition-colors cursor-pointer">
<svg width="13" height="13" viewBox="0 0 16 16" aria-hidden="true"><path d="M6 9l4-4M5 4h2a3 3 0 010 6h-1M11 12H9a3 3 0 010-6h1" stroke="currentColor" stroke-width="1.3" fill="none" stroke-linecap="round" /></svg>
<span x-text="copied ? 'Kopiert!' : 'Link kopieren'">Link kopieren</span>
<span x-text="copied ? @js(__('web.detail.copied')) : @js(__('web.detail.copy_link'))">{{ __('web.detail.copy_link') }}</span>
</button>
</div>
</div>
@ -355,7 +327,7 @@
{{-- Schlagwörter --}}
@if ($keywords->isNotEmpty())
<div>
<div class="eyebrow muted text-[9.5px] mb-2.5">Schlagwörter</div>
<div class="eyebrow muted text-[9.5px] mb-2.5">{{ __('web.detail.keywords') }}</div>
<div class="flex flex-wrap gap-[5px]">
@foreach ($keywords as $keyword)
<a href="{{ route('suche', ['q' => $keyword]) }}" class="px-2.5 py-1 text-[11px] font-medium bg-white border border-bg-rule-strong text-ink-2 hover:text-ink transition-colors cursor-pointer">{{ $keyword }}</a>
@ -364,40 +336,26 @@
</div>
@endif
{{-- Newsletter --}}
<div class="p-4 bg-ink text-white">
<div class="eyebrow on-dark text-[9.5px] mb-2">Newsletter</div>
<h4 class="font-serif text-[17px] font-semibold m-0 mb-2 leading-[1.25]">
{{ $categoryName ?: 'Wirtschaft' }} · ab Score 80
</h4>
<p class="text-[11.5px] text-white/70 leading-[1.5] m-0 mb-3">
Höchstens 2 Mails pro Woche. Nur Meldungen ab Content-Score 80.
</p>
<a href="#newsletter" class="block text-center w-full py-2.5 text-[12px] font-semibold bg-brand hover:bg-brand-deep text-white transition-colors cursor-pointer">Abonnieren →</a>
</div>
{{-- Newsletter-Box bewusst entfernt: kommt nachgelagert mit echtem
Double-Opt-in (siehe dev/release/entwicklungsplan-release.md). --}}
{{-- Weiterführend --}}
<div>
<div class="eyebrow muted text-[9.5px] mb-2.5">Weiterführend</div>
<div class="eyebrow muted text-[9.5px] mb-2.5">{{ __('web.detail.further') }}</div>
<div class="flex flex-col border border-bg-rule-strong bg-white">
<a href="#" class="flex items-center gap-2.5 px-3 py-2.5 text-[12px] text-ink-2 hover:bg-bg-elev transition-colors cursor-pointer">
<svg width="13" height="13" viewBox="0 0 14 14" class="text-ink-3 flex-shrink-0" aria-hidden="true"><path d="M2 1h7l3 3v9H2z" stroke="currentColor" stroke-width="1.3" fill="none" /><path d="M9 1v3h3" stroke="currentColor" stroke-width="1.3" fill="none" /></svg>
<span class="flex-1">Permalink &amp; Zitiervorschlag</span>
<svg width="9" height="9" viewBox="0 0 12 12" fill="none" class="text-ink-4" aria-hidden="true"><path d="M4 2l4 4-4 4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" /></svg>
</a>
<a href="#" class="flex items-center gap-2.5 px-3 py-2.5 text-[12px] text-ink-2 border-t border-bg-rule hover:bg-bg-elev transition-colors cursor-pointer">
<button type="button" onclick="window.print()" class="flex items-center gap-2.5 px-3 py-2.5 text-[12px] text-ink-2 hover:bg-bg-elev transition-colors cursor-pointer text-left">
<svg width="13" height="13" viewBox="0 0 14 14" class="text-ink-3 flex-shrink-0" aria-hidden="true"><path d="M2 4h10v8H2zM2 4V2h10v2" stroke="currentColor" stroke-width="1.3" fill="none" /></svg>
<span class="flex-1">Drucken &amp; PDF</span>
<span class="flex-1">{{ __('web.detail.print') }}</span>
<svg width="9" height="9" viewBox="0 0 12 12" fill="none" class="text-ink-4" aria-hidden="true"><path d="M4 2l4 4-4 4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" /></svg>
</a>
</button>
<a href="{{ route('legal-request.create', ['slug' => $release->slug, 'type' => 'report']) }}" class="flex items-center gap-2.5 px-3 py-2.5 text-[12px] text-ink-2 border-t border-bg-rule hover:bg-bg-elev transition-colors cursor-pointer">
<svg width="13" height="13" viewBox="0 0 14 14" class="text-ink-3 flex-shrink-0" aria-hidden="true"><circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-width="1.3" fill="none" /><path d="M7 4v3.5M7 9.5v.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" /></svg>
<span class="flex-1">Pressemitteilung melden</span>
<span class="flex-1">{{ __('web.detail.report_release') }}</span>
<svg width="9" height="9" viewBox="0 0 12 12" fill="none" class="text-ink-4" aria-hidden="true"><path d="M4 2l4 4-4 4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" /></svg>
</a>
<a href="{{ route('legal-request.create', ['slug' => $release->slug, 'type' => 'dsgvo']) }}" class="flex items-center gap-2.5 px-3 py-2.5 text-[12px] text-ink-2 border-t border-bg-rule hover:bg-bg-elev transition-colors cursor-pointer">
<svg width="13" height="13" viewBox="0 0 14 14" class="text-ink-3 flex-shrink-0" aria-hidden="true"><path d="M7 1l5 2v4c0 3-2.2 5.2-5 6-2.8-.8-5-3-5-6V3z" stroke="currentColor" stroke-width="1.3" fill="none" stroke-linejoin="round" /></svg>
<span class="flex-1">Datenschutz &amp; Persönlichkeitsrecht</span>
<span class="flex-1">{{ __('web.detail.privacy_rights') }}</span>
<svg width="9" height="9" viewBox="0 0 12 12" fill="none" class="text-ink-4" aria-hidden="true"><path d="M4 2l4 4-4 4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" /></svg>
</a>
</div>
@ -411,26 +369,26 @@
<div class="grid grid-cols-1 md:grid-cols-2 gap-10">
@if ($companyReleases->isNotEmpty())
<div>
<h3 class="font-serif text-[20px] font-semibold m-0 mb-1 tracking-[-0.2px]">Mehr von {{ $companyName }}</h3>
<div class="text-[11.5px] text-ink-3 mb-3.5">Aktuelle Mitteilungen aus diesem Newsroom</div>
<h3 class="font-serif text-[20px] font-semibold m-0 mb-1 tracking-[-0.2px]">{{ __('web.detail.more_from', ['company' => $companyName]) }}</h3>
<div class="text-[11.5px] text-ink-3 mb-3.5">{{ __('web.detail.more_from_sub') }}</div>
<hr class="rule-strong mb-1" />
@foreach ($companyReleases as $companyRelease)
<x-web.feed-item :release="$companyRelease" />
@endforeach
<a href="{{ $companyHref }}" class="block mt-3.5 text-[12.5px] font-semibold text-brand hover:text-brand-deep transition-colors cursor-pointer">Alle Mitteilungen von {{ $companyName }} →</a>
<a href="{{ $companyHref }}" class="block mt-3.5 text-[12.5px] font-semibold text-brand hover:text-brand-deep transition-colors cursor-pointer">{{ __('web.detail.all_from', ['company' => $companyName]) }} →</a>
</div>
@endif
@if ($relatedReleases->isNotEmpty())
<div>
<h3 class="font-serif text-[20px] font-semibold m-0 mb-1 tracking-[-0.2px]">Verwandte Meldungen</h3>
<div class="text-[11.5px] text-ink-3 mb-3.5">Reaktionen, ähnliche Themen, Branchenkontext</div>
<h3 class="font-serif text-[20px] font-semibold m-0 mb-1 tracking-[-0.2px]">{{ __('web.detail.related') }}</h3>
<div class="text-[11.5px] text-ink-3 mb-3.5">{{ __('web.detail.related_sub') }}</div>
<hr class="rule-strong mb-1" />
@foreach ($relatedReleases as $relatedRelease)
<x-web.feed-item :release="$relatedRelease" />
@endforeach
@if ($categoryName)
<a href="{{ $categoryHref }}" class="block mt-3.5 text-[12.5px] font-semibold text-brand hover:text-brand-deep transition-colors cursor-pointer">Alle Meldungen aus {{ $categoryName }} →</a>
<a href="{{ $categoryHref }}" class="block mt-3.5 text-[12.5px] font-semibold text-brand hover:text-brand-deep transition-colors cursor-pointer">{{ __('web.detail.all_from_category', ['category' => $categoryName]) }} →</a>
@endif
</div>
@endif

View file

@ -6,8 +6,8 @@
$brandAccent = $brandConfig['accent'] ?? '24';
@endphp
@section('title', 'Pressemitteilungen durchsuchen – '.$brandName.$brandAccent)
@section('meta_description', 'Durchsuchen Sie das geprüfte Pressemitteilungs-Archiv nach Stichwort, Unternehmen und Branche – redaktionell geprüft und dauerhaft auffindbar im DACH-Raum.')
@section('title', __('web.search.meta_title', ['brand' => $brandName.$brandAccent]))
@section('meta_description', __('web.search.meta_description'))
@section('hreflang')
<link rel="alternate" hreflang="de" href="{{ url('/de/suche') }}">
@ -24,19 +24,19 @@
<div class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 py-2.5 flex items-center gap-2 text-[11.5px] text-ink-3">
<a href="{{ route('web.home') }}" class="hover:text-ink transition-colors">{{ $brandName }}{{ $brandAccent }}</a>
<span class="text-ink-4" aria-hidden="true">›</span>
<span class="text-ink font-semibold">Suche</span>
<span class="text-ink font-semibold">{{ __('web.header.search_eyebrow') }}</span>
</div>
</div>
{{-- Masthead --}}
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 pt-8 lg:pt-10">
<div class="max-w-[680px]">
<div class="eyebrow mb-3">Archiv-Suche</div>
<div class="eyebrow mb-3">{{ __('web.search.eyebrow') }}</div>
<h1 class="font-serif text-[36px] sm:text-[46px] lg:text-[50px] font-semibold m-0 mb-4 leading-[1.05] tracking-[-1px] text-ink text-balance">
Pressemitteilungen durchsuchen
{{ __('web.header.search_title') }}
</h1>
<p class="font-serif text-[16px] leading-[1.55] m-0 text-ink-2">
Stichwort, Unternehmen oder Branche – durchsuchen Sie das vollständige, redaktionell geprüfte Archiv.
{{ __('web.search.intro') }}
</p>
</div>
<hr class="rule-strong mt-8">

View file

@ -27,9 +27,10 @@
@section('title', 'Pressemitteilung veröffentlichen – '.$brandName.$brandAccent)
@section('meta_description', 'Pressemitteilungen geprüft veröffentlichen und dauerhaft auffindbar im Archiv. Faire Preise, keine Vertragsbindung – Einreichung über den zentralen Publisher-Bereich.')
{{-- Kein hreflang="en": Der Seiteninhalt liegt bisher nur auf Deutsch vor.
EN-Übersetzung der Langform-Seiten ist nachgelagert (siehe Release-Plan). --}}
@section('hreflang')
<link rel="alternate" hreflang="de" href="{{ url('/de/veroeffentlichen') }}">
<link rel="alternate" hreflang="en" href="{{ url('/en/veroeffentlichen') }}">
<link rel="alternate" hreflang="x-default" href="{{ url('/de/veroeffentlichen') }}">
@endsection
@ -48,7 +49,7 @@
<div class="hidden md:flex items-center gap-[18px]">
<span class="inline-flex items-center gap-1.5">
<svg width="11" height="11" viewBox="0 0 11 11" aria-hidden="true"><path d="M2 5.5l2.2 2.2L9 3" stroke="currentColor" class="text-ok" stroke-width="1.6" fill="none" stroke-linecap="round"/></svg>
<span>Redaktionell geprüft seit {{ $sinceYear }}</span>
<span>Qualitätsgeprüft seit {{ $sinceYear }}</span>
</span>
<span class="text-ink-4">·</span>
<a href="{{ route('hilfe') }}" class="text-ink-2 hover:text-ink transition-colors">Hilfe &amp; Support</a>
@ -229,8 +230,8 @@
<div class="grid grid-cols-1 md:grid-cols-3 gap-px bg-bg-rule border-y border-bg-rule-strong">
@foreach ([
['n' => '01', 'meta' => '≈ 2 Minuten', 't' => 'Konto anlegen', 'd' => 'Mit E-Mail und Passwort oder Google-Konto. Konto und Abrechnung liegen im zentralen Publisher-Bereich — ein Konto für beide Portale.'],
['n' => '02', 'meta' => 'werktags · innerhalb 24 h', 't' => 'Mitteilung einreichen', 'd' => 'Text, Bild, Ansprechpartner. Eine automatische Qualitätsprüfung läuft parallel zu einer kurzen redaktionellen Sichtung.'],
['n' => '01', 'meta' => '≈ 2 Minuten', 't' => 'Konto anlegen', 'd' => 'Mit E-Mail-Adresse und Passwort — Anmeldung wahlweise auch passwortlos per Magic-Link. Konto und Abrechnung liegen im zentralen Publisher-Bereich — ein Konto für beide Portale.'],
['n' => '02', 'meta' => 'werktags · innerhalb 24 h', 't' => 'Mitteilung einreichen', 'd' => 'Text, Bild, Ansprechpartner. Die automatisierte Inhaltsprüfung läuft direkt beim Einreichen mit.'],
['n' => '03', 'meta' => 'permanent · indexiert', 't' => 'Veröffentlichung', 'd' => 'Nach Freigabe online und im Archiv. Bei Bedarf jederzeit korrigierbar — die URL bleibt stabil, Verweise bestehen weiter.'],
] as $step)
<div class="bg-bg-elev px-7 pt-8 pb-9">
@ -291,7 +292,7 @@
Nicht geeignet sind reine Werbeanzeigen, SEO-Linkbuilding-Texte oder Inhalte ohne nachvollziehbaren Pressewert.
</h3>
<p class="mt-[18px] mb-0 text-[13.5px] leading-[1.6] text-ink-2">
Die redaktionelle Sichtung sichert den Charakter der Plattform. Mitteilungen, die diese Schwelle nicht
Die Inhaltsprüfung sichert den Charakter der Plattform. Mitteilungen, die diese Schwelle nicht
erreichen, werden mit einer kurzen Begründung zurückgegeben — meist mit einem konkreten Korrekturvorschlag.
</p>
<hr class="rule my-5" />
@ -382,7 +383,7 @@
<div class="grid items-start gap-10 lg:gap-16 grid-cols-1 lg:grid-cols-[1fr_1.6fr]">
<div class="lg:sticky lg:top-6 pt-2">
<p class="font-serif m-0 text-[16px] leading-[1.55] text-ink-2">Sie finden hier keine Antwort?</p>
<a href="mailto:{{ config('domains.domains.'.config('app.theme').'.brand.contact_email') ?? 'info@businessportal24.com' }}" class="mt-3.5 inline-flex items-center gap-1.5 text-[13.5px] font-medium text-brand border-b border-brand pb-0.5">Redaktion direkt anschreiben</a>
<a href="mailto:{{ config('domains.domains.'.config('app.theme').'.brand.contact_email') ?? 'info@businessportal24.com' }}" class="mt-3.5 inline-flex items-center gap-1.5 text-[13.5px] font-medium text-brand border-b border-brand pb-0.5">Direkt Kontakt aufnehmen</a>
<div class="mt-3.5 text-[12px] text-ink-3 leading-[1.55]">Antwort werktags per E-Mail</div>
</div>
@ -419,7 +420,7 @@
<div class="eyebrow mb-3.5 text-[10.5px] text-brand-soft">Mitteilung einreichen · Schritt eins</div>
<h2 class="font-serif m-0 text-[34px] lg:text-[48px] font-semibold leading-[1.08] text-ink-on-dark max-w-[700px] tracking-[-0.9px] text-balance">Bereit, Ihre Mitteilung einzureichen?</h2>
<p class="font-serif mt-5 mb-0 text-[16px] lg:text-[17px] leading-[1.55] text-ink-on-dark-2 max-w-[580px]">
Konto in zwei Minuten anlegen, Text und Bild einreichen, nach redaktioneller Sichtung veröffentlicht.
Konto in zwei Minuten anlegen, Text und Bild einreichen, nach bestandener Inhaltsprüfung veröffentlicht.
Einmaliges Konto — beide Portale (businessportal24 &amp; presseecho.de) nutzbar.
</p>
</div>