presseportale/resources/views/components/web/feed-top-item.blade.php
Kevin Adametz 075d0d931f legal/web: Zustimmungsgate je Dokumentversion (aus bis AGB 0.7), OG-Variante mit eingebranntem Bildnachweis, Nachweis in Teasern (Bildkennzeichnung Blöcke G und H)
- legal_document_acceptances (insert-only), LegalAcceptanceGate, Pflicht-Schalter im Einreichungs-Modal über den gemeinsamen Trait; API: GET/POST /api/v1/legal/acceptances, submit antwortet 428 mit den geforderten Fassungen; LEGAL_ACCEPTANCE_GATE
- ImageService: og-Variante (1200×630) mit halbtransparentem Balken und Inter SemiBold, regenerateOgVariant() für Korrekturen und Bestand; Fokuspunkt/Letterbox getestet
- Uploader brennt den Nachweis beim Upload ein, ImageCorrectionService baut die OG-Variante nach einer Korrektur neu; Artikelseite nutzt og für og:image
- Teaser: Nachweis in alt/title (Feed, Hero, Kategorie, Newsroom), Unterschrift am Hero-Bild; PressRelease::cardImageCredit()

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 10:12:17 +00:00

75 lines
4 KiB
PHP

@props([
'release' => null,
])
@php
$categoryName = $release?->localizedCategoryName();
$imageUrl = $release?->cardImageUrl();
$placeholderUrl = $imageUrl ? null : $release?->chosenPlaceholderUrl();
$teaser = $release?->teaserText(180) ?? '';
$company = $release?->company?->name;
$title = $release->title;
$imageCredit = $imageUrl ? $release?->cardImageCredit() : null;
$href = route('release.detail', ['slug' => $release->slug]);
$time = $release?->compactPublishedLabel();
$city = $release?->company?->city ?? null;
$readTime = $release?->readTimeMinutes() ?? 1;
@endphp
<article class="py-6 border-b border-bg-rule grid gap-6 grid-cols-1 md:grid-cols-[240px_1fr] group">
<a href="{{ $href }}" class="relative overflow-hidden bg-feature-grad block cursor-pointer" style="width:100%; max-width:240px; height:160px;">
@if ($imageUrl)
<img src="{{ $imageUrl }}" alt="{{ $imageCredit ? $title.' · '.$imageCredit : $title }}" @if ($imageCredit) title="{{ $imageCredit }}" @endif class="absolute inset-0 h-full w-full object-cover transition-transform group-hover:scale-105" loading="lazy">
@elseif ($placeholderUrl)
<img src="{{ $placeholderUrl }}" alt="" aria-hidden="true" class="absolute inset-0 h-full w-full object-cover transition-transform group-hover:scale-105" loading="lazy">
@else
<svg width="100%" height="100%" viewBox="0 0 240 160" class="absolute inset-0" aria-hidden="true">
<g opacity="0.5">
<line x1="40" y1="55" x2="40" y2="150" stroke="var(--color-feature-line)" stroke-width="1.8" />
<circle cx="40" cy="55" r="3" fill="var(--color-feature-dot)" />
</g>
<g opacity="0.65">
<line x1="100" y1="55" x2="100" y2="150" stroke="var(--color-feature-line)" stroke-width="1.8" />
<circle cx="100" cy="55" r="3" fill="var(--color-feature-dot)" />
</g>
<g opacity="0.8">
<line x1="160" y1="55" x2="160" y2="150" stroke="var(--color-feature-line)" stroke-width="1.8" />
<circle cx="160" cy="55" r="3" fill="var(--color-feature-dot)" />
</g>
<g opacity="0.95">
<line x1="210" y1="55" x2="210" y2="150" stroke="var(--color-feature-line)" stroke-width="1.8" />
<circle cx="210" cy="55" r="3" fill="var(--color-feature-dot)" />
</g>
</svg>
@endif
<span class="bp-tag absolute top-2.5 left-2.5">{{ __('web.hero.top_story') }}</span>
</a>
<div>
<div class="flex justify-between items-baseline mb-2 flex-wrap gap-2">
<span class="bp-cat">{{ $categoryName }}</span>
<span class="font-mono text-[11.5px] text-ink-3">{{ $time }}</span>
</div>
<h3 class="font-serif text-[24px] leading-[1.2] m-0 font-semibold tracking-[-0.3px] text-ink">
<a href="{{ $href }}" class="cursor-pointer hover:text-brand transition-colors">{{ $title }}</a>
</h3>
@if ($teaser)
<p class="font-serif text-[14px] text-ink-2 leading-[1.5] mt-2.5">
{{ $teaser }}
</p>
@endif
<div class="mt-3 text-[11.5px] text-ink-3 flex items-center gap-1.5 flex-wrap">
<svg width="11" height="11" viewBox="0 0 11 11" class="text-ok flex-shrink-0" aria-hidden="true">
<circle cx="5.5" cy="5.5" r="5" fill="currentColor" />
<path d="M3 5.5l1.8 1.8L8 4" stroke="white" stroke-width="1.4" fill="none" stroke-linecap="round" />
</svg>
<span>{{ $company }}</span>
@if ($city)
<span aria-hidden="true">·</span>
<span>{{ $city }}</span>
@endif
<span aria-hidden="true">·</span>
<span>{{ __('web.shared.read_time', ['minutes' => $readTime]) }}</span>
</div>
</div>
</article>