Mountain: 8 shorter steps + summit celebration, replace Kacheln section
- Replace 11 full-sentence steps with 8 two-line pairs (title + sub) - Reduce waypoints from 11 to 8, recalculate smooth bezier ridge - Summit card: gradient indigo→violet bubble with celebration text - Figure lifts flag and bounces at summit (atSummit) - Move MountainClimb into "Nach 8 Wochen nimmst du mit:" section - Remove redundant static IconCard grid (8 Kacheln) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
badba0a9f7
commit
6afb4151cf
2 changed files with 112 additions and 75 deletions
|
|
@ -2,32 +2,31 @@
|
||||||
|
|
||||||
import { useState, useEffect, useRef } from "react";
|
import { useState, useEffect, useRef } from "react";
|
||||||
|
|
||||||
const STEPS = [
|
interface Step {
|
||||||
"Deinen Wunschkunden klar definiert \u2014 wer er ist, was er braucht, was er schon versucht hat",
|
title: string;
|
||||||
"Dein Angebot auf den Punkt gebracht \u2014 was du anbietest, welches Problem du l\u00f6st",
|
sub: string;
|
||||||
"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",
|
const STEPS: Step[] = [
|
||||||
"Deinen 90-Tage-Marketingplan + Entscheidung welche 2 Kan\u00e4le du fokussierst",
|
{ title: "Klare Wunschkunden-Persona", sub: "+ vollst\u00e4ndiger Marketing-Audit" },
|
||||||
"Deinen 4-Wochen Content-Plan + Themen die zeigen wof\u00fcr du stehst \u2014 f\u00fcr alle Plattformen",
|
{ title: "Angebot auf den Punkt", sub: "Positionierung in einem Satz \u2014 f\u00fcr alle Kan\u00e4le" },
|
||||||
"Deinen Launch-Plan \u2014 wie du dein Angebot aktiv \u00fcber Social Media in den Markt bringst",
|
{ title: "Deine Verkaufsseite", sub: "Vollst\u00e4ndige Struktur \u2014 fertig zum Umsetzen" },
|
||||||
"Video-Setup erkl\u00e4rt \u2014 professionelle Videos mit dem Handy",
|
{ title: "90-Tage-Marketingplan", sub: "+ 2 fokussierte Kan\u00e4le entschieden" },
|
||||||
"Dein pers\u00f6nliches Verkaufsskript f\u00fcr Direktansprache und Netzwerk",
|
{ title: "Content-Plan 4 Wochen", sub: "Was, wann und warum du postest" },
|
||||||
"Dein Google Business Profil optimiert + SEO-Grundlagen f\u00fcr deine Website",
|
{ title: "Social Media Verkauf", sub: "+ professionelles Video-Setup mit dem Handy" },
|
||||||
|
{ title: "Dein Verkaufsskript", sub: "F\u00fcr Direktansprache und Netzwerkveranstaltungen" },
|
||||||
|
{ title: "Google Business optimiert", sub: "+ SEO-Grundlagen f\u00fcr deine Website" },
|
||||||
];
|
];
|
||||||
|
|
||||||
// Waypoints along the mountain ridge (SVG user units, viewBox 940 × 580)
|
// Waypoints along the mountain ridge (SVG user units, viewBox 940 × 580)
|
||||||
const WP = [
|
const WP = [
|
||||||
{ x: 65, y: 520, lean: 8 },
|
{ x: 65, y: 520, lean: 8 },
|
||||||
{ x: 155, y: 500, lean: 9 },
|
{ x: 195, y: 488, lean: 12 },
|
||||||
{ x: 248, y: 477, lean: 12 },
|
{ x: 325, y: 450, lean: 15 },
|
||||||
{ x: 338, y: 449, lean: 13 },
|
{ x: 450, y: 407, lean: 17 },
|
||||||
{ x: 425, y: 416, lean: 16 },
|
{ x: 565, y: 358, lean: 20 },
|
||||||
{ x: 508, y: 378, lean: 19 },
|
{ x: 670, y: 303, lean: 22 },
|
||||||
{ x: 587, y: 334, lean: 20 },
|
{ x: 757, y: 248, lean: 24 },
|
||||||
{ x: 660, y: 290, lean: 19 },
|
|
||||||
{ x: 727, y: 252, lean: 18 },
|
|
||||||
{ x: 787, y: 220, lean: 18 },
|
|
||||||
{ x: 840, y: 192, lean: 0 },
|
{ x: 840, y: 192, lean: 0 },
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
|
@ -37,25 +36,24 @@ const VH = 580;
|
||||||
// Smooth quadratic-bezier path through all waypoints (midpoint technique)
|
// Smooth quadratic-bezier path through all waypoints (midpoint technique)
|
||||||
const RIDGE =
|
const RIDGE =
|
||||||
"M 65 520" +
|
"M 65 520" +
|
||||||
" Q 110 510 155 500" +
|
" Q 130 504 195 488" +
|
||||||
" Q 201.5 488.5 248 477" +
|
" Q 260 469 325 450" +
|
||||||
" Q 293 463 338 449" +
|
" Q 387.5 428.5 450 407" +
|
||||||
" Q 381.5 432.5 425 416" +
|
" Q 507.5 382.5 565 358" +
|
||||||
" Q 466.5 397 508 378" +
|
" Q 617.5 330.5 670 303" +
|
||||||
" Q 547.5 356 587 334" +
|
" Q 713.5 275.5 757 248" +
|
||||||
" Q 623.5 312 660 290" +
|
" Q 798.5 220 840 192";
|
||||||
" Q 693.5 271 727 252" +
|
|
||||||
" Q 757 236 787 220" +
|
|
||||||
" Q 813.5 206 840 192";
|
|
||||||
|
|
||||||
// Filled mountain silhouette (ridge + right slope + base)
|
// Filled mountain silhouette (ridge + right slope + base)
|
||||||
const FILL =
|
const FILL =
|
||||||
`M 0 ${VH} L 0 540 L ` +
|
`M 0 ${VH} L 0 540 L ` +
|
||||||
RIDGE.slice(2) + // "65 520 Q …" — continues from first waypoint to summit
|
RIDGE.slice(2) +
|
||||||
` L 940 265 L 940 ${VH} Z`;
|
` L 940 265 L 940 ${VH} Z`;
|
||||||
|
|
||||||
const CARD_W = 234;
|
const CARD_W = 234;
|
||||||
const CARD_H = 128;
|
const CARD_H = 110;
|
||||||
|
const SUMMIT_W = 294;
|
||||||
|
const SUMMIT_H = 80;
|
||||||
|
|
||||||
export default function MountainClimb() {
|
export default function MountainClimb() {
|
||||||
const [step, setStep] = useState(-1);
|
const [step, setStep] = useState(-1);
|
||||||
|
|
@ -90,12 +88,16 @@ export default function MountainClimb() {
|
||||||
const atSummit = step === STEPS.length - 1;
|
const atSummit = step === STEPS.length - 1;
|
||||||
const wp = step >= 0 ? WP[step] : WP[0];
|
const wp = step >= 0 ? WP[step] : WP[0];
|
||||||
|
|
||||||
// Card x: centred on person, clamped inside viewBox
|
// Regular card positioning
|
||||||
const rawCX = wp.x - CARD_W / 2;
|
const rawCX = wp.x - CARD_W / 2;
|
||||||
const cardX = Math.min(Math.max(rawCX, 8), VW - CARD_W - 8);
|
const cardX = Math.min(Math.max(rawCX, 8), VW - CARD_W - 8);
|
||||||
// Card y: above figure head (figure is 3× scaled → head at ~87 SVG units above foot)
|
|
||||||
const cardY = Math.max(wp.y - CARD_H - 110, 4);
|
const cardY = Math.max(wp.y - CARD_H - 110, 4);
|
||||||
|
|
||||||
|
// Summit card positioning
|
||||||
|
const summitRawCX = wp.x - SUMMIT_W / 2;
|
||||||
|
const summitCardX = Math.min(Math.max(summitRawCX, 8), VW - SUMMIT_W - 8);
|
||||||
|
const summitCardY = Math.max(wp.y - SUMMIT_H - 120, 4);
|
||||||
|
|
||||||
const replay = () => {
|
const replay = () => {
|
||||||
started.current = true;
|
started.current = true;
|
||||||
setStep(0);
|
setStep(0);
|
||||||
|
|
@ -108,10 +110,10 @@ export default function MountainClimb() {
|
||||||
<div className="text-center mb-12">
|
<div className="text-center mb-12">
|
||||||
<span className="inline-flex items-center gap-2 bg-indigo-50 text-indigo-700 text-xs font-bold uppercase tracking-widest rounded-full px-4 py-2 border border-indigo-100">
|
<span className="inline-flex items-center gap-2 bg-indigo-50 text-indigo-700 text-xs font-bold uppercase tracking-widest rounded-full px-4 py-2 border border-indigo-100">
|
||||||
<span className="w-2 h-2 rounded-full bg-indigo-500 animate-pulse" />
|
<span className="w-2 h-2 rounded-full bg-indigo-500 animate-pulse" />
|
||||||
Komplettpaket
|
Deine Ergebnisse
|
||||||
</span>
|
</span>
|
||||||
<h2 className="mt-4 text-3xl md:text-4xl font-extrabold text-slate-900">
|
<h2 className="mt-4 text-3xl md:text-4xl font-extrabold text-slate-900">
|
||||||
Was du in 8 Wochen baust — und mit nach Hause nimmst
|
Nach 8 Wochen nimmst du mit:
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -182,8 +184,8 @@ export default function MountainClimb() {
|
||||||
</g>
|
</g>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ── Text card ── */}
|
{/* ── Regular step card ── */}
|
||||||
{step >= 0 && (
|
{step >= 0 && !atSummit && (
|
||||||
<>
|
<>
|
||||||
{/* Dashed connector: card → figure head */}
|
{/* Dashed connector: card → figure head */}
|
||||||
<line
|
<line
|
||||||
|
|
@ -217,20 +219,75 @@ export default function MountainClimb() {
|
||||||
letterSpacing: "0.12em",
|
letterSpacing: "0.12em",
|
||||||
textTransform: "uppercase",
|
textTransform: "uppercase",
|
||||||
color: "#6366f1",
|
color: "#6366f1",
|
||||||
marginBottom: "5px",
|
marginBottom: "4px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Schritt {step + 1} / {STEPS.length}
|
Schritt {step + 1} / {STEPS.length}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
fontSize: "12.5px",
|
fontSize: "13px",
|
||||||
color: "#334155",
|
color: "#0f172a",
|
||||||
lineHeight: 1.55,
|
fontWeight: 700,
|
||||||
fontWeight: 500,
|
lineHeight: 1.3,
|
||||||
|
marginBottom: "4px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{STEPS[step]}
|
{STEPS[step].title}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "11px",
|
||||||
|
color: "#64748b",
|
||||||
|
lineHeight: 1.4,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{STEPS[step].sub}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* ── Summit celebration card ── */}
|
||||||
|
{atSummit && (
|
||||||
|
<>
|
||||||
|
<line
|
||||||
|
x1={summitCardX + SUMMIT_W / 2}
|
||||||
|
y1={summitCardY + SUMMIT_H}
|
||||||
|
x2={wp.x}
|
||||||
|
y2={wp.y - 90}
|
||||||
|
stroke="#a5b4fc"
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeDasharray="4 3"
|
||||||
|
/>
|
||||||
|
<foreignObject
|
||||||
|
key="summit"
|
||||||
|
x={summitCardX}
|
||||||
|
y={summitCardY}
|
||||||
|
width={SUMMIT_W}
|
||||||
|
height={SUMMIT_H}
|
||||||
|
className="mc-fade-in"
|
||||||
|
style={{ overflow: "visible" }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
background: "linear-gradient(135deg, #6366f1, #8b5cf6)",
|
||||||
|
borderRadius: "14px",
|
||||||
|
padding: "16px 18px",
|
||||||
|
boxShadow: "0 8px 32px rgba(99,102,241,0.45)",
|
||||||
|
textAlign: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
fontSize: "15px",
|
||||||
|
fontWeight: 800,
|
||||||
|
color: "#ffffff",
|
||||||
|
lineHeight: 1.35,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Ich habe jetzt ein Kundengewinnungssystem
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
|
|
@ -241,7 +298,7 @@ export default function MountainClimb() {
|
||||||
{/* Pause hint */}
|
{/* Pause hint */}
|
||||||
{step >= 0 && !atSummit && (
|
{step >= 0 && !atSummit && (
|
||||||
<p className="text-center text-xs text-slate-400 mt-2 select-none">
|
<p className="text-center text-xs text-slate-400 mt-2 select-none">
|
||||||
{paused ? "▶ Klicken zum Fortsetzen" : "⏸ Klicken zum Pausieren"}
|
{paused ? "\u25B6 Klicken zum Fortsetzen" : "\u23F8 Klicken zum Pausieren"}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -252,7 +309,7 @@ export default function MountainClimb() {
|
||||||
onClick={replay}
|
onClick={replay}
|
||||||
className="text-sm text-indigo-600 border border-indigo-200 rounded-full px-5 py-2 hover:bg-indigo-50 transition-colors"
|
className="text-sm text-indigo-600 border border-indigo-200 rounded-full px-5 py-2 hover:bg-indigo-50 transition-colors"
|
||||||
>
|
>
|
||||||
Nochmal ansehen ↺
|
Nochmal ansehen \u21BA
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -260,12 +317,15 @@ export default function MountainClimb() {
|
||||||
|
|
||||||
{/* ── Mobile fallback: numbered list ── */}
|
{/* ── Mobile fallback: numbered list ── */}
|
||||||
<div className="md:hidden space-y-3">
|
<div className="md:hidden space-y-3">
|
||||||
{STEPS.map((text, i) => (
|
{STEPS.map((s, i) => (
|
||||||
<div key={i} className="mc-card p-4 flex items-start gap-3">
|
<div key={i} className="mc-card p-4 flex items-start gap-3">
|
||||||
<span className="w-7 h-7 rounded-full bg-gradient-to-br from-indigo-500 to-violet-500 text-white text-xs font-bold flex items-center justify-center flex-shrink-0 mt-0.5">
|
<span className="w-7 h-7 rounded-full bg-gradient-to-br from-indigo-500 to-violet-500 text-white text-xs font-bold flex items-center justify-center flex-shrink-0 mt-0.5">
|
||||||
{i + 1}
|
{i + 1}
|
||||||
</span>
|
</span>
|
||||||
<p className="text-slate-700 text-sm leading-relaxed">{text}</p>
|
<div>
|
||||||
|
<p className="text-slate-700 text-sm font-semibold leading-snug">{s.title}</p>
|
||||||
|
<p className="text-slate-500 text-xs leading-relaxed mt-0.5">{s.sub}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,7 @@ import FlipCards from "./components/FlipCards";
|
||||||
import MountainClimb from "./components/MountainClimb";
|
import MountainClimb from "./components/MountainClimb";
|
||||||
import {
|
import {
|
||||||
CalendarIcon, GradCapIcon, UsersIcon, ClipboardIcon,
|
CalendarIcon, GradCapIcon, UsersIcon, ClipboardIcon,
|
||||||
TargetIcon, LightbulbIcon, DocumentIcon, PhoneIcon,
|
PhoneIcon, VideoCameraIcon, HandshakeIcon, MapIcon,
|
||||||
VideoCameraIcon, HandshakeIcon, SearchIcon, MapIcon,
|
|
||||||
PackageIcon, ChatIcon, CheckIcon,
|
PackageIcon, ChatIcon, CheckIcon,
|
||||||
} from "./components/Icons";
|
} from "./components/Icons";
|
||||||
|
|
||||||
|
|
@ -178,29 +177,7 @@ export default function Home() {
|
||||||
|
|
||||||
{/* ══════════════════════════════════════════
|
{/* ══════════════════════════════════════════
|
||||||
S3b — NACH 8 WOCHEN NIMMST DU MIT
|
S3b — NACH 8 WOCHEN NIMMST DU MIT
|
||||||
2×4 Icon-Kacheln
|
Mountain animation (ersetzt Kacheln)
|
||||||
══════════════════════════════════════════ */}
|
|
||||||
<section className="py-20 bg-white">
|
|
||||||
<div className="max-w-5xl mx-auto px-6">
|
|
||||||
<div className="text-center mb-12">
|
|
||||||
<Pill>Deine Ergebnisse</Pill>
|
|
||||||
<h2 className="mt-4 text-3xl md:text-4xl font-extrabold text-slate-900">Nach 8 Wochen nimmst du mit:</h2>
|
|
||||||
</div>
|
|
||||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-5">
|
|
||||||
<IconCard icon={<TargetIcon className="w-7 h-7 text-white" />} title="Klare Wunschkunden-Persona" sub="+ vollständiger Marketing-Audit" />
|
|
||||||
<IconCard icon={<LightbulbIcon className="w-7 h-7 text-white" />} title="Angebot auf den Punkt" sub="Positionierung in einem Satz — für alle Kanäle" />
|
|
||||||
<IconCard icon={<DocumentIcon className="w-7 h-7 text-white" />} title="Deine Verkaufsseite" sub="Vollständige Struktur — fertig zum Umsetzen" />
|
|
||||||
<IconCard icon={<CalendarIcon className="w-7 h-7 text-white" />} title="90-Tage-Marketingplan" sub="+ 2 fokussierte Kanäle entschieden" />
|
|
||||||
<IconCard icon={<PhoneIcon className="w-7 h-7 text-white" />} title="Content-Plan 4 Wochen" sub="Was, wann und warum du postest" />
|
|
||||||
<IconCard icon={<VideoCameraIcon className="w-7 h-7 text-white" />} title="Social Media Verkauf" sub="+ professionelles Video-Setup mit dem Handy" />
|
|
||||||
<IconCard icon={<HandshakeIcon className="w-7 h-7 text-white" />} title="Dein Verkaufsskript" sub="Für Direktansprache und Netzwerkveranstaltungen" />
|
|
||||||
<IconCard icon={<SearchIcon className="w-7 h-7 text-white" />} title="Google Business optimiert" sub="+ SEO-Grundlagen für deine Website" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
{/* ══════════════════════════════════════════
|
|
||||||
S4 — WAS DU BAUST (Mountain animation)
|
|
||||||
══════════════════════════════════════════ */}
|
══════════════════════════════════════════ */}
|
||||||
<MountainClimb />
|
<MountainClimb />
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue