- Hero: deutlich groessere Headline, langsam atmendes Bild, Wabenraster, Honigtropfen als Scroll-Hinweis, Hauptaktion in Honig - "Sechs Schritte" als Weg: eine Honiglinie fuellt sich beim Scrollen und laesst die Waben der Schritte nacheinander aufleuchten (waagerecht ab lg, senkrecht auf dem Handy; reduzierte Bewegung: sofort gefuellt) - Philosophie mit Waben statt Nummern, Verantwortung als geteiltes Layout mit mitlaufender Ueberschrift - Bilder mit versetztem Honigrahmen, Wabenraster auf dunklen Flaechen, grosse Anfuehrungszeichen bei den Kundenstimmen - Knopf-Varianten "inverted"/"accent" fuer dunkle Flaechen ersetzen !-Overrides, die den Fuell-Effekt ausgehebelt haetten - Fix: Ueberschrift der Kundenstimmen war Waldgruen auf Waldgruen Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
96 lines
3.5 KiB
TypeScript
96 lines
3.5 KiB
TypeScript
"use client";
|
|
|
|
import { useRef } from "react";
|
|
import { motion, useReducedMotion, useScroll, useSpring, useTransform, type MotionValue } from "motion/react";
|
|
|
|
interface Step {
|
|
number: string;
|
|
title: string;
|
|
text: string;
|
|
}
|
|
|
|
/**
|
|
* "Vom Bienenstock ins Glas" als Weg, den der Honig nimmt: eine Honiglinie
|
|
* fuellt sich im Takt des Scrollens und laesst die Waben der einzelnen
|
|
* Schritte der Reihe nach aufleuchten. Hier traegt die Bewegung Bedeutung —
|
|
* die Reihenfolge IST der Inhalt.
|
|
*
|
|
* Ab lg waagerecht (sechs Spalten), darunter senkrecht mit Linie links.
|
|
* Bei reduzierter Bewegung ist der Weg von Anfang an gefuellt.
|
|
*/
|
|
export function ProcessPath({ steps }: { steps: Step[] }) {
|
|
const ref = useRef<HTMLOListElement>(null);
|
|
const reduceMotion = useReducedMotion();
|
|
const { scrollYProgress } = useScroll({ target: ref, offset: ["start 85%", "end 55%"] });
|
|
// Gefedert statt direkt am Scrollwert: die Linie "fliesst" nach, wie Honig.
|
|
const smooth = useSpring(scrollYProgress, { stiffness: 90, damping: 22, mass: 0.6 });
|
|
const full = useTransform(smooth, () => 1);
|
|
const progress = reduceMotion ? full : smooth;
|
|
|
|
return (
|
|
<ol ref={ref} className="relative mt-16 grid gap-10 pl-10 lg:grid-cols-6 lg:gap-8 lg:pl-0 lg:pt-12">
|
|
{/* Leitung (Grundlinie) und Honigfuellung — waagerecht ab lg, sonst senkrecht. */}
|
|
<span aria-hidden="true" className="absolute left-[11px] top-2 bottom-2 w-px bg-ink/15 lg:hidden" />
|
|
<motion.span
|
|
aria-hidden="true"
|
|
style={{ scaleY: progress }}
|
|
className="absolute left-[10px] top-2 bottom-2 w-[3px] origin-top rounded-full bg-honey lg:hidden"
|
|
/>
|
|
<span aria-hidden="true" className="absolute left-3 right-[calc((100%_-_10rem)/6_-_12px)] top-[11px] hidden h-px bg-ink/15 lg:block" />
|
|
<motion.span
|
|
aria-hidden="true"
|
|
style={{ scaleX: progress }}
|
|
className="absolute left-3 right-[calc((100%_-_10rem)/6_-_12px)] top-[10px] hidden h-[3px] origin-left rounded-full bg-honey lg:block"
|
|
/>
|
|
|
|
{steps.map((step, i) => (
|
|
<ProcessStep key={step.number} step={step} index={i} total={steps.length} progress={progress} />
|
|
))}
|
|
</ol>
|
|
);
|
|
}
|
|
|
|
function ProcessStep({
|
|
step,
|
|
index,
|
|
total,
|
|
progress,
|
|
}: {
|
|
step: Step;
|
|
index: number;
|
|
total: number;
|
|
progress: MotionValue<number>;
|
|
}) {
|
|
// Die Wabe "entzuendet" sich, sobald die Linie ihre Position erreicht.
|
|
const at = total > 1 ? index / (total - 1) : 0;
|
|
const lit = useTransform(progress, [Math.max(0, at - 0.06), at + 0.02], [0, 1]);
|
|
const scale = useTransform(lit, [0, 1], [0.85, 1]);
|
|
|
|
return (
|
|
<li className="relative">
|
|
<motion.span
|
|
aria-hidden="true"
|
|
style={{ scale }}
|
|
className="absolute -left-10 top-0 flex h-6 w-6 items-center justify-center lg:-top-12 lg:left-0"
|
|
>
|
|
<svg viewBox="0 0 24 26" className="h-6 w-6">
|
|
<polygon
|
|
points="12,1 22.4,7 22.4,19 12,25 1.6,19 1.6,7"
|
|
fill="var(--color-background)"
|
|
stroke="var(--color-honey-dark)"
|
|
strokeWidth="1.5"
|
|
/>
|
|
<motion.polygon
|
|
points="12,4.5 19.4,8.75 19.4,17.25 12,21.5 4.6,17.25 4.6,8.75"
|
|
fill="var(--color-honey)"
|
|
style={{ opacity: lit }}
|
|
/>
|
|
</svg>
|
|
</motion.span>
|
|
<span className="font-serif text-sm text-honey-dark tabular-nums">{step.number}</span>
|
|
<h3 className="mt-1 text-xl text-forest">{step.title}</h3>
|
|
<p className="mt-2 text-sm text-ink/70 leading-relaxed">{step.text}</p>
|
|
</li>
|
|
);
|
|
}
|