web: Transparenzseiten — was kostet, ohne Abo, loeschen/aendern (Roadmap 2.4)
Drei Seiten mit unterschiedlicher Suchintention, DE/EN, Hub + Spokes: - /was-kostet-eine-pressemitteilung: kurze Antwort im ersten Bildschirm, vier Abrechnungsmodelle ohne Anbieternamen und fremde Preise, sechs Prueffragen fuer Folgekosten, "Was bei uns gilt" (sieben Zusagen mit Einloesung), Rechenbeispiel Einzelabrechnung gegen Starter-Monate mit Zeilen fuer beide Seiten. - /pressemitteilung-veroeffentlichen-ohne-abo: Ablauf, enthalten / nicht enthalten, nichts verfaellt, wann sich ein Tarif lohnt. - /pressemitteilung-loeschen-oder-aendern-lassen: fuenf Wege als Tabelle (Korrektur, Aenderung, DSGVO, Depublikation, DSA), Antragsweg ueber /melden/pm, Korrektur statt Loeschung, Absatz fuer Meldungen auf fremden Portalen ohne Zusagen ueber Dritte. PricingTransparencyData liefert alle Zahlen aus config/billing, credits, legal und dem Starter-Tarif; TransparencyPageController leitet die Marke aus dem Host ab. Tabellen-Typografie fuer .pm-body. Verlinkt aus Preisuebersicht, Hilfe-Center, Sitemaps und llms.txt. Test TransparencyPagesTest (9) erzwingt u. a., dass im Rechenbeispiel beide Modelle Zeilen gewinnen. Protokoll Teil 5, Roadmap 2.4 abgehakt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4616bb7aad
commit
106edb1384
18 changed files with 953 additions and 4 deletions
|
|
@ -172,6 +172,34 @@
|
|||
.pm-body strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
/* Tabellen der Info-/Transparenzseiten (Roadmap 2.4). */
|
||||
.pm-body > table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 0 0 18px;
|
||||
font-size: 14.5px;
|
||||
line-height: 1.5;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
.pm-body > table th,
|
||||
.pm-body > table td {
|
||||
padding: 10px 12px 10px 0;
|
||||
border-bottom: 1px solid var(--color-bg-rule);
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
.pm-body > table thead th {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 10.5px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.08em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-ink-3);
|
||||
border-bottom: 1px solid var(--color-bg-rule-strong);
|
||||
}
|
||||
.pm-body > table tbody th {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Button Base Styles */
|
||||
.btn {
|
||||
|
|
|
|||
|
|
@ -30,12 +30,14 @@
|
|||
['label' => __('static.help.link_good_release'), 'href' => route('gute-pressemitteilung')],
|
||||
['label' => __('static.help.link_file_formats'), 'href' => route('faq')],
|
||||
['label' => __('static.help.link_seo'), 'href' => route('faq')],
|
||||
['label' => __('static.help.link_corrections'), 'href' => route('faq')],
|
||||
['label' => __('static.help.link_corrections'), 'href' => route('pressemitteilung-loeschen-oder-aendern-lassen')],
|
||||
],
|
||||
],
|
||||
[
|
||||
'title' => __('static.help.topic_account'),
|
||||
'links' => [
|
||||
['label' => __('static.help.link_cost'), 'href' => route('was-kostet-eine-pressemitteilung')],
|
||||
['label' => __('static.help.link_no_subscription'), 'href' => route('pressemitteilung-veroeffentlichen-ohne-abo')],
|
||||
['label' => __('static.help.link_change_plan'), 'href' => route('preise')],
|
||||
['label' => __('static.help.link_invoices'), 'href' => $publisherUrl.'/login'],
|
||||
['label' => __('static.help.link_cancel'), 'href' => route('kuendigung')],
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@
|
|||
@endif
|
||||
|
||||
<p class="text-[11.5px] text-ink-3 m-0 mt-4 max-w-[680px]">{{ __('pricing.vat_note') }}</p>
|
||||
<p class="text-[11.5px] text-ink-3 m-0 mt-2 max-w-[680px] [&_a]:underline [&_a]:underline-offset-2 [&_a:hover]:text-ink">{!! __('pricing.transparency_links', ['cost_url' => route('was-kostet-eine-pressemitteilung'), 'no_sub_url' => route('pressemitteilung-veroeffentlichen-ohne-abo'), 'change_url' => route('pressemitteilung-loeschen-oder-aendern-lassen')]) !!}</p>
|
||||
|
||||
{{-- Render-Pflichten der Leistungsbeschreibung (Slots/Credits/Boost/
|
||||
Partnerportale) — die AGB verweisen auf diese Seite. --}}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
@extends('web.layouts.web-master')
|
||||
|
||||
@php
|
||||
// Roadmap 2.4, Transparenzseite 3 (nicht in der Roadmap, aus dem Briefing
|
||||
// 17.09.2026): das Meldeverfahren als Antwort auf ein akutes Problem.
|
||||
// Anfragen zu fremden Portalen fängt der letzte Abschnitt auf — ohne
|
||||
// Zusagen über Dritte (docs/legal/Entscheidung.md).
|
||||
$params = [
|
||||
'change' => $changeNet,
|
||||
'depub' => $depublicationNet,
|
||||
'pm_url' => route('melden.pm'),
|
||||
'report_url' => route('melden'),
|
||||
];
|
||||
@endphp
|
||||
|
||||
@section('title', __('static.change_delete.meta_title', ['brand' => $brandLabel]))
|
||||
@section('meta_description', __('static.change_delete.meta_description', $params))
|
||||
|
||||
@section('content')
|
||||
<x-web.static-page
|
||||
:eyebrow="__('static.change_delete.eyebrow')"
|
||||
:title="__('static.change_delete.title')"
|
||||
:lead="__('static.change_delete.lead')"
|
||||
:breadcrumb="__('static.change_delete.breadcrumb')"
|
||||
>
|
||||
<div class="pm-body max-w-[760px]">
|
||||
<h2 id="wege">{{ __('static.change_delete.ways_heading') }}</h2>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{ __('static.change_delete.ways_col_concern') }}</th>
|
||||
<th scope="col">{{ __('static.change_delete.ways_col_who') }}</th>
|
||||
<th scope="col">{{ __('static.change_delete.ways_col_cost') }}</th>
|
||||
<th scope="col">{{ __('static.change_delete.ways_col_result') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ([1, 2, 3, 4, 5] as $way)
|
||||
<tr>
|
||||
<th scope="row">{{ __('static.change_delete.way_'.$way) }}</th>
|
||||
<td>{{ __('static.change_delete.way_'.$way.'_who') }}</td>
|
||||
<td class="whitespace-nowrap">{{ __('static.change_delete.way_'.$way.'_cost', $params) }}</td>
|
||||
<td>{{ __('static.change_delete.way_'.$way.'_result') }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<p>{{ __('static.change_delete.ways_note') }}</p>
|
||||
|
||||
<h2 id="beantragen">{{ __('static.change_delete.how_heading') }}</h2>
|
||||
<p>{!! __('static.change_delete.how_p1', $params) !!}</p>
|
||||
<p>{!! __('static.change_delete.how_p2', $params) !!}</p>
|
||||
<p>{{ __('static.change_delete.how_p3') }}</p>
|
||||
|
||||
<h2 id="warum">{{ __('static.change_delete.why_heading') }}</h2>
|
||||
<p>{{ __('static.change_delete.why_p1') }}</p>
|
||||
<p>{{ __('static.change_delete.why_p2') }}</p>
|
||||
|
||||
<h2 id="andere-portale">{{ __('static.change_delete.other_heading') }}</h2>
|
||||
<p>{{ __('static.change_delete.other_p1') }}</p>
|
||||
<p>{{ __('static.change_delete.other_p2') }}</p>
|
||||
<p>{{ __('static.change_delete.other_p3') }}</p>
|
||||
|
||||
<div class="mt-10 p-6 sm:p-8 bg-bg-elev border border-bg-rule">
|
||||
<h2 class="font-serif text-[20px] font-semibold m-0 mb-4 text-ink">{{ __('static.change_delete.cta_heading') }}</h2>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<a href="{{ route('melden.pm') }}" class="inline-flex items-center justify-center px-[18px] py-3 text-[14px] font-semibold bg-brand text-white hover:bg-brand-deep transition-colors no-underline">{{ __('static.change_delete.cta_button') }} →</a>
|
||||
<a href="{{ route('melden') }}" class="inline-flex items-center justify-center px-[18px] py-3 text-[14px] font-semibold text-ink border border-bg-rule-strong bg-white hover:bg-bg-elev transition-colors no-underline">{{ __('static.change_delete.cta_all_ways') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 id="weiterlesen">{{ __('static.change_delete.related_heading') }}</h2>
|
||||
<ul>
|
||||
<li><a href="{{ route('was-kostet-eine-pressemitteilung') }}">{{ __('static.change_delete.related_cost') }}</a></li>
|
||||
<li><a href="{{ route('pressemitteilung-veroeffentlichen-ohne-abo') }}">{{ __('static.change_delete.related_no_sub') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</x-web.static-page>
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
@extends('web.layouts.web-master')
|
||||
|
||||
@php
|
||||
// Roadmap 2.4, Transparenzseite 2: Einzelveröffentlichung — was enthalten
|
||||
// ist, was nicht (ehrlich), wann ein Tarif trotzdem lohnt.
|
||||
$publisherUrl = rtrim((string) config('domains.domain_portal_url', config('app.url')), '/');
|
||||
$params = [
|
||||
'net' => $singleNet,
|
||||
'starter' => $starterName,
|
||||
'starter_price' => $starterMonthlyNet,
|
||||
'quota' => $starterQuota,
|
||||
'cost_url' => route('was-kostet-eine-pressemitteilung'),
|
||||
];
|
||||
@endphp
|
||||
|
||||
@section('title', __('static.no_subscription.meta_title', ['brand' => $brandLabel]))
|
||||
@section('meta_description', __('static.no_subscription.meta_description', ['price' => $singleNet]))
|
||||
|
||||
@section('content')
|
||||
<x-web.static-page
|
||||
:eyebrow="__('static.no_subscription.eyebrow')"
|
||||
:title="__('static.no_subscription.title')"
|
||||
:lead="__('static.no_subscription.lead')"
|
||||
:breadcrumb="__('static.no_subscription.breadcrumb')"
|
||||
>
|
||||
<div class="pm-body max-w-[760px]">
|
||||
<h2 id="ablauf">{{ __('static.no_subscription.how_heading') }}</h2>
|
||||
<ol>
|
||||
@foreach ([1, 2, 3, 4] as $step)
|
||||
<li>{{ __('static.no_subscription.step_'.$step, $params) }}</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
|
||||
<h2 id="enthalten">{{ __('static.no_subscription.included_heading') }}</h2>
|
||||
<ul>
|
||||
@foreach ([1, 2, 3, 4, 5, 6] as $item)
|
||||
<li>{{ __('static.no_subscription.included_'.$item) }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
||||
<h2 id="nicht-enthalten">{{ __('static.no_subscription.excluded_heading') }}</h2>
|
||||
<ul>
|
||||
@foreach ([1, 2, 3] as $item)
|
||||
<li>{{ __('static.no_subscription.excluded_'.$item) }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
||||
<h2 id="verfall">{{ __('static.no_subscription.no_expiry_heading') }}</h2>
|
||||
<p>{{ __('static.no_subscription.no_expiry_p') }}</p>
|
||||
|
||||
<h2 id="tarif">{{ __('static.no_subscription.plan_heading') }}</h2>
|
||||
<p>{!! __('static.no_subscription.plan_p', $params) !!}</p>
|
||||
|
||||
<div class="mt-10 p-6 sm:p-8 bg-ink text-white">
|
||||
<h2 class="font-serif text-[22px] font-semibold m-0 mb-2 text-white">{{ __('static.no_subscription.cta_heading') }}</h2>
|
||||
<p class="text-[14px] leading-[1.55] m-0 mb-5 text-white/80">{{ __('static.no_subscription.cta_text') }}</p>
|
||||
<div class="flex flex-wrap gap-3">
|
||||
<a href="{{ $publisherUrl }}/register" class="inline-flex items-center justify-center px-[18px] py-3 text-[14px] font-semibold bg-brand text-white hover:bg-brand-deep transition-colors no-underline">{{ __('static.no_subscription.cta_button') }} →</a>
|
||||
<a href="{{ route('preise') }}" class="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 no-underline">{{ __('static.no_subscription.cta_pricing') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-web.static-page>
|
||||
@endsection
|
||||
114
resources/views/web/was-kostet-eine-pressemitteilung.blade.php
Normal file
114
resources/views/web/was-kostet-eine-pressemitteilung.blade.php
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
@extends('web.layouts.web-master')
|
||||
|
||||
@php
|
||||
// Roadmap 2.4, Transparenzseite 1: Modellvergleich ohne Anbieternamen
|
||||
// und fremde Preise (kein Vergleich im Sinne von § 6 UWG, weil kein
|
||||
// Wettbewerber erkennbar), Prüfliste, eigene Zusagen, Rechenbeispiel nur
|
||||
// mit eigenen Optionen. Alle Zahlen aus PricingTransparencyData.
|
||||
$params = [
|
||||
'net' => $singleNet,
|
||||
'gross' => $singleGross,
|
||||
'vat' => $vatPercent,
|
||||
'starter' => $starterName,
|
||||
'starter_price' => $starterMonthlyNet,
|
||||
'quota' => $starterQuota,
|
||||
'change' => $changeNet,
|
||||
'depub' => $depublicationNet,
|
||||
'extra' => $extraPmStarterNet,
|
||||
'pricing_url' => route('preise'),
|
||||
'cancel_url' => route('kuendigung'),
|
||||
'change_url' => route('pressemitteilung-loeschen-oder-aendern-lassen'),
|
||||
];
|
||||
$spreadLabel = fn (array $row): string => __('static.cost.spread_'.$row['spread'], ['months' => $row['months'], 'per' => $starterQuota]);
|
||||
$cheaperLabel = fn (array $row): string => __('static.cost.cheaper_'.$row['cheaper'], ['starter' => $starterName]);
|
||||
@endphp
|
||||
|
||||
@section('title', __('static.cost.meta_title', ['brand' => $brandLabel]))
|
||||
@section('meta_description', __('static.cost.meta_description', ['price' => $singleNet]))
|
||||
|
||||
@section('content')
|
||||
<x-web.static-page
|
||||
:eyebrow="__('static.cost.eyebrow')"
|
||||
:title="__('static.cost.title')"
|
||||
:lead="__('static.cost.lead')"
|
||||
:breadcrumb="__('static.cost.breadcrumb')"
|
||||
>
|
||||
<div class="pm-body max-w-[760px]">
|
||||
<h2 id="kurz">{{ __('static.cost.short_heading') }}</h2>
|
||||
<p>{!! __('static.cost.short_p1', $params) !!}</p>
|
||||
<p>{!! __('static.cost.short_p2', $params) !!}</p>
|
||||
|
||||
<h2 id="modelle">{{ __('static.cost.models_heading') }}</h2>
|
||||
<p>{{ __('static.cost.models_intro') }}</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{ __('static.cost.models_col_model') }}</th>
|
||||
<th scope="col">{{ __('static.cost.models_col_cost') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ([1, 2, 3, 4] as $model)
|
||||
<tr>
|
||||
<th scope="row">{{ __('static.cost.model_'.$model) }}</th>
|
||||
<td>{{ __('static.cost.model_'.$model.'_cost') }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<p>{{ __('static.cost.models_note') }}</p>
|
||||
|
||||
<h2 id="folgekosten">{{ __('static.cost.check_heading') }}</h2>
|
||||
<p>{{ __('static.cost.check_intro') }}</p>
|
||||
<ol>
|
||||
@foreach ([1, 2, 3, 4, 5, 6] as $question)
|
||||
<li>{{ __('static.cost.check_'.$question) }}</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
|
||||
<h2 id="bei-uns">{{ __('static.cost.ours_heading') }}</h2>
|
||||
<p>{{ __('static.cost.ours_intro') }}</p>
|
||||
<ol>
|
||||
@foreach ([1, 2, 3, 4, 5, 6, 7] as $promise)
|
||||
<li><strong>{{ __('static.cost.ours_'.$promise.'_t') }}</strong> — {!! __('static.cost.ours_'.$promise.'_d', $params) !!}</li>
|
||||
@endforeach
|
||||
</ol>
|
||||
|
||||
@if ($examples !== [])
|
||||
<h2 id="rechenbeispiel">{{ __('static.cost.example_heading') }}</h2>
|
||||
<p>{{ __('static.cost.example_intro', $params) }}</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{ __('static.cost.example_col_count') }}</th>
|
||||
<th scope="col">{{ __('static.cost.example_col_spread') }}</th>
|
||||
<th scope="col" class="text-right">{{ __('static.cost.example_col_single') }}</th>
|
||||
<th scope="col" class="text-right">{{ __('static.cost.example_col_starter', ['starter' => $starterName]) }}</th>
|
||||
<th scope="col">{{ __('static.cost.example_col_cheaper') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($examples as $row)
|
||||
<tr>
|
||||
<td class="tabular-nums">{{ $row['count'] }}</td>
|
||||
<td>{{ $spreadLabel($row) }}</td>
|
||||
<td class="text-right tabular-nums">{{ $row['single'] }} €</td>
|
||||
<td class="text-right tabular-nums">{{ $row['starter'] }} €</td>
|
||||
<td><strong>{{ $cheaperLabel($row) }}</strong></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<p>{{ __('static.cost.example_note') }}</p>
|
||||
<p>{!! __('static.cost.example_extra', $params) !!}</p>
|
||||
@endif
|
||||
|
||||
<h2 id="weiterlesen">{{ __('static.cost.related_heading') }}</h2>
|
||||
<ul>
|
||||
<li><a href="{{ route('pressemitteilung-veroeffentlichen-ohne-abo') }}">{{ __('static.cost.related_no_sub') }}</a></li>
|
||||
<li><a href="{{ route('pressemitteilung-loeschen-oder-aendern-lassen') }}">{{ __('static.cost.related_change') }}</a></li>
|
||||
<li><a href="{{ route('preise') }}">{{ __('static.cost.related_pricing') }}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</x-web.static-page>
|
||||
@endsection
|
||||
Loading…
Add table
Add a link
Reference in a new issue