feat(ui): refine ROI calculator for B2B lead-gen and niche traffic
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 8s
Build & Deploy / 🏗️ Build (push) Failing after 36s
Build & Deploy / 🧪 QA (push) Failing after 1m56s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s

This commit is contained in:
2026-02-22 17:04:45 +01:00
parent 38f2cc8b85
commit 498db2a42c
4 changed files with 51 additions and 33 deletions

View File

@@ -5,10 +5,10 @@ import { ComponentShareButton } from '../ComponentShareButton';
import { Reveal } from '../Reveal'; import { Reveal } from '../Reveal';
export function PerformanceROICalculator({ className = '' }: { className?: string }) { export function PerformanceROICalculator({ className = '' }: { className?: string }) {
const [traffic, setTraffic] = useState(100); // 1000 visitors/month (approx 30/day) const [traffic, setTraffic] = useState(800); // Typical niche B2B traffic
const [aov, setAov] = useState(100); // e.g. average value of a craftsman quote or small B2B service const [aov, setAov] = useState(25000); // Typical B2B project value
const [loadTime, setLoadTime] = useState(2.0); const [loadTime, setLoadTime] = useState(4.5);
const [baseConv, setBaseConv] = useState(2.0); const [baseConv, setBaseConv] = useState(2.0); // 2% Lead-Rate as default
// B2B Deloitte metric: 0.1s improvement = 8.4% conversion relative lift // B2B Deloitte metric: 0.1s improvement = 8.4% conversion relative lift
// We cap the improvement to realistic bounds (e.g. optimizing to 1.5s) // We cap the improvement to realistic bounds (e.g. optimizing to 1.5s)
@@ -32,55 +32,67 @@ export function PerformanceROICalculator({ className = '' }: { className?: strin
<div id="sim-performance-roi" className="relative bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden"> <div id="sim-performance-roi" className="relative bg-white rounded-2xl border border-slate-200 shadow-sm overflow-hidden">
<div data-share-wrapper="true" className="absolute top-4 right-4 md:opacity-0 group-hover:opacity-100 transition-opacity z-50"> <div data-share-wrapper="true" className="absolute top-4 right-4 md:opacity-0 group-hover:opacity-100 transition-opacity z-50">
<ComponentShareButton targetId="sim-performance-roi" title="Performance ROI Simulator" /> <ComponentShareButton targetId="sim-performance-roi" title="B2B Lead ROI Simulator" />
</div> </div>
<div className="p-6 md:p-8 bg-slate-50 border-b border-slate-200"> <div className="p-6 md:p-8 bg-slate-50 border-b border-slate-200">
<div className="flex items-center gap-3 mb-2"> <div className="flex items-center gap-3 mb-2">
<span className="text-2xl"></span> <span className="text-2xl"></span>
<h3 className="font-bold text-slate-900 m-0">Performance ROI für den Mittelstand</h3> <h3 className="font-bold text-slate-900 m-0">B2B Lead-Potential Kalkulator</h3>
</div> </div>
<p className="text-sm text-slate-500 m-0 leading-relaxed"> <p className="text-sm text-slate-500 m-0 leading-relaxed">
Simulieren Sie, wie sich die Ladezeit auf die Jahresumsätze Ihres Betriebs (Handwerk, Kanzlei, B2B-Service) auswirkt. Basierend auf der Branchen-Erkenntnis: Schon 0.1s schnellere Ladezeit hebt die Kontakt-Wandlungsrate um bis zu 8,4%. Für B2B-Unternehmen: Berechnen Sie, wie viele zusätzliche qualifizierte Anfragen (Leads) und Projekt-Umsätze Ihnen durch eine langsame Website entgehen.
</p> </p>
</div> </div>
<div className="grid md:grid-cols-5 divide-y md:divide-y-0 md:divide-x divide-slate-100"> <div className="grid md:grid-cols-5 divide-y md:divide-y-0 md:divide-x divide-slate-100">
{/* Inputs */} {/* Inputs */}
<div className="md:col-span-2 p-6 md:p-8 space-y-8 bg-white"> <div className="md:col-span-2 p-6 md:p-8 space-y-7 bg-white">
<div className="space-y-3"> <div className="space-y-3">
<div className="flex justify-between items-end"> <div className="flex justify-between items-end">
<label className="text-xs font-bold text-slate-400 uppercase tracking-widest">Ø Ladezeit (Sekunden)</label> <label className="text-xs font-bold text-slate-400 uppercase tracking-widest">Aktuelle Ø Ladezeit</label>
<span className="font-mono font-bold text-red-500">{loadTime.toFixed(1)}s</span> <span className="font-mono font-bold text-red-500">{loadTime.toFixed(1)}s</span>
</div> </div>
<input <input
type="range" min="1.5" max="10" step="0.1" type="range" min="1.5" max="10" step="0.1"
value={loadTime} onChange={(e) => setLoadTime(Number(e.target.value))} value={loadTime} onChange={(e) => setLoadTime(Number(e.target.value))}
className="w-full accent-slate-900" className="w-full h-1.5 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900"
/> />
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
<div className="flex justify-between items-end"> <div className="flex justify-between items-end">
<label className="text-xs font-bold text-slate-400 uppercase tracking-widest">Monatliche Besucher</label> <label className="text-xs font-bold text-slate-400 uppercase tracking-widest">Besucher / Monat</label>
<span className="font-mono font-bold text-slate-700">{traffic.toLocaleString('de-DE')}</span> <span className="font-mono font-bold text-slate-700">{traffic.toLocaleString('de-DE')}</span>
</div> </div>
<input <input
type="range" min="100" max="25000" step="100" type="range" min="100" max="5000" step="100"
value={traffic} onChange={(e) => setTraffic(Number(e.target.value))} value={traffic} onChange={(e) => setTraffic(Number(e.target.value))}
className="w-full accent-slate-900" className="w-full h-1.5 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900"
/> />
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
<div className="flex justify-between items-end"> <div className="flex justify-between items-end">
<label className="text-xs font-bold text-slate-400 uppercase tracking-widest">Ø Projektwert / Marge</label> <label className="text-xs font-bold text-slate-400 uppercase tracking-widest">Aktuelle Lead-Rate (%)</label>
<span className="font-mono font-bold text-slate-700">{baseConv.toFixed(1)}%</span>
</div>
<input
type="range" min="0.1" max="10" step="0.1"
value={baseConv} onChange={(e) => setBaseConv(Number(e.target.value))}
className="w-full h-1.5 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900"
/>
</div>
<div className="space-y-3">
<div className="flex justify-between items-end">
<label className="text-xs font-bold text-slate-400 uppercase tracking-widest">Ø Projektvolumen</label>
<span className="font-mono font-bold text-slate-700">{formatCurrency(aov)}</span> <span className="font-mono font-bold text-slate-700">{formatCurrency(aov)}</span>
</div> </div>
<input <input
type="range" min="100" max="15000" step="100" type="range" min="1000" max="250000" step="1000"
value={aov} onChange={(e) => setAov(Number(e.target.value))} value={aov} onChange={(e) => setAov(Number(e.target.value))}
className="w-full accent-slate-900" className="w-full h-1.5 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900"
/> />
</div> </div>
</div> </div>
@@ -89,29 +101,35 @@ export function PerformanceROICalculator({ className = '' }: { className?: strin
<div className="md:col-span-3 p-6 md:p-8 bg-slate-50 flex flex-col justify-center"> <div className="md:col-span-3 p-6 md:p-8 bg-slate-50 flex flex-col justify-center">
<div className="grid grid-cols-2 gap-6 mb-8"> <div className="grid grid-cols-2 gap-6 mb-8">
<div className="space-y-1"> <div className="space-y-1">
<div className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Status Quo Conv.</div> <div className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">Status Quo</div>
<div className="text-2xl font-mono text-slate-400">{baseConv.toFixed(2)}%</div> <div className="text-2xl font-mono text-slate-400">{(traffic * (baseConv / 100)).toFixed(1)} <span className="text-xs uppercase">Leads</span></div>
<div className="text-xs text-slate-400 font-mono mt-2">{formatCurrency(currentRevenue * 12)} / Jahr</div> <div className="text-[10px] text-slate-400 font-mono mt-1">pro Monat</div>
</div> </div>
<div className="space-y-1 border-l pl-6 border-slate-200"> <div className="space-y-1 border-l pl-6 border-slate-200">
<div className="text-[10px] font-bold text-green-500 uppercase tracking-widest">Ziel Konversion (1.5s)</div> <div className="text-[10px] font-bold text-emerald-500 uppercase tracking-widest">Ziel-Impact (1.5s)</div>
<div className="text-2xl font-mono font-bold text-slate-900 flex items-center gap-2"> <div className="text-2xl font-mono font-bold text-slate-900 flex items-center gap-2">
{newConv.toFixed(2)}% {(traffic * (newConv / 100)).toFixed(1)}
{relativeLiftPercentage > 0 && <span className="text-xs font-bold text-green-500 bg-green-50 px-2 py-0.5 rounded-full">+{relativeLiftPercentage.toFixed(1)}%</span>} {relativeLiftPercentage > 0 && <span className="text-[10px] font-bold text-emerald-600 bg-emerald-50 px-2 py-0.5 rounded-full">+{relativeLiftPercentage.toFixed(0)}%</span>}
</div> </div>
<div className="text-xs text-slate-600 font-mono mt-2">{formatCurrency(newRevenue * 12)} / Jahr</div> <div className="text-[10px] text-slate-500 font-mono mt-1">Leads pro Monat</div>
</div> </div>
</div> </div>
<div className="p-6 bg-slate-900 rounded-xl relative overflow-hidden"> <div className="p-6 bg-slate-900 rounded-2xl relative overflow-hidden transition-all duration-500">
<div className="absolute inset-0 opacity-[0.03] pointer-events-none" style={{ backgroundImage: "radial-gradient(#ffffff 1px, transparent 0)", backgroundSize: "15px 15px" }} /> <div className="absolute inset-0 opacity-[0.05] pointer-events-none" style={{ backgroundImage: "radial-gradient(#ffffff 1px, transparent 0)", backgroundSize: "20px 20px" }} />
<div className="relative z-10 flex flex-col md:flex-row md:items-center justify-between gap-4"> <div className="relative z-10 space-y-4">
<div> <div>
<div className="text-[10px] font-bold text-emerald-400 uppercase tracking-widest mb-1">Potenzieller Mehrumsatz / Jahr</div> <div className="text-[10px] font-bold text-emerald-400 uppercase tracking-widest mb-1">Zusätzliches Projekt-Volumen / Jahr</div>
<div className="text-xs text-slate-400">Durch {loadTime.toFixed(1)}s Ladezeit vs. Industrie-Standard (1.5s) entgangen.</div> <div className="text-xs text-slate-400">Verlorenes Potenzial durch {loadTime.toFixed(1)}s Ladezeit gegenüber einem schnellen Mintel-System.</div>
</div> </div>
<div className="text-3xl md:text-4xl font-mono font-black text-white"> <div className="flex items-end justify-between gap-4">
{additionalAnnualRevenue > 0 ? '+' : ''}{formatCurrency(additionalAnnualRevenue)} <div className="text-3xl md:text-5xl font-mono font-black text-white tracking-tight">
{additionalAnnualRevenue > 0 ? '+' : ''}{formatCurrency(additionalAnnualRevenue)}
</div>
<div className="text-right">
<div className="text-[10px] font-bold text-emerald-500 uppercase tracking-widest mb-1">Extra Leads / Jahr</div>
<div className="text-xl font-mono text-white">+{Math.round((traffic * (newConv / 100) - (traffic * (baseConv / 100))) * 12)}</div>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -12,7 +12,7 @@ import { MouseCursor } from "../components/MouseCursor";
import { Button } from "@/src/components/Button"; import { Button } from "@/src/components/Button";
import { Loader2, Check, ShieldCheck } from "lucide-react"; import { Loader2, Check, ShieldCheck } from "lucide-react";
/* eslint-disable no-unused-vars */
// Import logo using the alias setup in remotion.config.ts // Import logo using the alias setup in remotion.config.ts
import IconBlack from "@/src/assets/logo/Icon Black Transparent.svg"; import IconBlack from "@/src/assets/logo/Icon Black Transparent.svg";

View File

@@ -10,7 +10,7 @@ import {
Img, Img,
} from "remotion"; } from "remotion";
/* eslint-disable no-unused-vars */
import { MouseCursor } from "../components/MouseCursor"; import { MouseCursor } from "../components/MouseCursor";
import { ContactForm } from "@/src/components/ContactForm"; import { ContactForm } from "@/src/components/ContactForm";
import { BackgroundGrid } from "@/src/components/Layout"; import { BackgroundGrid } from "@/src/components/Layout";

View File

@@ -1,4 +1,4 @@
/* eslint-disable no-unused-vars */
import React from "react"; import React from "react";
// ULTRA-CRITICAL ANIMATION KILLER // ULTRA-CRITICAL ANIMATION KILLER