Add tests for featured thumbnail generation; apply Pint formatting and related edits

This commit is contained in:
2026-05-06 18:55:40 +02:00
parent 7a8bc8e22a
commit 82f2b1f660
65 changed files with 11325 additions and 49545 deletions

View File

@@ -16,97 +16,78 @@
$shouldBlur = (bool) ($maturity['should_blur'] ?? false);
$cardImageId = ($idPrefix ?? 'artwork') . '-image-' . ($index ?? 0);
$medalScore = (int) data_get($artwork, 'medals.score_30d', data_get($artwork, 'medals.score', 0));
$cardFrameClass = ($layout ?? 'grid') === 'rail'
? 'aspect-video'
: 'aspect-[4/5] sm:aspect-[5/4] lg:aspect-video';
@endphp
<article class="{{ ($layout ?? 'grid') === 'rail' ? 'min-w-[72%] snap-start sm:min-w-[44%] lg:min-w-0' : 'min-w-0' }}">
<div class="group overflow-hidden rounded-2xl bg-black/20 shadow-lg shadow-black/40 ring-1 ring-white/5 transition-all duration-200 ease-out hover:-translate-y-0.5 focus-within:ring-2 focus-within:ring-sky-300/70">
<a href="{{ $artworkUrl }}" class="relative block overflow-hidden">
<div class="relative aspect-video overflow-hidden bg-neutral-900">
<div class="pointer-events-none absolute inset-0 z-10 bg-gradient-to-br from-white/10 via-white/5 to-transparent"></div>
<img
id="{{ $cardImageId }}"
src="{{ $thumbUrl }}"
@if (!empty($artwork['thumb_srcset']))
srcset="{{ $artwork['thumb_srcset'] }}"
sizes="{{ $sizes ?? '100vw' }}"
@endif
alt="{{ $titleText }}"
width="{{ max(1, (int) ($artwork['width'] ?? 1600)) }}"
height="{{ max(1, (int) ($artwork['height'] ?? 900)) }}"
class="h-full w-full object-cover transition-[transform,filter] duration-300 ease-out group-hover:scale-[1.04] {{ $shouldBlur ? 'blur-2xl scale-[1.03]' : '' }}"
loading="lazy"
decoding="async"
>
@if (!empty($badge))
<div class="absolute left-3 top-3 z-30">
<span class="inline-flex items-center rounded-md px-2 py-1 text-[11px] font-bold ring-1 ring-white/10 backdrop-blur-sm {{ $badgeClass ?? 'bg-sky-500/80 text-white' }}">
{{ $badge }}
</span>
</div>
@elseif ($metricBadge && !empty($metricBadge['label']))
<div class="absolute left-3 top-3 z-30">
<span class="inline-flex items-center rounded-full border border-sky-300/30 bg-sky-500/14 px-2.5 py-1 text-[11px] font-semibold text-sky-100 ring-1 ring-sky-300/20 backdrop-blur-sm">
{{ $metricBadge['label'] }}
</span>
</div>
<a href="{{ $artworkUrl }}" class="group relative block overflow-hidden rounded-2xl bg-black/20 shadow-lg shadow-black/40 ring-1 ring-white/5 transition-all duration-200 ease-out hover:-translate-y-0.5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-300/70">
<div class="relative {{ $cardFrameClass }} overflow-hidden bg-neutral-900">
<div class="pointer-events-none absolute inset-0 z-10 bg-gradient-to-br from-white/10 via-white/5 to-transparent"></div>
<img
id="{{ $cardImageId }}"
src="{{ $thumbUrl }}"
@if (!empty($artwork['thumb_srcset']))
srcset="{{ $artwork['thumb_srcset'] }}"
sizes="{{ $sizes ?? '100vw' }}"
@endif
alt="{{ $titleText }}"
width="{{ max(1, (int) ($artwork['width'] ?? 1600)) }}"
height="{{ max(1, (int) ($artwork['height'] ?? 900)) }}"
class="h-full w-full object-cover transition-[transform,filter] duration-300 ease-out group-hover:scale-[1.04] {{ $shouldBlur ? 'blur-2xl scale-[1.03]' : '' }}"
loading="lazy"
decoding="async"
>
@if ($medalScore > 0)
<div class="absolute right-3 top-3 z-30">
<span class="inline-flex items-center rounded-full border border-amber-300/20 bg-amber-300/12 px-2.5 py-1 text-[11px] font-semibold text-amber-100 ring-1 ring-amber-300/20 backdrop-blur-sm">
Medal {{ number_format($medalScore) }}
</span>
</div>
@endif
@if (!empty($badge))
<div class="absolute left-3 top-3 z-30">
<span class="inline-flex items-center rounded-md px-2 py-1 text-[11px] font-bold ring-1 ring-white/10 backdrop-blur-sm {{ $badgeClass ?? 'bg-sky-500/80 text-white' }}">
{{ $badge }}
</span>
</div>
@elseif ($metricBadge && !empty($metricBadge['label']))
<div class="absolute left-3 top-3 z-30">
<span class="inline-flex items-center rounded-full border border-sky-300/30 bg-sky-500/14 px-2.5 py-1 text-[11px] font-semibold text-sky-100 ring-1 ring-sky-300/20 backdrop-blur-sm">
{{ $metricBadge['label'] }}
</span>
</div>
@endif
@if ($shouldBlur)
<div class="absolute inset-0 z-20 flex items-center justify-center bg-slate-950/55 p-4" data-home-mature-overlay>
<div class="rounded-2xl border border-white/10 bg-black/45 px-4 py-4 text-center shadow-2xl backdrop-blur-md">
<p class="text-xs font-semibold uppercase tracking-[0.18em] text-white/70">Mature content</p>
<p class="mt-2 max-w-[16rem] text-sm text-white/90">This artwork may contain mature material.</p>
<button
type="button"
data-home-mature-toggle="{{ $cardImageId }}"
class="mt-4 inline-flex items-center rounded-full border border-white/15 bg-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white transition hover:bg-white/20"
>
Reveal image
</button>
</div>
</div>
@endif
@if ($medalScore > 0)
<div class="absolute right-3 top-3 z-30">
<span class="inline-flex items-center rounded-full border border-amber-300/20 bg-amber-300/12 px-2.5 py-1 text-[11px] font-semibold text-amber-100 ring-1 ring-amber-300/20 backdrop-blur-sm">
Medal {{ number_format($medalScore) }}
</span>
</div>
@endif
<div class="pointer-events-none absolute inset-x-0 bottom-0 z-20 bg-gradient-to-t from-black/85 via-black/45 to-transparent p-3 backdrop-blur-[2px] opacity-100 transition-opacity duration-200 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100">
<div class="truncate text-sm font-semibold text-white">{{ $titleText }}</div>
<div class="mt-1 flex items-center gap-2 text-xs text-white/80">
<img src="{{ $authorAvatar }}" alt="{{ $authorName }}" class="h-6 w-6 shrink-0 rounded-full object-cover" loading="lazy" decoding="async">
<span class="truncate">{{ $authorName }}</span>
@if ($authorUsername !== '')
<span class="shrink-0 text-white/50">@{{ $authorUsername }}</span>
@endif
@if ($shouldBlur)
<div class="absolute inset-0 z-20 flex items-center justify-center bg-slate-950/55 p-4" data-home-mature-overlay>
<div class="rounded-2xl border border-white/10 bg-black/45 px-4 py-4 text-center shadow-2xl backdrop-blur-md">
<p class="text-xs font-semibold uppercase tracking-[0.18em] text-white/70">Mature content</p>
<p class="mt-2 max-w-[16rem] text-sm text-white/90">This artwork may contain mature material.</p>
<button
type="button"
data-home-mature-toggle="{{ $cardImageId }}"
class="mt-4 inline-flex items-center rounded-full border border-white/15 bg-white/10 px-4 py-2 text-xs font-semibold uppercase tracking-[0.16em] text-white transition hover:bg-white/20"
>
Reveal image
</button>
</div>
</div>
</div>
</a>
@endif
<div class="flex items-start justify-between gap-3 border-t border-white/5 bg-slate-950/40 px-3 py-3">
<div class="min-w-0">
<a href="{{ $artworkUrl }}" class="block truncate text-sm font-semibold text-white transition hover:text-sky-100">{{ $titleText }}</a>
<div class="mt-1 flex items-center gap-2 text-xs text-soft">
@if ($authorUrl)
<a href="{{ $authorUrl }}" class="truncate text-nova-200 transition hover:text-white">{{ $authorName }}</a>
@else
<span class="truncate">{{ $authorName }}</span>
@endif
@if (!empty($artwork['category_name']))
<span class="shrink-0 text-white/35"></span>
<span class="truncate">{{ $artwork['category_name'] }}</span>
<div class="pointer-events-none absolute inset-x-0 bottom-0 z-20 bg-gradient-to-t from-black/85 via-black/45 to-transparent p-3 backdrop-blur-[2px] opacity-100 transition-opacity duration-200 md:opacity-0 md:group-hover:opacity-100 md:group-focus-within:opacity-100">
<div class="truncate text-sm font-semibold text-white">{{ $titleText }}</div>
<div class="mt-1 flex items-center gap-2 text-xs text-white/80">
<img src="{{ $authorAvatar }}" alt="{{ $authorName }}" class="h-6 w-6 shrink-0 rounded-full object-cover" loading="lazy" decoding="async">
<span class="truncate">{{ $authorName }}</span>
@if ($authorUsername !== '')
<span class="shrink-0 text-white/50">{{ $authorUsername }}</span>
@endif
</div>
</div>
<a href="{{ $artworkUrl }}" class="shrink-0 rounded-full border border-white/10 bg-white/[0.04] px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] text-white/80 transition hover:border-white/20 hover:bg-white/[0.08] hover:text-white">
View
</a>
</div>
</div>
</a>
</article>