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:
@@ -50,12 +50,17 @@ const genreLine = GENRES.map((g) => g.name).join(' • ');
|
|||||||
Die Figur liegt bewusst absolut und nicht im Textfluss: als Grid-Spalte
|
Die Figur liegt bewusst absolut und nicht im Textfluss: als Grid-Spalte
|
||||||
wuerde ihre Eigenhoehe (649x1919 px) die Zeile auf ueber 1200 px aufziehen
|
wuerde ihre Eigenhoehe (649x1919 px) die Zeile auf ueber 1200 px aufziehen
|
||||||
und Ueberschrift samt Buttons unter die Falz druecken.
|
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
|
<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"
|
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
|
<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"
|
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]}
|
widths={[420, 649]}
|
||||||
sizes="(min-width: 1024px) 26rem, 60vw"
|
sizes="(min-width: 1024px) 26rem, 60vw"
|
||||||
loading="eager"
|
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>
|
||||||
</div>
|
</div>
|
||||||
@@ -129,13 +134,22 @@ const genreLine = GENRES.map((g) => g.name).join(' • ');
|
|||||||
|
|
||||||
{/* Genre-Laufband */}
|
{/* Genre-Laufband */}
|
||||||
<div
|
<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"
|
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(() => (
|
[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) => (
|
{GENRES.map((g) => (
|
||||||
<span class="flex items-center">
|
<span class="flex items-center">
|
||||||
<span class="px-6 font-display text-sm tracking-[0.18em] text-white/45 uppercase sm:text-base">
|
<span class="px-6 font-display text-sm tracking-[0.18em] text-white/45 uppercase sm:text-base">
|
||||||
|
|||||||
@@ -30,9 +30,11 @@
|
|||||||
--animate-cue: cue 2.2s ease-in-out infinite;
|
--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 {
|
@keyframes marquee {
|
||||||
from { transform: translateX(0); }
|
from { transform: translateX(0); }
|
||||||
to { transform: translateX(-50%); }
|
to { transform: translateX(-100%); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes sweep {
|
@keyframes sweep {
|
||||||
|
|||||||
Reference in New Issue
Block a user