Files
Wabenhain/src/components/process-path.tsx
T
Nick SzaunigandClaude Opus 5.5 3de17ca070 feat(ui): Startseite mutiger gestaltet
- 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]>
2026-09-25 07:48:08 +02:00

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>
);
}