fix: mobile mountain animation + white text on dark backgrounds
- MountainClimb: mobile SVG viewport now follows the person (pan/zoom)
- MountainClimb: restored desktop SVG, removed card-only mobile fallback
- page.tsx: inline styles for all text in mc-dark-bg sections (white)
- page.tsx: remove "Nur noch 8 frei" badge
- page.tsx: fix negative copy ("kein neues Wissen") → positive umsetzungsfokus
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
9f09b4a3e7
commit
79f03d429d
2 changed files with 128 additions and 22 deletions
|
|
@ -98,6 +98,11 @@ export default function MountainClimb() {
|
||||||
const summitCardX = Math.min(Math.max(summitRawCX, 8), VW - SUMMIT_W - 8);
|
const summitCardX = Math.min(Math.max(summitRawCX, 8), VW - SUMMIT_W - 8);
|
||||||
const summitCardY = Math.max(wp.y - SUMMIT_H - 120, 4);
|
const summitCardY = Math.max(wp.y - SUMMIT_H - 120, 4);
|
||||||
|
|
||||||
|
// Mobile pan: viewport 380×440 follows the person
|
||||||
|
const MOB_W = 380, MOB_H = 440;
|
||||||
|
const mobPanX = Math.min(0, Math.max(-(VW - MOB_W), -(wp.x - MOB_W / 2)));
|
||||||
|
const mobPanY = Math.min(0, Math.max(-(VH - MOB_H), -(wp.y - Math.round(MOB_H * 0.68))));
|
||||||
|
|
||||||
const replay = () => {
|
const replay = () => {
|
||||||
started.current = true;
|
started.current = true;
|
||||||
setStep(0);
|
setStep(0);
|
||||||
|
|
@ -117,7 +122,7 @@ export default function MountainClimb() {
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ── Mountain animation (md+) ── */}
|
{/* ── Mountain animation (desktop only) ── */}
|
||||||
<div
|
<div
|
||||||
className="hidden md:block"
|
className="hidden md:block"
|
||||||
onClick={() => !atSummit && setPaused((p) => !p)}
|
onClick={() => !atSummit && setPaused((p) => !p)}
|
||||||
|
|
@ -315,20 +320,121 @@ export default function MountainClimb() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ── Mobile fallback: numbered list ── */}
|
{/* ── Mobile: same SVG, viewport follows the person ── */}
|
||||||
<div className="md:hidden space-y-3">
|
<div
|
||||||
{STEPS.map((s, i) => (
|
className="md:hidden"
|
||||||
<div key={i} className="mc-card p-4 flex items-start gap-3">
|
onClick={() => !atSummit && setPaused((p) => !p)}
|
||||||
<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">
|
style={{ cursor: atSummit ? "default" : "pointer" }}
|
||||||
{i + 1}
|
>
|
||||||
</span>
|
<svg
|
||||||
<div>
|
viewBox={`0 0 ${MOB_W} ${MOB_H}`}
|
||||||
<p className="text-slate-700 text-sm font-semibold leading-snug">{s.title}</p>
|
className="w-full rounded-2xl"
|
||||||
<p className="text-slate-500 text-xs leading-relaxed mt-0.5">{s.sub}</p>
|
style={{ display: "block", overflow: "hidden", background: "linear-gradient(160deg, #f5f4ff, #f4f7fa)" }}
|
||||||
</div>
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="mgFillMob" x1="0" y1="0" x2="0" y2="1">
|
||||||
|
<stop offset="0%" stopColor="#e0e7ff" stopOpacity="0.55" />
|
||||||
|
<stop offset="100%" stopColor="#ede9fe" stopOpacity="0.12" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
{/* Pan group — smoothly follows the person */}
|
||||||
|
<g style={{ transform: `translate(${mobPanX}px, ${mobPanY}px)`, transition: "transform 0.75s cubic-bezier(0.4,0.2,0.2,1)" }}>
|
||||||
|
|
||||||
|
{/* Mountain */}
|
||||||
|
<path d={FILL} fill="url(#mgFillMob)" />
|
||||||
|
<path d={RIDGE} fill="none" stroke="#a5b4fc" strokeWidth="2.5" strokeLinecap="round" />
|
||||||
|
|
||||||
|
{/* Dots */}
|
||||||
|
{WP.map((w, i) => (
|
||||||
|
<circle key={i} cx={w.x} cy={w.y}
|
||||||
|
r={step >= 0 && i <= step ? 5.5 : 3.5}
|
||||||
|
fill={step >= 0 && i <= step ? "#6366f1" : "#c7d2fe"}
|
||||||
|
style={{ transition: "r 0.3s, fill 0.3s" }}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Stick figure */}
|
||||||
|
{step >= 0 && (
|
||||||
|
<g
|
||||||
|
transform={`translate(${wp.x}, ${wp.y}) rotate(${wp.lean})`}
|
||||||
|
style={{ transition: "transform 0.75s cubic-bezier(0.4,0.2,0.2,1)" }}
|
||||||
|
>
|
||||||
|
<g transform="scale(3)" className={atSummit ? "mc-bounce" : ""}
|
||||||
|
style={{ transformBox: "fill-box", transformOrigin: "50% 100%" }}>
|
||||||
|
<circle cx="0" cy="-29" r="7.5" fill="none" stroke="#4f46e5" strokeWidth="0.5" />
|
||||||
|
<line x1="0" y1="-21" x2="0" y2="-3" stroke="#4f46e5" strokeWidth="0.5" strokeLinecap="round" />
|
||||||
|
<line x1="0" y1="-16" x2="-10" y2="-8" stroke="#4f46e5" strokeWidth="0.5" strokeLinecap="round" />
|
||||||
|
<line x1="0" y1="-16" x2="10" y2="-24" stroke="#4f46e5" strokeWidth="0.5" strokeLinecap="round" />
|
||||||
|
<line x1="0" y1="-3" x2="-7" y2="10" stroke="#4f46e5" strokeWidth="0.5" strokeLinecap="round" />
|
||||||
|
<line x1="0" y1="-3" x2="7" y2="10" stroke="#4f46e5" strokeWidth="0.5" strokeLinecap="round" />
|
||||||
|
{atSummit && (
|
||||||
|
<g className="mc-fade-in" transform="translate(9, -25)">
|
||||||
|
<line x1="0" y1="0" x2="0" y2="-22" stroke="#6366f1" strokeWidth="0.5" strokeLinecap="round" />
|
||||||
|
<polygon points="0,-22 18,-15 0,-8" fill="#6366f1" />
|
||||||
|
</g>
|
||||||
|
)}
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Step card */}
|
||||||
|
{step >= 0 && !atSummit && (
|
||||||
|
<>
|
||||||
|
<line x1={cardX + CARD_W / 2} y1={cardY + CARD_H} x2={wp.x} y2={wp.y - 90}
|
||||||
|
stroke="#c7d2fe" strokeWidth="1" strokeDasharray="4 3" />
|
||||||
|
<foreignObject key={step} x={cardX} y={cardY} width={CARD_W} height={CARD_H}
|
||||||
|
className="mc-fade-in" style={{ overflow: "visible" }}>
|
||||||
|
<div className="bg-white rounded-xl border border-indigo-100 shadow-lg" style={{ padding: "10px 12px" }}>
|
||||||
|
<div style={{ fontSize: "9px", fontWeight: 800, letterSpacing: "0.12em", textTransform: "uppercase", color: "#6366f1", marginBottom: "4px" }}>
|
||||||
|
Schritt {step + 1} / {STEPS.length}
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: "13px", color: "#0f172a", fontWeight: 700, lineHeight: 1.3, marginBottom: "4px" }}>
|
||||||
|
{STEPS[step].title}
|
||||||
|
</div>
|
||||||
|
<div style={{ fontSize: "11px", color: "#64748b", lineHeight: 1.4 }}>
|
||||||
|
{STEPS[step].sub}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</foreignObject>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Summit 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-mob" 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>
|
||||||
|
</foreignObject>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{/* Hints */}
|
||||||
|
{step >= 0 && !atSummit && (
|
||||||
|
<p className="text-center text-xs text-slate-400 mt-2 select-none">
|
||||||
|
{paused ? "▶ Tippen zum Fortsetzen" : "⏸ Tippen zum Pausieren"}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
{atSummit && (
|
||||||
|
<div className="text-center mt-3">
|
||||||
|
<button onClick={replay} className="text-sm text-indigo-600 border border-indigo-200 rounded-full px-5 py-2 hover:bg-indigo-50 transition-colors">
|
||||||
|
Nochmal ansehen ↺
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ export default function Home() {
|
||||||
<div className="flex flex-col items-center gap-4">
|
<div className="flex flex-col items-center gap-4">
|
||||||
<Btn xl>Meinen Platz sichern →</Btn>
|
<Btn xl>Meinen Platz sichern →</Btn>
|
||||||
<p className="text-sm text-slate-500">
|
<p className="text-sm text-slate-500">
|
||||||
Exklusive Kleingruppe · Maximal 10 Plätze · Nur noch 8 frei
|
Exklusive Kleingruppe · Maximal 10 Plätze
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -157,7 +157,7 @@ export default function Home() {
|
||||||
Das <strong className="text-slate-900">8-Wochen Kundengewinnungs-System</strong> macht genau das: Marketing, Vertrieb und Social Media — in einem System, das Woche für Woche aufgebaut wird.
|
Das <strong className="text-slate-900">8-Wochen Kundengewinnungs-System</strong> macht genau das: Marketing, Vertrieb und Social Media — in einem System, das Woche für Woche aufgebaut wird.
|
||||||
</p>
|
</p>
|
||||||
<p className="text-slate-800 font-semibold text-lg leading-relaxed">
|
<p className="text-slate-800 font-semibold text-lg leading-relaxed">
|
||||||
Du baust kein neues Wissen auf. Du nimmst alles was du hast — und bringst es in eine Struktur, die planbar die richtigen Kunden anzieht.
|
Kein Theorie-Overload. Du nimmst alles was du hast — und setzt es endlich in eine Struktur um, die planbar die richtigen Kunden anzieht.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -167,10 +167,10 @@ export default function Home() {
|
||||||
══════════════════════════════════════════ */}
|
══════════════════════════════════════════ */}
|
||||||
<section className="mc-dark-bg py-16 text-center">
|
<section className="mc-dark-bg py-16 text-center">
|
||||||
<div className="max-w-2xl mx-auto px-6 space-y-5">
|
<div className="max-w-2xl mx-auto px-6 space-y-5">
|
||||||
<h2 className="text-2xl md:text-3xl font-extrabold text-white">
|
<h2 className="text-2xl md:text-3xl font-extrabold" style={{ color: "#ffffff" }}>
|
||||||
Nur noch <span className="bg-gradient-to-r from-indigo-400 to-violet-400 bg-clip-text text-transparent">8 Plätze</span> verfügbar.
|
Sichere dir jetzt deinen Platz.
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-slate-400">Start: 1. Juli 2027 · Pilotpreis: 500 € (statt 3.000 €)</p>
|
<p style={{ color: "#e2e8f0" }}>Start: 1. Juli 2027 · Pilotpreis: 500 € (statt 3.000 €)</p>
|
||||||
<Btn xl>Meinen Platz sichern →</Btn>
|
<Btn xl>Meinen Platz sichern →</Btn>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -410,20 +410,20 @@ export default function Home() {
|
||||||
══════════════════════════════════════════ */}
|
══════════════════════════════════════════ */}
|
||||||
<section className="mc-dark-bg py-24 text-center">
|
<section className="mc-dark-bg py-24 text-center">
|
||||||
<div className="max-w-2xl mx-auto px-6 space-y-7">
|
<div className="max-w-2xl mx-auto px-6 space-y-7">
|
||||||
<h2 className="text-3xl md:text-5xl font-extrabold text-white leading-tight">
|
<h2 className="text-3xl md:text-5xl font-extrabold leading-tight" style={{ color: "#ffffff" }}>
|
||||||
Dein Wissen ist da.{" "}
|
Dein Wissen ist da.{" "}
|
||||||
<span className="bg-gradient-to-r from-indigo-400 to-violet-400 bg-clip-text text-transparent">
|
<span className="bg-gradient-to-r from-indigo-400 to-violet-400 bg-clip-text text-transparent">
|
||||||
Jetzt bekommt es die Struktur die Kunden bringt.
|
Jetzt bekommt es die Struktur die Kunden bringt.
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-slate-400">Maximal 10 Plätze · Start: 1. Juli 2027</p>
|
<p style={{ color: "#e2e8f0" }}>Maximal 10 Plätze · Start: 1. Juli 2027</p>
|
||||||
<Btn xl>Meinen Platz sichern →</Btn>
|
<Btn xl>Meinen Platz sichern →</Btn>
|
||||||
<p className="text-sm text-slate-500">Ein kurzes Gespräch — du entscheidest danach.</p>
|
<p className="text-sm" style={{ color: "#cbd5e1" }}>Ein kurzes Gespräch — du entscheidest danach.</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{/* FOOTER */}
|
{/* FOOTER */}
|
||||||
<footer className="mc-nav-bg py-8 text-center text-slate-400 text-xs">
|
<footer className="mc-nav-bg py-8 text-center text-xs" style={{ color: "#cbd5e1" }}>
|
||||||
© 2026 Market Compass · Katja Pestereva
|
© 2026 Market Compass · Katja Pestereva
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue