diff --git a/src/app/components/MountainClimb.tsx b/src/app/components/MountainClimb.tsx new file mode 100644 index 0000000..4b4cbfe --- /dev/null +++ b/src/app/components/MountainClimb.tsx @@ -0,0 +1,266 @@ +"use client"; + +import { useState, useEffect, useRef } from "react"; + +const STEPS = [ + "Deinen Wunschkunden klar definiert \u2014 wer er ist, was er braucht, was er schon versucht hat", + "Dein Angebot auf den Punkt gebracht \u2014 was du anbietest, welches Problem du l\u00f6st", + "Deine Positionierung in einem Satz \u2014 klar, sofort verst\u00e4ndlich, f\u00fcr alle Kan\u00e4le nutzbar", + "Die komplette Struktur f\u00fcr deine Verkaufsseite \u2014 mit Feedback zur Umsetzung", + "Deine Marketing-Systemkarte \u2014 wie Sichtbarkeit, Vertrauen, Anfrage und Kauf zusammenh\u00e4ngen", + "Deinen 90-Tage-Marketingplan + Entscheidung welche 2 Kan\u00e4le du fokussierst", + "Deinen 4-Wochen Content-Plan + Themen die zeigen wof\u00fcr du stehst \u2014 f\u00fcr alle Plattformen", + "Deinen Launch-Plan \u2014 wie du dein Angebot aktiv \u00fcber Social Media in den Markt bringst", + "Video-Setup erkl\u00e4rt \u2014 professionelle Videos mit dem Handy", + "Dein pers\u00f6nliches Verkaufsskript f\u00fcr Direktansprache und Netzwerk", + "Dein Google Business Profil optimiert + SEO-Grundlagen f\u00fcr deine Website", +]; + +// Waypoints along the mountain ridge (SVG user units, viewBox 940 × 580) +const WP = [ + { x: 65, y: 520, lean: 8 }, + { x: 155, y: 500, lean: 9 }, + { x: 248, y: 477, lean: 12 }, + { x: 338, y: 449, lean: 13 }, + { x: 425, y: 416, lean: 16 }, + { x: 508, y: 378, lean: 19 }, + { x: 587, y: 334, lean: 20 }, + { x: 660, y: 290, lean: 19 }, + { x: 727, y: 252, lean: 18 }, + { x: 787, y: 220, lean: 18 }, + { x: 840, y: 192, lean: 0 }, +] as const; + +const VW = 940; +const VH = 580; + +// Smooth quadratic-bezier path through all waypoints (midpoint technique) +const RIDGE = + "M 65 520" + + " Q 110 510 155 500" + + " Q 201.5 488.5 248 477" + + " Q 293 463 338 449" + + " Q 381.5 432.5 425 416" + + " Q 466.5 397 508 378" + + " Q 547.5 356 587 334" + + " Q 623.5 312 660 290" + + " Q 693.5 271 727 252" + + " Q 757 236 787 220" + + " Q 813.5 206 840 192"; + +// Filled mountain silhouette (ridge + right slope + base) +const FILL = + `M 0 ${VH} L 0 540 L ` + + RIDGE.slice(2) + // "65 520 Q …" — continues from first waypoint to summit + ` L 940 265 L 940 ${VH} Z`; + +const CARD_W = 234; +const CARD_H = 128; + +export default function MountainClimb() { + const [step, setStep] = useState(-1); + const sectionRef = useRef(null); + const started = useRef(false); + + // Auto-start when section scrolls into view + useEffect(() => { + const el = sectionRef.current; + if (!el) return; + const obs = new IntersectionObserver( + ([e]) => { + if (e.isIntersecting && !started.current) { + started.current = true; + setStep(0); + } + }, + { threshold: 0.25 } + ); + obs.observe(el); + return () => obs.disconnect(); + }, []); + + // Advance one step every 1.6 s + useEffect(() => { + if (step < 0 || step >= STEPS.length - 1) return; + const t = setTimeout(() => setStep((s) => s + 1), 1600); + return () => clearTimeout(t); + }, [step]); + + const atSummit = step === STEPS.length - 1; + const wp = step >= 0 ? WP[step] : WP[0]; + + // Card x: centred on person, clamped inside viewBox + const rawCX = wp.x - CARD_W / 2; + const cardX = Math.min(Math.max(rawCX, 8), VW - CARD_W - 8); + // Card y: above figure head, clamped to top of viewBox + const cardY = Math.max(wp.y - CARD_H - 58, 4); + + const replay = () => { + started.current = true; + setStep(0); + }; + + return ( +
+
+ {/* Header */} +
+ + + Komplettpaket + +

+ Was du in 8 Wochen baust — und mit nach Hause nimmst +

+
+ + {/* ── Mountain animation (md+) ── */} +
+ + + {/* Replay button */} + {atSummit && ( +
+ +
+ )} +
+ + {/* ── Mobile fallback: numbered list ── */} +
+ {STEPS.map((text, i) => ( +
+ + {i + 1} + +

{text}

+
+ ))} +
+
+
+ ); +} diff --git a/src/app/components/WeekTimeline.tsx b/src/app/components/WeekTimeline.tsx index 7fe3afa..1dea4b7 100644 --- a/src/app/components/WeekTimeline.tsx +++ b/src/app/components/WeekTimeline.tsx @@ -141,7 +141,7 @@ function WeekCard({ week, isLeft }: { week: Week; isLeft: boolean }) { )} {/* Title */} -

{week.title}

+

{week.title}

{/* Body */}

{week.body}

{/* Vorlagen */} diff --git a/src/app/globals.css b/src/app/globals.css index 993116f..da6e9dd 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -75,6 +75,23 @@ p { details summary::-webkit-details-marker { display: none; } +/* ── Shared micro-animations ── */ +@keyframes mc-fade-in { + from { opacity: 0; transform: translateY(5px); } + to { opacity: 1; transform: translateY(0); } +} +.mc-fade-in { animation: mc-fade-in 0.35s ease forwards; } + +@keyframes mc-bounce { + 0% { transform: translateY(0); } + 30% { transform: translateY(-14px); } + 55% { transform: translateY(-6px); } + 75% { transform: translateY(-10px); } + 90% { transform: translateY(-2px); } + 100% { transform: translateY(0); } +} +.mc-bounce { animation: mc-bounce 0.9s ease forwards; } + /* ── Flip Cards ── */ .flip-card-wrapper { perspective: 1000px; diff --git a/src/app/page.tsx b/src/app/page.tsx index 2fa24f3..6d6cccf 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,11 +1,12 @@ import Image from "next/image"; import WeekTimeline from "./components/WeekTimeline"; import FlipCards from "./components/FlipCards"; +import MountainClimb from "./components/MountainClimb"; import { CalendarIcon, GradCapIcon, UsersIcon, ClipboardIcon, TargetIcon, LightbulbIcon, DocumentIcon, PhoneIcon, - VideoCameraIcon, HandshakeIcon, SearchIcon, MapPinIcon, - MapIcon, RocketIcon, PackageIcon, ChatIcon, CheckIcon, + VideoCameraIcon, HandshakeIcon, SearchIcon, MapIcon, + PackageIcon, ChatIcon, CheckIcon, } from "./components/Icons"; const CTA_HREF = "#platz-sichern"; @@ -37,8 +38,8 @@ function IconCard({ icon, title, sub }: { icon: React.ReactNode; title: string;
{icon}
-

{title}

-

{sub}

+

{title}

+

{sub}

); } @@ -199,38 +200,9 @@ export default function Home() { {/* ══════════════════════════════════════════ - S4 — WAS DU BAUST (Content Grid) + S4 — WAS DU BAUST (Mountain animation) ══════════════════════════════════════════ */} -
-
-
- Komplettpaket -

Was du in 8 Wochen baust — und mit nach Hause nimmst

-
-
- {( - [ - { icon: , text: "Deinen Wunschkunden klar definiert — wer er ist, was er braucht, was er schon versucht hat" }, - { icon: , text: "Dein Angebot auf den Punkt gebracht — was du anbietest, welches Problem du löst" }, - { icon: , text: "Deine Positionierung in einem Satz — klar, sofort verständlich, für alle Kanäle nutzbar" }, - { icon: , text: "Die komplette Struktur für deine Verkaufsseite — mit Feedback zur Umsetzung" }, - { icon: , text: "Deine Marketing-Systemkarte — wie Sichtbarkeit, Vertrauen, Anfrage und Kauf zusammenhängen" }, - { icon: , text: "Deinen 90-Tage-Marketingplan + Entscheidung welche 2 Kanäle du fokussierst" }, - { icon: , text: "Deinen 4-Wochen Content-Plan + Themen die zeigen wofür du stehst — für alle Plattformen" }, - { icon: , text: "Deinen Launch-Plan — wie du dein Angebot aktiv über Social Media in den Markt bringst" }, - { icon: , text: "Video-Setup erklärt — professionelle Videos mit dem Handy" }, - { icon: , text: "Dein persönliches Verkaufsskript für Direktansprache und Netzwerk" }, - { icon: , text: "Dein Google Business Profil optimiert + SEO-Grundlagen für deine Website" }, - ] as { icon: React.ReactNode; text: string }[] - ).map(({ icon, text }, i) => ( -
- {icon} -

{text}

-
- ))} -
-
-
+ @@ -351,8 +323,8 @@ export default function Home() { Wert: {val}

Bonus {n}

-

{title}

-

{desc}

+

{title}

+

{desc}

))} @@ -449,7 +421,7 @@ export default function Home() { {q} -
{a}
+
{a}
))}