x-web.transparency-nav (Label + drei Chips) statt der kleinen Zeile unter dem USt-Hinweis; Komponente kennt `current` fuer spaetere Wiederverwendung. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
300 lines
19 KiB
PHP
300 lines
19 KiB
PHP
@extends('web.layouts.web-master')
|
|
|
|
{{--
|
|
Öffentliche Preise-/Tarifseite (Editorial-Design).
|
|
Reihenfolge laut Vorgabe: 1) Abo-Tarife 2) Einzel-Pressemitteilung 3) Add-ons.
|
|
|
|
Datenquellen (alles aus dem System, nichts hartkodiert):
|
|
- Abos: Plan::active() -> $plans
|
|
- Einzel-PM: config('billing.single_pm_price_cents') -> $singlePmPriceCents
|
|
- Add-ons: config('credits.*') -> $extraPm, $boost, $proofPdf, $creditPacks
|
|
- Depublizieren: config('billing.depublication_price_cents') -> $depublicationPriceCents (Direktkauf in Euro)
|
|
|
|
Inhalte/Texte: lang/de/pricing.php + lang/en/pricing.php (Schlüssel pricing.*).
|
|
|
|
HINWEIS (bewusst teilweise mit Kommentaren): Die korrespondierende In-App-Buchungs-
|
|
seite (resources/views/livewire/customer/bookings.blade.php) wird gerade überarbeitet.
|
|
Buchungs-CTAs verlinken vorerst auf den Veröffentlichen-Funnel; die Deep-Links in den
|
|
Checkout/zur Registrierung mit Tarif-Vorauswahl folgen, sobald der Flow final ist.
|
|
--}}
|
|
|
|
@section('title', __('pricing.meta_title'))
|
|
@section('meta_description', __('pricing.meta_description'))
|
|
|
|
@section('hreflang')
|
|
<link rel="alternate" hreflang="de" href="{{ url('/de/preise') }}">
|
|
<link rel="alternate" hreflang="en" href="{{ url('/en/preise') }}">
|
|
<link rel="alternate" hreflang="x-default" href="{{ url('/de/preise') }}">
|
|
@endsection
|
|
|
|
@php
|
|
// 1 Credit = 1 €. Preise sind ganzzahlige Euro -> ohne Nachkommastellen,
|
|
// sonst mit zwei Stellen (deutsche Schreibweise).
|
|
$euro = static fn (int $cents): string => number_format($cents / 100, $cents % 100 === 0 ? 0 : 2, ',', '.');
|
|
$popularPlan = 'business';
|
|
$submitHref = route('veroeffentlichen');
|
|
@endphp
|
|
|
|
@section('content')
|
|
<x-web.site-header />
|
|
|
|
<main class="bg-bg text-ink">
|
|
{{-- ============================================================
|
|
MASTHEAD
|
|
============================================================ --}}
|
|
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 pt-8 lg:pt-10">
|
|
<x-web.transparency-nav class="mb-6" />
|
|
<div class="eyebrow mb-3">{{ __('pricing.eyebrow') }}</div>
|
|
<h1 class="font-serif text-[36px] sm:text-[48px] lg:text-[52px] font-semibold m-0 leading-[1.02] tracking-[-1.2px] text-ink">
|
|
{{ __('pricing.headline') }}
|
|
</h1>
|
|
<p class="font-serif text-[16px] leading-[1.55] m-0 mt-4 max-w-[680px] text-ink-2">
|
|
{{ __('pricing.intro') }}
|
|
</p>
|
|
</section>
|
|
|
|
{{-- ============================================================
|
|
1) ABO-TARIFE (Daten: Plan::active())
|
|
============================================================ --}}
|
|
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-10">
|
|
<header class="flex items-baseline justify-between mb-4 flex-wrap gap-3">
|
|
<div>
|
|
<div class="eyebrow muted mb-1">{{ __('pricing.plans.eyebrow') }}</div>
|
|
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">{{ __('pricing.plans.title') }}</h2>
|
|
</div>
|
|
<p class="text-[12.5px] text-ink-3 m-0 max-w-[360px]">{{ __('pricing.plans.subtitle') }}</p>
|
|
</header>
|
|
<hr class="rule-strong">
|
|
|
|
@if ($plans->isNotEmpty())
|
|
<div class="grid gap-px bg-bg-rule border border-bg-rule grid-cols-1 sm:grid-cols-2 lg:grid-cols-4">
|
|
@foreach ($plans as $plan)
|
|
@php
|
|
$isPopular = $plan->slug === $popularPlan;
|
|
$hasMonthly = (int) $plan->monthly_price_cents > 0;
|
|
@endphp
|
|
<div class="relative flex flex-col p-6 bg-bg {{ $isPopular ? 'ring-1 ring-inset ring-brand' : '' }}">
|
|
@if ($isPopular)
|
|
<span class="absolute top-0 right-0 inline-flex items-center px-2.5 py-1 text-[9.5px] font-bold uppercase tracking-[0.14em] text-white bg-brand">
|
|
{{ __('pricing.plans.popular') }}
|
|
</span>
|
|
@endif
|
|
|
|
<div class="eyebrow muted mb-2">{{ $plan->name }}</div>
|
|
|
|
<div class="flex items-baseline gap-1.5 mb-1">
|
|
<span class="font-serif text-[34px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $euro((int) $plan->monthly_price_cents) }} €</span>
|
|
@if ($hasMonthly)
|
|
<span class="text-[12px] text-ink-3">{{ __('pricing.plans.per_month') }}</span>
|
|
@endif
|
|
</div>
|
|
|
|
@if ($hasMonthly && (int) $plan->yearly_price_cents > 0)
|
|
<div class="text-[11.5px] text-ink-3 mb-4">
|
|
{{ __('pricing.plans.yearly_hint', ['price' => $euro((int) $plan->yearly_price_cents)]) }}
|
|
</div>
|
|
@else
|
|
<div class="mb-4"></div>
|
|
@endif
|
|
|
|
<ul class="space-y-2 mb-6 flex-1 list-none p-0 m-0 text-[12.5px] text-ink-2">
|
|
<li class="flex items-baseline gap-2">
|
|
<span class="font-mono text-[12px] font-semibold text-ink">{{ $plan->press_release_quota }}</span>
|
|
<span>{{ __('pricing.plans.quota', ['count' => $plan->press_release_quota]) }}</span>
|
|
</li>
|
|
<li class="flex items-baseline gap-2">
|
|
@if ($plan->daily_limit !== null)
|
|
<span class="font-mono text-[12px] font-semibold text-ink">{{ $plan->daily_limit }}</span>
|
|
<span>{{ __('pricing.plans.daily_limit', ['count' => $plan->daily_limit]) }}</span>
|
|
@else
|
|
<span class="font-mono text-[12px] text-ink-3">∞</span>
|
|
<span class="text-ink-3">{{ __('pricing.plans.no_daily_limit') }}</span>
|
|
@endif
|
|
</li>
|
|
@forelse ($plan->benefitsList() as $benefit)
|
|
<li class="flex items-baseline gap-2 text-ink-3">
|
|
<span>{{ $benefit }}</span>
|
|
</li>
|
|
@empty
|
|
<li class="flex items-baseline gap-2 text-ink-3">
|
|
<span>{{ __('pricing.plans.included') }}</span>
|
|
</li>
|
|
@endforelse
|
|
</ul>
|
|
|
|
{{-- TODO: Deep-Link zu Checkout/Registrierung mit Tarif-Vorauswahl,
|
|
sobald der Buchungs-Flow (bookings.blade.php) final ist. --}}
|
|
<a href="{{ $submitHref }}"
|
|
class="inline-flex items-center justify-center gap-1.5 w-full px-4 py-2.5 text-[12.5px] font-semibold rounded-[2px] transition-colors cursor-pointer
|
|
{{ $isPopular ? 'bg-brand text-white hover:bg-brand-deep' : 'border border-bg-rule-strong text-ink hover:bg-bg-elev' }}">
|
|
{{ __('pricing.plans.cta') }}
|
|
<svg width="11" height="11" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
|
<path d="M2 6h8M6 2l4 4-4 4" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" />
|
|
</svg>
|
|
</a>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
|
|
<p class="text-[12px] text-ink-3 m-0 mt-4 max-w-[680px]">{{ __('pricing.plans.enterprise') }}</p>
|
|
@else
|
|
<p class="text-[13px] text-ink-3 m-0 mt-6">{{ __('pricing.plans.empty') }}</p>
|
|
@endif
|
|
</section>
|
|
|
|
{{-- ============================================================
|
|
2) EINZEL-PRESSEMITTEILUNG (Daten: config('billing'))
|
|
============================================================ --}}
|
|
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-14">
|
|
<header class="mb-4">
|
|
<div class="eyebrow muted mb-1">{{ __('pricing.single.eyebrow') }}</div>
|
|
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">{{ __('pricing.single.title') }}</h2>
|
|
</header>
|
|
<hr class="rule-strong">
|
|
|
|
<div class="bg-bg-elev border border-bg-rule p-6 sm:p-8 grid gap-6 md:grid-cols-[1fr_auto] md:items-center">
|
|
<p class="text-[13.5px] leading-[1.6] text-ink-2 m-0 max-w-[560px]">
|
|
{{ __('pricing.single.description') }}
|
|
</p>
|
|
<div class="flex flex-wrap items-center gap-4 md:flex-col md:flex-nowrap md:items-end md:gap-3">
|
|
<div class="md:text-right">
|
|
<div class="font-serif text-[34px] font-semibold leading-none tracking-[-0.6px] text-ink">{{ $euro($singlePmPriceCents) }} €</div>
|
|
<div class="text-[11.5px] text-ink-3 mt-1">{{ __('pricing.single.price_suffix') }} · {{ __('pricing.single.net') }}</div>
|
|
</div>
|
|
<a href="{{ $submitHref }}"
|
|
class="inline-flex items-center justify-center gap-1.5 px-5 py-2.5 text-[12.5px] font-semibold text-white bg-brand hover:bg-brand-deep rounded-[2px] transition-colors cursor-pointer whitespace-nowrap">
|
|
{{ __('pricing.single.cta') }}
|
|
<svg width="11" height="11" viewBox="0 0 12 12" fill="none" aria-hidden="true">
|
|
<path d="M2 6h8M6 2l4 4-4 4" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round" />
|
|
</svg>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{{-- ============================================================
|
|
3) ADD-ONS & EINZELKOSTEN (Daten: config('credits'))
|
|
Spiegelt die In-App-Buchungsseite (bookings.blade.php), die noch
|
|
überarbeitet wird — daher Lineup/Preise hier als „teilweise final".
|
|
============================================================ --}}
|
|
<section class="max-w-layout mx-auto px-4 sm:px-6 lg:px-8 mt-14">
|
|
<header class="flex items-baseline justify-between mb-4 flex-wrap gap-3">
|
|
<div>
|
|
<div class="eyebrow muted mb-1">{{ __('pricing.addons.eyebrow') }}</div>
|
|
<h2 class="font-serif text-[28px] font-semibold m-0 tracking-[-0.3px] text-ink">{{ __('pricing.addons.title') }}</h2>
|
|
</div>
|
|
<p class="text-[12.5px] text-ink-3 m-0 max-w-[420px]">{{ __('pricing.addons.subtitle') }}</p>
|
|
</header>
|
|
<hr class="rule-strong">
|
|
|
|
<div class="grid gap-px bg-bg-rule border border-bg-rule grid-cols-1 md:grid-cols-2">
|
|
{{-- Extra-PM (tier-gestaffelt) --}}
|
|
<div class="bg-bg p-6">
|
|
<h3 class="text-[15px] font-semibold text-ink m-0">{{ __('pricing.addons.extra_pm.title') }}</h3>
|
|
<p class="text-[12.5px] leading-[1.5] text-ink-2 mt-1 mb-4">{{ __('pricing.addons.extra_pm.description') }}</p>
|
|
<table class="w-full text-[12.5px] border-collapse">
|
|
<thead>
|
|
<tr class="text-left text-ink-3 border-b border-bg-rule">
|
|
<th class="font-medium py-1.5">{{ __('pricing.addons.extra_pm.tier_label') }}</th>
|
|
<th class="font-medium py-1.5 text-right">{{ __('pricing.addons.extra_pm.price_label') }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach ($extraPm as $row)
|
|
<tr class="border-b border-bg-rule last:border-b-0">
|
|
<td class="py-1.5 text-ink-2">{{ $row['tier'] }}</td>
|
|
<td class="py-1.5 text-right font-mono text-ink">{{ $row['credits'] }} {{ __('pricing.addons.credits_unit') }}</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{{-- Boost-Platzierung (zwei Stufen, nach Dauer — 13.07.2026) --}}
|
|
<div class="bg-bg p-6">
|
|
<h3 class="text-[15px] font-semibold text-ink m-0">{{ __('pricing.addons.boost.title') }}</h3>
|
|
<p class="text-[12.5px] leading-[1.5] text-ink-2 mt-1 mb-4">{{ __('pricing.addons.boost.description') }}</p>
|
|
<div class="text-[11px] font-semibold uppercase tracking-wide text-ink-3">{{ __('pricing.addons.boost.home_label') }}</div>
|
|
<ul class="list-none p-0 m-0 divide-y divide-bg-rule">
|
|
@foreach ($boost as $row)
|
|
<li class="flex items-baseline justify-between py-1.5 text-[12.5px]">
|
|
<span class="text-ink-2">{{ __('pricing.addons.boost.days', ['count' => $row['days']]) }}</span>
|
|
<span class="font-mono text-ink">{{ $row['credits'] }} {{ __('pricing.addons.credits_unit') }}</span>
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
<div class="text-[11px] font-semibold uppercase tracking-wide text-ink-3 mt-4">{{ __('pricing.addons.boost.category_label') }}</div>
|
|
<ul class="list-none p-0 m-0 divide-y divide-bg-rule">
|
|
@foreach ($boostCategory as $row)
|
|
<li class="flex items-baseline justify-between py-1.5 text-[12.5px]">
|
|
<span class="text-ink-2">{{ __('pricing.addons.boost.days', ['count' => $row['days']]) }}</span>
|
|
<span class="font-mono text-ink">{{ $row['credits'] }} {{ __('pricing.addons.credits_unit') }}</span>
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
|
|
{{-- Veröffentlichungsnachweis-PDF --}}
|
|
<div class="bg-bg p-6">
|
|
<h3 class="text-[15px] font-semibold text-ink m-0">{{ __('pricing.addons.proof_pdf.title') }}</h3>
|
|
<p class="text-[12.5px] leading-[1.5] text-ink-2 mt-1 mb-4">{{ __('pricing.addons.proof_pdf.description') }}</p>
|
|
<div class="flex items-baseline gap-2">
|
|
<span class="font-serif text-[24px] font-semibold text-ink">{{ $proofPdf }}</span>
|
|
<span class="text-[12px] text-ink-3">{{ __('pricing.addons.credits_unit') }} · {{ __('pricing.addons.proof_pdf.unit') }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Credit-Pakete --}}
|
|
<div class="bg-bg p-6">
|
|
<h3 class="text-[15px] font-semibold text-ink m-0">{{ __('pricing.addons.packs.title') }}</h3>
|
|
<p class="text-[12.5px] leading-[1.5] text-ink-2 mt-1 mb-4">{{ __('pricing.addons.packs.description') }}</p>
|
|
<div class="grid grid-cols-2 gap-2">
|
|
@foreach ($creditPacks as $pack)
|
|
@php $bonus = (int) $pack['credits'] - intdiv((int) $pack['price_cents'], 100); @endphp
|
|
<div class="border border-bg-rule bg-bg-elev p-3">
|
|
<div class="text-[14px] font-semibold text-ink">{{ __('pricing.addons.packs.credits', ['count' => $pack['credits']]) }}</div>
|
|
<div class="text-[11.5px] text-ink-3">{{ $euro((int) $pack['price_cents']) }} € {{ __('pricing.addons.packs.net') }}</div>
|
|
@if ($bonus > 0)
|
|
<span class="inline-block mt-1 text-[10px] font-semibold text-gain">{{ __('pricing.addons.packs.bonus', ['count' => $bonus]) }}</span>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Weitere Leistungen: aktuell nur Depublizieren (Direktkauf in
|
|
Euro, nicht Credits). Korrektur/Update folgen erst mit dem
|
|
Bookings-/Magic-Link-Rework und bleiben bis dahin draußen. --}}
|
|
@if ($depublicationPriceCents > 0)
|
|
<div class="mt-px bg-bg border border-bg-rule border-t-0 p-6">
|
|
<div class="eyebrow muted mb-3">{{ __('pricing.addons.more.title') }}</div>
|
|
<div class="flex flex-wrap gap-x-8 gap-y-2 text-[12.5px]">
|
|
<span class="inline-flex items-baseline gap-2">
|
|
<span class="text-ink-2">{{ __('pricing.addons.more.depublish') }}</span>
|
|
<span class="font-mono text-ink">{{ $euro($depublicationPriceCents) }} €</span>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<p class="text-[11.5px] text-ink-3 m-0 mt-4 max-w-[680px]">{{ __('pricing.vat_note') }}</p>
|
|
|
|
{{-- Render-Pflichten der Leistungsbeschreibung (Slots/Credits/Boost/
|
|
Partnerportale) — die AGB verweisen auf diese Seite. --}}
|
|
<div class="mt-10 grid gap-px bg-bg-rule border border-bg-rule grid-cols-1 md:grid-cols-2">
|
|
@foreach (['slots', 'credits', 'boost', 'partners'] as $noteKey)
|
|
<div class="bg-bg p-6">
|
|
<h3 class="text-[13.5px] font-semibold text-ink m-0 mb-2">{{ __('pricing.notes.'.$noteKey.'.title') }}</h3>
|
|
<p class="text-[12.5px] leading-[1.6] text-ink-2 m-0">{{ __('pricing.notes.'.$noteKey.'.text') }}</p>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</section>
|
|
|
|
{{-- Newsletter-Sektion bewusst entfernt: kommt nachgelagert mit echtem
|
|
Double-Opt-in (siehe dev/release/entwicklungsplan-release.md). --}}
|
|
</main>
|
|
|
|
<x-web.site-footer />
|
|
@endsection
|