React · TypeScript · Vercel Serverless

MDV Interiors

Vollständige Service-Website für einen Wohnungsvorbereitungs-Dienstleister — mit GSAP-Animationsengine, Lenis Smooth Scroll, 3D-Tilt Pricing-Cards, animiertem Preiszähler und Node.js Serverless-Backend auf Vercel.

Live · mdv-interiors.de · Hero Section
MDV Interiors Hero
▲ Ausgangslage

Greenfield-Projekt. Kein bestehendes Design, kein Template, keine Vorlage — kompletter Aufbau von Null: Architekturentscheidungen, Design System, Komponenten-Struktur, Backend und Deployment vollständig selbst konzipiert und umgesetzt.

✓ Umsetzung

Kompletter Rebuild mit React 19 + TypeScript: GSAP ScrollTrigger über Custom Hook, Lenis Smooth Scroll in GSAP Ticker integriert, 3D-Tilt auf Pricing-Cards via CSS Custom Properties, Vercel Serverless Functions für E-Mail und Quote-Kalkulation mit Rate Limiting.

GSAP + Lenis Engine
Custom useScrollReveal Hook mit Stagger-Support und prefers-reduced-motion. Lenis läuft im GSAP Ticker — perfekt synchronisiertes Smooth Scroll.
ScrollTrigger staggerChildren once: true
💳
3D Pricing Cards
Mousemove-Tracking setzt CSS Custom Properties --rx/--ry für GPU-beschleunigten 3D-Tilt. GSAP tweent den Reset auf Leave. Animierter Preiszähler bei Tier-Wechsel.
perspective(800px) gsap.to()
🔧
Serverless Node.js API
Zwei Vercel Functions: api/send.ts (E-Mail via Resend + Bestätigung) und api/quote.ts (serverseitige Preiskalkulation mit Rate Limiting + Logging).
Resend rate-limit structured log
Pricing Section · Flächenstaffel interaktiv · Preis animiert bei Wechsel
MDV Interiors Pricing
Custom Hook + Rate-Limited API

Wiederverwendbarer Scroll-Animation-Hook und ein serverseitiger Quote-Calculator mit In-Memory Rate Limiting — keine externen Dependencies.

React Hook useScrollReveal.ts
export function useScrollReveal<T>( opts: Options = {} ) { const ref = useRef<T>(null) useEffect(() => { const el = ref.current if (!el || prefersReduced()) return const { y=36, staggerChildren, staggerDelay=0.08 } = opts const ctx = gsap.context(() => { if (staggerChildren) { gsap.fromTo(el.children, { y, opacity: 0 }, { y:0, opacity:1, stagger: staggerDelay, scrollTrigger: { trigger: el, start: 'top 88%', once: true } }) } }, el) return () => ctx.revert() }, []) return ref }
Serverless API api/quote.ts
// In-Memory Rate Limiter const rateMap = new Map<string, { count: number; resetAt: number }>() function checkLimit(ip: string): boolean { const now = Date.now() const e = rateMap.get(ip) if (!e || now > e.resetAt) { rateMap.set(ip, { count: 1, resetAt: now + 60_000 }) return true } if (e.count >= 20) return false e.count++ return true } // POST { tier, squareMeters } → // { net, vatAmount, gross, note }

Architektur-Entscheidung: Preisberechnung läuft serverseitig in api/quote.ts — nicht im Client-Bundle. Das verhindert Manipulation und hält die Business-Logik zentral wartbar. Rate Limiting (20 req/min/IP) schützt ohne externe Redis-Dependency.

375KB
JS Bundle (gzip: 124 KB) — inkl. GSAP + Lenis
1.0s
Produktions-Build-Zeit (Vite 8 + tsc -b)
8+
Sections mit Scroll-Reveal-Animationen
2×
Vercel Serverless Endpoints (Email + Quote)