Hero: Figur unter den Header, Kopfabschnitt auf Mobil und Marquee-Sprung

Drei Fehler an der Live-Seite:

1. Die Figur begann bei top-0 und ragte damit in die Navigationsleiste -
   Kopf und Schulter lagen hinter "Start" und "Ueber mich". Sie startet
   jetzt bei top-16 bzw. top-20, also genau unter dem Header.

2. Auf schmalen Screens war der Kopf komplett abgeschnitten. Das Bild
   skalierte ueber die Breite (h-auto w-full); bei 72 % Breite wird das
   hochformatige Motiv hoeher als sein Container, und items-end schneidet
   dann oben ab. Es skaliert jetzt durchgehend ueber die Hoehe
   (h-full w-auto object-bottom), damit passt es immer hinein.

3. Das Genre-Laufband sprang sichtbar zurueck. Zwei Kopien wurden um -50 %
   verschoben, aber eine Kopie ist auf breiten Bildschirmen schmaler als der
   Viewport - dadurch klaffte vor dem Neustart eine Luecke. Jetzt zwei Spuren
   mit min-w-full, beide um ihre volle eigene Breite (-100 %); Spur 2 steht
   beim Neustart exakt auf der Startposition von Spur 1. Das umgebende
   Element bekam ausserdem das fehlende overflow-hidden.

Nachgemessen bei 1265x720 und 375x812: Kopf unterhalb der Headerkante,
beide Spuren gleich breit und mindestens viewportbreit, kein horizontaler
Scroll.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 23:35:44 +02:00
co-authored by Claude Opus 5
parent de7e8e3c37
commit fb10b9d94c
2 changed files with 23 additions and 7 deletions
+20 -6
View File
@@ -50,12 +50,17 @@ const genreLine = GENRES.map((g) => g.name).join(' • ');
Die Figur liegt bewusst absolut und nicht im Textfluss: als Grid-Spalte
wuerde ihre Eigenhoehe (649x1919 px) die Zeile auf ueber 1200 px aufziehen
und Ueberschrift samt Buttons unter die Falz druecken.
Sie skaliert ueber die Hoehe (h-full w-auto), nicht ueber die Breite -
sonst wird das hochformatige Bild auf schmalen Screens hoeher als der
Container und items-end schneidet oben den Kopf ab. top-16/top-20
entspricht der Headerhoehe, damit sie nicht in die Navigation ragt.
*/}
<div
class="pointer-events-none absolute top-0 right-[-8%] bottom-12 -z-5 flex w-[72%] items-end opacity-25 sm:right-0 sm:w-[52%] sm:opacity-35 lg:right-[4%] lg:bottom-14 lg:z-0 lg:w-auto lg:opacity-100"
class="pointer-events-none absolute top-16 right-[-8%] bottom-12 -z-5 flex w-[72%] items-end justify-end opacity-25 sm:top-20 sm:right-0 sm:w-[52%] sm:opacity-35 lg:right-[4%] lg:bottom-14 lg:z-0 lg:w-auto lg:opacity-100"
aria-hidden="true"
>
<div class="relative ml-auto w-full max-w-[26rem] lg:h-full lg:w-auto lg:max-w-none">
<div class="relative h-full">
<div
class="absolute inset-x-[-30%] bottom-[6%] -z-10 aspect-square rounded-full bg-[radial-gradient(closest-side,--alpha(var(--color-gold-400)/22%),transparent)] blur-2xl"
>
@@ -66,7 +71,7 @@ const genreLine = GENRES.map((g) => g.name).join(' • ');
widths={[420, 649]}
sizes="(min-width: 1024px) 26rem, 60vw"
loading="eager"
class="h-auto w-full object-contain drop-shadow-[0_25px_45px_rgba(0,0,0,0.55)] [mask-image:linear-gradient(to_top,transparent_0%,black_7%)] lg:h-full lg:w-auto"
class="h-full w-auto max-w-none object-contain object-bottom drop-shadow-[0_25px_45px_rgba(0,0,0,0.55)] [mask-image:linear-gradient(to_top,transparent_0%,black_7%)]"
/>
</div>
</div>
@@ -129,13 +134,22 @@ const genreLine = GENRES.map((g) => g.name).join(' • ');
{/* Genre-Laufband */}
<div
class="absolute inset-x-0 bottom-0 z-10 border-y border-white/10 bg-ink-950/60 py-3.5 backdrop-blur-md"
class="absolute inset-x-0 bottom-0 z-10 overflow-hidden border-y border-white/10 bg-ink-950/60 py-3.5 backdrop-blur-md"
aria-hidden="true"
>
<div class="flex w-max animate-marquee">
{/*
Zwei identische Spuren, beide gleichzeitig um ihre volle eigene Breite
nach links. Sobald Spur 1 draussen ist, steht Spur 2 exakt an deren
Startposition - der Neustart faellt nicht auf.
min-w-full ist der entscheidende Teil: ohne das ist eine Spur auf breiten
Bildschirmen schmaler als der Viewport, es klafft eine Luecke und das Band
springt sichtbar zurueck.
*/}
<div class="flex">
{
[0, 1].map(() => (
<div class="flex shrink-0 items-center">
<div class="flex min-w-full shrink-0 animate-marquee items-center justify-around">
{GENRES.map((g) => (
<span class="flex items-center">
<span class="px-6 font-display text-sm tracking-[0.18em] text-white/45 uppercase sm:text-base">
+3 -1
View File
@@ -30,9 +30,11 @@
--animate-cue: cue 2.2s ease-in-out infinite;
}
/* Jede Spur wandert um ihre eigene volle Breite. Zwei Spuren nebeneinander
ergeben daraus einen nahtlosen Lauf - siehe Hero.astro. */
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
to { transform: translateX(-100%); }
}
@keyframes sweep {