Fix mobile package card overflow, gate scroll hint on visibility, fix dead-end service links
Kachel-Mindesthoehe war fix auf 640px, dadurch ragten Pakete auf dem Handy weit ueber den Bildschirm hinaus (Kundenfeedback). Jetzt 420px auf Mobile, 640px ab Desktop-Breite. Der Mausrad-Hinweis lief bisher sofort beim Laden ab, oft bevor die Kartenreihe ueberhaupt sichtbar gescrollt war - deshalb kam er beim Kunden nicht an. Spielt jetzt erst ab, sobald die Reihe tatsaechlich im Blickfeld ist. Leistungen-Karten ohne eigenen CTA (alles ausser Car-Hifi) hatten gar keinen Link. Fallen jetzt auf das Kontaktformular zurueck statt ins Leere zu laufen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
464164ff36
commit
0a96080427
5 changed files with 53 additions and 28 deletions
|
|
@ -55,11 +55,14 @@ export default function Leistungen() {
|
||||||
<div className="p-6 pt-8">
|
<div className="p-6 pt-8">
|
||||||
<h2 className="mb-2 font-semibold text-neutral-900 dark:text-white">{service.title}</h2>
|
<h2 className="mb-2 font-semibold text-neutral-900 dark:text-white">{service.title}</h2>
|
||||||
<p className="mb-3 text-sm text-neutral-600 dark:text-neutral-300">{service.description}</p>
|
<p className="mb-3 text-sm text-neutral-600 dark:text-neutral-300">{service.description}</p>
|
||||||
{service.cta_label && service.cta_url && (
|
{/* Karten ohne eigenen CTA (alles ausser Car-Hifi, das auf /fahrzeuge zeigt)
|
||||||
<Link to={service.cta_url} className="text-sm font-semibold text-brand-600 hover:underline dark:text-brand-400">
|
landen auf dem Kontaktformular statt ins Leere zu laufen. */}
|
||||||
{service.cta_label} →
|
<Link
|
||||||
|
to={service.cta_url || '/kontakt'}
|
||||||
|
className="text-sm font-semibold text-brand-600 hover:underline dark:text-brand-400"
|
||||||
|
>
|
||||||
|
{service.cta_label || t('leistungen.contact')} →
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -122,12 +122,12 @@ function PackageCard({ pkg, tier, tierT, layout, bullets, formatPrice, contactUr
|
||||||
}}
|
}}
|
||||||
className={
|
className={
|
||||||
layout === 'strip'
|
layout === 'strip'
|
||||||
? 'relative flex min-h-[640px] grow shrink basis-[190px] min-w-[190px] max-w-[240px] snap-start flex-col overflow-hidden rounded-[18px] border shadow-xl shadow-neutral-900/20 dark:shadow-black/40 sm:basis-[210px]'
|
? 'relative flex min-h-[420px] grow shrink basis-[190px] min-w-[190px] max-w-[240px] snap-start flex-col overflow-hidden rounded-[18px] border shadow-xl shadow-neutral-900/20 dark:shadow-black/40 sm:min-h-[640px] sm:basis-[210px]'
|
||||||
: layout === 'coverflow'
|
: layout === 'coverflow'
|
||||||
? // Feste Breite + snap-center: die 3D-Transformation (rotateY/scale/translateZ)
|
? // Feste Breite + snap-center: die 3D-Transformation (rotateY/scale/translateZ)
|
||||||
// setzt der Scroll-Handler in ModelPage direkt per style.transform.
|
// setzt der Scroll-Handler in ModelPage direkt per style.transform.
|
||||||
'relative flex min-h-[640px] w-[230px] shrink-0 snap-center flex-col overflow-hidden rounded-[18px] border shadow-xl shadow-neutral-900/20 will-change-transform dark:shadow-black/40'
|
'relative flex min-h-[420px] w-[230px] shrink-0 snap-center flex-col overflow-hidden rounded-[18px] border shadow-xl shadow-neutral-900/20 will-change-transform dark:shadow-black/40 sm:min-h-[640px]'
|
||||||
: 'relative flex min-h-[640px] flex-col overflow-hidden rounded-[18px] border shadow-xl shadow-neutral-900/20 dark:shadow-black/40'
|
: 'relative flex min-h-[420px] flex-col overflow-hidden rounded-[18px] border shadow-xl shadow-neutral-900/20 dark:shadow-black/40 sm:min-h-[640px]'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{/* Vollflaechiges Straßen-Glow-Bild der Preisstufe (Referenzdesign). */}
|
{/* Vollflaechiges Straßen-Glow-Bild der Preisstufe (Referenzdesign). */}
|
||||||
|
|
@ -336,9 +336,12 @@ export default function ModelPage() {
|
||||||
const isTouch = window.matchMedia('(pointer: coarse)').matches;
|
const isTouch = window.matchMedia('(pointer: coarse)').matches;
|
||||||
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||||
if (reducedMotion) return undefined;
|
if (reducedMotion) return undefined;
|
||||||
|
|
||||||
|
let timers = [];
|
||||||
|
const playHint = () => {
|
||||||
hintPlayedRef.current = true;
|
hintPlayedRef.current = true;
|
||||||
const peek = Math.min(el.clientWidth * 0.4, 160);
|
const peek = Math.min(el.clientWidth * 0.4, 160);
|
||||||
const timers = [
|
timers = [
|
||||||
setTimeout(() => el.scrollTo({ left: peek, behavior: 'smooth' }), 500),
|
setTimeout(() => el.scrollTo({ left: peek, behavior: 'smooth' }), 500),
|
||||||
setTimeout(() => el.scrollTo({ left: 0, behavior: 'smooth' }), 1250),
|
setTimeout(() => el.scrollTo({ left: 0, behavior: 'smooth' }), 1250),
|
||||||
];
|
];
|
||||||
|
|
@ -346,7 +349,26 @@ export default function ModelPage() {
|
||||||
timers.push(setTimeout(() => setWheelHintVisible(true), 450));
|
timers.push(setTimeout(() => setWheelHintVisible(true), 450));
|
||||||
timers.push(setTimeout(() => setWheelHintVisible(false), 1700));
|
timers.push(setTimeout(() => setWheelHintVisible(false), 1700));
|
||||||
}
|
}
|
||||||
return () => timers.forEach(clearTimeout);
|
};
|
||||||
|
|
||||||
|
// Kundenfeedback: der Hinweis lief bisher direkt beim Laden ab, oft bevor die
|
||||||
|
// Kartenreihe ueberhaupt in den sichtbaren Bereich gescrollt war - dann hat ihn
|
||||||
|
// niemand gesehen. Jetzt erst abspielen, wenn die Reihe wirklich im Blick ist.
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
([entry]) => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
observer.disconnect();
|
||||||
|
playHint();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ threshold: 0.35 },
|
||||||
|
);
|
||||||
|
observer.observe(el);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
observer.disconnect();
|
||||||
|
timers.forEach(clearTimeout);
|
||||||
|
};
|
||||||
}, [layout, data]);
|
}, [layout, data]);
|
||||||
|
|
||||||
// Mausrad ueber der Kartenreihe scrollt horizontal (Kundenfeedback: die Scroll-
|
// Mausrad ueber der Kartenreihe scrollt horizontal (Kundenfeedback: die Scroll-
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -43,9 +43,9 @@
|
||||||
"sameAs": ["https://www.youtube.com/@hifiplanet2812"]
|
"sameAs": ["https://www.youtube.com/@hifiplanet2812"]
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script type="module" crossorigin src="/assets/index-DsWWCZq0.js"></script>
|
<script type="module" crossorigin src="/assets/index-DO8EIr5z.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/assets/lucide-icons-66ioQXWI.js">
|
<link rel="modulepreload" crossorigin href="/assets/lucide-icons-66ioQXWI.js">
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-B83Ts70I.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DK8bkdcK.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="bg-white text-slate-900 dark:bg-slate-950 dark:text-slate-100">
|
<body class="bg-white text-slate-900 dark:bg-slate-950 dark:text-slate-100">
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue